提交 15cac63b 编写于 作者: H Heejae Chang

fix merge conflict upstream/master

...@@ -10,6 +10,12 @@ REM internal repositories. ...@@ -10,6 +10,12 @@ REM internal repositories.
set RoslynSolution=%1 set RoslynSolution=%1
if "%RoslynSolution%" == "" set RoslynSolution=%~dp0Roslyn.sln if "%RoslynSolution%" == "" set RoslynSolution=%~dp0Roslyn.sln
echo Deleting project.lock.json files
pushd "%~dp0src"
echo "Dummy lock file to avoid error when there is no project.lock.json file" > project.lock.json
del /s /q project.lock.json
popd
echo Restoring packages: Toolsets echo Restoring packages: Toolsets
call %NugetExe% restore "%~dp0build\ToolsetPackages\project.json" %NuGetAdditionalCommandLineArgs% || goto :RestoreFailed call %NugetExe% restore "%~dp0build\ToolsetPackages\project.json" %NuGetAdditionalCommandLineArgs% || goto :RestoreFailed
......
...@@ -8,7 +8,8 @@ export HOME=$(cd ~ && pwd) ...@@ -8,7 +8,8 @@ export HOME=$(cd ~ && pwd)
# NuGet often exceeds the limit of open files on Mac # NuGet often exceeds the limit of open files on Mac
# https://github.com/NuGet/Home/issues/2163 # https://github.com/NuGet/Home/issues/2163
if [ "$(uname -s)" == "Darwin" ] OS=$(uname -s)
if [ "$OS" == "Darwin" || "$OS" == "Linux" ]
then then
ulimit -n 6500 ulimit -n 6500
fi fi
......
...@@ -13,7 +13,7 @@ This document reflects the status, and planned work, for the compiler team. It ...@@ -13,7 +13,7 @@ This document reflects the status, and planned work, for the compiler team. It
| [Local Functions](https://github.com/dotnet/roslyn/blob/future/docs/features/local-functions.md) | [future](https://github.com/dotnet/roslyn/tree/future) | Finishing | [agocke](https://github.com/agocke), [jaredpar](https://github.com/jaredpar), [vsadov](https://github.com/vsadov) | [gafter](https://github.com/gafter) | | [Local Functions](https://github.com/dotnet/roslyn/blob/future/docs/features/local-functions.md) | [future](https://github.com/dotnet/roslyn/tree/future) | Finishing | [agocke](https://github.com/agocke), [jaredpar](https://github.com/jaredpar), [vsadov](https://github.com/vsadov) | [gafter](https://github.com/gafter) |
| [Pattern Matching](https://github.com/dotnet/roslyn/blob/future/docs/features/patterns.md) | [features/patterns](https://github.com/dotnet/roslyn/tree/features/patterns) | Prototyping | [gafter](https://github.com/gafter), [alekseyts](https://github.com/alekseyts), [agocke](https://github.com/agocke) | [gafter](https://github.com/gafter) | | [Pattern Matching](https://github.com/dotnet/roslyn/blob/future/docs/features/patterns.md) | [features/patterns](https://github.com/dotnet/roslyn/tree/features/patterns) | Prototyping | [gafter](https://github.com/gafter), [alekseyts](https://github.com/alekseyts), [agocke](https://github.com/agocke) | [gafter](https://github.com/gafter) |
| [Ref Returns](https://github.com/dotnet/roslyn/issues/118) | [future](https://github.com/dotnet/roslyn/tree/future) | Finishing | [vsadov](https://github.com/vsadov), [agocke](https://github.com/agocke), [jaredpar](https://github.com/jaredpar) | [vsadov](https://github.com/vsadov) | | [Ref Returns](https://github.com/dotnet/roslyn/issues/118) | [future](https://github.com/dotnet/roslyn/tree/future) | Finishing | [vsadov](https://github.com/vsadov), [agocke](https://github.com/agocke), [jaredpar](https://github.com/jaredpar) | [vsadov](https://github.com/vsadov) |
| Source Generation | [future](https://github.com/dotnet/roslyn/tree/features/generators) | Prototyping | [cston](https://github.com/cston), [vsadov](https://github.com/vsadov) | [mattwar](https://github.com/mattwar) | | [Source Generators](https://github.com/dotnet/roslyn/blob/features/generators/docs/features/generators.md) | [future](https://github.com/dotnet/roslyn/tree/features/generators) | Prototyping | [cston](https://github.com/cston), [agocke](https://github.com/agocke), [vsadov](https://github.com/vsadov) | [mattwar](https://github.com/mattwar) |
| [Throw Expr](https://github.com/dotnet/roslyn/blob/future/docs/features/patterns.md) | [features/patterns](https://github.com/dotnet/roslyn/tree/features/patterns) | Prototyping | [agocke](https://github.com/agocke), [tyoverby](https://github.com/tyoverby), [gafter](https://github.com/gafter) | [gafter](https://github.com/gafter) | | [Throw Expr](https://github.com/dotnet/roslyn/blob/future/docs/features/patterns.md) | [features/patterns](https://github.com/dotnet/roslyn/tree/features/patterns) | Prototyping | [agocke](https://github.com/agocke), [tyoverby](https://github.com/tyoverby), [gafter](https://github.com/gafter) | [gafter](https://github.com/gafter) |
| [Tuples](https://github.com/dotnet/roslyn/issues/347) | [features/tuples](https://github.com/dotnet/roslyn/tree/features/tuples) | Prototyping | [vsadov](https://github.com/vsadov), [jcouv](https://github.com/jcouv) | [madstorgerson](https://github.com/MadsTorgersen) | | [Tuples](https://github.com/dotnet/roslyn/issues/347) | [features/tuples](https://github.com/dotnet/roslyn/tree/features/tuples) | Prototyping | [vsadov](https://github.com/vsadov), [jcouv](https://github.com/jcouv) | [madstorgerson](https://github.com/MadsTorgersen) |
| [Out var](https://github.com/dotnet/roslyn/issues/6183) | none | Feature Specification | [alekseyts](https://github.com/alekseyts) | [gafter](https://github.com/gafter) | | [Out var](https://github.com/dotnet/roslyn/issues/6183) | none | Feature Specification | [alekseyts](https://github.com/alekseyts) | [gafter](https://github.com/gafter) |
......
The CI restore works by downloading the contents of the packages directory from Azure directly. Hence if a package is updated this zip will need to be rebuilt.
This is done by executing the following on a Windows box.
- Change to the root of the enlistment.
- delete the contents of the `~\.nuget\packages`
- Run Restore.cmd
- Zip the `~\.nuget` directory (via explorer) and name it nuget.X.zip (where X is one higher than the previous number)
- Use [azcopy](https://azure.microsoft.com/en-us/documentation/articles/storage-use-azcopy) to upload to https://dotnetci.blob.core.windows.net/roslyn
- Change cibuild.sh and cibuild.cmd to reference the new package.
...@@ -17,6 +17,18 @@ static void addEmailPublisher(def myJob) { ...@@ -17,6 +17,18 @@ static void addEmailPublisher(def myJob) {
} }
} }
// Calls a web hook on Jenkins build events. Allows our build monitoring jobs to be push notified
// vs. polling
static void addBuildEventWebHook(def myJob) {
myJob.with {
notifications {
endpoint('https://jaredpar.azurewebsites.net/api/BuildEvent?code=tts2pvyelahoiliwu7lo6flxr8ps9kaip4hyr4m0ofa3o3l3di77tzcdpk22kf9gex5m6cbrcnmi') {
event('all')
}
}
}
}
// Generates the standard trigger phrases. This is the regex which ends up matching lines like: // Generates the standard trigger phrases. This is the regex which ends up matching lines like:
// test win32 please // test win32 please
static String generateTriggerPhrase(String jobName, String opsysName, String triggerKeyword = 'this') { static String generateTriggerPhrase(String jobName, String opsysName, String triggerKeyword = 'this') {
...@@ -42,6 +54,8 @@ static void addRoslynJob(def myJob, String jobName, String branchName, String tr ...@@ -42,6 +54,8 @@ static void addRoslynJob(def myJob, String jobName, String branchName, String tr
Utilities.addGithubPushTrigger(myJob) Utilities.addGithubPushTrigger(myJob)
addEmailPublisher(myJob) addEmailPublisher(myJob)
} }
addBuildEventWebHook(myJob)
} }
def branchNames = [] def branchNames = []
......
...@@ -16,6 +16,8 @@ internal sealed partial class BinderFactory ...@@ -16,6 +16,8 @@ internal sealed partial class BinderFactory
private sealed class BinderFactoryVisitor : CSharpSyntaxVisitor<Binder> private sealed class BinderFactoryVisitor : CSharpSyntaxVisitor<Binder>
{ {
private int _position; private int _position;
private CSharpSyntaxNode _memberDeclarationOpt;
private Symbol _memberOpt;
private readonly BinderFactory _factory; private readonly BinderFactory _factory;
internal BinderFactoryVisitor(BinderFactory factory) internal BinderFactoryVisitor(BinderFactory factory)
...@@ -23,12 +25,13 @@ internal BinderFactoryVisitor(BinderFactory factory) ...@@ -23,12 +25,13 @@ internal BinderFactoryVisitor(BinderFactory factory)
_factory = factory; _factory = factory;
} }
internal int Position internal void Initialize(int position, CSharpSyntaxNode memberDeclarationOpt, Symbol memberOpt)
{ {
set Debug.Assert((memberDeclarationOpt == null) == (memberOpt == null));
{
_position = value; _position = position;
} _memberDeclarationOpt = memberDeclarationOpt;
_memberOpt = memberOpt;
} }
private CSharpCompilation compilation private CSharpCompilation compilation
...@@ -449,6 +452,11 @@ private static string GetPropertyOrEventName(BasePropertyDeclarationSyntax baseP ...@@ -449,6 +452,11 @@ private static string GetPropertyOrEventName(BasePropertyDeclarationSyntax baseP
// Get the correct methods symbol within container that corresponds to the given method syntax. // Get the correct methods symbol within container that corresponds to the given method syntax.
private SourceMethodSymbol GetMethodSymbol(BaseMethodDeclarationSyntax baseMethodDeclarationSyntax, Binder outerBinder) private SourceMethodSymbol GetMethodSymbol(BaseMethodDeclarationSyntax baseMethodDeclarationSyntax, Binder outerBinder)
{ {
if (baseMethodDeclarationSyntax == _memberDeclarationOpt)
{
return (SourceMethodSymbol)_memberOpt;
}
NamedTypeSymbol container = GetContainerType(outerBinder, baseMethodDeclarationSyntax); NamedTypeSymbol container = GetContainerType(outerBinder, baseMethodDeclarationSyntax);
if ((object)container == null) if ((object)container == null)
{ {
...@@ -461,6 +469,11 @@ private SourceMethodSymbol GetMethodSymbol(BaseMethodDeclarationSyntax baseMetho ...@@ -461,6 +469,11 @@ private SourceMethodSymbol GetMethodSymbol(BaseMethodDeclarationSyntax baseMetho
private SourcePropertySymbol GetPropertySymbol(BasePropertyDeclarationSyntax basePropertyDeclarationSyntax, Binder outerBinder) private SourcePropertySymbol GetPropertySymbol(BasePropertyDeclarationSyntax basePropertyDeclarationSyntax, Binder outerBinder)
{ {
if (basePropertyDeclarationSyntax == _memberDeclarationOpt)
{
return (SourcePropertySymbol)_memberOpt;
}
Debug.Assert(basePropertyDeclarationSyntax.Kind() == SyntaxKind.PropertyDeclaration || basePropertyDeclarationSyntax.Kind() == SyntaxKind.IndexerDeclaration); Debug.Assert(basePropertyDeclarationSyntax.Kind() == SyntaxKind.PropertyDeclaration || basePropertyDeclarationSyntax.Kind() == SyntaxKind.IndexerDeclaration);
NamedTypeSymbol container = GetContainerType(outerBinder, basePropertyDeclarationSyntax); NamedTypeSymbol container = GetContainerType(outerBinder, basePropertyDeclarationSyntax);
...@@ -475,6 +488,11 @@ private SourcePropertySymbol GetPropertySymbol(BasePropertyDeclarationSyntax bas ...@@ -475,6 +488,11 @@ private SourcePropertySymbol GetPropertySymbol(BasePropertyDeclarationSyntax bas
private SourceEventSymbol GetEventSymbol(EventDeclarationSyntax eventDeclarationSyntax, Binder outerBinder) private SourceEventSymbol GetEventSymbol(EventDeclarationSyntax eventDeclarationSyntax, Binder outerBinder)
{ {
if (eventDeclarationSyntax == _memberDeclarationOpt)
{
return (SourceEventSymbol)_memberOpt;
}
NamedTypeSymbol container = GetContainerType(outerBinder, eventDeclarationSyntax); NamedTypeSymbol container = GetContainerType(outerBinder, eventDeclarationSyntax);
if ((object)container == null) if ((object)container == null)
{ {
......
...@@ -87,34 +87,38 @@ private bool InScript ...@@ -87,34 +87,38 @@ private bool InScript
} }
/// <summary> /// <summary>
/// Note, there is no guarantee that the factory always gives back the same binder instance for the same <param name="node"/>. /// Return binder for binding at node.
/// <paramref name="memberDeclarationOpt"/> and <paramref name="memberOpt"/>
/// are optional syntax and symbol for the member containing <paramref name="node"/>.
/// If provided, the <see cref="BinderFactoryVisitor"/> will use the member symbol rather
/// than looking up the member in the containing type, allowing this method to be called
/// while calculating the member list.
/// </summary> /// </summary>
internal Binder GetBinder(CSharpSyntaxNode node) /// <remarks>
/// Note, there is no guarantee that the factory always gives back the same binder instance for the same node.
/// </remarks>
internal Binder GetBinder(CSharpSyntaxNode node, CSharpSyntaxNode memberDeclarationOpt = null, Symbol memberOpt = null)
{ {
int position = node.SpanStart; int position = node.SpanStart;
// Special case: In interactive code, we may be trying to retrieve a binder for global statements // Unless this is interactive retrieving a binder for global statements
// at the *very* top-level (i.e. in a completely empty file). In this case, we use the compilation unit // at the very top-level (i.e. in a completely empty file) use
// directly since it's parent would be null. // node.Parent to maintain existing behavior.
if (InScript && node.Kind() == SyntaxKind.CompilationUnit) if (!InScript || node.Kind() != SyntaxKind.CompilationUnit)
{ {
return GetBinder(node, position); node = node.Parent;
} }
// ACASEY: Using node.Parent here to maintain existing behavior, return GetBinder(node, position, memberDeclarationOpt, memberOpt);
// but I have no idea why.
return GetBinder(node.Parent, position);
} }
internal Binder GetBinder(CSharpSyntaxNode node, int position) internal Binder GetBinder(CSharpSyntaxNode node, int position, CSharpSyntaxNode memberDeclarationOpt = null, Symbol memberOpt = null)
{ {
Debug.Assert(node != null); Debug.Assert(node != null);
Binder result = null;
BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate(); BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate();
visitor.Position = position; visitor.Initialize(position, memberDeclarationOpt, memberOpt);
result = node.Accept(visitor); Binder result = node.Accept(visitor);
_binderFactoryVisitorPool.Free(visitor); _binderFactoryVisitorPool.Free(visitor);
return result; return result;
...@@ -135,7 +139,7 @@ internal InContainerBinder GetImportsBinder(CSharpSyntaxNode unit, bool inUsing ...@@ -135,7 +139,7 @@ internal InContainerBinder GetImportsBinder(CSharpSyntaxNode unit, bool inUsing
case SyntaxKind.NamespaceDeclaration: case SyntaxKind.NamespaceDeclaration:
{ {
BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate(); BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate();
visitor.Position = 0; visitor.Initialize(0, null, null);
var result = visitor.VisitNamespaceDeclaration((NamespaceDeclarationSyntax)unit, unit.SpanStart, inBody: true, inUsing: inUsing); var result = visitor.VisitNamespaceDeclaration((NamespaceDeclarationSyntax)unit, unit.SpanStart, inBody: true, inUsing: inUsing);
_binderFactoryVisitorPool.Free(visitor); _binderFactoryVisitorPool.Free(visitor);
return result; return result;
...@@ -145,7 +149,7 @@ internal InContainerBinder GetImportsBinder(CSharpSyntaxNode unit, bool inUsing ...@@ -145,7 +149,7 @@ internal InContainerBinder GetImportsBinder(CSharpSyntaxNode unit, bool inUsing
// imports are bound by the Script class binder: // imports are bound by the Script class binder:
{ {
BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate(); BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate();
visitor.Position = 0; visitor.Initialize(0, null, null);
var result = visitor.VisitCompilationUnit((CompilationUnitSyntax)unit, inUsing: inUsing, inScript: InScript); var result = visitor.VisitCompilationUnit((CompilationUnitSyntax)unit, inUsing: inUsing, inScript: InScript);
_binderFactoryVisitorPool.Free(visitor); _binderFactoryVisitorPool.Free(visitor);
return result; return result;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities; using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols namespace Microsoft.CodeAnalysis.CSharp.Symbols
{ {
internal static class BaseTypeAnalysis internal static class BaseTypeAnalysis
{ {
// let's keep up to 16 hashsets so that we do not need to allocate them over and over. internal static bool ClassDependsOn(NamedTypeSymbol depends, NamedTypeSymbol on)
// we do not allocate hashsets recursively, so even for big hierarchies, one hashset is sufficient
// We may need more than one in a case of running this analysis concurrently, so we will keep up to 16
// which seems plenty for this scenario.
private static readonly ObjectPool<HashSet<Symbol>> s_hsPool =
new ObjectPool<HashSet<Symbol>>(() => new HashSet<Symbol>(ReferenceEqualityComparer.Instance), 16);
internal static bool ClassDependsOn(TypeSymbol depends, TypeSymbol on)
{ {
if ((object)depends == null || (object)on == null) Debug.Assert((object)depends != null);
{ Debug.Assert((object)on != null);
return false; Debug.Assert(on.IsDefinition);
}
var hs = s_hsPool.Allocate(); var hs = PooledHashSet<Symbol>.GetInstance();
ClassDependsClosure(depends, depends.DeclaringCompilation, hs); ClassDependsClosure(depends, depends.DeclaringCompilation, hs);
var result = hs.Contains(on.OriginalDefinition); var result = hs.Contains(on);
hs.Clear(); hs.Free();
s_hsPool.Free(hs);
return result; return result;
} }
private static void ClassDependsClosure(TypeSymbol type, CSharpCompilation currentCompilation, HashSet<Symbol> partialClosure) private static void ClassDependsClosure(NamedTypeSymbol type, CSharpCompilation currentCompilation, HashSet<Symbol> partialClosure)
{ {
if ((object)type == null) if ((object)type == null)
{ {
return; return;
} }
var namedType = type.OriginalDefinition as NamedTypeSymbol; type = type.OriginalDefinition;
if ((object)namedType != null && partialClosure.Add(namedType)) if (partialClosure.Add(type))
{ {
ClassDependsClosure(namedType.GetDeclaredBaseType(null), currentCompilation, partialClosure); ClassDependsClosure(type.GetDeclaredBaseType(null), currentCompilation, partialClosure);
// containment is interesting only for the current compilation // containment is interesting only for the current compilation
if (currentCompilation != null && namedType.IsFromCompilation(currentCompilation)) if (currentCompilation != null && type.IsFromCompilation(currentCompilation))
{ {
ClassDependsClosure(namedType.ContainingType, currentCompilation, partialClosure); ClassDependsClosure(type.ContainingType, currentCompilation, partialClosure);
} }
} }
} }
internal static bool StructDependsOn(TypeSymbol depends, NamedTypeSymbol on) internal static bool StructDependsOn(NamedTypeSymbol depends, NamedTypeSymbol on)
{ {
if ((object)depends == null || (object)on == null) Debug.Assert((object)depends != null);
{ Debug.Assert((object)on != null);
return false; Debug.Assert(on.IsDefinition);
}
var hs = s_hsPool.Allocate(); var hs = PooledHashSet<Symbol>.GetInstance();
StructDependsClosure(depends, hs, on); StructDependsClosure(depends, hs, on);
var result = hs.Contains(on); var result = hs.Contains(on);
hs.Clear(); hs.Free();
s_hsPool.Free(hs);
return result; return result;
} }
private static void StructDependsClosure(TypeSymbol type, HashSet<Symbol> partialClosure, NamedTypeSymbol on) private static void StructDependsClosure(NamedTypeSymbol type, HashSet<Symbol> partialClosure, NamedTypeSymbol on)
{ {
if ((object)type == null) Debug.Assert((object)type != null);
{
return;
}
var nt = type as NamedTypeSymbol; if ((object)type.OriginalDefinition == on)
if ((object)nt != null && ReferenceEquals(nt.OriginalDefinition, on))
{ {
// found a possibly expanding cycle, for example // found a possibly expanding cycle, for example
// struct X<T> { public T t; } // struct X<T> { public T t; }
...@@ -90,7 +72,8 @@ private static void StructDependsClosure(TypeSymbol type, HashSet<Symbol> partia ...@@ -90,7 +72,8 @@ private static void StructDependsClosure(TypeSymbol type, HashSet<Symbol> partia
partialClosure.Add(on); partialClosure.Add(on);
return; return;
} }
if ((object)nt != null && partialClosure.Add(nt))
if (partialClosure.Add(type))
{ {
foreach (var member in type.GetMembersUnordered()) foreach (var member in type.GetMembersUnordered())
{ {
...@@ -100,7 +83,7 @@ private static void StructDependsClosure(TypeSymbol type, HashSet<Symbol> partia ...@@ -100,7 +83,7 @@ private static void StructDependsClosure(TypeSymbol type, HashSet<Symbol> partia
continue; continue;
} }
StructDependsClosure(field.Type, partialClosure, on); StructDependsClosure((NamedTypeSymbol)field.Type, partialClosure, on);
} }
} }
} }
...@@ -134,41 +117,36 @@ internal static bool IsManagedType(NamedTypeSymbol type) ...@@ -134,41 +117,36 @@ internal static bool IsManagedType(NamedTypeSymbol type)
} }
// Otherwise, we have to build and inspect the closure of depended-upon types. // Otherwise, we have to build and inspect the closure of depended-upon types.
HashSet<Symbol> closure = s_hsPool.Allocate(); var hs = PooledHashSet<Symbol>.GetInstance();
bool result = DependsOnDefinitelyManagedType(type, closure); bool result = DependsOnDefinitelyManagedType(type, hs);
closure.Clear(); hs.Free();
s_hsPool.Free(closure);
return result; return result;
} }
private static bool DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet<Symbol> partialClosure) private static bool DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet<Symbol> partialClosure)
{ {
Debug.Assert(!ReferenceEquals(type, null)); Debug.Assert((object)type != null);
// NOTE: unlike in StructDependsClosure, we don't have to check for expanding cycles, // NOTE: unlike in StructDependsClosure, we don't have to check for expanding cycles,
// because as soon as we see something with non-zero arity we kick out (generic => managed). // because as soon as we see something with non-zero arity we kick out (generic => managed).
if (partialClosure.Add(type)) if (partialClosure.Add(type))
{ {
foreach (var member in type.GetMembersUnordered()) foreach (var member in type.GetInstanceFieldsAndEvents())
{ {
// Only instance fields (including field-like events) affect the outcome. // Only instance fields (including field-like events) affect the outcome.
if (member.IsStatic) FieldSymbol field;
{
continue;
}
FieldSymbol field = null;
switch (member.Kind) switch (member.Kind)
{ {
case SymbolKind.Field: case SymbolKind.Field:
field = (FieldSymbol)member; field = (FieldSymbol)member;
Debug.Assert(ReferenceEquals(field.AssociatedSymbol as EventSymbol, null), Debug.Assert((object)(field.AssociatedSymbol as EventSymbol) == null,
"Didn't expect to find a field-like event backing field in the member list."); "Didn't expect to find a field-like event backing field in the member list.");
break; break;
case SymbolKind.Event: case SymbolKind.Event:
field = ((EventSymbol)member).AssociatedField; field = ((EventSymbol)member).AssociatedField;
break; break;
default:
throw ExceptionUtilities.UnexpectedValue(member.Kind);
} }
if ((object)field == null) if ((object)field == null)
...@@ -275,29 +253,27 @@ private static ThreeState IsManagedTypeHelper(NamedTypeSymbol type) ...@@ -275,29 +253,27 @@ private static ThreeState IsManagedTypeHelper(NamedTypeSymbol type)
} }
} }
internal static bool InterfaceDependsOn(TypeSymbol depends, TypeSymbol on) internal static bool InterfaceDependsOn(NamedTypeSymbol depends, NamedTypeSymbol on)
{ {
if ((object)depends == null || (object)on == null) Debug.Assert((object)depends != null);
{ Debug.Assert((object)on != null);
return false; Debug.Assert(on.IsDefinition);
}
var hs = s_hsPool.Allocate(); var hs = PooledHashSet<Symbol>.GetInstance();
InterfaceDependsClosure(depends, hs); InterfaceDependsClosure(depends, hs);
var result = hs.Contains(on.OriginalDefinition); var result = hs.Contains(on);
hs.Clear(); hs.Free();
s_hsPool.Free(hs);
return result; return result;
} }
private static void InterfaceDependsClosure(TypeSymbol type, HashSet<Symbol> partialClosure) private static void InterfaceDependsClosure(NamedTypeSymbol type, HashSet<Symbol> partialClosure)
{ {
var nt = type.OriginalDefinition as NamedTypeSymbol; type = type.OriginalDefinition;
if ((object)nt != null && partialClosure.Add(nt)) if (partialClosure.Add(type))
{ {
foreach (var bt in nt.GetDeclaredInterfaces(null)) foreach (var bt in type.GetDeclaredInterfaces(null))
{ {
InterfaceDependsClosure(bt, partialClosure); InterfaceDependsClosure(bt, partialClosure);
// containment is not interesting for interfaces as they cannot nest in C# // containment is not interesting for interfaces as they cannot nest in C#
......
...@@ -561,6 +561,32 @@ internal virtual ImmutableArray<Symbol> GetSimpleNonTypeMembers(string name) ...@@ -561,6 +561,32 @@ internal virtual ImmutableArray<Symbol> GetSimpleNonTypeMembers(string name)
/// returns an empty ImmutableArray. Never returns null.</returns> /// returns an empty ImmutableArray. Never returns null.</returns>
public abstract override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity); public abstract override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity);
/// <summary>
/// Get all instance field and event members.
/// </summary>
/// <remarks>
/// For source symbols may be called while calculating
/// <see cref="NamespaceOrTypeSymbol.GetMembersUnordered"/>.
/// </remarks>
internal virtual IEnumerable<Symbol> GetInstanceFieldsAndEvents()
{
return GetMembersUnordered().Where(IsInstanceFieldOrEvent);
}
protected static Func<Symbol, bool> IsInstanceFieldOrEvent = symbol =>
{
if (!symbol.IsStatic)
{
switch (symbol.Kind)
{
case SymbolKind.Field:
case SymbolKind.Event:
return true;
}
}
return false;
};
/// <summary> /// <summary>
/// Get this accessibility that was declared on this symbol. For symbols that do not have /// Get this accessibility that was declared on this symbol. For symbols that do not have
/// accessibility declared on them, returns NotApplicable. /// accessibility declared on them, returns NotApplicable.
......
...@@ -431,10 +431,6 @@ internal override NamedTypeSymbol BaseTypeNoUseSiteDiagnostics ...@@ -431,10 +431,6 @@ internal override NamedTypeSymbol BaseTypeNoUseSiteDiagnostics
if (ReferenceEquals(_lazyBaseType, ErrorTypeSymbol.UnknownResultType)) if (ReferenceEquals(_lazyBaseType, ErrorTypeSymbol.UnknownResultType))
{ {
NamedTypeSymbol acyclicBase = GetDeclaredBaseType(null); NamedTypeSymbol acyclicBase = GetDeclaredBaseType(null);
if (BaseTypeAnalysis.ClassDependsOn(acyclicBase, this))
{
return CyclicInheritanceError(this, acyclicBase);
}
if ((object)acyclicBase == null) if ((object)acyclicBase == null)
{ {
...@@ -446,6 +442,11 @@ internal override NamedTypeSymbol BaseTypeNoUseSiteDiagnostics ...@@ -446,6 +442,11 @@ internal override NamedTypeSymbol BaseTypeNoUseSiteDiagnostics
} }
} }
if ((object)acyclicBase != null && BaseTypeAnalysis.ClassDependsOn(acyclicBase, this))
{
return CyclicInheritanceError(this, acyclicBase);
}
Interlocked.CompareExchange(ref _lazyBaseType, acyclicBase, ErrorTypeSymbol.UnknownResultType); Interlocked.CompareExchange(ref _lazyBaseType, acyclicBase, ErrorTypeSymbol.UnknownResultType);
} }
......
...@@ -1297,6 +1297,12 @@ private MembersAndInitializers GetMembersAndInitializers() ...@@ -1297,6 +1297,12 @@ private MembersAndInitializers GetMembersAndInitializers()
return _lazyMembersDictionary; return _lazyMembersDictionary;
} }
internal override IEnumerable<Symbol> GetInstanceFieldsAndEvents()
{
var membersAndInitializers = this.GetMembersAndInitializers();
return membersAndInitializers.NonTypeNonIndexerMembers.Where(IsInstanceFieldOrEvent);
}
protected void AfterMembersChecks(DiagnosticBag diagnostics) protected void AfterMembersChecks(DiagnosticBag diagnostics)
{ {
if (IsInterface) if (IsInterface)
...@@ -1769,7 +1775,7 @@ private bool HasStructCircularity(DiagnosticBag diagnostics) ...@@ -1769,7 +1775,7 @@ private bool HasStructCircularity(DiagnosticBag diagnostics)
var type = field.Type; var type = field.Type;
if (((object)type != null) && if (((object)type != null) &&
(type.TypeKind == TypeKind.Struct) && (type.TypeKind == TypeKind.Struct) &&
BaseTypeAnalysis.StructDependsOn(type, this) && BaseTypeAnalysis.StructDependsOn((NamedTypeSymbol)type, this) &&
!type.IsPrimitiveRecursiveStruct()) // allow System.Int32 to contain a field of its own type !type.IsPrimitiveRecursiveStruct()) // allow System.Int32 to contain a field of its own type
{ {
// If this is a backing field, report the error on the associated property. // If this is a backing field, report the error on the associated property.
......
...@@ -37,14 +37,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol ...@@ -37,14 +37,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol
/// </summary> /// </summary>
private SourceMemberMethodSymbol _otherPartOfPartial; private SourceMemberMethodSymbol _otherPartOfPartial;
/// <summary>
/// A binder to use for binding generic constraints. The field is only non-null while the .ctor
/// is executing, and allows constraints to be bound before the method is added to the
/// containing type. (Until the method symbol has been added to the container, we cannot
/// get a binder for the method without triggering a recursive attempt to bind the method.)
/// </summary>
private readonly Binder _constraintClauseBinder;
public static SourceMemberMethodSymbol CreateMethodSymbol( public static SourceMemberMethodSymbol CreateMethodSymbol(
NamedTypeSymbol containingType, NamedTypeSymbol containingType,
Binder bodyBinder, Binder bodyBinder,
...@@ -63,7 +55,7 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol ...@@ -63,7 +55,7 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol
? MethodKind.Ordinary ? MethodKind.Ordinary
: MethodKind.ExplicitInterfaceImplementation; : MethodKind.ExplicitInterfaceImplementation;
return new SourceMemberMethodSymbol(containingType, explicitInterfaceType, name, location, bodyBinder, syntax, methodKind, diagnostics); return new SourceMemberMethodSymbol(containingType, explicitInterfaceType, name, location, syntax, methodKind, diagnostics);
} }
private SourceMemberMethodSymbol( private SourceMemberMethodSymbol(
...@@ -71,7 +63,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol ...@@ -71,7 +63,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol
TypeSymbol explicitInterfaceType, TypeSymbol explicitInterfaceType,
string name, string name,
Location location, Location location,
Binder bodyBinder,
MethodDeclarationSyntax syntax, MethodDeclarationSyntax syntax,
MethodKind methodKind, MethodKind methodKind,
DiagnosticBag diagnostics) : DiagnosticBag diagnostics) :
...@@ -103,25 +94,9 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol ...@@ -103,25 +94,9 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol
this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isMetadataVirtualIgnoringModifiers); this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isMetadataVirtualIgnoringModifiers);
// NOTE: by creating a WithMethodTypeParametersBinder, we are effectively duplicating the _typeParameters = (syntax.Arity == 0) ?
// functionality of the BinderFactory. Unfortunately, we cannot use the BinderFactory ImmutableArray<TypeParameterSymbol>.Empty :
// because it depends on having access to the member list of our containing type and MakeTypeParameters(syntax, diagnostics);
// that list cannot be complete because we're not finished constructing this member.
// TODO: at least keep this in sync with BinderFactory.VisitMethodDeclaration.
bodyBinder = bodyBinder.WithUnsafeRegionIfNecessary(modifiers);
Binder withTypeParamsBinder;
if (syntax.Arity == 0)
{
withTypeParamsBinder = bodyBinder;
_typeParameters = ImmutableArray<TypeParameterSymbol>.Empty;
}
else
{
var parameterBinder = new WithMethodTypeParametersBinder(this, bodyBinder);
withTypeParamsBinder = parameterBinder;
_typeParameters = MakeTypeParameters(syntax, diagnostics);
}
bool hasBlockBody = syntax.Body != null; bool hasBlockBody = syntax.Body != null;
_isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null;
...@@ -136,23 +111,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol ...@@ -136,23 +111,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol
{ {
diagnostics.Add(info, location); diagnostics.Add(info, location);
} }
if (this.IsPartial)
{
// Partial methods must be completed early because they are matched up
// by signature while producing the enclosing type's member list. However,
// that means any type parameter constraints will be bound before the method
// is added to the containing type. To enable binding of constraints before the
// .ctor completes we hold on to the current binder while the .ctor is executing.
// If we change the handling of partial methods, so that partial methods are
// completed lazily, the 'constraintClauseBinder' field should be removed.
_constraintClauseBinder = withTypeParamsBinder;
state.NotePartComplete(CompletionPart.StartMethodChecks);
MethodChecks(syntax, withTypeParamsBinder, diagnostics);
state.NotePartComplete(CompletionPart.FinishMethodChecks);
_constraintClauseBinder = null;
}
} }
public override bool ReturnsVoid public override bool ReturnsVoid
...@@ -453,7 +411,7 @@ protected sealed override void LazyAsyncMethodChecks(CancellationToken cancellat ...@@ -453,7 +411,7 @@ protected sealed override void LazyAsyncMethodChecks(CancellationToken cancellat
protected override void MethodChecks(DiagnosticBag diagnostics) protected override void MethodChecks(DiagnosticBag diagnostics)
{ {
var syntax = GetSyntax(); var syntax = GetSyntax();
var withTypeParamsBinder = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree).GetBinder(syntax.ReturnType); var withTypeParamsBinder = this.DeclaringCompilation.GetBinderFactory(syntax.SyntaxTree).GetBinder(syntax.ReturnType, syntax, this);
MethodChecks(syntax, withTypeParamsBinder, diagnostics); MethodChecks(syntax, withTypeParamsBinder, diagnostics);
} }
...@@ -512,17 +470,9 @@ private ImmutableArray<TypeParameterConstraintClause> MakeTypeParameterConstrain ...@@ -512,17 +470,9 @@ private ImmutableArray<TypeParameterConstraintClause> MakeTypeParameterConstrain
} }
var syntaxTree = syntax.SyntaxTree; var syntaxTree = syntax.SyntaxTree;
var compilation = this.DeclaringCompilation;
// If we're binding these constraints before the method has been var binderFactory = compilation.GetBinderFactory(syntaxTree);
// fully constructed (see partial method comment in .ctor), we have var binder = binderFactory.GetBinder(constraintClauses[0]);
// a binder. Otherwise, lookup the binder in the BinderFactory.
var binder = _constraintClauseBinder;
if (binder == null)
{
var compilation = this.DeclaringCompilation;
var binderFactory = compilation.GetBinderFactory(syntaxTree);
binder = binderFactory.GetBinder(constraintClauses[0]);
}
// Wrap binder from factory in a generic constraints specific binder // Wrap binder from factory in a generic constraints specific binder
// to avoid checking constraints when binding type names. // to avoid checking constraints when binding type names.
......
...@@ -3001,6 +3001,19 @@ public unsafe struct S ...@@ -3001,6 +3001,19 @@ public unsafe struct S
Diagnostic(ErrorCode.ERR_ManagedAddr, "S*").WithArguments("S")); Diagnostic(ErrorCode.ERR_ManagedAddr, "S*").WithArguments("S"));
} }
[WorkItem(10195, "https://github.com/dotnet/roslyn/issues/10195")]
[Fact]
public void PointerToStructInPartialMethodSignature()
{
string text =
@"unsafe partial struct S
{
partial void M(S *p) { }
partial void M(S *p);
}";
CreateCompilationWithMscorlib(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics();
}
#endregion IsManagedType #endregion IsManagedType
#region AddressOf operand kinds #region AddressOf operand kinds
......
...@@ -14,21 +14,21 @@ ...@@ -14,21 +14,21 @@
</group> </group>
<group targetFramework="netstandard1.1"> <group targetFramework="netstandard1.1">
<dependency id="Microsoft.DiaSymReader" version="1.0.8-rc2-60409-05" /> <dependency id="Microsoft.DiaSymReader" version="1.0.8-rc2-60409-05" />
<dependency id="System.Collections" version="4.0.11-rc2-24008" /> <dependency id="System.Collections" version="4.0.11-rc2-24022" />
<dependency id="System.Collections.Immutable" version="1.2.0-rc2-24008" /> <dependency id="System.Collections.Immutable" version="1.2.0-rc2-24022" />
<dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24008" /> <dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24022" />
<dependency id="System.Globalization" version="4.0.0-rc2-24008" /> <dependency id="System.Globalization" version="4.0.0-rc2-24022" />
<dependency id="System.IO" version="4.1.0-rc2-24008" /> <dependency id="System.IO" version="4.1.0-rc2-24022" />
<dependency id="System.Linq" version="4.1.0-rc2-24008" /> <dependency id="System.Linq" version="4.1.0-rc2-24022" />
<dependency id="System.Reflection" version="4.1.0-rc2-24008" /> <dependency id="System.Reflection" version="4.1.0-rc2-24022" />
<dependency id="System.Reflection.Metadata" version="1.3.0-rc2-24008" /> <dependency id="System.Reflection.Metadata" version="1.3.0-rc2-24022" />
<dependency id="System.Reflection.Primitives" version="4.0.1-rc2-24008" /> <dependency id="System.Reflection.Primitives" version="4.0.1-rc2-24022" />
<dependency id="System.Runtime" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24022" />
<dependency id="System.Text.Encoding" version="4.0.11-rc2-24008" /> <dependency id="System.Text.Encoding" version="4.0.11-rc2-24022" />
<dependency id="System.Threading" version="4.0.11-rc2-24008" /> <dependency id="System.Threading" version="4.0.11-rc2-24022" />
<dependency id="System.Xml.XDocument" version="4.0.11-rc2-24008" /> <dependency id="System.Xml.XDocument" version="4.0.11-rc2-24022" />
</group> </group>
</dependencies> </dependencies>
<language>en-US</language> <language>en-US</language>
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
"dependencies": { "dependencies": {
"Microsoft.VisualStudio.Designer.Interfaces": "1.1.4322", "Microsoft.VisualStudio.Designer.Interfaces": "1.1.4322",
"Microsoft.VisualStudio.Editor": "14.1.24720", "Microsoft.VisualStudio.Editor": "14.1.24720",
"Microsoft.VisualStudio.Shell.Design": "14.1.24720",
"Microsoft.VisualStudio.Shell.14.0": "14.1.24720", "Microsoft.VisualStudio.Shell.14.0": "14.1.24720",
"Microsoft.VisualStudio.Shell.Interop.10.0": "10.0.30319", "Microsoft.VisualStudio.Shell.Interop.10.0": "10.0.30319",
"Microsoft.VisualStudio.Shell.Interop.11.0": "11.0.61030", "Microsoft.VisualStudio.Shell.Interop.11.0": "11.0.61030",
......
...@@ -287,22 +287,21 @@ public async Task<IEnumerable<CodeFixCollection>> GetFixesAsync(Document documen ...@@ -287,22 +287,21 @@ public async Task<IEnumerable<CodeFixCollection>> GetFixesAsync(Document documen
// If the fix provider supports fix all occurrences, then get the corresponding FixAllProviderInfo and fix all context. // If the fix provider supports fix all occurrences, then get the corresponding FixAllProviderInfo and fix all context.
var fixAllProviderInfo = extensionManager.PerformFunction(fixer, () => ImmutableInterlocked.GetOrAdd(ref _fixAllProviderMap, fixer, FixAllProviderInfo.Create), defaultValue: null); var fixAllProviderInfo = extensionManager.PerformFunction(fixer, () => ImmutableInterlocked.GetOrAdd(ref _fixAllProviderMap, fixer, FixAllProviderInfo.Create), defaultValue: null);
FixAllProvider fixAllProvider = null; FixAllState fixAllState = null;
FixAllContext fixAllContext = null;
IEnumerable<FixAllScope> supportedScopes = null; IEnumerable<FixAllScope> supportedScopes = null;
if (fixAllProviderInfo != null) if (fixAllProviderInfo != null)
{ {
var codeFixProvider = (fixer as CodeFixProvider) ?? new WrapperCodeFixProvider((ISuppressionFixProvider)fixer, diagnostics.Select(d => d.Id)); var codeFixProvider = (fixer as CodeFixProvider) ?? new WrapperCodeFixProvider((ISuppressionFixProvider)fixer, diagnostics.Select(d => d.Id));
fixAllProvider = fixAllProviderInfo.FixAllProvider; fixAllState = FixAllState.Create(
fixAllContext = FixAllContext.Create( fixAllProviderInfo.FixAllProvider,
document, fixAllProviderInfo, codeFixProvider, diagnostics, document, fixAllProviderInfo, codeFixProvider, diagnostics,
this.GetDocumentDiagnosticsAsync, this.GetProjectDiagnosticsAsync, cancellationToken); this.GetDocumentDiagnosticsAsync, this.GetProjectDiagnosticsAsync);
supportedScopes = fixAllProviderInfo.SupportedScopes; supportedScopes = fixAllProviderInfo.SupportedScopes;
} }
result = result ?? new List<CodeFixCollection>(); result = result ?? new List<CodeFixCollection>();
var codeFix = new CodeFixCollection( var codeFix = new CodeFixCollection(
fixer, span, fixes, fixAllProvider, fixAllContext, fixer, span, fixes, fixAllState,
supportedScopes, diagnostics.First()); supportedScopes, diagnostics.First());
result.Add(codeFix); result.Add(codeFix);
} }
......
...@@ -46,8 +46,7 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi ...@@ -46,8 +46,7 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi
internal static SuggestedActionSet GetFixAllSuggestedActionSet( internal static SuggestedActionSet GetFixAllSuggestedActionSet(
CodeAction action, CodeAction action,
int actionCount, int actionCount,
FixAllProvider fixAllProvider, FixAllState fixAllState,
FixAllContext fixAllCodeActionContext,
IEnumerable<FixAllScope> supportedScopes, IEnumerable<FixAllScope> supportedScopes,
Diagnostic firstDiagnostic, Diagnostic firstDiagnostic,
Workspace workspace, Workspace workspace,
...@@ -56,7 +55,7 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi ...@@ -56,7 +55,7 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi
IWaitIndicator waitIndicator, IWaitIndicator waitIndicator,
IAsynchronousOperationListener operationListener) IAsynchronousOperationListener operationListener)
{ {
if (fixAllCodeActionContext == null) if (fixAllState == null)
{ {
return null; return null;
} }
...@@ -69,11 +68,11 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi ...@@ -69,11 +68,11 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi
var fixAllSuggestedActions = ImmutableArray.CreateBuilder<FixAllSuggestedAction>(); var fixAllSuggestedActions = ImmutableArray.CreateBuilder<FixAllSuggestedAction>();
foreach (var scope in supportedScopes) foreach (var scope in supportedScopes)
{ {
var fixAllContext = fixAllCodeActionContext.GetContextForScopeAndActionId(scope, action.EquivalenceKey); var fixAllStateForScope = fixAllState.WithScopeAndEquivalenceKey(scope, action.EquivalenceKey);
var fixAllAction = new FixAllCodeAction(fixAllContext, fixAllProvider, showPreviewChangesDialog: true); var fixAllAction = new FixAllCodeAction(fixAllStateForScope, showPreviewChangesDialog: true);
var fixAllSuggestedAction = new FixAllSuggestedAction( var fixAllSuggestedAction = new FixAllSuggestedAction(
workspace, subjectBuffer, editHandler, waitIndicator, fixAllAction, workspace, subjectBuffer, editHandler, waitIndicator, fixAllAction,
fixAllProvider, firstDiagnostic, operationListener); fixAllStateForScope.FixAllProvider, firstDiagnostic, operationListener);
fixAllSuggestedActions.Add(fixAllSuggestedAction); fixAllSuggestedActions.Add(fixAllSuggestedAction);
} }
......
...@@ -30,9 +30,9 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) ...@@ -30,9 +30,9 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
return this; return this;
} }
public async Task<Solution> GetFixAllChangedSolutionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) public async Task<Solution> GetFixAllChangedSolutionAsync(FixAllContext fixAllContext)
{ {
var codeAction = await GetFixAllCodeActionAsync(fixAllProvider, fixAllContext).ConfigureAwait(false); var codeAction = await GetFixAllCodeActionAsync(fixAllContext).ConfigureAwait(false);
if (codeAction == null) if (codeAction == null)
{ {
return fixAllContext.Solution; return fixAllContext.Solution;
...@@ -42,25 +42,27 @@ public async Task<Solution> GetFixAllChangedSolutionAsync(FixAllProvider fixAllP ...@@ -42,25 +42,27 @@ public async Task<Solution> GetFixAllChangedSolutionAsync(FixAllProvider fixAllP
return await codeAction.GetChangedSolutionInternalAsync(cancellationToken: fixAllContext.CancellationToken).ConfigureAwait(false); return await codeAction.GetChangedSolutionInternalAsync(cancellationToken: fixAllContext.CancellationToken).ConfigureAwait(false);
} }
public async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext, bool showPreviewChangesDialog) public async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(
FixAllContext fixAllContext, bool showPreviewChangesDialog)
{ {
var codeAction = await GetFixAllCodeActionAsync(fixAllProvider, fixAllContext).ConfigureAwait(false); var codeAction = await GetFixAllCodeActionAsync(fixAllContext).ConfigureAwait(false);
if (codeAction == null) if (codeAction == null)
{ {
return null; return null;
} }
return await GetFixAllOperationsAsync(codeAction, fixAllContext, showPreviewChangesDialog).ConfigureAwait(false); return await GetFixAllOperationsAsync(
codeAction, showPreviewChangesDialog, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false);
} }
private async Task<CodeAction> GetFixAllCodeActionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) private async Task<CodeAction> GetFixAllCodeActionAsync(FixAllContext fixAllContext)
{ {
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken)) using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken))
{ {
CodeAction action = null; CodeAction action = null;
try try
{ {
action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); action = await fixAllContext.FixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false);
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
...@@ -82,13 +84,14 @@ private async Task<CodeAction> GetFixAllCodeActionAsync(FixAllProvider fixAllPro ...@@ -82,13 +84,14 @@ private async Task<CodeAction> GetFixAllCodeActionAsync(FixAllProvider fixAllPro
} }
} }
private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext, bool showPreviewChangesDialog) private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(
CodeAction codeAction, bool showPreviewChangesDialog,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
// We have computed the fix all occurrences code fix. // We have computed the fix all occurrences code fix.
// Now fetch the new solution with applied fix and bring up the Preview changes dialog. // Now fetch the new solution with applied fix and bring up the Preview changes dialog.
var cancellationToken = fixAllContext.CancellationToken; var workspace = fixAllState.Project.Solution.Workspace;
var workspace = fixAllContext.Project.Solution.Workspace;
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false); var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false);
...@@ -103,11 +106,11 @@ private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(Co ...@@ -103,11 +106,11 @@ private async Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(Co
if (showPreviewChangesDialog) if (showPreviewChangesDialog)
{ {
newSolution = PreviewChanges( newSolution = PreviewChanges(
fixAllContext.Project.Solution, fixAllState.Project.Solution,
newSolution, newSolution,
FeaturesResources.FixAllOccurrences, FeaturesResources.FixAllOccurrences,
codeAction.Title, codeAction.Title,
fixAllContext.Project.Language, fixAllState.Project.Language,
workspace, workspace,
cancellationToken); cancellationToken);
if (newSolution == null) if (newSolution == null)
......
...@@ -50,10 +50,10 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) ...@@ -50,10 +50,10 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
string waitDialogMessage, string waitDialogMessage,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var fixMultipleContext = FixAllContext.Create(diagnosticsToFix, fixProvider, equivalenceKey, cancellationToken); var fixMultipleState = FixAllState.Create(fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
var triggerDiagnostic = diagnosticsToFix.First().Value.First(); var triggerDiagnostic = diagnosticsToFix.First().Value.First();
var suggestedAction = GetSuggestedAction(fixMultipleContext, triggerDiagnostic, workspace, fixAllProvider, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken); var suggestedAction = GetSuggestedAction(fixMultipleState, triggerDiagnostic, workspace, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken);
return suggestedAction.GetChangedSolution(cancellationToken); return suggestedAction.GetChangedSolution(cancellationToken);
} }
...@@ -67,25 +67,26 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) ...@@ -67,25 +67,26 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices)
string waitDialogMessage, string waitDialogMessage,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var fixMultipleContext = FixAllContext.Create(diagnosticsToFix, fixProvider, equivalenceKey, cancellationToken); var fixMultipleState = FixAllState.Create(fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey);
var triggerDiagnostic = diagnosticsToFix.First().Value.First(); var triggerDiagnostic = diagnosticsToFix.First().Value.First();
var suggestedAction = GetSuggestedAction(fixMultipleContext, triggerDiagnostic, workspace, fixAllProvider, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken); var suggestedAction = GetSuggestedAction(fixMultipleState, triggerDiagnostic, workspace, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken);
return suggestedAction.GetChangedSolution(cancellationToken); return suggestedAction.GetChangedSolution(cancellationToken);
} }
private FixMultipleSuggestedAction GetSuggestedAction( private FixMultipleSuggestedAction GetSuggestedAction(
FixAllContext fixAllContext, FixAllState fixAllState,
Diagnostic triggerDiagnostic, Diagnostic triggerDiagnostic,
Workspace workspace, Workspace workspace,
FixAllProvider fixAllProvider,
string title, string title,
string waitDialogMessage, string waitDialogMessage,
bool showPreviewChangesDialog, bool showPreviewChangesDialog,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var fixMultipleCodeAction = new FixMultipleCodeAction(fixAllContext, triggerDiagnostic, fixAllProvider, title, waitDialogMessage, showPreviewChangesDialog); var fixMultipleCodeAction = new FixMultipleCodeAction(fixAllState, triggerDiagnostic, title, waitDialogMessage, showPreviewChangesDialog);
return new FixMultipleSuggestedAction(_listener, workspace, _editHandler, _waitIndicator, fixMultipleCodeAction, fixAllProvider); return new FixMultipleSuggestedAction(
_listener, workspace, _editHandler, _waitIndicator,
fixMultipleCodeAction, fixAllState.FixAllProvider);
} }
} }
} }
...@@ -33,9 +33,9 @@ internal class FixMultipleSuggestedAction : FixAllSuggestedAction ...@@ -33,9 +33,9 @@ internal class FixMultipleSuggestedAction : FixAllSuggestedAction
ITextBuffer subjectBufferOpt = null) ITextBuffer subjectBufferOpt = null)
: base(workspace, subjectBufferOpt, editHandler, waitIndicator, codeAction, provider, originalFixedDiagnostic: codeAction.GetTriggerDiagnostic(), operationListener: operationListener) : base(workspace, subjectBufferOpt, editHandler, waitIndicator, codeAction, provider, originalFixedDiagnostic: codeAction.GetTriggerDiagnostic(), operationListener: operationListener)
{ {
_triggerDocumentOpt = codeAction.FixAllContext.Document; _triggerDocumentOpt = codeAction.FixAllState.Document;
_telemetryId = GetTelemetryId(codeAction.FixAllContext.DiagnosticIds); _telemetryId = GetTelemetryId(codeAction.FixAllState.DiagnosticIds);
} }
private static string GetTelemetryId(IEnumerable<string> diagnosticIds) private static string GetTelemetryId(IEnumerable<string> diagnosticIds)
......
...@@ -285,7 +285,7 @@ private List<CodeFixCollection> FilterOnUIThread(List<CodeFixCollection> collect ...@@ -285,7 +285,7 @@ private List<CodeFixCollection> FilterOnUIThread(List<CodeFixCollection> collect
: applicableFixes.Count == collection.Fixes.Length : applicableFixes.Count == collection.Fixes.Length
? collection ? collection
: new CodeFixCollection(collection.Provider, collection.TextSpan, applicableFixes, : new CodeFixCollection(collection.Provider, collection.TextSpan, applicableFixes,
collection.FixAllProvider, collection.FixAllContext, collection.FixAllState,
collection.SupportedScopes, collection.FirstDiagnostic); collection.SupportedScopes, collection.FirstDiagnostic);
} }
...@@ -350,10 +350,10 @@ private IEnumerable<SuggestedActionSet> OrganizeFixes(Workspace workspace, IEnum ...@@ -350,10 +350,10 @@ private IEnumerable<SuggestedActionSet> OrganizeFixes(Workspace workspace, IEnum
Func<CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet = Func<CodeAction, SuggestedActionSet> getFixAllSuggestedActionSet =
codeAction => CodeFixSuggestedAction.GetFixAllSuggestedActionSet( codeAction => CodeFixSuggestedAction.GetFixAllSuggestedActionSet(
codeAction, fixCount, fixCollection.FixAllProvider, codeAction, fixCount, fixCollection.FixAllState,
fixCollection.FixAllContext, fixCollection.SupportedScopes, fixCollection.SupportedScopes, fixCollection.FirstDiagnostic,
fixCollection.FirstDiagnostic, workspace, _subjectBuffer, workspace, _subjectBuffer, _owner._editHandler,
_owner._editHandler, _owner._waitIndicator, _owner._listener); _owner._waitIndicator, _owner._listener);
foreach (var fix in fixes) foreach (var fix in fixes)
{ {
......
...@@ -144,7 +144,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri ...@@ -144,7 +144,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri
{ {
var codeFix = new CodeFixCollection( var codeFix = new CodeFixCollection(
fixer, diagnostic.Location.SourceSpan, fixes, fixer, diagnostic.Location.SourceSpan, fixes,
fixAllProvider: null, fixAllContext: null, supportedScopes: null, firstDiagnostic: null); fixAllState: null, supportedScopes: null, firstDiagnostic: null);
result.Add(Tuple.Create(diagnostic, codeFix)); result.Add(Tuple.Create(diagnostic, codeFix));
} }
} }
...@@ -155,7 +155,8 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri ...@@ -155,7 +155,8 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri
var fixAllProvider = fixer.GetFixAllProvider(); var fixAllProvider = fixer.GetFixAllProvider();
Assert.NotNull(fixAllProvider); Assert.NotNull(fixAllProvider);
var fixAllContext = GetFixAllContext(diagnostics, provider, fixer, testDriver, document, scope.Value, fixAllActionId); var fixAllState = GetFixAllState(fixAllProvider, diagnostics, provider, fixer, testDriver, document, scope.Value, fixAllActionId);
var fixAllContext = fixAllState.CreateFixAllContext(CancellationToken.None);
var fixAllFix = await fixAllProvider.GetFixAsync(fixAllContext); var fixAllFix = await fixAllProvider.GetFixAsync(fixAllContext);
if (fixAllFix != null) if (fixAllFix != null)
{ {
...@@ -165,7 +166,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri ...@@ -165,7 +166,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri
var diagnosticSpan = diagnostic.Location.IsInSource ? diagnostic.Location.SourceSpan : default(TextSpan); var diagnosticSpan = diagnostic.Location.IsInSource ? diagnostic.Location.SourceSpan : default(TextSpan);
var codeFix = new CodeFixCollection( var codeFix = new CodeFixCollection(
fixAllProvider, diagnosticSpan, ImmutableArray.Create(new CodeFix(document.Project, fixAllFix, diagnostic)), fixAllProvider, diagnosticSpan, ImmutableArray.Create(new CodeFix(document.Project, fixAllFix, diagnostic)),
fixAllProvider: null, fixAllContext: null, supportedScopes: null, firstDiagnostic: null); fixAllState: null, supportedScopes: null, firstDiagnostic: null);
result.Add(Tuple.Create(diagnostic, codeFix)); result.Add(Tuple.Create(diagnostic, codeFix));
} }
} }
...@@ -174,7 +175,8 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri ...@@ -174,7 +175,8 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri
return result; return result;
} }
private static FixAllContext GetFixAllContext( private static FixAllState GetFixAllState(
FixAllProvider fixAllProvider,
IEnumerable<Diagnostic> diagnostics, IEnumerable<Diagnostic> diagnostics,
DiagnosticAnalyzer provider, DiagnosticAnalyzer provider,
CodeFixProvider fixer, CodeFixProvider fixer,
...@@ -189,7 +191,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri ...@@ -189,7 +191,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri
{ {
// Bulk fixing diagnostics in selected scope. // Bulk fixing diagnostics in selected scope.
var diagnosticsToFix = ImmutableDictionary.CreateRange(SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, diagnostics.ToImmutableArray()))); var diagnosticsToFix = ImmutableDictionary.CreateRange(SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, diagnostics.ToImmutableArray())));
return FixAllContext.Create(diagnosticsToFix, fixer, fixAllActionId, CancellationToken.None); return FixAllState.Create(fixAllProvider, diagnosticsToFix, fixer, fixAllActionId);
} }
var diagnostic = diagnostics.First(); var diagnostic = diagnostics.First();
...@@ -213,10 +215,10 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri ...@@ -213,10 +215,10 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri
}; };
var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id); var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id);
var fixAllDiagnosticProvider = new FixAllContext.FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync); var fixAllDiagnosticProvider = new FixAllState.FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
return diagnostic.Location.IsInSource return diagnostic.Location.IsInSource
? new FixAllContext(document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider, CancellationToken.None) ? new FixAllState(fixAllProvider, document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider)
: new FixAllContext(document.Project, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider, CancellationToken.None); : new FixAllState(fixAllProvider, document.Project, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider);
} }
protected async Task TestEquivalenceKeyAsync(string initialMarkup, string equivalenceKey) protected async Task TestEquivalenceKeyAsync(string initialMarkup, string equivalenceKey)
......
...@@ -114,8 +114,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics ...@@ -114,8 +114,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics
If fixes.Any() Then If fixes.Any() Then
result.Add(Tuple.Create(diagnostic, New CodeFixCollection( result.Add(Tuple.Create(diagnostic, New CodeFixCollection(
fixer, diagnostic.Location.SourceSpan, fixes, fixer, diagnostic.Location.SourceSpan, fixes,
fixAllProvider:=Nothing, fixAllContext:=Nothing, fixAllState:=Nothing, supportedScopes:=Nothing, firstDiagnostic:=Nothing)))
supportedScopes:=Nothing, firstDiagnostic:=Nothing)))
End If End If
Next Next
......
...@@ -1918,7 +1918,6 @@ class MyClass ...@@ -1918,7 +1918,6 @@ class MyClass
</Workspace> </Workspace>
Using workspace = TestWorkspace.CreateWorkspace(test) Using workspace = TestWorkspace.CreateWorkspace(test)
' set csharp closed diagnostic option on
workspace.Options = workspace.Options.WithChangedOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, LanguageNames.CSharp, True) workspace.Options = workspace.Options.WithChangedOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, LanguageNames.CSharp, True)
Dim project = workspace.CurrentSolution.Projects.Single() Dim project = workspace.CurrentSolution.Projects.Single()
......
...@@ -7073,6 +7073,80 @@ End Module ...@@ -7073,6 +7073,80 @@ End Module
Await VerifyItemExistsAsync(text, "Length") Await VerifyItemExistsAsync(text, "Length")
End Function End Function
<WorkItem(153633, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/153633")>
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function LocalInForLoop() As Task
Dim text =
<code><![CDATA[
Module Program
Sub Main(args As String())
Dim x As Integer
For $$
End Sub
End Module
]]></code>.Value
Await VerifyItemExistsAsync(text, "x")
End Function
<WorkItem(153633, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/153633")>
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function ExcludeConstLocalInForLoop() As Task
Dim text =
<code><![CDATA[
Module Program
Sub Main(args As String())
Dim const x As Integer
For $$
End Sub
End Module
]]></code>.Value
Await VerifyItemIsAbsentAsync(text, "x")
End Function
<WorkItem(153633, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/153633")>
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function ExcludeConstFieldInForLoop() As Task
Dim text =
<code><![CDATA[
Class Program
Const x As Integer = 0
Sub Main(args As String())
For $$
End Sub
End Class
]]></code>.Value
Await VerifyItemIsAbsentAsync(text, "x")
End Function
<WorkItem(153633, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/153633")>
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function ExcludeReadOnlyFieldInForLoop() As Task
Dim text =
<code><![CDATA[
Class Program
ReadOnly x As Integer
Sub Main(args As String())
For $$
End Sub
End Class
]]></code>.Value
Await VerifyItemIsAbsentAsync(text, "x")
End Function
<WorkItem(153633, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/153633")>
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function FieldInForLoop() As Task
Dim text =
<code><![CDATA[
Class Program
Dim x As Integer
Sub Main(args As String())
For $$
End Sub
End Class
]]></code>.Value
Await VerifyItemExistsAsync(text, "x")
End Function
End Class End Class
End Namespace End Namespace
...@@ -32,6 +32,11 @@ ...@@ -32,6 +32,11 @@
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="Project References"> <ItemGroup Label="Project References">
<ProjectReference Include="..\..\Dependencies\VisualStudio\VisualStudio.csproj">
<Project>{8da861d8-0cce-4334-b6c0-01a846c881ec}</Project>
<Name>VisualStudio</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\VisualStudio\Setup\VisualStudioSetup.csproj"> <ProjectReference Include="..\..\VisualStudio\Setup\VisualStudioSetup.csproj">
<Project>{201EC5B7-F91E-45E5-B9F2-67A266CCE6FC}</Project> <Project>{201EC5B7-F91E-45E5-B9F2-67A266CCE6FC}</Project>
<Name>VisualStudioSetup</Name> <Name>VisualStudioSetup</Name>
...@@ -86,16 +91,10 @@ ...@@ -86,16 +91,10 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.VisualStudio.Shell.14.0, Version=$(VisualStudioReferenceAssemblyVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>false</Private>
<HintPath>$(DevEnvDir)\PrivateAssemblies\Microsoft.VisualStudio.Shell.14.0.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>false</Private>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="project.json" />
<None Include="source.extension.vsixmanifest"> <None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</None> </None>
...@@ -109,4 +108,4 @@ ...@@ -109,4 +108,4 @@
<ImportGroup Label="Targets"> <ImportGroup Label="Targets">
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" /> <Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>
\ No newline at end of file
{
"dependencies": {
},
"frameworks": {
"net46": { }
},
"runtimes": {
"win7": { },
"win7-anycpu": { }
}
}
...@@ -20,8 +20,7 @@ internal class CodeFixCollection ...@@ -20,8 +20,7 @@ internal class CodeFixCollection
/// <summary> /// <summary>
/// Optional fix all context, which is non-null if the given <see cref="Provider"/> supports fix all occurrences code fix. /// Optional fix all context, which is non-null if the given <see cref="Provider"/> supports fix all occurrences code fix.
/// </summary> /// </summary>
public FixAllProvider FixAllProvider { get; } public FixAllState FixAllState { get; }
public FixAllContext FixAllContext { get; }
public IEnumerable<FixAllScope> SupportedScopes { get; } public IEnumerable<FixAllScope> SupportedScopes { get; }
public Diagnostic FirstDiagnostic { get; } public Diagnostic FirstDiagnostic { get; }
...@@ -29,11 +28,10 @@ internal class CodeFixCollection ...@@ -29,11 +28,10 @@ internal class CodeFixCollection
object provider, object provider,
TextSpan span, TextSpan span,
IEnumerable<CodeFix> fixes, IEnumerable<CodeFix> fixes,
FixAllProvider fixAllProvider, FixAllState fixAllState,
FixAllContext fixAllContext,
IEnumerable<FixAllScope> supportedScopes, IEnumerable<FixAllScope> supportedScopes,
Diagnostic firstDiagnostic) : Diagnostic firstDiagnostic) :
this(provider, span, fixes.ToImmutableArray(), fixAllProvider, fixAllContext, supportedScopes, firstDiagnostic) this(provider, span, fixes.ToImmutableArray(), fixAllState, supportedScopes, firstDiagnostic)
{ {
} }
...@@ -41,16 +39,14 @@ internal class CodeFixCollection ...@@ -41,16 +39,14 @@ internal class CodeFixCollection
object provider, object provider,
TextSpan span, TextSpan span,
ImmutableArray<CodeFix> fixes, ImmutableArray<CodeFix> fixes,
FixAllProvider fixAllProvider, FixAllState fixAllState,
FixAllContext fixAllContext,
IEnumerable<FixAllScope> supportedScopes, IEnumerable<FixAllScope> supportedScopes,
Diagnostic firstDiagnostic) Diagnostic firstDiagnostic)
{ {
this.Provider = provider; this.Provider = provider;
this.TextSpan = span; this.TextSpan = span;
this.Fixes = fixes; this.Fixes = fixes;
this.FixAllProvider = fixAllProvider; this.FixAllState = fixAllState;
this.FixAllContext = fixAllContext;
this.SupportedScopes = supportedScopes; this.SupportedScopes = supportedScopes;
this.FirstDiagnostic = firstDiagnostic; this.FirstDiagnostic = firstDiagnostic;
} }
......
...@@ -15,15 +15,14 @@ namespace Microsoft.CodeAnalysis.CodeFixes ...@@ -15,15 +15,14 @@ namespace Microsoft.CodeAnalysis.CodeFixes
/// </summary> /// </summary>
internal partial class FixAllCodeAction : CodeAction internal partial class FixAllCodeAction : CodeAction
{ {
private readonly FixAllContext _fixAllContext; private readonly FixAllState _fixAllState;
private readonly FixAllProvider _fixAllProvider;
private readonly bool _showPreviewChangesDialog; private readonly bool _showPreviewChangesDialog;
private static readonly HashSet<string> s_predefinedCodeFixProviderNames = GetPredefinedCodeFixProviderNames(); private static readonly HashSet<string> s_predefinedCodeFixProviderNames = GetPredefinedCodeFixProviderNames();
internal FixAllCodeAction(FixAllContext fixAllContext, FixAllProvider fixAllProvider, bool showPreviewChangesDialog) internal FixAllCodeAction(
FixAllState fixAllState, bool showPreviewChangesDialog)
{ {
_fixAllContext = fixAllContext; _fixAllState = fixAllState;
_fixAllProvider = fixAllProvider;
_showPreviewChangesDialog = showPreviewChangesDialog; _showPreviewChangesDialog = showPreviewChangesDialog;
} }
...@@ -31,7 +30,7 @@ public override string Title ...@@ -31,7 +30,7 @@ public override string Title
{ {
get get
{ {
switch (_fixAllContext.Scope) switch (_fixAllState.Scope)
{ {
case FixAllScope.Document: case FixAllScope.Document:
return FeaturesResources.FixAllTitle_Document; return FeaturesResources.FixAllTitle_Document;
...@@ -47,28 +46,31 @@ public override string Title ...@@ -47,28 +46,31 @@ public override string Title
internal override string Message => FeaturesResources.ComputingFixAllOccurrences; internal override string Message => FeaturesResources.ComputingFixAllOccurrences;
public FixAllContext FixAllContext => _fixAllContext; public FixAllState FixAllState => _fixAllState;
protected override async Task<IEnumerable<CodeActionOperation>> ComputeOperationsAsync(CancellationToken cancellationToken) protected override async Task<IEnumerable<CodeActionOperation>> ComputeOperationsAsync(CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
FixAllLogger.LogContext(_fixAllContext, IsInternalCodeFixProvider(_fixAllContext.CodeFixProvider)); FixAllLogger.LogState(_fixAllState, IsInternalCodeFixProvider(_fixAllState.CodeFixProvider));
var service = _fixAllContext.Project.Solution.Workspace.Services.GetService<IFixAllGetFixesService>(); var service = _fixAllState.Project.Solution.Workspace.Services.GetService<IFixAllGetFixesService>();
// Use the new cancellation token instead of the stale one present inside _fixAllContext. // Use the new cancellation token instead of the stale one present inside _fixAllContext.
return await service.GetFixAllOperationsAsync(_fixAllProvider, _fixAllContext.WithCancellationToken(cancellationToken), _showPreviewChangesDialog).ConfigureAwait(false); return await service.GetFixAllOperationsAsync(
_fixAllState.CreateFixAllContext(cancellationToken),
_showPreviewChangesDialog).ConfigureAwait(false);
} }
protected async override Task<Solution> GetChangedSolutionAsync(CancellationToken cancellationToken) protected async override Task<Solution> GetChangedSolutionAsync(CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
FixAllLogger.LogContext(_fixAllContext, IsInternalCodeFixProvider(_fixAllContext.CodeFixProvider)); FixAllLogger.LogState(_fixAllState, IsInternalCodeFixProvider(_fixAllState.CodeFixProvider));
var service = _fixAllContext.Project.Solution.Workspace.Services.GetService<IFixAllGetFixesService>(); var service = _fixAllState.Project.Solution.Workspace.Services.GetService<IFixAllGetFixesService>();
// Use the new cancellation token instead of the stale one present inside _fixAllContext. // Use the new cancellation token instead of the stale one present inside _fixAllContext.
return await service.GetFixAllChangedSolutionAsync(_fixAllProvider, _fixAllContext.WithCancellationToken(cancellationToken)).ConfigureAwait(false); return await service.GetFixAllChangedSolutionAsync(
_fixAllState.CreateFixAllContext(cancellationToken)).ConfigureAwait(false);
} }
private static bool IsInternalCodeFixProvider(CodeFixProvider fixer) private static bool IsInternalCodeFixProvider(CodeFixProvider fixer)
......
...@@ -12,13 +12,12 @@ internal partial class FixMultipleCodeAction : FixAllCodeAction ...@@ -12,13 +12,12 @@ internal partial class FixMultipleCodeAction : FixAllCodeAction
private readonly string _computingFixWaitDialogMessage; private readonly string _computingFixWaitDialogMessage;
internal FixMultipleCodeAction( internal FixMultipleCodeAction(
FixAllContext fixAllContext, FixAllState fixAllState,
Diagnostic triggerDiagnostic, Diagnostic triggerDiagnostic,
FixAllProvider fixAllProvider,
string title, string title,
string computingFixWaitDialogMessage, string computingFixWaitDialogMessage,
bool showPreviewChangesDialog) bool showPreviewChangesDialog)
: base(fixAllContext, fixAllProvider, showPreviewChangesDialog) : base(fixAllState, showPreviewChangesDialog)
{ {
_triggerDiagnostic = triggerDiagnostic; _triggerDiagnostic = triggerDiagnostic;
_title = title; _title = title;
......
...@@ -13,11 +13,11 @@ internal interface IFixAllGetFixesService : IWorkspaceService ...@@ -13,11 +13,11 @@ internal interface IFixAllGetFixesService : IWorkspaceService
/// Computes the fix all occurrences code fix, brings up the preview changes dialog for the fix and /// Computes the fix all occurrences code fix, brings up the preview changes dialog for the fix and
/// returns the code action operations corresponding to the fix. /// returns the code action operations corresponding to the fix.
/// </summary> /// </summary>
Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext, bool showPreviewChangesDialog); Task<IEnumerable<CodeActionOperation>> GetFixAllOperationsAsync(FixAllContext fixAllContext, bool showPreviewChangesDialog);
/// <summary> /// <summary>
/// Computes the fix all occurrences code fix and returns the changed solution. /// Computes the fix all occurrences code fix and returns the changed solution.
/// </summary> /// </summary>
Task<Solution> GetFixAllChangedSolutionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext); Task<Solution> GetFixAllChangedSolutionAsync(FixAllContext fixAllContext);
} }
} }
...@@ -37,18 +37,20 @@ public async override Task<CodeAction> GetFixAsync(FixAllContext fixAllContext) ...@@ -37,18 +37,20 @@ public async override Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
var documentsAndDiagnosticsToFixMap = var documentsAndDiagnosticsToFixMap =
await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false); await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false);
return !isGlobalSuppression ? return !isGlobalSuppression
await batchFixer.GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) : ? await batchFixer.GetFixAsync(
GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap); documentsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false)
: GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap);
} }
else else
{ {
var projectsAndDiagnosticsToFixMap = var projectsAndDiagnosticsToFixMap =
await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false); await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false);
return !isGlobalSuppression ? return !isGlobalSuppression
await batchFixer.GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) : ? await batchFixer.GetFixAsync(
GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap); projectsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false)
: GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap);
} }
} }
} }
......
...@@ -25,15 +25,16 @@ private static class PragmaBatchFixHelpers ...@@ -25,15 +25,16 @@ private static class PragmaBatchFixHelpers
Document document, Document document,
ImmutableArray<IPragmaBasedCodeAction> pragmaActions, ImmutableArray<IPragmaBasedCodeAction> pragmaActions,
ImmutableArray<Diagnostic> pragmaDiagnostics, ImmutableArray<Diagnostic> pragmaDiagnostics,
FixAllContext fixAllContext) FixAllState fixAllState,
CancellationToken cancellationToken)
{ {
// This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005. // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005.
#pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction #pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction
return CodeAction.Create( return CodeAction.Create(
((CodeAction)pragmaActions[0]).Title, ((CodeAction)pragmaActions[0]).Title,
createChangedDocument: ct => createChangedDocument: ct =>
BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllContext.CancellationToken), BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, cancellationToken),
equivalenceKey: fixAllContext.CodeActionEquivalenceKey); equivalenceKey: fixAllState.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
} }
......
...@@ -26,7 +26,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr ...@@ -26,7 +26,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr
_suppressionFixProvider = suppressionFixProvider; _suppressionFixProvider = suppressionFixProvider;
} }
public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext) public override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>(); var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>();
var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder<Diagnostic>(); var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder<Diagnostic>();
...@@ -34,11 +36,12 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr ...@@ -34,11 +36,12 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed)) foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed))
{ {
var span = diagnostic.Location.SourceSpan; var span = diagnostic.Location.SourceSpan;
var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync(document, span, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false); var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync(
document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);
var pragmaSuppression = pragmaSuppressions.SingleOrDefault(); var pragmaSuppression = pragmaSuppressions.SingleOrDefault();
if (pragmaSuppression != null) if (pragmaSuppression != null)
{ {
if (fixAllContext.IsFixMultiple) if (fixAllState.IsFixMultiple)
{ {
pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext(); pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext();
} }
...@@ -51,8 +54,10 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr ...@@ -51,8 +54,10 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
// Get the pragma batch fix. // Get the pragma batch fix.
if (pragmaActionsBuilder.Count > 0) if (pragmaActionsBuilder.Count > 0)
{ {
var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document, var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext); _suppressionFixProvider, document,
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(),
fixAllState, cancellationToken);
addFix(pragmaBatchFix); addFix(pragmaBatchFix);
} }
......
...@@ -32,7 +32,9 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) ...@@ -32,7 +32,9 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
_suppressionFixProvider = suppressionFixProvider; _suppressionFixProvider = suppressionFixProvider;
} }
public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext) public override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
// Batch all the pragma remove suppression fixes by executing them sequentially for the document. // Batch all the pragma remove suppression fixes by executing them sequentially for the document.
var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>(); var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>();
...@@ -40,14 +42,15 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr ...@@ -40,14 +42,15 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && d.IsSuppressed)) foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && d.IsSuppressed))
{ {
var span = diagnostic.Location.SourceSpan; var span = diagnostic.Location.SourceSpan;
var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(document, span, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false); var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(
document, span, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);
var removeSuppressionFix = removeSuppressionFixes.SingleOrDefault(); var removeSuppressionFix = removeSuppressionFixes.SingleOrDefault();
if (removeSuppressionFix != null) if (removeSuppressionFix != null)
{ {
var codeAction = removeSuppressionFix.Action as RemoveSuppressionCodeAction; var codeAction = removeSuppressionFix.Action as RemoveSuppressionCodeAction;
if (codeAction != null) if (codeAction != null)
{ {
if (fixAllContext.IsFixMultiple) if (fixAllState.IsFixMultiple)
{ {
codeAction = codeAction.CloneForFixMultipleContext(); codeAction = codeAction.CloneForFixMultipleContext();
} }
...@@ -69,22 +72,27 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr ...@@ -69,22 +72,27 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr
// Get the pragma batch fix. // Get the pragma batch fix.
if (pragmaActionsBuilder.Count > 0) if (pragmaActionsBuilder.Count > 0)
{ {
var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document, var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext); _suppressionFixProvider, document,
pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(),
fixAllState, cancellationToken);
addFix(pragmaBatchFix); addFix(pragmaBatchFix);
} }
} }
public async override Task AddProjectFixesAsync(Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext) public async override Task AddProjectFixesAsync(
Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed)) foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed))
{ {
var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(project, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false); var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(
project, SpecializedCollections.SingletonEnumerable(diagnostic), cancellationToken).ConfigureAwait(false);
var removeSuppressionCodeAction = removeSuppressionFixes.SingleOrDefault()?.Action as RemoveSuppressionCodeAction; var removeSuppressionCodeAction = removeSuppressionFixes.SingleOrDefault()?.Action as RemoveSuppressionCodeAction;
if (removeSuppressionCodeAction != null) if (removeSuppressionCodeAction != null)
{ {
if (fixAllContext.IsFixMultiple) if (fixAllState.IsFixMultiple)
{ {
removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext(); removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext();
} }
...@@ -94,14 +102,14 @@ public async override Task AddProjectFixesAsync(Project project, ImmutableArray< ...@@ -94,14 +102,14 @@ public async override Task AddProjectFixesAsync(Project project, ImmutableArray<
} }
} }
public override async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeAction> batchOfFixes, FixAllContext fixAllContext) public override async Task<CodeAction> TryGetMergedFixAsync(
IEnumerable<CodeAction> batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken)
{ {
// Batch all the attribute removal fixes into a single fix. // Batch all the attribute removal fixes into a single fix.
// Pragma removal fixes have already been batch for each document AddDocumentFixes method. // Pragma removal fixes have already been batch for each document AddDocumentFixes method.
// This ensures no merge conflicts in merging all fixes by our base implementation. // This ensures no merge conflicts in merging all fixes by our base implementation.
var cancellationToken = fixAllContext.CancellationToken; var oldSolution = fixAllState.Project.Solution;
var oldSolution = fixAllContext.Project.Solution;
var currentSolution = oldSolution; var currentSolution = oldSolution;
var attributeRemoveFixes = new List<AttributeRemoveAction>(); var attributeRemoveFixes = new List<AttributeRemoveAction>();
...@@ -139,13 +147,13 @@ public override async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeActi ...@@ -139,13 +147,13 @@ public override async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeActi
var batchAttributeRemoveFix = Create( var batchAttributeRemoveFix = Create(
attributeRemoveFixes.First().Title, attributeRemoveFixes.First().Title,
createChangedSolution: ct => Task.FromResult(currentSolution), createChangedSolution: ct => Task.FromResult(currentSolution),
equivalenceKey: fixAllContext.CodeActionEquivalenceKey); equivalenceKey: fixAllState.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
newBatchOfFixes.Insert(0, batchAttributeRemoveFix); newBatchOfFixes.Insert(0, batchAttributeRemoveFix);
} }
return await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllContext).ConfigureAwait(false); return await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllState, cancellationToken).ConfigureAwait(false);
} }
private static async Task<ImmutableArray<SyntaxNode>> GetAttributeNodesToFixAsync(ImmutableArray<AttributeRemoveAction> attributeRemoveFixes, CancellationToken cancellationToken) private static async Task<ImmutableArray<SyntaxNode>> GetAttributeNodesToFixAsync(ImmutableArray<AttributeRemoveAction> attributeRemoveFixes, CancellationToken cancellationToken)
......
...@@ -143,7 +143,7 @@ private Task ClearOnlyDocumentStates(Document document) ...@@ -143,7 +143,7 @@ private Task ClearOnlyDocumentStates(Document document)
private bool CheckOptions(Project project, bool forceAnalysis) private bool CheckOptions(Project project, bool forceAnalysis)
{ {
var workspace = project.Solution.Workspace; var workspace = project.Solution.Workspace;
if (workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, project.Language) && if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace, project.Language) &&
workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis)) workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
{ {
return true; return true;
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Shared.Options namespace Microsoft.CodeAnalysis.Shared.Options
...@@ -9,12 +8,33 @@ internal static class ServiceFeatureOnOffOptions ...@@ -9,12 +8,33 @@ internal static class ServiceFeatureOnOffOptions
{ {
public const string OptionName = "ServiceFeaturesOnOff"; public const string OptionName = "ServiceFeaturesOnOff";
private const bool CSharpClosedFileDiagnosticsEnabledByDefault = false;
private const bool DefaultClosedFileDiagnosticsEnabledByDefault = true;
/// <summary> /// <summary>
/// this option is solely for performance. don't confused by option name. /// this option is solely for performance. don't confused by option name.
/// this option doesn't mean we will show all diagnostics that belong to opened files when turned off, /// this option doesn't mean we will show all diagnostics that belong to opened files when turned off,
/// rather it means we will only show diagnostics that are cheap to calculate for small scope such as opened files. /// rather it means we will only show diagnostics that are cheap to calculate for small scope such as opened files.
/// </summary> /// </summary>
public static readonly PerLanguageOption<bool> ClosedFileDiagnostic = new PerLanguageOption<bool>( public static readonly PerLanguageOption<bool?> ClosedFileDiagnostic = new PerLanguageOption<bool?>(OptionName, "Closed File Diagnostic", defaultValue: null);
OptionName, "Closed File Diagnostic", defaultValue: true, perLanguageDefaults: ImmutableDictionary<string, bool>.Empty.Add(LanguageNames.CSharp, false));
public static bool IsClosedFileDiagnosticsEnabled(Workspace workspace, string language)
{
var optionsService = workspace.Services.GetService<IOptionService>();
return optionsService != null && IsClosedFileDiagnosticsEnabled(optionsService, language);
}
public static bool IsClosedFileDiagnosticsEnabled(IOptionService optionService, string language)
{
var option = optionService.GetOption(ClosedFileDiagnostic, language);
if (!option.HasValue)
{
return language == LanguageNames.CSharp ?
CSharpClosedFileDiagnosticsEnabledByDefault :
DefaultClosedFileDiagnosticsEnabledByDefault;
}
return option.Value;
}
} }
} }
...@@ -21,44 +21,44 @@ Supported Platforms: ...@@ -21,44 +21,44 @@ Supported Platforms:
<group targetFramework="netstandard1.3"> <group targetFramework="netstandard1.3">
<dependency id="Microsoft.CodeAnalysis.Analyzers" version="$codeAnalysisAnalyzersVersion$" /> <dependency id="Microsoft.CodeAnalysis.Analyzers" version="$codeAnalysisAnalyzersVersion$" />
<dependency id="System.AppContext" version="4.1.0-rc2-24008" /> <dependency id="System.AppContext" version="4.1.0-rc2-24022" />
<dependency id="System.Collections" version="4.0.11-rc2-24008" /> <dependency id="System.Collections" version="4.0.11-rc2-24022" />
<dependency id="System.Collections.Concurrent" version="4.0.12-rc2-24008" /> <dependency id="System.Collections.Concurrent" version="4.0.12-rc2-24022" />
<dependency id="System.Collections.Immutable" version="1.2.0-rc2-24008" /> <dependency id="System.Collections.Immutable" version="1.2.0-rc2-24022" />
<dependency id="System.Console" version="4.0.0-rc2-24008" /> <dependency id="System.Console" version="4.0.0-rc2-24022" />
<dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24008" /> <dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24022" />
<dependency id="System.Diagnostics.FileVersionInfo" version="4.0.0-rc2-24008" exclude="Compile" /> <dependency id="System.Diagnostics.FileVersionInfo" version="4.0.0-rc2-24022" exclude="Compile" />
<dependency id="System.Diagnostics.StackTrace" version="4.0.1-rc2-24008" exclude="Compile" /> <dependency id="System.Diagnostics.StackTrace" version="4.0.1-rc2-24022" exclude="Compile" />
<dependency id="System.Diagnostics.Tools" version="4.0.1-rc2-24008" /> <dependency id="System.Diagnostics.Tools" version="4.0.1-rc2-24022" />
<dependency id="System.Dynamic.Runtime" version="4.0.11-rc2-24008" /> <dependency id="System.Dynamic.Runtime" version="4.0.11-rc2-24022" />
<dependency id="System.Globalization" version="4.0.11-rc2-24008" /> <dependency id="System.Globalization" version="4.0.11-rc2-24022" />
<dependency id="System.IO.FileSystem" version="4.0.1-rc2-24008" /> <dependency id="System.IO.FileSystem" version="4.0.1-rc2-24022" />
<dependency id="System.IO.FileSystem.Primitives" version="4.0.1-rc2-24008" /> <dependency id="System.IO.FileSystem.Primitives" version="4.0.1-rc2-24022" />
<dependency id="System.Linq" version="4.1.0-rc2-24008" /> <dependency id="System.Linq" version="4.1.0-rc2-24022" />
<dependency id="System.Linq.Expressions" version="4.0.11-rc2-24008" /> <dependency id="System.Linq.Expressions" version="4.0.11-rc2-24022" />
<dependency id="System.Reflection" version="4.1.0-rc2-24008" /> <dependency id="System.Reflection" version="4.1.0-rc2-24022" />
<dependency id="System.Reflection.Metadata" version="1.3.0-rc2-24008" /> <dependency id="System.Reflection.Metadata" version="1.3.0-rc2-24022" />
<dependency id="System.Reflection.Primitives" version="4.0.1-rc2-24008" /> <dependency id="System.Reflection.Primitives" version="4.0.1-rc2-24022" />
<dependency id="System.Resources.ResourceManager" version="4.0.1-rc2-24008" /> <dependency id="System.Resources.ResourceManager" version="4.0.1-rc2-24022" />
<dependency id="System.Runtime" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Handles" version="4.0.1-rc2-24008" /> <dependency id="System.Runtime.Handles" version="4.0.1-rc2-24022" />
<dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Numerics" version="4.0.1-rc2-24008" /> <dependency id="System.Runtime.Numerics" version="4.0.1-rc2-24022" />
<dependency id="System.Security.Cryptography.Algorithms" version="4.1.0-rc2-24008" /> <dependency id="System.Security.Cryptography.Algorithms" version="4.1.0-rc2-24022" />
<dependency id="System.Security.Cryptography.Encoding" version="4.0.0-rc2-24008" /> <dependency id="System.Security.Cryptography.Encoding" version="4.0.0-rc2-24022" />
<dependency id="System.Security.Cryptography.X509Certificates" version="4.1.0-rc2-24008" /> <dependency id="System.Security.Cryptography.X509Certificates" version="4.1.0-rc2-24022" />
<dependency id="System.Text.Encoding" version="4.0.11-rc2-24008" /> <dependency id="System.Text.Encoding" version="4.0.11-rc2-24022" />
<dependency id="System.Text.Encoding.CodePages" version="4.0.1-rc2-24008" exclude="Compile" /> <dependency id="System.Text.Encoding.CodePages" version="4.0.1-rc2-24022" exclude="Compile" />
<dependency id="System.Text.Encoding.Extensions" version="4.0.11-rc2-24008" /> <dependency id="System.Text.Encoding.Extensions" version="4.0.11-rc2-24022" />
<dependency id="System.Threading" version="4.0.11-rc2-24008" exclude="Compile" /> <dependency id="System.Threading" version="4.0.11-rc2-24022" exclude="Compile" />
<dependency id="System.Threading.Tasks" version="4.0.11-rc2-24008" /> <dependency id="System.Threading.Tasks" version="4.0.11-rc2-24022" />
<dependency id="System.Threading.Tasks.Parallel" version="4.0.1-rc2-24008" /> <dependency id="System.Threading.Tasks.Parallel" version="4.0.1-rc2-24022" />
<dependency id="System.Threading.Thread" version="4.0.0-rc2-24008" exclude="Compile" /> <dependency id="System.Threading.Thread" version="4.0.0-rc2-24022" exclude="Compile" />
<dependency id="System.Xml.ReaderWriter" version="4.0.11-rc2-24008" /> <dependency id="System.Xml.ReaderWriter" version="4.0.11-rc2-24022" />
<dependency id="System.Xml.XDocument" version="4.0.11-rc2-24008" /> <dependency id="System.Xml.XDocument" version="4.0.11-rc2-24022" />
<dependency id="System.Xml.XmlDocument" version="4.0.1-rc2-24008" exclude="Compile" /> <dependency id="System.Xml.XmlDocument" version="4.0.1-rc2-24022" exclude="Compile" />
<dependency id="System.Xml.XPath.XDocument" version="4.0.1-rc2-24008" exclude="Compile" /> <dependency id="System.Xml.XPath.XDocument" version="4.0.1-rc2-24022" exclude="Compile" />
</group> </group>
</dependencies> </dependencies>
......
...@@ -18,25 +18,25 @@ ...@@ -18,25 +18,25 @@
<dependencies> <dependencies>
<dependency id="Microsoft.CodeAnalysis.Common" version="[$version$]" /> <dependency id="Microsoft.CodeAnalysis.Common" version="[$version$]" />
<dependency id="System.AppContext" version="4.1.0-rc2-24008" /> <dependency id="System.AppContext" version="4.1.0-rc2-24022" />
<dependency id="System.Collections" version="4.0.11-rc2-24008" /> <dependency id="System.Collections" version="4.0.11-rc2-24022" />
<dependency id="System.Collections.Immutable" version="1.2.0-rc2-24008" /> <dependency id="System.Collections.Immutable" version="1.2.0-rc2-24022" />
<dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24008" /> <dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24022" />
<dependency id="System.Diagnostics.StackTrace" version="4.0.1-rc2-24008" /> <dependency id="System.Diagnostics.StackTrace" version="4.0.1-rc2-24022" />
<dependency id="System.Diagnostics.Tools" version="4.0.1-rc2-24008" /> <dependency id="System.Diagnostics.Tools" version="4.0.1-rc2-24022" />
<dependency id="System.Globalization" version="4.0.11-rc2-24008" /> <dependency id="System.Globalization" version="4.0.11-rc2-24022" />
<dependency id="System.IO" version="4.1.0-rc2-24008" /> <dependency id="System.IO" version="4.1.0-rc2-24022" />
<dependency id="System.IO.FileSystem" version="4.0.1-rc2-24008" /> <dependency id="System.IO.FileSystem" version="4.0.1-rc2-24022" />
<dependency id="System.Linq" version="4.1.0-rc2-24008" /> <dependency id="System.Linq" version="4.1.0-rc2-24022" />
<dependency id="System.Linq.Expressions" version="4.0.11-rc2-24008" /> <dependency id="System.Linq.Expressions" version="4.0.11-rc2-24022" />
<dependency id="System.Reflection" version="4.1.0-rc2-24008" /> <dependency id="System.Reflection" version="4.1.0-rc2-24022" />
<dependency id="System.Reflection.Extensions" version="4.0.1-rc2-24008" /> <dependency id="System.Reflection.Extensions" version="4.0.1-rc2-24022" />
<dependency id="System.Resources.ResourceManager" version="4.0.1-rc2-24008" /> <dependency id="System.Resources.ResourceManager" version="4.0.1-rc2-24022" />
<dependency id="System.Runtime" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24022" />
<dependency id="System.Threading" version="4.0.11-rc2-24008" /> <dependency id="System.Threading" version="4.0.11-rc2-24022" />
<dependency id="System.Threading.Tasks" version="4.0.11-rc2-24008" /> <dependency id="System.Threading.Tasks" version="4.0.11-rc2-24022" />
</dependencies> </dependencies>
</metadata> </metadata>
<files> <files>
......
...@@ -19,30 +19,7 @@ ...@@ -19,30 +19,7 @@
<group targetFramework="dnxcore50"> <group targetFramework="dnxcore50">
<dependency id="Microsoft.CodeAnalysis.Compilers" version="$version$" /> <dependency id="Microsoft.CodeAnalysis.Compilers" version="$version$" />
<dependency id="Microsoft.CodeAnalysis.Scripting" version="$version$" /> <dependency id="Microsoft.CodeAnalysis.Scripting" version="$version$" />
<dependency id="System.AppContext" version="4.0.1-rc2-24008" /> <dependency id="NETStandard.Library" version="1.5.0-rc2-24022" />
<dependency id="System.Collections" version="4.0.11-rc2-24008" />
<dependency id="System.Collections.Immutable" version="1.1.37" />
<dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24008" />
<dependency id="System.Diagnostics.StackTrace" version="4.0.1-rc2-24008" />
<dependency id="System.Diagnostics.Tools" version="4.0.1-rc2-24008" />
<dependency id="System.Globalization" version="4.0.11-rc2-24008" />
<dependency id="System.IO" version="4.0.11-rc2-24008" />
<dependency id="System.IO.FileSystem" version="4.0.1-rc2-24008" />
<dependency id="System.IO.FileSystem.Primitives" version="4.0.1-rc2-24008" />
<dependency id="System.Linq" version="4.0.1-rc2-24008" />
<dependency id="System.Linq.Expressions" version="4.0.11-rc2-24008" />
<dependency id="System.Reflection" version="4.1.0-rc2-24008" />
<dependency id="System.Reflection.Metadata" version="1.1.0-rc2-24008" />
<dependency id="System.Reflection.Primitives" version="4.0.1-rc2-24008" />
<dependency id="System.Resources.ResourceManager" version="4.0.1-rc2-24008" />
<dependency id="System.Runtime" version="4.0.21-rc2-24008" />
<dependency id="System.Runtime.Extensions" version="4.0.11-rc2-24008" />
<dependency id="System.Runtime.Handles" version="4.0.1-rc2-24008" />
<dependency id="System.Runtime.InteropServices" version="4.0.21-rc2-24008" />
<dependency id="System.Text.Encoding" version="4.0.11-rc2-24008" />
<dependency id="System.Text.Encoding.Extensions" version="4.0.11-rc2-24008" />
<dependency id="System.Threading" version="4.0.11-rc2-24008" />
<dependency id="System.Threading.Tasks" version="4.0.11-rc2-24008" />
</group> </group>
</dependencies> </dependencies>
</metadata> </metadata>
......
...@@ -18,44 +18,44 @@ ...@@ -18,44 +18,44 @@
<dependencies> <dependencies>
<group targetFramework="dnxcore50"> <group targetFramework="dnxcore50">
<dependency id="Microsoft.CodeAnalysis.Compilers" version="[$version$]" /> <dependency id="Microsoft.CodeAnalysis.Compilers" version="[$version$]" />
<dependency id="System.AppContext" version="4.1.0-rc2-24008" /> <dependency id="System.AppContext" version="4.1.0-rc2-24022" />
<dependency id="System.Collections" version="4.0.11-rc2-24008" /> <dependency id="System.Collections" version="4.0.11-rc2-24022" />
<dependency id="System.Collections.Concurrent" version="4.0.12-rc2-24008" /> <dependency id="System.Collections.Concurrent" version="4.0.12-rc2-24022" />
<dependency id="System.Collections.Immutable" version="1.2.0-rc2-24008" /> <dependency id="System.Collections.Immutable" version="1.2.0-rc2-24022" />
<dependency id="System.Console" version="4.0.0-rc2-24008" /> <dependency id="System.Console" version="4.0.0-rc2-24022" />
<dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24008" /> <dependency id="System.Diagnostics.Debug" version="4.0.11-rc2-24022" />
<dependency id="System.Diagnostics.FileVersionInfo" version="4.0.0-rc2-24008" /> <dependency id="System.Diagnostics.FileVersionInfo" version="4.0.0-rc2-24022" />
<dependency id="System.Diagnostics.StackTrace" version="4.0.1-rc2-24008" /> <dependency id="System.Diagnostics.StackTrace" version="4.0.1-rc2-24022" />
<dependency id="System.Diagnostics.Tools" version="4.0.1-rc2-24008" /> <dependency id="System.Diagnostics.Tools" version="4.0.1-rc2-24022" />
<dependency id="System.Dynamic.Runtime" version="4.0.11-rc2-24008" /> <dependency id="System.Dynamic.Runtime" version="4.0.11-rc2-24022" />
<dependency id="System.Globalization" version="4.0.11-rc2-24008" /> <dependency id="System.Globalization" version="4.0.11-rc2-24022" />
<dependency id="System.IO.FileSystem" version="4.0.1-rc2-24008" /> <dependency id="System.IO.FileSystem" version="4.0.1-rc2-24022" />
<dependency id="System.IO.FileSystem.Primitives" version="4.0.1-rc2-24008" /> <dependency id="System.IO.FileSystem.Primitives" version="4.0.1-rc2-24022" />
<dependency id="System.Linq" version="4.1.0-rc2-24008" /> <dependency id="System.Linq" version="4.1.0-rc2-24022" />
<dependency id="System.Linq.Expressions" version="4.0.11-rc2-24008" /> <dependency id="System.Linq.Expressions" version="4.0.11-rc2-24022" />
<dependency id="System.Reflection" version="4.1.0-rc2-24008" /> <dependency id="System.Reflection" version="4.1.0-rc2-24022" />
<dependency id="System.Reflection.Primitives" version="4.0.1-rc2-24008" /> <dependency id="System.Reflection.Primitives" version="4.0.1-rc2-24022" />
<dependency id="System.Resources.ResourceManager" version="4.0.1-rc2-24008" /> <dependency id="System.Resources.ResourceManager" version="4.0.1-rc2-24022" />
<dependency id="System.Runtime" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.Extensions" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Handles" version="4.0.1-rc2-24008" /> <dependency id="System.Runtime.Handles" version="4.0.1-rc2-24022" />
<dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24008" /> <dependency id="System.Runtime.InteropServices" version="4.1.0-rc2-24022" />
<dependency id="System.Runtime.Loader" version="4.0.0-rc2-24008" /> <dependency id="System.Runtime.Loader" version="4.0.0-rc2-24022" />
<dependency id="System.Runtime.Numerics" version="4.0.1-rc2-24008" /> <dependency id="System.Runtime.Numerics" version="4.0.1-rc2-24022" />
<dependency id="System.Security.Cryptography.Algorithms" version="4.1.0-rc2-24008" /> <dependency id="System.Security.Cryptography.Algorithms" version="4.1.0-rc2-24022" />
<dependency id="System.Security.Cryptography.Encoding" version="4.0.0-rc2-24008" /> <dependency id="System.Security.Cryptography.Encoding" version="4.0.0-rc2-24022" />
<dependency id="System.Security.Cryptography.X509Certificates" version="4.1.0-rc2-24008" /> <dependency id="System.Security.Cryptography.X509Certificates" version="4.1.0-rc2-24022" />
<dependency id="System.Text.Encoding" version="4.0.11-rc2-24008" /> <dependency id="System.Text.Encoding" version="4.0.11-rc2-24022" />
<dependency id="System.Text.Encoding.CodePages" version="4.0.1-rc2-24008" /> <dependency id="System.Text.Encoding.CodePages" version="4.0.1-rc2-24022" />
<dependency id="System.Text.Encoding.Extensions" version="4.0.11-rc2-24008" /> <dependency id="System.Text.Encoding.Extensions" version="4.0.11-rc2-24022" />
<dependency id="System.Threading" version="4.0.11-rc2-24008" /> <dependency id="System.Threading" version="4.0.11-rc2-24022" />
<dependency id="System.Threading.Tasks" version="4.0.11-rc2-24008" /> <dependency id="System.Threading.Tasks" version="4.0.11-rc2-24022" />
<dependency id="System.Threading.Tasks.Parallel" version="4.0.1-rc2-24008" /> <dependency id="System.Threading.Tasks.Parallel" version="4.0.1-rc2-24022" />
<dependency id="System.Threading.Thread" version="4.0.0-rc2-24008" /> <dependency id="System.Threading.Thread" version="4.0.0-rc2-24022" />
<dependency id="System.Xml.ReaderWriter" version="4.0.11-rc2-24008" /> <dependency id="System.Xml.ReaderWriter" version="4.0.11-rc2-24022" />
<dependency id="System.Xml.XDocument" version="4.0.11-rc2-24008" /> <dependency id="System.Xml.XDocument" version="4.0.11-rc2-24022" />
<dependency id="System.Xml.XmlDocument" version="4.0.1-rc2-24008" /> <dependency id="System.Xml.XmlDocument" version="4.0.1-rc2-24022" />
<dependency id="System.Xml.XPath.XDocument" version="4.0.1-rc2-24008" /> <dependency id="System.Xml.XPath.XDocument" version="4.0.1-rc2-24022" />
</group> </group>
</dependencies> </dependencies>
</metadata> </metadata>
......
...@@ -70,9 +70,6 @@ ...@@ -70,9 +70,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.VisualStudio.CoreUtility">
<Private>false</Private>
</Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="System" /> <Reference Include="System" />
......
...@@ -43,6 +43,11 @@ ...@@ -43,6 +43,11 @@
<Name>Composition</Name> <Name>Composition</Name>
<Private>False</Private> <Private>False</Private>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\Dependencies\VisualStudio\VisualStudio.csproj">
<Project>{8da861d8-0cce-4334-b6c0-01a846c881ec}</Project>
<Name>VisualStudio</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
...@@ -84,28 +89,6 @@ ...@@ -84,28 +89,6 @@
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.VisualStudio.CoreUtility, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Editor, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.10.0, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<Reference Include="Microsoft.VisualStudio.Text.Data, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.UI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.UI.Wpf, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TextManager.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>false</Private>
</Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
......
...@@ -39,6 +39,16 @@ ...@@ -39,6 +39,16 @@
<Name>Composition</Name> <Name>Composition</Name>
<Private>False</Private> <Private>False</Private>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\..\Dependencies\VisualStudioText\VisualStudioText.csproj">
<Project>{c25768b3-2fe1-4d6d-8c17-a6acd56f8389}</Project>
<Name>VisualStudioText</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Dependencies\VisualStudio\VisualStudio.csproj">
<Project>{8da861d8-0cce-4334-b6c0-01a846c881ec}</Project>
<Name>VisualStudio</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<NonShipping>true</NonShipping> <NonShipping>true</NonShipping>
...@@ -80,46 +90,6 @@ ...@@ -80,46 +90,6 @@
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.VisualStudio.CoreUtility">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Editor">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.OLE.Interop">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.10.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.Data">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.Logic">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.UI">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.UI.Wpf">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TextManager.Interop">
<Private>false</Private>
</Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="System" /> <Reference Include="System" />
......
...@@ -130,6 +130,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moq.net", "..\Dependencies\ ...@@ -130,6 +130,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moq.net", "..\Dependencies\
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Composition", "..\Dependencies\Composition\Composition.csproj", "{A57DDFE5-AB0E-4371-98E5-11B9218DF11C}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Composition", "..\Dependencies\Composition\Composition.csproj", "{A57DDFE5-AB0E-4371-98E5-11B9218DF11C}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualStudio", "..\Dependencies\VisualStudio\VisualStudio.csproj", "{8DA861D8-0CCE-4334-B6C0-01A846C881EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VisualStudioText", "..\Dependencies\VisualStudioText\VisualStudioText.csproj", "{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -556,6 +560,30 @@ Global ...@@ -556,6 +560,30 @@ Global
{A57DDFE5-AB0E-4371-98E5-11B9218DF11C}.Release|Mixed Platforms.Build.0 = Debug|Any CPU {A57DDFE5-AB0E-4371-98E5-11B9218DF11C}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{A57DDFE5-AB0E-4371-98E5-11B9218DF11C}.Release|x86.ActiveCfg = Debug|Any CPU {A57DDFE5-AB0E-4371-98E5-11B9218DF11C}.Release|x86.ActiveCfg = Debug|Any CPU
{A57DDFE5-AB0E-4371-98E5-11B9218DF11C}.Release|x86.Build.0 = Debug|Any CPU {A57DDFE5-AB0E-4371-98E5-11B9218DF11C}.Release|x86.Build.0 = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Debug|x86.ActiveCfg = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Debug|x86.Build.0 = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Release|Any CPU.Build.0 = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Release|x86.ActiveCfg = Debug|Any CPU
{8DA861D8-0CCE-4334-B6C0-01A846C881EC}.Release|x86.Build.0 = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Debug|x86.ActiveCfg = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Debug|x86.Build.0 = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Release|Any CPU.Build.0 = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Release|x86.ActiveCfg = Debug|Any CPU
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389}.Release|x86.Build.0 = Debug|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
...@@ -616,5 +644,7 @@ Global ...@@ -616,5 +644,7 @@ Global
{8635CB8F-D210-41ED-B4FF-71502CDB475C} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2} {8635CB8F-D210-41ED-B4FF-71502CDB475C} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2}
{A32EAB7F-691C-4D00-98C4-F50C37BB4754} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2} {A32EAB7F-691C-4D00-98C4-F50C37BB4754} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2}
{A57DDFE5-AB0E-4371-98E5-11B9218DF11C} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2} {A57DDFE5-AB0E-4371-98E5-11B9218DF11C} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2}
{8DA861D8-0CCE-4334-B6C0-01A846C881EC} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2}
{C25768B3-2FE1-4D6D-8C17-A6ACD56F8389} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal
...@@ -30,6 +30,16 @@ ...@@ -30,6 +30,16 @@
<Name>Composition</Name> <Name>Composition</Name>
<Private>False</Private> <Private>False</Private>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\..\Dependencies\VisualStudioText\VisualStudioText.csproj">
<Project>{c25768b3-2fe1-4d6d-8c17-a6acd56f8389}</Project>
<Name>VisualStudioText</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Dependencies\VisualStudio\VisualStudio.csproj">
<Project>{8da861d8-0cce-4334-b6c0-01a846c881ec}</Project>
<Name>VisualStudio</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
<NonShipping>true</NonShipping> <NonShipping>true</NonShipping>
...@@ -74,46 +84,6 @@ ...@@ -74,46 +84,6 @@
<Reference Include="EnvDTE"> <Reference Include="EnvDTE">
<Private>false</Private> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Microsoft.VisualStudio.CoreUtility">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Editor">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.OLE.Interop">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.10.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.Data">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.Logic">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.UI">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Text.UI.Wpf">
<Private>false</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TextManager.Interop">
<Private>false</Private>
</Reference>
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="System" /> <Reference Include="System" />
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<!-- Workaround for https://github.com/NuGet/Home/issues/1471 --> <!-- Workaround for https://github.com/NuGet/Home/issues/1471 -->
<Reference Include="$(NuGetPackageRoot)\System.Runtime.Loader\4.0.0-rc2-23931\ref\netstandard1.5\System.Runtime.Loader.dll"> <Reference Include="$(NuGetPackageRoot)\System.Runtime.Loader\4.0.0-rc2-24022\ref\netstandard1.5\System.Runtime.Loader.dll">
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
......
...@@ -41,13 +41,22 @@ foreach (dynamic test in testInstances) ...@@ -41,13 +41,22 @@ foreach (dynamic test in testInstances)
for (int i = 0; i < iterations; i++) for (int i = 0; i < iterations; i++)
{ {
traceManager.StartScenarios();
traceManager.Start(); traceManager.Start();
traceManager.StartScenario(test.Name + i, test.MeasuredProc); traceManager.StartScenarios();
traceManager.StartEvent();
test.Test(); if (test.ProvidesScenarios)
traceManager.EndEvent(); {
traceManager.EndScenario(); traceManager.WriteScenarios(test.GetScenarios());
test.Test();
}
else
{
traceManager.StartScenario(test.Name + i, test.MeasuredProc);
traceManager.StartEvent();
test.Test();
traceManager.EndEvent();
traceManager.EndScenario();
}
traceManager.EndScenarios(); traceManager.EndScenarios();
traceManager.WriteScenariosFileToDisk(); traceManager.WriteScenariosFileToDisk();
......
...@@ -30,6 +30,11 @@ class CSharpCompilerTest: PerfTest ...@@ -30,6 +30,11 @@ class CSharpCompilerTest: PerfTest
public override int Iterations => 2; public override int Iterations => 2;
public override string Name => "csharp " + _rspFile; public override string Name => "csharp " + _rspFile;
public override string MeasuredProc => "csc"; public override string MeasuredProc => "csc";
public override bool ProvidesScenarios => false;
public override string[] GetScenarios()
{
throw new System.NotImplementedException();
}
} }
TestThisPlease( TestThisPlease(
......
...@@ -24,6 +24,11 @@ class HelloWorldTest: PerfTest ...@@ -24,6 +24,11 @@ class HelloWorldTest: PerfTest
public override int Iterations => 2; public override int Iterations => 2;
public override string Name => "hello world"; public override string Name => "hello world";
public override string MeasuredProc => "csc"; public override string MeasuredProc => "csc";
public override bool ProvidesScenarios => false;
public override string[] GetScenarios()
{
throw new System.NotImplementedException();
}
} }
TestThisPlease(new HelloWorldTest()); TestThisPlease(new HelloWorldTest());
...@@ -51,7 +51,7 @@ public class ScenarioGenerator ...@@ -51,7 +51,7 @@ public class ScenarioGenerator
public void AddStartEvent(int absoluteInstance) public void AddStartEvent(int absoluteInstance)
{ {
WriteToBuffer($@"<from providerGuid=""{KernelProviderGuid}"" absoluteInstance=""{absoluteInstance}"" process=""csc"" eventName = ""Process/Start""/>"); WriteToBuffer($@"<from providerGuid=""{KernelProviderGuid}"" absoluteInstance=""{absoluteInstance}"" process=""csc"" eventName=""Process/Start""/>");
} }
public void AddEndEvent() public void AddEndEvent()
...@@ -63,6 +63,11 @@ public class ScenarioGenerator ...@@ -63,6 +63,11 @@ public class ScenarioGenerator
{ {
WriteToBuffer($@"<!-- {comment} -->"); WriteToBuffer($@"<!-- {comment} -->");
} }
public void AddLine(string line)
{
WriteToBuffer(line);
}
public void WriteToDisk() public void WriteToDisk()
{ {
......
...@@ -138,6 +138,8 @@ abstract class PerfTest: RelativeDirectory { ...@@ -138,6 +138,8 @@ abstract class PerfTest: RelativeDirectory {
Log(description + ": " + value.ToString()); Log(description + ": " + value.ToString());
} }
public abstract bool ProvidesScenarios { get; }
public abstract string[] GetScenarios();
public abstract void Setup(); public abstract void Setup();
public abstract void Test(); public abstract void Test();
public abstract int Iterations { get; } public abstract int Iterations { get; }
......
...@@ -21,6 +21,7 @@ interface ITraceManager ...@@ -21,6 +21,7 @@ interface ITraceManager
void StartScenario(string scenarioName, string processName); void StartScenario(string scenarioName, string processName);
void StartScenarios(); void StartScenarios();
void Stop(); void Stop();
void WriteScenarios(string[] scenarios);
void WriteScenariosFileToDisk(); void WriteScenariosFileToDisk();
} }
...@@ -106,6 +107,10 @@ class NoOpTraceManager : ITraceManager ...@@ -106,6 +107,10 @@ class NoOpTraceManager : ITraceManager
{ {
} }
public void WriteScenarios(string[] scenarios)
{
}
public void WriteScenariosFileToDisk() public void WriteScenariosFileToDisk()
{ {
} }
...@@ -209,6 +214,14 @@ class TraceManager: ITraceManager ...@@ -209,6 +214,14 @@ class TraceManager: ITraceManager
{ {
_scenarioGenerator.AddScenariosFileEnd(); _scenarioGenerator.AddScenariosFileEnd();
} }
public void WriteScenarios(string[] scenarios)
{
foreach (var line in scenarios)
{
_scenarioGenerator.AddLine(line);
}
}
public void WriteScenariosFileToDisk() public void WriteScenariosFileToDisk()
{ {
......
{ {
"dependencies": { "dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-23931", "Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24022",
"Microsoft.NETCore.Platforms": "1.0.1-rc2-23931", "Microsoft.NETCore.Platforms": "1.0.1-rc2-24022",
"Microsoft.NETCore.Runtime.CoreCLR": "1.0.2-rc2-23931", "Microsoft.NETCore.Runtime.CoreCLR": "1.0.2-rc2-24022",
"Microsoft.NETCore.TestHost": "1.0.0-rc2-23931", "Microsoft.NETCore.TestHost": "1.0.0-rc2-24022",
"System.AppContext": "4.1.0-rc2-23931", "System.AppContext": "4.1.0-rc2-24022",
"System.Collections": "4.0.11-rc2-23931", "System.Collections": "4.0.11-rc2-24022",
"System.Collections.Concurrent": "4.0.12-rc2-23931", "System.Collections.Concurrent": "4.0.12-rc2-24022",
"System.Collections.Immutable": "1.2.0-rc2-23931", "System.Collections.Immutable": "1.2.0-rc2-24022",
"System.Console": "4.0.0-rc2-23931", "System.Console": "4.0.0-rc2-24022",
"System.Diagnostics.Debug": "4.0.11-rc2-23931", "System.Diagnostics.Debug": "4.0.11-rc2-24022",
"System.Diagnostics.FileVersionInfo": "4.0.0-rc2-23931", "System.Diagnostics.FileVersionInfo": "4.0.0-rc2-24022",
"System.Diagnostics.Process": "4.1.0-rc2-23931", "System.Diagnostics.Process": "4.1.0-rc2-24022",
"System.Diagnostics.StackTrace": "4.0.1-rc2-23931", "System.Diagnostics.StackTrace": "4.0.1-rc2-24022",
"System.Diagnostics.Tools": "4.0.1-rc2-23931", "System.Diagnostics.Tools": "4.0.1-rc2-24022",
"System.Dynamic.Runtime": "4.0.11-rc2-23931", "System.Dynamic.Runtime": "4.0.11-rc2-24022",
"System.Globalization": "4.0.11-rc2-23931", "System.Globalization": "4.0.11-rc2-24022",
"System.IO.FileSystem": "4.0.1-rc2-23931", "System.IO.FileSystem": "4.0.1-rc2-24022",
"System.IO.FileSystem.Primitives": "4.0.1-rc2-23931", "System.IO.FileSystem.Primitives": "4.0.1-rc2-24022",
"System.IO.FileSystem.Watcher": "4.0.0-rc2-23931", "System.IO.FileSystem.Watcher": "4.0.0-rc2-24022",
"System.IO.Pipes": "4.0.0-rc2-23931", "System.IO.Pipes": "4.0.0-rc2-24022",
"System.Linq": "4.1.0-rc2-23931", "System.Linq": "4.1.0-rc2-24022",
"System.Linq.Expressions": "4.0.11-rc2-23931", "System.Linq.Expressions": "4.0.11-rc2-24022",
"System.Net.NameResolution": "4.0.0-rc2-23931", "System.Net.NameResolution": "4.0.0-rc2-24022",
"System.Net.Sockets": "4.1.0-rc2-23931", "System.Net.Sockets": "4.1.0-rc2-24022",
"System.Reflection": "4.1.0-rc2-23931", "System.Reflection": "4.1.0-rc2-24022",
"System.Reflection.Primitives": "4.0.1-rc2-23931", "System.Reflection.Primitives": "4.0.1-rc2-24022",
"System.Resources.ResourceManager": "4.0.1-rc2-23931", "System.Resources.ResourceManager": "4.0.1-rc2-24022",
"System.Runtime": "4.1.0-rc2-23931", "System.Runtime": "4.1.0-rc2-24022",
"System.Runtime.Extensions": "4.1.0-rc2-23931", "System.Runtime.Extensions": "4.1.0-rc2-24022",
"System.Runtime.Handles": "4.0.1-rc2-23931", "System.Runtime.Handles": "4.0.1-rc2-24022",
"System.Runtime.InteropServices": "4.1.0-rc2-23931", "System.Runtime.InteropServices": "4.1.0-rc2-24022",
"System.Runtime.Loader": "4.0.0-rc2-23931", "System.Runtime.Loader": "4.0.0-rc2-24022",
"System.Runtime.Numerics": "4.0.1-rc2-23931", "System.Runtime.Numerics": "4.0.1-rc2-24022",
"System.Security.Cryptography.Algorithms": "4.1.0-rc2-23931", "System.Security.Cryptography.Algorithms": "4.1.0-rc2-24022",
"System.Security.Cryptography.Encoding": "4.0.0-rc2-23931", "System.Security.Cryptography.Encoding": "4.0.0-rc2-24022",
"System.Security.Cryptography.X509Certificates": "4.1.0-rc2-23931", "System.Security.Cryptography.X509Certificates": "4.1.0-rc2-24022",
"System.Text.Encoding": "4.0.11-rc2-23931", "System.Text.Encoding": "4.0.11-rc2-24022",
"System.Text.Encoding.CodePages": "4.0.1-rc2-23931", "System.Text.Encoding.CodePages": "4.0.1-rc2-24022",
"System.Text.Encoding.Extensions": "4.0.11-rc2-23931", "System.Text.Encoding.Extensions": "4.0.11-rc2-24022",
"System.Threading": "4.0.11-rc2-23931", "System.Threading": "4.0.11-rc2-24022",
"System.Threading.Tasks": "4.0.11-rc2-23931", "System.Threading.Tasks": "4.0.11-rc2-24022",
"System.Threading.Tasks.Parallel": "4.0.1-rc2-23931", "System.Threading.Tasks.Parallel": "4.0.1-rc2-24022",
"System.Threading.Thread": "4.0.0-rc2-23931", "System.Threading.Thread": "4.0.0-rc2-24022",
"System.Xml.ReaderWriter": "4.0.11-rc2-23931", "System.Xml.ReaderWriter": "4.0.11-rc2-24022",
"System.Xml.XDocument": "4.0.11-rc2-23931", "System.Xml.XDocument": "4.0.11-rc2-24022",
"System.Xml.XmlDocument": "4.0.1-rc2-23931", "System.Xml.XmlDocument": "4.0.1-rc2-24022",
"System.Xml.XPath.XDocument": "4.0.1-rc2-23931" "System.Xml.XPath.XDocument": "4.0.1-rc2-24022"
}, },
"frameworks": { "frameworks": {
"dnxcore50": { "dnxcore50": {
"imports": "portable-net452" "imports": "portable-net452"
} }
} }
} }
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Completion;
...@@ -36,7 +37,22 @@ public int BringUpOnIdentifier ...@@ -36,7 +37,22 @@ public int BringUpOnIdentifier
set { SetBooleanOption(CompletionOptions.TriggerOnTypingLetters, value); } set { SetBooleanOption(CompletionOptions.TriggerOnTypingLetters, value); }
} }
[Obsolete("This SettingStore option has now been deprecated in favor of CSharpClosedFileDiagnostics")]
public int ClosedFileDiagnostics public int ClosedFileDiagnostics
{
get { return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic); }
set
{
// Even though this option has been deprecated, we want to respect the setting if the user has explicitly turned off closed file diagnostics (which is the non-default value for 'ClosedFileDiagnostics').
// So, we invoke the setter only for value = 0.
if (value == 0)
{
SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value);
}
}
}
public int CSharpClosedFileDiagnostics
{ {
get { return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic); } get { return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic); }
set { SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value); } set { SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value); }
...@@ -520,5 +536,24 @@ private void SetBooleanOption(PerLanguageOption<bool> key, int value) ...@@ -520,5 +536,24 @@ private void SetBooleanOption(PerLanguageOption<bool> key, int value)
optionSet = optionSet.WithChangedOption(key, LanguageNames.CSharp, value != 0); optionSet = optionSet.WithChangedOption(key, LanguageNames.CSharp, value != 0);
_optionService.SetOptions(optionSet); _optionService.SetOptions(optionSet);
} }
private int GetBooleanOption(PerLanguageOption<bool?> key)
{
var option = _optionService.GetOption(key, LanguageNames.CSharp);
if (!option.HasValue)
{
return -1;
}
return option.Value ? 1 : 0;
}
private void SetBooleanOption(PerLanguageOption<bool?> key, int value)
{
bool? boolValue = (value < 0) ? (bool?)null : (value > 0);
var optionSet = _optionService.GetOptions();
optionSet = optionSet.WithChangedOption(key, LanguageNames.CSharp, boolValue);
_optionService.SetOptions(optionSet);
}
} }
} }
...@@ -103,6 +103,20 @@ private bool ShouldIncludeOnOffOption(FieldInfo fieldInfo) ...@@ -103,6 +103,20 @@ private bool ShouldIncludeOnOffOption(FieldInfo fieldInfo)
protected override string SettingStorageRoot { get { return "TextEditor.CSharp.Specific."; } } protected override string SettingStorageRoot { get { return "TextEditor.CSharp.Specific."; } }
protected override string GetStorageKeyForOption(IOption option)
{
var name = option.Name;
if (option == ServiceFeatureOnOffOptions.ClosedFileDiagnostic)
{
// ClosedFileDiagnostics has been deprecated in favor of CSharpClosedFileDiagnostics.
// ClosedFileDiagnostics had a default value of 'true', while CSharpClosedFileDiagnostics has a default value of 'false'.
// We want to ensure that we don't fetch the setting store value for the old flag, as that can cause the default value for this option to change.
name = nameof(AutomationObject.CSharpClosedFileDiagnostics);
}
return SettingStorageRoot + name;
}
protected override bool SupportsOption(IOption option, string languageName) protected override bool SupportsOption(IOption option, string languageName)
{ {
if (option == OrganizerOptions.PlaceSystemNamespaceFirst || if (option == OrganizerOptions.PlaceSystemNamespaceFirst ||
......
...@@ -152,7 +152,7 @@ public void RemoveProject(ProjectId projectId) ...@@ -152,7 +152,7 @@ public void RemoveProject(ProjectId projectId)
private bool CheckOptions(Document document) private bool CheckOptions(Document document)
{ {
if (_workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, document.Project.Language) && if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_workspace, document.Project.Language) &&
_workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis)) _workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis))
{ {
return true; return true;
......
...@@ -251,9 +251,6 @@ ...@@ -251,9 +251,6 @@
<Reference Include="Microsoft.VisualStudio.ExtensionManager, Version=$(VisualStudioReferenceAssemblyVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <Reference Include="Microsoft.VisualStudio.ExtensionManager, Version=$(VisualStudioReferenceAssemblyVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<HintPath>$(DevEnvDir)\PrivateAssemblies\Microsoft.VisualStudio.ExtensionManager.dll</HintPath> <HintPath>$(DevEnvDir)\PrivateAssemblies\Microsoft.VisualStudio.ExtensionManager.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Design.dll">
<HintPath>$(DevEnvDir)\Microsoft.VisualStudio.Shell.Design.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.CSharp" /> <InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.CSharp" />
......
...@@ -34,7 +34,7 @@ public virtual bool TryPersist(OptionKey optionKey, object value) ...@@ -34,7 +34,7 @@ public virtual bool TryPersist(OptionKey optionKey, object value)
return TryPersist(optionKey, value, (r, k, o, v) => r.SetValue(k, (bool)v ? 1 : 0, RegistryValueKind.DWord)); return TryPersist(optionKey, value, (r, k, o, v) => r.SetValue(k, (bool)v ? 1 : 0, RegistryValueKind.DWord));
} }
protected bool TryFetch(OptionKey optionKey, Func<RegistryKey, string, OptionKey, object> valueGetter, out object value) protected bool TryFetch(OptionKey optionKey, Func<RegistryKey, string, IOption, object> valueGetter, out object value)
{ {
if (this.RegistryKey == null) if (this.RegistryKey == null)
{ {
...@@ -58,7 +58,7 @@ protected bool TryFetch(OptionKey optionKey, Func<RegistryKey, string, OptionKey ...@@ -58,7 +58,7 @@ protected bool TryFetch(OptionKey optionKey, Func<RegistryKey, string, OptionKey
return false; return false;
} }
value = valueGetter(subKey, collectionPathAndPropertyName.Item2, optionKey); value = valueGetter(subKey, collectionPathAndPropertyName.Item2, optionKey.Option);
return true; return true;
} }
} }
......
...@@ -146,7 +146,7 @@ public virtual bool TryFetch(OptionKey optionKey, out object value) ...@@ -146,7 +146,7 @@ public virtual bool TryFetch(OptionKey optionKey, out object value)
} }
var storageKey = GetStorageKeyForOption(optionKey.Option); var storageKey = GetStorageKeyForOption(optionKey.Option);
value = this.Manager.GetValueOrDefault(storageKey, optionKey.DefaultValue); value = this.Manager.GetValueOrDefault(storageKey, optionKey.Option.DefaultValue);
return true; return true;
} }
......
...@@ -11,7 +11,7 @@ internal class FullSolutionAnalysisOptionBinding ...@@ -11,7 +11,7 @@ internal class FullSolutionAnalysisOptionBinding
private readonly string _languageName; private readonly string _languageName;
private readonly Option<bool> _fullSolutionAnalysis; private readonly Option<bool> _fullSolutionAnalysis;
private readonly PerLanguageOption<bool> _closedFileDiagnostics; private readonly PerLanguageOption<bool?> _closedFileDiagnostics;
public FullSolutionAnalysisOptionBinding(IOptionService optionService, string languageName) public FullSolutionAnalysisOptionBinding(IOptionService optionService, string languageName)
{ {
...@@ -26,7 +26,7 @@ public bool Value ...@@ -26,7 +26,7 @@ public bool Value
{ {
get get
{ {
return _optionService.GetOption(_closedFileDiagnostics, _languageName) && return ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_optionService, _languageName) &&
_optionService.GetOption(_fullSolutionAnalysis); _optionService.GetOption(_fullSolutionAnalysis);
} }
......
...@@ -44,11 +44,25 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options ...@@ -44,11 +44,25 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
End Set End Set
End Property End Property
<Obsolete("This SettingStore option has now been deprecated in favor of BasicClosedFileDiagnostics")>
Public Property ClosedFileDiagnostics As Boolean Public Property ClosedFileDiagnostics As Boolean
Get Get
Return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic) Return ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_optionService, LanguageNames.VisualBasic)
End Get End Get
Set(value As Boolean) Set(value As Boolean)
' Even though this option has been deprecated, we want to respect the setting if the user has explicitly turned off closed file diagnostics (which is the non-default value for 'ClosedFileDiagnostics').
' So, we invoke the setter only for value = False.
If Not value Then
SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value:=0)
End If
End Set
End Property
Public Property BasicClosedFileDiagnostics As Integer
Get
Return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic)
End Get
Set(value As Integer)
SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value) SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value)
End Set End Set
End Property End Property
...@@ -171,5 +185,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options ...@@ -171,5 +185,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
optionSet = optionSet.WithChangedOption(key, LanguageNames.VisualBasic, value) optionSet = optionSet.WithChangedOption(key, LanguageNames.VisualBasic, value)
_optionService.SetOptions(optionSet) _optionService.SetOptions(optionSet)
End Sub End Sub
Private Function GetBooleanOption(key As PerLanguageOption(Of Boolean?)) As Integer
Dim [option] = _optionService.GetOption(key, LanguageNames.VisualBasic)
If Not [option].HasValue Then
Return -1
End If
Return If([option].Value, 1, 0)
End Function
Private Sub SetBooleanOption(key As PerLanguageOption(Of Boolean?), value As Integer)
Dim boolValue As Boolean? = If(value < 0, Nothing, value > 0)
Dim optionSet = _optionService.GetOptions()
optionSet = optionSet.WithChangedOption(key, LanguageNames.VisualBasic, boolValue)
_optionService.SetOptions(optionSet)
End Sub
End Class End Class
End Namespace End Namespace
...@@ -31,12 +31,12 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext) ...@@ -31,12 +31,12 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
if (fixAllContext.Document != null) if (fixAllContext.Document != null)
{ {
var documentsAndDiagnosticsToFixMap = await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false); var documentsAndDiagnosticsToFixMap = await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false);
return await GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false); return await GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false);
} }
else else
{ {
var projectsAndDiagnosticsToFixMap = await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false); var projectsAndDiagnosticsToFixMap = await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false);
return await GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false); return await GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false);
} }
} }
...@@ -44,7 +44,7 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext) ...@@ -44,7 +44,7 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
internal override async Task<CodeAction> GetFixAsync( internal override async Task<CodeAction> GetFixAsync(
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentsAndDiagnosticsToFixMap, ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentsAndDiagnosticsToFixMap,
FixAllContext fixAllContext) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
if (documentsAndDiagnosticsToFixMap != null && documentsAndDiagnosticsToFixMap.Any()) if (documentsAndDiagnosticsToFixMap != null && documentsAndDiagnosticsToFixMap.Any())
{ {
...@@ -52,22 +52,22 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext) ...@@ -52,22 +52,22 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
var fixesBag = new ConcurrentBag<CodeAction>(); var fixesBag = new ConcurrentBag<CodeAction>();
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, fixAllContext.CancellationToken)) using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, cancellationToken))
{ {
fixAllContext.CancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var documents = documentsAndDiagnosticsToFixMap.Keys; var documents = documentsAndDiagnosticsToFixMap.Keys;
var tasks = documents.Select(d => AddDocumentFixesAsync(d, documentsAndDiagnosticsToFixMap[d], fixesBag.Add, fixAllContext)) var tasks = documents.Select(d => AddDocumentFixesAsync(d, documentsAndDiagnosticsToFixMap[d], fixesBag.Add, fixAllState, cancellationToken))
.ToArray(); .ToArray();
await Task.WhenAll(tasks).ConfigureAwait(false); await Task.WhenAll(tasks).ConfigureAwait(false);
} }
if (fixesBag.Any()) if (fixesBag.Any())
{ {
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, fixAllContext.CancellationToken)) using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, cancellationToken))
{ {
FixAllLogger.LogFixesToMergeStats(fixesBag); FixAllLogger.LogFixesToMergeStats(fixesBag);
return await TryGetMergedFixAsync(fixesBag, fixAllContext).ConfigureAwait(false); return await TryGetMergedFixAsync(fixesBag, fixAllState, cancellationToken).ConfigureAwait(false);
} }
} }
} }
...@@ -75,10 +75,11 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext) ...@@ -75,10 +75,11 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
return null; return null;
} }
public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext) public async virtual Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
Debug.Assert(!diagnostics.IsDefault); Debug.Assert(!diagnostics.IsDefault);
var cancellationToken = fixAllContext.CancellationToken;
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var fixerTasks = new Task[diagnostics.Length]; var fixerTasks = new Task[diagnostics.Length];
...@@ -105,13 +106,13 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra ...@@ -105,13 +106,13 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
// TODO: Wrap call to ComputeFixesAsync() below in IExtensionManager.PerformFunctionAsync() so that // TODO: Wrap call to ComputeFixesAsync() below in IExtensionManager.PerformFunctionAsync() so that
// a buggy extension that throws can't bring down the host? // a buggy extension that throws can't bring down the host?
var task = fixAllContext.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask; var task = fixAllState.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask;
await task.ConfigureAwait(false); await task.ConfigureAwait(false);
foreach (var fix in fixes) foreach (var fix in fixes)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
if (fix != null && fix.EquivalenceKey == fixAllContext.CodeActionEquivalenceKey) if (fix != null && fix.EquivalenceKey == fixAllState.CodeActionEquivalenceKey)
{ {
addFix(fix); addFix(fix);
} }
...@@ -124,7 +125,7 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra ...@@ -124,7 +125,7 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
internal override async Task<CodeAction> GetFixAsync( internal override async Task<CodeAction> GetFixAsync(
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> projectsAndDiagnosticsToFixMap, ImmutableDictionary<Project, ImmutableArray<Diagnostic>> projectsAndDiagnosticsToFixMap,
FixAllContext fixAllContext) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
if (projectsAndDiagnosticsToFixMap != null && projectsAndDiagnosticsToFixMap.Any()) if (projectsAndDiagnosticsToFixMap != null && projectsAndDiagnosticsToFixMap.Any())
{ {
...@@ -132,20 +133,20 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra ...@@ -132,20 +133,20 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
var fixesBag = new ConcurrentBag<CodeAction>(); var fixesBag = new ConcurrentBag<CodeAction>();
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, fixAllContext.CancellationToken)) using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, cancellationToken))
{ {
var projects = projectsAndDiagnosticsToFixMap.Keys; var projects = projectsAndDiagnosticsToFixMap.Keys;
var tasks = projects.Select(p => AddProjectFixesAsync(p, projectsAndDiagnosticsToFixMap[p], fixesBag.Add, fixAllContext)) var tasks = projects.Select(p => AddProjectFixesAsync(p, projectsAndDiagnosticsToFixMap[p], fixesBag.Add, fixAllState, cancellationToken))
.ToArray(); .ToArray();
await Task.WhenAll(tasks).ConfigureAwait(false); await Task.WhenAll(tasks).ConfigureAwait(false);
} }
if (fixesBag.Any()) if (fixesBag.Any())
{ {
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, fixAllContext.CancellationToken)) using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, cancellationToken))
{ {
FixAllLogger.LogFixesToMergeStats(fixesBag); FixAllLogger.LogFixesToMergeStats(fixesBag);
return await TryGetMergedFixAsync(fixesBag, fixAllContext).ConfigureAwait(false); return await TryGetMergedFixAsync(fixesBag, fixAllState, cancellationToken).ConfigureAwait(false);
} }
} }
} }
...@@ -153,10 +154,11 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra ...@@ -153,10 +154,11 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra
return null; return null;
} }
public virtual async Task AddProjectFixesAsync(Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext) public virtual async Task AddProjectFixesAsync(
Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
Debug.Assert(!diagnostics.IsDefault); Debug.Assert(!diagnostics.IsDefault);
var cancellationToken = fixAllContext.CancellationToken;
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var fixes = new List<CodeAction>(); var fixes = new List<CodeAction>();
...@@ -175,39 +177,39 @@ public virtual async Task AddProjectFixesAsync(Project project, ImmutableArray<D ...@@ -175,39 +177,39 @@ public virtual async Task AddProjectFixesAsync(Project project, ImmutableArray<D
// TODO: Wrap call to ComputeFixesAsync() below in IExtensionManager.PerformFunctionAsync() so that // TODO: Wrap call to ComputeFixesAsync() below in IExtensionManager.PerformFunctionAsync() so that
// a buggy extension that throws can't bring down the host? // a buggy extension that throws can't bring down the host?
var task = fixAllContext.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask; var task = fixAllState.CodeFixProvider.RegisterCodeFixesAsync(context) ?? SpecializedTasks.EmptyTask;
await task.ConfigureAwait(false); await task.ConfigureAwait(false);
foreach (var fix in fixes) foreach (var fix in fixes)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
if (fix != null && fix.EquivalenceKey == fixAllContext.CodeActionEquivalenceKey) if (fix != null && fix.EquivalenceKey == fixAllState.CodeActionEquivalenceKey)
{ {
addFix(fix); addFix(fix);
} }
} }
} }
public virtual async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeAction> batchOfFixes, FixAllContext fixAllContext) public virtual async Task<CodeAction> TryGetMergedFixAsync(
IEnumerable<CodeAction> batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken)
{ {
Contract.ThrowIfNull(batchOfFixes); Contract.ThrowIfNull(batchOfFixes);
Contract.ThrowIfFalse(batchOfFixes.Any()); Contract.ThrowIfFalse(batchOfFixes.Any());
var solution = fixAllContext.Solution; var solution = fixAllState.Solution;
var cancellationToken = fixAllContext.CancellationToken;
var newSolution = await TryMergeFixesAsync(solution, batchOfFixes, cancellationToken).ConfigureAwait(false); var newSolution = await TryMergeFixesAsync(solution, batchOfFixes, cancellationToken).ConfigureAwait(false);
if (newSolution != null && newSolution != solution) if (newSolution != null && newSolution != solution)
{ {
var title = GetFixAllTitle(fixAllContext); var title = GetFixAllTitle(fixAllState);
return new CodeAction.SolutionChangeAction(title, _ => Task.FromResult(newSolution)); return new CodeAction.SolutionChangeAction(title, _ => Task.FromResult(newSolution));
} }
return null; return null;
} }
public virtual string GetFixAllTitle(FixAllContext fixAllContext) public virtual string GetFixAllTitle(FixAllState fixAllState)
{ {
var diagnosticIds = fixAllContext.DiagnosticIds; var diagnosticIds = fixAllState.DiagnosticIds;
string diagnosticId; string diagnosticId;
if (diagnosticIds.Count() == 1) if (diagnosticIds.Count() == 1)
{ {
...@@ -218,17 +220,17 @@ public virtual string GetFixAllTitle(FixAllContext fixAllContext) ...@@ -218,17 +220,17 @@ public virtual string GetFixAllTitle(FixAllContext fixAllContext)
diagnosticId = string.Join(",", diagnosticIds.ToArray()); diagnosticId = string.Join(",", diagnosticIds.ToArray());
} }
switch (fixAllContext.Scope) switch (fixAllState.Scope)
{ {
case FixAllScope.Custom: case FixAllScope.Custom:
return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnostic, diagnosticId); return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnostic, diagnosticId);
case FixAllScope.Document: case FixAllScope.Document:
var document = fixAllContext.Document; var document = fixAllState.Document;
return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, document.Name); return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, document.Name);
case FixAllScope.Project: case FixAllScope.Project:
var project = fixAllContext.Project; var project = fixAllState.Project;
return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, project.Name); return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, project.Name);
case FixAllScope.Solution: case FixAllScope.Solution:
......
...@@ -23,10 +23,13 @@ internal class BatchSimplificationFixAllProvider : BatchFixAllProvider ...@@ -23,10 +23,13 @@ internal class BatchSimplificationFixAllProvider : BatchFixAllProvider
protected BatchSimplificationFixAllProvider() { } protected BatchSimplificationFixAllProvider() { }
public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext) public override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
var changedDocument = await AddSimplifierAnnotationsAsync(document, diagnostics, fixAllContext).ConfigureAwait(false); var changedDocument = await AddSimplifierAnnotationsAsync(
var title = GetFixAllTitle(fixAllContext); document, diagnostics, fixAllState, cancellationToken).ConfigureAwait(false);
var title = GetFixAllTitle(fixAllState);
var codeAction = new MyCodeAction(title, (c) => Task.FromResult(changedDocument)); var codeAction = new MyCodeAction(title, (c) => Task.FromResult(changedDocument));
addFix(codeAction); addFix(codeAction);
} }
...@@ -52,19 +55,20 @@ protected virtual Task<Document> AddSimplifyAnnotationsAsync(Document document, ...@@ -52,19 +55,20 @@ protected virtual Task<Document> AddSimplifyAnnotationsAsync(Document document,
} }
/// <summary> /// <summary>
/// By default, this property returns false and <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllContext)"/> will just add <see cref="Simplifier.Annotation"/> to each node to simplify /// By default, this property returns false and <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllState, CancellationToken)"/> will just add <see cref="Simplifier.Annotation"/> to each node to simplify
/// returned by <see cref="GetNodeToSimplify(SyntaxNode, SemanticModel, Diagnostic, Workspace, out string, CancellationToken)"/>. /// returned by <see cref="GetNodeToSimplify(SyntaxNode, SemanticModel, Diagnostic, Workspace, out string, CancellationToken)"/>.
/// ///
/// Override this property to return true if the fix all provider needs to add simplify annotations/fixup any of the parent nodes of the nodes to simplify. /// Override this property to return true if the fix all provider needs to add simplify annotations/fixup any of the parent nodes of the nodes to simplify.
/// This could be the case if simplifying certain nodes can enable cascaded simplifications, such as parentheses removal on parenting node. /// This could be the case if simplifying certain nodes can enable cascaded simplifications, such as parentheses removal on parenting node.
/// <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllContext)"/> will end up invoking <see cref="AddSimplifyAnnotationsAsync(Document, SyntaxNode, CancellationToken)"/> for each node to simplify. /// <see cref="AddSimplifierAnnotationsAsync(Document, ImmutableArray{Diagnostic}, FixAllState, CancellationToken)"/> will end up invoking <see cref="AddSimplifyAnnotationsAsync(Document, SyntaxNode, CancellationToken)"/> for each node to simplify.
/// Ensure that you override <see cref="AddSimplifyAnnotationsAsync(Document, SyntaxNode, CancellationToken)"/> method when this property returns true. /// Ensure that you override <see cref="AddSimplifyAnnotationsAsync(Document, SyntaxNode, CancellationToken)"/> method when this property returns true.
/// </summary> /// </summary>
protected virtual bool NeedsParentFixup { get { return false; } } protected virtual bool NeedsParentFixup { get { return false; } }
private async Task<Document> AddSimplifierAnnotationsAsync(Document document, ImmutableArray<Diagnostic> diagnostics, FixAllContext fixAllContext) private async Task<Document> AddSimplifierAnnotationsAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
FixAllState fixAllState, CancellationToken cancellationToken)
{ {
var cancellationToken = fixAllContext.CancellationToken;
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
...@@ -73,8 +77,8 @@ private async Task<Document> AddSimplifierAnnotationsAsync(Document document, Im ...@@ -73,8 +77,8 @@ private async Task<Document> AddSimplifierAnnotationsAsync(Document document, Im
foreach (var diagnostic in diagnostics) foreach (var diagnostic in diagnostics)
{ {
string codeActionEquivalenceKey; string codeActionEquivalenceKey;
var node = GetNodeToSimplify(root, model, diagnostic, fixAllContext.Solution.Workspace, out codeActionEquivalenceKey, cancellationToken); var node = GetNodeToSimplify(root, model, diagnostic, fixAllState.Solution.Workspace, out codeActionEquivalenceKey, cancellationToken);
if (node != null && fixAllContext.CodeActionEquivalenceKey == codeActionEquivalenceKey) if (node != null && fixAllState.CodeActionEquivalenceKey == codeActionEquivalenceKey)
{ {
nodesToSimplify.Add(node); nodesToSimplify.Add(node);
} }
......
...@@ -160,7 +160,8 @@ private static Document GetReportedDocument(Diagnostic diagnostic, ImmutableDict ...@@ -160,7 +160,8 @@ private static Document GetReportedDocument(Diagnostic diagnostic, ImmutableDict
return null; return null;
} }
internal virtual async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>>> GetProjectDiagnosticsToFixAsync(FixAllContext fixAllContext) internal virtual async Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>>> GetProjectDiagnosticsToFixAsync(
FixAllContext fixAllContext)
{ {
using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken)) using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken))
{ {
......
...@@ -16,45 +16,47 @@ namespace Microsoft.CodeAnalysis.CodeFixes ...@@ -16,45 +16,47 @@ namespace Microsoft.CodeAnalysis.CodeFixes
/// </summary> /// </summary>
public sealed partial class FixAllContext public sealed partial class FixAllContext
{ {
private readonly DiagnosticProvider _diagnosticProvider; internal FixAllState State { get; }
internal FixAllProvider FixAllProvider => State.FixAllProvider;
/// <summary> /// <summary>
/// Solution to fix all occurrences. /// Solution to fix all occurrences.
/// </summary> /// </summary>
public Solution Solution { get { return this.Project.Solution; } } public Solution Solution => State.Solution;
/// <summary> /// <summary>
/// Project within which fix all occurrences was triggered. /// Project within which fix all occurrences was triggered.
/// </summary> /// </summary>
public Project Project { get; } public Project Project => State.Project;
/// <summary> /// <summary>
/// Document within which fix all occurrences was triggered. /// Document within which fix all occurrences was triggered.
/// Can be null if the context was created using <see cref="FixAllContext.FixAllContext(Project, CodeFixProvider, FixAllScope, string, IEnumerable{string}, DiagnosticProvider, CancellationToken)"/>. /// Can be null if the context was created using <see cref="FixAllContext.FixAllContext(Project, CodeFixProvider, FixAllScope, string, IEnumerable{string}, DiagnosticProvider, CancellationToken)"/>.
/// </summary> /// </summary>
public Document Document { get; } public Document Document => State.Document;
/// <summary> /// <summary>
/// Underlying <see cref="CodeFixes.CodeFixProvider"/> which triggered this fix all. /// Underlying <see cref="CodeFixes.CodeFixProvider"/> which triggered this fix all.
/// </summary> /// </summary>
public CodeFixProvider CodeFixProvider { get; } public CodeFixProvider CodeFixProvider => State.CodeFixProvider;
/// <summary> /// <summary>
/// <see cref="FixAllScope"/> to fix all occurrences. /// <see cref="FixAllScope"/> to fix all occurrences.
/// </summary> /// </summary>
public FixAllScope Scope { get; } public FixAllScope Scope => State.Scope;
/// <summary> /// <summary>
/// Diagnostic Ids to fix. /// Diagnostic Ids to fix.
/// Note that <see cref="GetDocumentDiagnosticsAsync(Document)"/>, <see cref="GetProjectDiagnosticsAsync(Project)"/> and <see cref="GetAllDiagnosticsAsync(Project)"/> methods /// Note that <see cref="GetDocumentDiagnosticsAsync(Document)"/>, <see cref="GetProjectDiagnosticsAsync(Project)"/> and <see cref="GetAllDiagnosticsAsync(Project)"/> methods
/// return only diagnostics whose IDs are contained in this set of Ids. /// return only diagnostics whose IDs are contained in this set of Ids.
/// </summary> /// </summary>
public ImmutableHashSet<string> DiagnosticIds { get; } public ImmutableHashSet<string> DiagnosticIds => State.DiagnosticIds;
/// <summary> /// <summary>
/// The <see cref="CodeAction.EquivalenceKey"/> value expected of a <see cref="CodeAction"/> participating in this fix all. /// The <see cref="CodeAction.EquivalenceKey"/> value expected of a <see cref="CodeAction"/> participating in this fix all.
/// </summary> /// </summary>
public string CodeActionEquivalenceKey { get; } public string CodeActionEquivalenceKey => State.CodeActionEquivalenceKey;
/// <summary> /// <summary>
/// CancellationToken for fix all session. /// CancellationToken for fix all session.
...@@ -82,7 +84,7 @@ public sealed partial class FixAllContext ...@@ -82,7 +84,7 @@ public sealed partial class FixAllContext
IEnumerable<string> diagnosticIds, IEnumerable<string> diagnosticIds,
DiagnosticProvider fixAllDiagnosticProvider, DiagnosticProvider fixAllDiagnosticProvider,
CancellationToken cancellationToken) CancellationToken cancellationToken)
: this(document, document.Project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider, cancellationToken) : this(new FixAllState(null, document, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider), cancellationToken)
{ {
if (document == null) if (document == null)
{ {
...@@ -111,7 +113,7 @@ public sealed partial class FixAllContext ...@@ -111,7 +113,7 @@ public sealed partial class FixAllContext
IEnumerable<string> diagnosticIds, IEnumerable<string> diagnosticIds,
DiagnosticProvider fixAllDiagnosticProvider, DiagnosticProvider fixAllDiagnosticProvider,
CancellationToken cancellationToken) CancellationToken cancellationToken)
: this(null, project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider, cancellationToken) : this(new FixAllState(null, project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider), cancellationToken)
{ {
if (project == null) if (project == null)
{ {
...@@ -119,71 +121,14 @@ public sealed partial class FixAllContext ...@@ -119,71 +121,14 @@ public sealed partial class FixAllContext
} }
} }
private FixAllContext( internal FixAllContext(
Document document, FixAllState state,
Project project,
CodeFixProvider codeFixProvider,
FixAllScope scope,
string codeActionEquivalenceKey,
IEnumerable<string> diagnosticIds,
DiagnosticProvider fixAllDiagnosticProvider,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
Contract.ThrowIfNull(project); State = state;
if (codeFixProvider == null)
{
throw new ArgumentNullException(nameof(codeFixProvider));
}
if (diagnosticIds == null)
{
throw new ArgumentNullException(nameof(diagnosticIds));
}
if (diagnosticIds.Any(d => d == null))
{
throw new ArgumentException(WorkspacesResources.DiagnosticCannotBeNull, nameof(diagnosticIds));
}
if (fixAllDiagnosticProvider == null)
{
throw new ArgumentNullException(nameof(fixAllDiagnosticProvider));
}
this.Document = document;
this.Project = project;
this.CodeFixProvider = codeFixProvider;
this.Scope = scope;
this.CodeActionEquivalenceKey = codeActionEquivalenceKey;
this.DiagnosticIds = ImmutableHashSet.CreateRange(diagnosticIds);
_diagnosticProvider = fixAllDiagnosticProvider;
this.CancellationToken = cancellationToken; this.CancellationToken = cancellationToken;
} }
internal bool IsFixMultiple => _diagnosticProvider.IsFixMultiple;
/// <summary>
/// Transforms this context into the public <see cref="FixAllContext"/> to be used for <see cref="FixAllProvider.GetFixAsync(FixAllContext)"/> invocation.
/// </summary>
internal FixAllContext GetContextForScopeAndActionId(
FixAllScope scope, string codeActionEquivalenceKey)
{
if (this.Scope == scope && this.CodeActionEquivalenceKey == codeActionEquivalenceKey)
{
return this;
}
if (this.Document != null)
{
return new FixAllContext(this.Document, this.CodeFixProvider, scope, codeActionEquivalenceKey,
this.DiagnosticIds, this._diagnosticProvider, this.CancellationToken);
}
return new FixAllContext(this.Project, this.CodeFixProvider, scope, codeActionEquivalenceKey,
this.DiagnosticIds, this._diagnosticProvider, this.CancellationToken);
}
/// <summary> /// <summary>
/// Gets all the diagnostics in the given document filtered by <see cref="DiagnosticIds"/>. /// Gets all the diagnostics in the given document filtered by <see cref="DiagnosticIds"/>.
/// </summary> /// </summary>
...@@ -199,7 +144,7 @@ public async Task<ImmutableArray<Diagnostic>> GetDocumentDiagnosticsAsync(Docume ...@@ -199,7 +144,7 @@ public async Task<ImmutableArray<Diagnostic>> GetDocumentDiagnosticsAsync(Docume
return ImmutableArray<Diagnostic>.Empty; return ImmutableArray<Diagnostic>.Empty;
} }
var getDiagnosticsTask = _diagnosticProvider.GetDocumentDiagnosticsAsync(document, this.CancellationToken); var getDiagnosticsTask = State.DiagnosticProvider.GetDocumentDiagnosticsAsync(document, this.CancellationToken);
return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false); return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false);
} }
...@@ -258,9 +203,9 @@ private async Task<ImmutableArray<Diagnostic>> GetProjectDiagnosticsAsync(Projec ...@@ -258,9 +203,9 @@ private async Task<ImmutableArray<Diagnostic>> GetProjectDiagnosticsAsync(Projec
return ImmutableArray<Diagnostic>.Empty; return ImmutableArray<Diagnostic>.Empty;
} }
var getDiagnosticsTask = includeAllDocumentDiagnostics ? var getDiagnosticsTask = includeAllDocumentDiagnostics
_diagnosticProvider.GetAllDiagnosticsAsync(project, CancellationToken) : ? State.DiagnosticProvider.GetAllDiagnosticsAsync(project, CancellationToken)
_diagnosticProvider.GetProjectDiagnosticsAsync(project, CancellationToken); : State.DiagnosticProvider.GetProjectDiagnosticsAsync(project, CancellationToken);
return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false); return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false);
} }
...@@ -275,132 +220,17 @@ public FixAllContext WithCancellationToken(CancellationToken cancellationToken) ...@@ -275,132 +220,17 @@ public FixAllContext WithCancellationToken(CancellationToken cancellationToken)
return this; return this;
} }
return new FixAllContext( return new FixAllContext(State, cancellationToken);
this.Document,
this.Project,
this.CodeFixProvider,
this.Scope,
this.CodeActionEquivalenceKey,
this.DiagnosticIds,
_diagnosticProvider,
cancellationToken);
}
internal static FixAllContext Create(
Document document,
FixAllProviderInfo fixAllProviderInfo,
CodeFixProvider originalFixProvider,
IEnumerable<Diagnostic> originalFixDiagnostics,
Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync,
Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync,
CancellationToken cancellationToken)
{
var diagnosticIds = GetFixAllDiagnosticIds(fixAllProviderInfo, originalFixDiagnostics).ToImmutableHashSet();
var diagnosticProvider = new FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
return new FixAllContext(
document: document,
codeFixProvider: originalFixProvider,
scope: FixAllScope.Document,
codeActionEquivalenceKey: null,
diagnosticIds: diagnosticIds,
fixAllDiagnosticProvider: diagnosticProvider,
cancellationToken: cancellationToken);
}
internal static FixAllContext Create(
Project project,
FixAllProviderInfo fixAllProviderInfo,
CodeFixProvider originalFixProvider,
IEnumerable<Diagnostic> originalFixDiagnostics,
Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync,
Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync,
CancellationToken cancellationToken)
{
var diagnosticIds = GetFixAllDiagnosticIds(fixAllProviderInfo, originalFixDiagnostics).ToImmutableHashSet();
var diagnosticProvider = new FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
return new FixAllContext(
project: project,
codeFixProvider: originalFixProvider,
scope: FixAllScope.Project,
codeActionEquivalenceKey: null, diagnosticIds: diagnosticIds,
fixAllDiagnosticProvider: diagnosticProvider,
cancellationToken: cancellationToken);
}
private static IEnumerable<string> GetFixAllDiagnosticIds(FixAllProviderInfo fixAllProviderInfo, IEnumerable<Diagnostic> originalFixDiagnostics)
{
return originalFixDiagnostics
.Where(fixAllProviderInfo.CanBeFixed)
.Select(d => d.Id);
}
#region FixMultiple
/// <summary>
/// Creates a new <see cref="FixAllContext"/>.
/// Use this overload when applying fix multiple diagnostics with a source location.
/// </summary>
/// <param name="diagnosticsToFix">Specific set of diagnostics to fix. Must be a non-empty set.</param>
/// <param name="codeFixProvider">Underlying <see cref="CodeFixes.CodeFixProvider"/> which triggered this fix all.</param>
/// <param name="codeActionEquivalenceKey">The <see cref="CodeAction.EquivalenceKey"/> value expected of a <see cref="CodeAction"/> participating in this fix all.</param>
/// <param name="cancellationToken">Cancellation token for fix all computation.</param>
internal static FixAllContext Create(
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix,
CodeFixProvider codeFixProvider,
string codeActionEquivalenceKey,
CancellationToken cancellationToken)
{
var triggerDocument = diagnosticsToFix.First().Key;
var diagnosticIds = GetDiagnosticsIds(diagnosticsToFix.Values);
var diagnosticProvider = new FixMultipleDiagnosticProvider(diagnosticsToFix);
return new FixAllContext(
triggerDocument, codeFixProvider, FixAllScope.Custom, codeActionEquivalenceKey, diagnosticIds, diagnosticProvider, cancellationToken);
}
/// <summary>
/// Creates a new <see cref="FixAllContext"/>.
/// Use this overload when applying fix multiple diagnostics with no source location.
/// </summary>
/// <param name="diagnosticsToFix">Specific set of diagnostics to fix. Must be a non-empty set.</param>
/// <param name="codeFixProvider">Underlying <see cref="CodeFixes.CodeFixProvider"/> which triggered this fix all.</param>
/// <param name="codeActionEquivalenceKey">The <see cref="CodeAction.EquivalenceKey"/> value expected of a <see cref="CodeAction"/> participating in this fix all.</param>
/// <param name="cancellationToken">Cancellation token for fix all computation.</param>
internal static FixAllContext Create(
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix,
CodeFixProvider codeFixProvider,
string codeActionEquivalenceKey,
CancellationToken cancellationToken)
{
var triggerProject = diagnosticsToFix.First().Key;
var diagnosticIds = GetDiagnosticsIds(diagnosticsToFix.Values);
var diagnosticProvider = new FixMultipleDiagnosticProvider(diagnosticsToFix);
return new FixAllContext(triggerProject, codeFixProvider, FixAllScope.Custom, codeActionEquivalenceKey, diagnosticIds, diagnosticProvider, cancellationToken);
}
private static ImmutableHashSet<string> GetDiagnosticsIds(IEnumerable<ImmutableArray<Diagnostic>> diagnosticsCollection)
{
var uniqueIds = ImmutableHashSet.CreateBuilder<string>();
foreach (var diagnostics in diagnosticsCollection)
{
foreach (var diagnostic in diagnostics)
{
uniqueIds.Add(diagnostic.Id);
}
}
return uniqueIds.ToImmutable();
} }
#endregion
internal Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixAsync() internal Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixAsync()
{ {
return _diagnosticProvider.GetDocumentDiagnosticsToFixAsync(this); return State.DiagnosticProvider.GetDocumentDiagnosticsToFixAsync(this);
} }
internal Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>>> GetProjectDiagnosticsToFixAsync() internal Task<ImmutableDictionary<Project, ImmutableArray<Diagnostic>>> GetProjectDiagnosticsToFixAsync()
{ {
return _diagnosticProvider.GetProjectDiagnosticsToFixAsync(this); return State.DiagnosticProvider.GetProjectDiagnosticsToFixAsync(this);
} }
} }
} }
\ No newline at end of file
...@@ -35,32 +35,32 @@ internal static class FixAllLogger ...@@ -35,32 +35,32 @@ internal static class FixAllLogger
private static readonly string s_totalDiagnosticsToFix = "TotalDiagnosticsToFix"; private static readonly string s_totalDiagnosticsToFix = "TotalDiagnosticsToFix";
private static readonly string s_totalFixesToMerge = "TotalFixesToMerge"; private static readonly string s_totalFixesToMerge = "TotalFixesToMerge";
public static void LogContext(FixAllContext fixAllContext, bool isInternalCodeFixProvider) public static void LogState(FixAllState fixAllState, bool isInternalCodeFixProvider)
{ {
Logger.Log(FunctionId.CodeFixes_FixAllOccurrencesContext, KeyValueLogMessage.Create(m => Logger.Log(FunctionId.CodeFixes_FixAllOccurrencesContext, KeyValueLogMessage.Create(m =>
{ {
if (isInternalCodeFixProvider) if (isInternalCodeFixProvider)
{ {
m[s_codeFixProvider] = fixAllContext.CodeFixProvider.GetType().FullName; m[s_codeFixProvider] = fixAllState.CodeFixProvider.GetType().FullName;
m[s_codeActionEquivalenceKey] = fixAllContext.CodeActionEquivalenceKey; m[s_codeActionEquivalenceKey] = fixAllState.CodeActionEquivalenceKey;
m[s_languageName] = fixAllContext.Project.Language; m[s_languageName] = fixAllState.Project.Language;
} }
else else
{ {
m[s_codeFixProvider] = fixAllContext.CodeFixProvider.GetType().FullName.GetHashCode().ToString(); m[s_codeFixProvider] = fixAllState.CodeFixProvider.GetType().FullName.GetHashCode().ToString();
m[s_codeActionEquivalenceKey] = fixAllContext.CodeActionEquivalenceKey != null ? fixAllContext.CodeActionEquivalenceKey.GetHashCode().ToString() : null; m[s_codeActionEquivalenceKey] = fixAllState.CodeActionEquivalenceKey != null ? fixAllState.CodeActionEquivalenceKey.GetHashCode().ToString() : null;
m[s_languageName] = fixAllContext.Project.Language.GetHashCode().ToString(); m[s_languageName] = fixAllState.Project.Language.GetHashCode().ToString();
} }
m[s_fixAllScope] = fixAllContext.Scope.ToString(); m[s_fixAllScope] = fixAllState.Scope.ToString();
switch (fixAllContext.Scope) switch (fixAllState.Scope)
{ {
case CodeFixes.FixAllScope.Project: case CodeFixes.FixAllScope.Project:
m[s_documentCount] = fixAllContext.Project.DocumentIds.Count; m[s_documentCount] = fixAllState.Project.DocumentIds.Count;
break; break;
case CodeFixes.FixAllScope.Solution: case CodeFixes.FixAllScope.Solution:
m[s_documentCount] = fixAllContext.Solution.Projects.Sum(p => p.DocumentIds.Count); m[s_documentCount] = fixAllState.Solution.Projects.Sum(p => p.DocumentIds.Count);
break; break;
} }
})); }));
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeActions;
...@@ -42,14 +43,14 @@ public virtual IEnumerable<string> GetSupportedFixAllDiagnosticIds(CodeFixProvid ...@@ -42,14 +43,14 @@ public virtual IEnumerable<string> GetSupportedFixAllDiagnosticIds(CodeFixProvid
internal virtual Task<CodeAction> GetFixAsync( internal virtual Task<CodeAction> GetFixAsync(
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentsAndDiagnosticsToFixMap, ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentsAndDiagnosticsToFixMap,
FixAllContext fixAllContext) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
return Task.FromResult<CodeAction>(null); return Task.FromResult<CodeAction>(null);
} }
internal virtual Task<CodeAction> GetFixAsync( internal virtual Task<CodeAction> GetFixAsync(
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> projectsAndDiagnosticsToFixMap, ImmutableDictionary<Project, ImmutableArray<Diagnostic>> projectsAndDiagnosticsToFixMap,
FixAllContext fixAllContext) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
return Task.FromResult<CodeAction>(null); return Task.FromResult<CodeAction>(null);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
namespace Microsoft.CodeAnalysis.CodeFixes namespace Microsoft.CodeAnalysis.CodeFixes
{ {
public partial class FixAllContext internal partial class FixAllState
{ {
// Internal for testing purposes. // Internal for testing purposes.
internal class FixAllDiagnosticProvider : FixAllContext.DiagnosticProvider internal class FixAllDiagnosticProvider : FixAllContext.DiagnosticProvider
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
namespace Microsoft.CodeAnalysis.CodeFixes namespace Microsoft.CodeAnalysis.CodeFixes
{ {
public partial class FixAllContext internal partial class FixAllState
{ {
/// <summary> /// <summary>
/// Diagnostic provider to fetch document/project diagnostics to fix in a <see cref="FixAllContext"/>. /// Diagnostic provider to fetch document/project diagnostics to fix in a <see cref="FixAllContext"/>.
......
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeFixes
{
internal partial class FixAllState
{
internal FixAllContext.DiagnosticProvider DiagnosticProvider { get; }
public FixAllProvider FixAllProvider { get; }
public string CodeActionEquivalenceKey { get; }
public CodeFixProvider CodeFixProvider { get; }
public ImmutableHashSet<string> DiagnosticIds { get; }
public Document Document { get; }
public Project Project { get; }
public FixAllScope Scope { get; }
public Solution Solution => this.Project.Solution;
internal FixAllState(
FixAllProvider fixAllProvider,
Document document,
CodeFixProvider codeFixProvider,
FixAllScope scope,
string codeActionEquivalenceKey,
IEnumerable<string> diagnosticIds,
FixAllContext.DiagnosticProvider fixAllDiagnosticProvider)
: this(fixAllProvider, document, document.Project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider)
{
if (document == null)
{
throw new ArgumentNullException(nameof(document));
}
}
internal FixAllState(
FixAllProvider fixAllProvider,
Project project,
CodeFixProvider codeFixProvider,
FixAllScope scope,
string codeActionEquivalenceKey,
IEnumerable<string> diagnosticIds,
FixAllContext.DiagnosticProvider fixAllDiagnosticProvider)
: this(fixAllProvider, null, project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider)
{
if (project == null)
{
throw new ArgumentNullException(nameof(project));
}
}
private FixAllState(
FixAllProvider fixAllProvider,
Document document,
Project project,
CodeFixProvider codeFixProvider,
FixAllScope scope,
string codeActionEquivalenceKey,
IEnumerable<string> diagnosticIds,
FixAllContext.DiagnosticProvider fixAllDiagnosticProvider)
{
Contract.ThrowIfNull(project);
if (codeFixProvider == null)
{
throw new ArgumentNullException(nameof(codeFixProvider));
}
if (diagnosticIds == null)
{
throw new ArgumentNullException(nameof(diagnosticIds));
}
if (diagnosticIds.Any(d => d == null))
{
throw new ArgumentException(WorkspacesResources.DiagnosticCannotBeNull, nameof(diagnosticIds));
}
if (fixAllDiagnosticProvider == null)
{
throw new ArgumentNullException(nameof(fixAllDiagnosticProvider));
}
this.FixAllProvider = fixAllProvider;
this.Document = document;
this.Project = project;
this.CodeFixProvider = codeFixProvider;
this.Scope = scope;
this.CodeActionEquivalenceKey = codeActionEquivalenceKey;
this.DiagnosticIds = ImmutableHashSet.CreateRange(diagnosticIds);
this.DiagnosticProvider = fixAllDiagnosticProvider;
}
internal bool IsFixMultiple => this.DiagnosticProvider.IsFixMultiple;
public FixAllState WithScopeAndEquivalenceKey(FixAllScope scope, string codeActionEquivalenceKey)
{
if (this.Scope == scope && this.CodeActionEquivalenceKey == codeActionEquivalenceKey)
{
return this;
}
return new FixAllState(
this.FixAllProvider,
this.Document, this.Project, this.CodeFixProvider,
scope, codeActionEquivalenceKey,
this.DiagnosticIds, this.DiagnosticProvider);
}
public FixAllContext CreateFixAllContext(CancellationToken cancellationToken)
{
return new FixAllContext(this, cancellationToken);
}
internal static FixAllState Create(
FixAllProvider fixAllProvider,
Document document,
FixAllProviderInfo fixAllProviderInfo,
CodeFixProvider originalFixProvider,
IEnumerable<Diagnostic> originalFixDiagnostics,
Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync,
Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync)
{
var diagnosticIds = GetFixAllDiagnosticIds(fixAllProviderInfo, originalFixDiagnostics).ToImmutableHashSet();
var diagnosticProvider = new FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
return new FixAllState(
fixAllProvider: fixAllProvider,
document: document,
codeFixProvider: originalFixProvider,
scope: FixAllScope.Document,
codeActionEquivalenceKey: null,
diagnosticIds: diagnosticIds,
fixAllDiagnosticProvider: diagnosticProvider);
}
internal static FixAllState Create(
FixAllProvider fixAllProvider,
Project project,
FixAllProviderInfo fixAllProviderInfo,
CodeFixProvider originalFixProvider,
IEnumerable<Diagnostic> originalFixDiagnostics,
Func<Document, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getDocumentDiagnosticsAsync,
Func<Project, bool, ImmutableHashSet<string>, CancellationToken, Task<IEnumerable<Diagnostic>>> getProjectDiagnosticsAsync)
{
var diagnosticIds = GetFixAllDiagnosticIds(fixAllProviderInfo, originalFixDiagnostics).ToImmutableHashSet();
var diagnosticProvider = new FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync);
return new FixAllState(
fixAllProvider: fixAllProvider,
project: project,
codeFixProvider: originalFixProvider,
scope: FixAllScope.Project,
codeActionEquivalenceKey: null, diagnosticIds: diagnosticIds,
fixAllDiagnosticProvider: diagnosticProvider);
}
private static IEnumerable<string> GetFixAllDiagnosticIds(FixAllProviderInfo fixAllProviderInfo, IEnumerable<Diagnostic> originalFixDiagnostics)
{
return originalFixDiagnostics
.Where(fixAllProviderInfo.CanBeFixed)
.Select(d => d.Id);
}
#region FixMultiple
internal static FixAllState Create(
FixAllProvider fixAllProvider,
ImmutableDictionary<Document, ImmutableArray<Diagnostic>> diagnosticsToFix,
CodeFixProvider codeFixProvider,
string codeActionEquivalenceKey)
{
var triggerDocument = diagnosticsToFix.First().Key;
var diagnosticIds = GetDiagnosticsIds(diagnosticsToFix.Values);
var diagnosticProvider = new FixMultipleDiagnosticProvider(diagnosticsToFix);
return new FixAllState(
fixAllProvider,
triggerDocument, codeFixProvider,
FixAllScope.Custom, codeActionEquivalenceKey,
diagnosticIds, diagnosticProvider);
}
internal static FixAllState Create(
FixAllProvider fixAllProvider,
ImmutableDictionary<Project, ImmutableArray<Diagnostic>> diagnosticsToFix,
CodeFixProvider codeFixProvider,
string codeActionEquivalenceKey)
{
var triggerProject = diagnosticsToFix.First().Key;
var diagnosticIds = GetDiagnosticsIds(diagnosticsToFix.Values);
var diagnosticProvider = new FixMultipleDiagnosticProvider(diagnosticsToFix);
return new FixAllState(
fixAllProvider,
triggerProject, codeFixProvider,
FixAllScope.Custom, codeActionEquivalenceKey,
diagnosticIds, diagnosticProvider);
}
private static ImmutableHashSet<string> GetDiagnosticsIds(IEnumerable<ImmutableArray<Diagnostic>> diagnosticsCollection)
{
var uniqueIds = ImmutableHashSet.CreateBuilder<string>();
foreach (var diagnostics in diagnosticsCollection)
{
foreach (var diagnostic in diagnostics)
{
uniqueIds.Add(diagnostic.Id);
}
}
return uniqueIds.ToImmutable();
}
#endregion
}
}
\ No newline at end of file
...@@ -278,7 +278,12 @@ private int BinarySearch(string name) ...@@ -278,7 +278,12 @@ private int BinarySearch(string name)
return info; return info;
} }
info = await LoadOrCreateSymbolTreeInfoAsync(solution, assembly, reference.FilePath, loadOnly, cancellationToken).ConfigureAwait(false); // We don't include internals from metadata assemblies. It's less likely that
// a project would have IVT to it and so it helps us save on memory. It also
// means we can avoid loading lots and lots of obfuscated code in the case hte
// dll was obfuscated.
info = await LoadOrCreateSymbolTreeInfoAsync(solution, assembly, reference.FilePath,
loadOnly, includeInternal: false, cancellationToken: cancellationToken).ConfigureAwait(false);
if (info == null && loadOnly) if (info == null && loadOnly)
{ {
return null; return null;
...@@ -293,12 +298,15 @@ private int BinarySearch(string name) ...@@ -293,12 +298,15 @@ private int BinarySearch(string name)
{ {
var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
// We want to know about internal symbols from source assemblies. Thre's a reasonable
// chance a project might have IVT access to it.
return await LoadOrCreateSymbolTreeInfoAsync( return await LoadOrCreateSymbolTreeInfoAsync(
project.Solution, compilation.Assembly, project.FilePath, loadOnly: false, cancellationToken: cancellationToken).ConfigureAwait(false); project.Solution, compilation.Assembly, project.FilePath,
loadOnly: false, includeInternal: true, cancellationToken: cancellationToken).ConfigureAwait(false);
} }
internal static SymbolTreeInfo CreateSymbolTreeInfo( internal static SymbolTreeInfo CreateSymbolTreeInfo(
Solution solution, VersionStamp version, IAssemblySymbol assembly, string filePath, CancellationToken cancellationToken) Solution solution, VersionStamp version, IAssemblySymbol assembly, string filePath, bool includeInternal, CancellationToken cancellationToken)
{ {
if (assembly == null) if (assembly == null)
{ {
...@@ -306,7 +314,8 @@ private int BinarySearch(string name) ...@@ -306,7 +314,8 @@ private int BinarySearch(string name)
} }
var list = new List<Node>(); var list = new List<Node>();
GenerateNodes(assembly.GlobalNamespace, list); var lookup = includeInternal ? s_getMembersNoPrivate : s_getMembersNoPrivateOrInternal;
GenerateNodes(assembly.GlobalNamespace, list, lookup);
var sortedNodes = SortNodes(list); var sortedNodes = SortNodes(list);
var createSpellCheckerTask = GetSpellCheckerTask(solution, version, assembly, filePath, sortedNodes); var createSpellCheckerTask = GetSpellCheckerTask(solution, version, assembly, filePath, sortedNodes);
...@@ -387,44 +396,65 @@ private static int CompareNodes(Node x, Node y, IReadOnlyList<Node> nodeList) ...@@ -387,44 +396,65 @@ private static int CompareNodes(Node x, Node y, IReadOnlyList<Node> nodeList)
} }
// generate nodes for the global namespace an all descendants // generate nodes for the global namespace an all descendants
private static void GenerateNodes(INamespaceSymbol globalNamespace, List<Node> list) private static void GenerateNodes(
INamespaceSymbol globalNamespace,
List<Node> list,
Func<ISymbol, IEnumerable<ISymbol>> lookup)
{ {
var node = new Node(globalNamespace.Name, Node.RootNodeParentIndex); var node = new Node(globalNamespace.Name, Node.RootNodeParentIndex);
list.Add(node); list.Add(node);
// Add all child members // Add all child members
var memberLookup = s_getMembers(globalNamespace).ToLookup(c => c.Name); var memberLookup = lookup(globalNamespace).ToLookup(c => c.Name);
foreach (var grouping in memberLookup) foreach (var grouping in memberLookup)
{ {
GenerateNodes(grouping.Key, 0 /*index of root node*/, grouping, list); GenerateNodes(grouping.Key, 0 /*index of root node*/, grouping, list, lookup);
} }
} }
private static readonly Func<ISymbol, bool> s_useSymbol = private static readonly Func<ISymbol, bool> s_useSymbolNoPrivate =
s => s.CanBeReferencedByName && s.DeclaredAccessibility != Accessibility.Private; s => s.CanBeReferencedByName && s.DeclaredAccessibility != Accessibility.Private;
private static readonly Func<ISymbol, bool> s_useSymbolNoPrivateOrInternal =
s => s.CanBeReferencedByName &&
s.DeclaredAccessibility != Accessibility.Private &&
s.DeclaredAccessibility != Accessibility.Internal;
// generate nodes for symbols that share the same name, and all their descendants // generate nodes for symbols that share the same name, and all their descendants
private static void GenerateNodes(string name, int parentIndex, IEnumerable<ISymbol> symbolsWithSameName, List<Node> list) private static void GenerateNodes(
string name,
int parentIndex,
IEnumerable<ISymbol> symbolsWithSameName,
List<Node> list,
Func<ISymbol, IEnumerable<ISymbol>> lookup)
{ {
var node = new Node(name, parentIndex); var node = new Node(name, parentIndex);
var nodeIndex = list.Count; var nodeIndex = list.Count;
list.Add(node); list.Add(node);
// Add all child members // Add all child members
var membersByName = symbolsWithSameName.SelectMany(s_getMembers).ToLookup(s => s.Name); var membersByName = symbolsWithSameName.SelectMany(lookup).ToLookup(s => s.Name);
foreach (var grouping in membersByName) foreach (var grouping in membersByName)
{ {
GenerateNodes(grouping.Key, nodeIndex, grouping, list); GenerateNodes(grouping.Key, nodeIndex, grouping, list, lookup);
} }
} }
private static Func<ISymbol, IEnumerable<ISymbol>> s_getMembers = symbol => private static Func<ISymbol, IEnumerable<ISymbol>> s_getMembersNoPrivate = symbol =>
{
var nt = symbol as INamespaceOrTypeSymbol;
return nt != null
? nt.GetMembers().Where(s_useSymbolNoPrivate)
: SpecializedCollections.EmptyEnumerable<ISymbol>();
};
private static Func<ISymbol, IEnumerable<ISymbol>> s_getMembersNoPrivateOrInternal = symbol =>
{ {
var nt = symbol as INamespaceOrTypeSymbol; var nt = symbol as INamespaceOrTypeSymbol;
return nt != null return nt != null
? nt.GetMembers().Where(s_useSymbol) ? nt.GetMembers().Where(s_useSymbolNoPrivateOrInternal)
: SpecializedCollections.EmptyEnumerable<ISymbol>(); : SpecializedCollections.EmptyEnumerable<ISymbol>();
}; };
......
...@@ -26,6 +26,7 @@ internal partial class SymbolTreeInfo : IObjectWritable ...@@ -26,6 +26,7 @@ internal partial class SymbolTreeInfo : IObjectWritable
IAssemblySymbol assembly, IAssemblySymbol assembly,
string filePath, string filePath,
bool loadOnly, bool loadOnly,
bool includeInternal,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
return LoadOrCreateAsync( return LoadOrCreateAsync(
...@@ -33,7 +34,7 @@ internal partial class SymbolTreeInfo : IObjectWritable ...@@ -33,7 +34,7 @@ internal partial class SymbolTreeInfo : IObjectWritable
assembly, assembly,
filePath, filePath,
loadOnly, loadOnly,
create: version => CreateSymbolTreeInfo(solution, version, assembly, filePath, cancellationToken), create: version => CreateSymbolTreeInfo(solution, version, assembly, filePath, includeInternal, cancellationToken),
keySuffix: "", keySuffix: "",
getVersion: info => info._version, getVersion: info => info._version,
readObject: reader => ReadSymbolTreeInfo(reader, (version, nodes) => GetSpellCheckerTask(solution, version, assembly, filePath, nodes)), readObject: reader => ReadSymbolTreeInfo(reader, (version, nodes) => GetSpellCheckerTask(solution, version, assembly, filePath, nodes)),
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.Options
{
internal interface IOption2 : IOption
{
object GetDefaultValue(string language);
}
}
...@@ -10,8 +10,6 @@ public struct OptionKey : IEquatable<OptionKey> ...@@ -10,8 +10,6 @@ public struct OptionKey : IEquatable<OptionKey>
public IOption Option { get; } public IOption Option { get; }
public string Language { get; } public string Language { get; }
internal object DefaultValue => ((IOption2)Option).GetDefaultValue(Language);
public OptionKey(IOption option, string language = null) public OptionKey(IOption option, string language = null)
{ {
if (option == null) if (option == null)
......
...@@ -81,7 +81,7 @@ private object LoadOptionFromSerializerOrGetDefault(OptionKey optionKey) ...@@ -81,7 +81,7 @@ private object LoadOptionFromSerializerOrGetDefault(OptionKey optionKey)
// Just use the default. We will still cache this so we aren't trying to deserialize // Just use the default. We will still cache this so we aren't trying to deserialize
// over and over. // over and over.
return optionKey.DefaultValue; return optionKey.Option.DefaultValue;
} }
} }
......
...@@ -51,7 +51,7 @@ public object GetOption(OptionKey optionKey) ...@@ -51,7 +51,7 @@ public object GetOption(OptionKey optionKey)
if (!_values.TryGetValue(optionKey, out value)) if (!_values.TryGetValue(optionKey, out value))
{ {
value = _service != null ? _service.GetOption(optionKey) : optionKey.DefaultValue; value = _service != null ? _service.GetOption(optionKey) : optionKey.Option.DefaultValue;
_values = _values.Add(optionKey, value); _values = _values.Add(optionKey, value);
} }
......
...@@ -7,7 +7,7 @@ namespace Microsoft.CodeAnalysis.Options ...@@ -7,7 +7,7 @@ namespace Microsoft.CodeAnalysis.Options
/// <summary> /// <summary>
/// An global option. An instance of this class can be used to access an option value from an OptionSet. /// An global option. An instance of this class can be used to access an option value from an OptionSet.
/// </summary> /// </summary>
public class Option<T> : IOption2, IOption public class Option<T> : IOption
{ {
/// <summary> /// <summary>
/// Feature this option is associated with. /// Feature this option is associated with.
...@@ -22,7 +22,10 @@ public class Option<T> : IOption2, IOption ...@@ -22,7 +22,10 @@ public class Option<T> : IOption2, IOption
/// <summary> /// <summary>
/// The type of the option value. /// The type of the option value.
/// </summary> /// </summary>
public Type Type => typeof(T); public Type Type
{
get { return typeof(T); }
}
/// <summary> /// <summary>
/// The default value of the option. /// The default value of the option.
...@@ -46,13 +49,19 @@ public Option(string feature, string name, T defaultValue = default(T)) ...@@ -46,13 +49,19 @@ public Option(string feature, string name, T defaultValue = default(T))
this.DefaultValue = defaultValue; this.DefaultValue = defaultValue;
} }
Type IOption.Type => typeof(T); Type IOption.Type
object IOption.DefaultValue => this.DefaultValue; {
bool IOption.IsPerLanguage => false; get { return typeof(T); }
}
object IOption.DefaultValue
{
get { return this.DefaultValue; }
}
object IOption2.GetDefaultValue(string language) bool IOption.IsPerLanguage
{ {
return this.DefaultValue; get { return false; }
} }
public override string ToString() public override string ToString()
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Options namespace Microsoft.CodeAnalysis.Options
{ {
...@@ -10,13 +8,8 @@ namespace Microsoft.CodeAnalysis.Options ...@@ -10,13 +8,8 @@ namespace Microsoft.CodeAnalysis.Options
/// An option that can be specified once per language. /// An option that can be specified once per language.
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
public class PerLanguageOption<T> : IOption2, IOption public class PerLanguageOption<T> : IOption
{ {
/// <summary>
/// Save per language defaults
/// </summary>
private readonly IImmutableDictionary<string, T> _perLanguageDefaults;
/// <summary> /// <summary>
/// Feature this option is associated with. /// Feature this option is associated with.
/// </summary> /// </summary>
...@@ -40,32 +33,7 @@ public Type Type ...@@ -40,32 +33,7 @@ public Type Type
/// </summary> /// </summary>
public T DefaultValue { get; } public T DefaultValue { get; }
/// <summary> public PerLanguageOption(string feature, string name, T defaultValue)
/// The default option value of specific language
/// </summary>
internal T GetDefaultValue(string language)
{
if (_perLanguageDefaults.Count == 0)
{
return DefaultValue;
}
T languageSpecificDefault;
if (!_perLanguageDefaults.TryGetValue(language, out languageSpecificDefault))
{
return DefaultValue;
}
return languageSpecificDefault;
}
public PerLanguageOption(string feature, string name, T defaultValue) :
this(feature, name, defaultValue, ImmutableDictionary<string, T>.Empty)
{
}
internal PerLanguageOption(
string feature, string name, T defaultValue, IDictionary<string, T> perLanguageDefaults)
{ {
if (string.IsNullOrWhiteSpace(feature)) if (string.IsNullOrWhiteSpace(feature))
{ {
...@@ -77,18 +45,9 @@ internal T GetDefaultValue(string language) ...@@ -77,18 +45,9 @@ internal T GetDefaultValue(string language)
throw new ArgumentException(nameof(name)); throw new ArgumentException(nameof(name));
} }
if (perLanguageDefaults == null)
{
throw new ArgumentNullException(nameof(perLanguageDefaults));
}
this.Feature = feature; this.Feature = feature;
this.Name = name; this.Name = name;
this.DefaultValue = defaultValue; this.DefaultValue = defaultValue;
this._perLanguageDefaults =
(perLanguageDefaults as IImmutableDictionary<string, T>) ??
ImmutableDictionary.CreateRange<string, T>(perLanguageDefaults);
} }
Type IOption.Type Type IOption.Type
...@@ -106,11 +65,6 @@ bool IOption.IsPerLanguage ...@@ -106,11 +65,6 @@ bool IOption.IsPerLanguage
get { return true; } get { return true; }
} }
object IOption2.GetDefaultValue(string language)
{
return this.GetDefaultValue(language);
}
public override string ToString() public override string ToString()
{ {
return string.Format("{0} - {1}", this.Feature, this.Name); return string.Format("{0} - {1}", this.Feature, this.Name);
......
...@@ -88,7 +88,7 @@ public IList<string> Find(string value, int? threshold = null) ...@@ -88,7 +88,7 @@ public IList<string> Find(string value, int? threshold = null)
threshold = threshold ?? WordSimilarityChecker.GetThreshold(value); threshold = threshold ?? WordSimilarityChecker.GetThreshold(value);
var result = new List<string>(); var result = new List<string>();
Lookup(_nodes[0], lowerCaseCharacters, value.Length, threshold.Value, result); Lookup(_nodes[0], lowerCaseCharacters, value.Length, threshold.Value, result, recursionCount: 0);
return result; return result;
} }
finally finally
...@@ -97,8 +97,28 @@ public IList<string> Find(string value, int? threshold = null) ...@@ -97,8 +97,28 @@ public IList<string> Find(string value, int? threshold = null)
} }
} }
private void Lookup(Node currentNode, char[] queryCharacters, int queryLength, int threshold, List<string> result) private void Lookup(
Node currentNode,
char[] queryCharacters,
int queryLength,
int threshold,
List<string> result,
int recursionCount)
{ {
// Don't bother recursing too deeply in the case of pathological trees.
// This really only happens when the actual code is strange (like
// 10,000 symbols all a single letter long). In htat case, searching
// down this path will be fairly fruitless anyways.
//
// Note: this won't affect good searches against good data even if this
// pathological chain exists. That's because the good items will still
// cluster near the root node in the tree, and won't be off the end of
// this long chain.
if (recursionCount > 256)
{
return;
}
// We always want to compute the real edit distance (ignoring any thresholds). This is // We always want to compute the real edit distance (ignoring any thresholds). This is
// because we need that edit distance to appropriately determine which edges to walk // because we need that edit distance to appropriately determine which edges to walk
// in the tree. // in the tree.
...@@ -124,7 +144,8 @@ private void Lookup(Node currentNode, char[] queryCharacters, int queryLength, i ...@@ -124,7 +144,8 @@ private void Lookup(Node currentNode, char[] queryCharacters, int queryLength, i
if (min <= childEditDistance && childEditDistance <= max) if (min <= childEditDistance && childEditDistance <= max)
{ {
Lookup(_nodes[_edges[i].ChildNodeIndex], Lookup(_nodes[_edges[i].ChildNodeIndex],
queryCharacters, queryLength, threshold, result); queryCharacters, queryLength, threshold, result,
recursionCount + 1);
} }
} }
} }
......
...@@ -11,7 +11,7 @@ namespace Roslyn.Utilities ...@@ -11,7 +11,7 @@ namespace Roslyn.Utilities
{ {
internal class SpellChecker internal class SpellChecker
{ {
private const string SerializationFormat = "1"; private const string SerializationFormat = "2";
public VersionStamp Version { get; } public VersionStamp Version { get; }
private readonly BKTree _bkTree; private readonly BKTree _bkTree;
......
...@@ -310,11 +310,12 @@ ...@@ -310,11 +310,12 @@
<Compile Include="CodeCleanup\Providers\SimplificationCodeCleanupProvider.cs" /> <Compile Include="CodeCleanup\Providers\SimplificationCodeCleanupProvider.cs" />
<Compile Include="CodeFixes\CodeFixContext.cs" /> <Compile Include="CodeFixes\CodeFixContext.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\BatchSimplificationFixAllProvider.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\BatchSimplificationFixAllProvider.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\FixAllContext.FixAllDiagnosticProvider.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\FixAllState.FixAllDiagnosticProvider.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\FixAllProviderInfo.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\FixAllProviderInfo.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\FixAllContext.FixMultipleDiagnosticProvider.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\FixAllState.FixMultipleDiagnosticProvider.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\FixAllLogger.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\FixAllLogger.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\FixAllContext.DiagnosticProvider.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\FixAllContext.DiagnosticProvider.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\FixAllState.cs" />
<Compile Include="CodeFixes\Supression\ISuppressionFixProvider.cs" /> <Compile Include="CodeFixes\Supression\ISuppressionFixProvider.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\WellKnownFixAllProviders.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\WellKnownFixAllProviders.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\BatchFixAllProvider.cs" /> <Compile Include="CodeFixes\FixAllOccurrences\BatchFixAllProvider.cs" />
...@@ -393,7 +394,6 @@ ...@@ -393,7 +394,6 @@
<Compile Include="FindSymbols\DeclaredSymbolInfo.cs" /> <Compile Include="FindSymbols\DeclaredSymbolInfo.cs" />
<Compile Include="FindSymbols\FindReferences\Finders\ILanguageServiceReferenceFinder.cs" /> <Compile Include="FindSymbols\FindReferences\Finders\ILanguageServiceReferenceFinder.cs" />
<Compile Include="LinkedFileDiffMerging\LinkedFileDiffMergingLogger.cs" /> <Compile Include="LinkedFileDiffMerging\LinkedFileDiffMergingLogger.cs" />
<Compile Include="Options\IOption2.cs" />
<Compile Include="Packaging\IPackageInstallerService.cs" /> <Compile Include="Packaging\IPackageInstallerService.cs" />
<Compile Include="Packaging\IPackageSearchService.cs" /> <Compile Include="Packaging\IPackageSearchService.cs" />
<Compile Include="FindSymbols\SymbolTree\ISymbolTreeInfoCacheService.cs" /> <Compile Include="FindSymbols\SymbolTree\ISymbolTreeInfoCacheService.cs" />
...@@ -978,4 +978,4 @@ ...@@ -978,4 +978,4 @@
<ImportGroup Label="Targets"> <ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" /> <Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup> </ImportGroup>
</Project> </Project>
\ No newline at end of file
...@@ -577,7 +577,8 @@ public static async Task TestSymbolTreeInfoSerialization() ...@@ -577,7 +577,8 @@ public static async Task TestSymbolTreeInfoSerialization()
// create symbol tree info from assembly // create symbol tree info from assembly
var version = VersionStamp.Create(); var version = VersionStamp.Create();
var info = SymbolTreeInfo.CreateSymbolTreeInfo(solution, version, assembly, "", CancellationToken.None); var info = SymbolTreeInfo.CreateSymbolTreeInfo(
solution, version, assembly, "", includeInternal: true, cancellationToken: CancellationToken.None);
using (var writerStream = new MemoryStream()) using (var writerStream = new MemoryStream())
{ {
......
...@@ -68,11 +68,29 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Recommendations ...@@ -68,11 +68,29 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Recommendations
Return GetUnqualifiedSymbolsForLabelContext(context, cancellationToken) Return GetUnqualifiedSymbolsForLabelContext(context, cancellationToken)
ElseIf context.SyntaxTree.IsRaiseEventContext(context.Position, context.TargetToken, cancellationToken) Then ElseIf context.SyntaxTree.IsRaiseEventContext(context.Position, context.TargetToken, cancellationToken) Then
Return GetUnqualifiedSymbolsForRaiseEvent(context, cancellationToken) Return GetUnqualifiedSymbolsForRaiseEvent(context, cancellationToken)
ElseIf context.TargetToken.IsKind(SyntaxKind.ForKeyword) Then
Dim symbols = GetUnqualifiedSymbolsForExpressionOrStatementContext(context, filterOutOfScopeLocals, cancellationToken) _
.Where(AddressOf IsWritableFieldOrLocal)
Return symbols
End If End If
Return SpecializedCollections.EmptyEnumerable(Of ISymbol)() Return SpecializedCollections.EmptyEnumerable(Of ISymbol)()
End Function End Function
Private Function IsWritableFieldOrLocal(symbol As ISymbol) As Boolean
If symbol.Kind() = SymbolKind.Field Then
Dim field = DirectCast(symbol, IFieldSymbol)
Return Not field.IsReadOnly AndAlso Not field.IsConst
End If
If symbol.Kind() = SymbolKind.Local Then
Dim local = DirectCast(symbol, ILocalSymbol)
Return Not local.IsConst
End If
Return False
End Function
Private Function GetSymbolsForGlobalStatementContext( Private Function GetSymbolsForGlobalStatementContext(
context As VisualBasicSyntaxContext, context As VisualBasicSyntaxContext,
cancellationToken As CancellationToken cancellationToken As CancellationToken
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册