diff --git a/Restore.cmd b/Restore.cmd index e475b4cef527d626151e02c4cd0b9778e626fa0a..5469f661d21681482124026c2dca1c26922a974b 100644 --- a/Restore.cmd +++ b/Restore.cmd @@ -10,6 +10,12 @@ REM internal repositories. set RoslynSolution=%1 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 call %NugetExe% restore "%~dp0build\ToolsetPackages\project.json" %NuGetAdditionalCommandLineArgs% || goto :RestoreFailed diff --git a/build/scripts/restore.sh b/build/scripts/restore.sh index 81731e62a8266fb87881dbfe4864e3131c22bb85..6160396e35d1f62de5dc21444463103ec5d86f27 100755 --- a/build/scripts/restore.sh +++ b/build/scripts/restore.sh @@ -8,7 +8,8 @@ export HOME=$(cd ~ && pwd) # NuGet often exceeds the limit of open files on Mac # https://github.com/NuGet/Home/issues/2163 -if [ "$(uname -s)" == "Darwin" ] +OS=$(uname -s) +if [ "$OS" == "Darwin" || "$OS" == "Linux" ] then ulimit -n 6500 fi diff --git a/docs/Language Feature Status.md b/docs/Language Feature Status.md index c6ec5a1f896a3b7c05e02e8ce74c09c9e751c522..7e26162f04677363003663f8893f50a7cd19975c 100644 --- a/docs/Language Feature Status.md +++ b/docs/Language Feature Status.md @@ -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) | | [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) | -| 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) | | [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) | diff --git a/docs/infrastructure/Updating NuGet ZIP file b/docs/infrastructure/Updating NuGet ZIP file deleted file mode 100644 index 2bdae4a3724f760c00593cd787b4dd524e4c5e9a..0000000000000000000000000000000000000000 --- a/docs/infrastructure/Updating NuGet ZIP file +++ /dev/null @@ -1,11 +0,0 @@ - -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. diff --git a/netci.groovy b/netci.groovy index 6a1fdd47760fd6edfde67bb9e8faaf26047093b7..cfb2a4508a36edcca819dc09be0624a558464492 100644 --- a/netci.groovy +++ b/netci.groovy @@ -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: // test win32 please 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 Utilities.addGithubPushTrigger(myJob) addEmailPublisher(myJob) } + + addBuildEventWebHook(myJob) } def branchNames = [] diff --git a/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs b/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs index df4b443133a376fc7840b1a2b13c13c2ca0489a3..12723d1f6befaeb1c37bdc866fd1323a03e42359 100644 --- a/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs +++ b/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs @@ -16,6 +16,8 @@ internal sealed partial class BinderFactory private sealed class BinderFactoryVisitor : CSharpSyntaxVisitor { private int _position; + private CSharpSyntaxNode _memberDeclarationOpt; + private Symbol _memberOpt; private readonly BinderFactory _factory; internal BinderFactoryVisitor(BinderFactory factory) @@ -23,12 +25,13 @@ internal BinderFactoryVisitor(BinderFactory factory) _factory = factory; } - internal int Position + internal void Initialize(int position, CSharpSyntaxNode memberDeclarationOpt, Symbol memberOpt) { - set - { - _position = value; - } + Debug.Assert((memberDeclarationOpt == null) == (memberOpt == null)); + + _position = position; + _memberDeclarationOpt = memberDeclarationOpt; + _memberOpt = memberOpt; } private CSharpCompilation compilation @@ -449,6 +452,11 @@ private static string GetPropertyOrEventName(BasePropertyDeclarationSyntax baseP // Get the correct methods symbol within container that corresponds to the given method syntax. private SourceMethodSymbol GetMethodSymbol(BaseMethodDeclarationSyntax baseMethodDeclarationSyntax, Binder outerBinder) { + if (baseMethodDeclarationSyntax == _memberDeclarationOpt) + { + return (SourceMethodSymbol)_memberOpt; + } + NamedTypeSymbol container = GetContainerType(outerBinder, baseMethodDeclarationSyntax); if ((object)container == null) { @@ -461,6 +469,11 @@ private SourceMethodSymbol GetMethodSymbol(BaseMethodDeclarationSyntax baseMetho private SourcePropertySymbol GetPropertySymbol(BasePropertyDeclarationSyntax basePropertyDeclarationSyntax, Binder outerBinder) { + if (basePropertyDeclarationSyntax == _memberDeclarationOpt) + { + return (SourcePropertySymbol)_memberOpt; + } + Debug.Assert(basePropertyDeclarationSyntax.Kind() == SyntaxKind.PropertyDeclaration || basePropertyDeclarationSyntax.Kind() == SyntaxKind.IndexerDeclaration); NamedTypeSymbol container = GetContainerType(outerBinder, basePropertyDeclarationSyntax); @@ -475,6 +488,11 @@ private SourcePropertySymbol GetPropertySymbol(BasePropertyDeclarationSyntax bas private SourceEventSymbol GetEventSymbol(EventDeclarationSyntax eventDeclarationSyntax, Binder outerBinder) { + if (eventDeclarationSyntax == _memberDeclarationOpt) + { + return (SourceEventSymbol)_memberOpt; + } + NamedTypeSymbol container = GetContainerType(outerBinder, eventDeclarationSyntax); if ((object)container == null) { diff --git a/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs b/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs index 113f43ef2b6715aca5e2d811679f9c4c21ff9934..82e1a2a87900d3447d5303269d6fba3a1c70080a 100644 --- a/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs +++ b/src/Compilers/CSharp/Portable/Binder/BinderFactory.cs @@ -87,34 +87,38 @@ private bool InScript } /// - /// Note, there is no guarantee that the factory always gives back the same binder instance for the same . + /// Return binder for binding at node. + /// and + /// are optional syntax and symbol for the member containing . + /// If provided, the 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. /// - internal Binder GetBinder(CSharpSyntaxNode node) + /// + /// Note, there is no guarantee that the factory always gives back the same binder instance for the same node. + /// + internal Binder GetBinder(CSharpSyntaxNode node, CSharpSyntaxNode memberDeclarationOpt = null, Symbol memberOpt = null) { int position = node.SpanStart; - // Special case: In interactive code, we may be trying to retrieve 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 - // directly since it's parent would be null. - if (InScript && node.Kind() == SyntaxKind.CompilationUnit) + // Unless this is interactive retrieving a binder for global statements + // at the very top-level (i.e. in a completely empty file) use + // node.Parent to maintain existing behavior. + if (!InScript || node.Kind() != SyntaxKind.CompilationUnit) { - return GetBinder(node, position); + node = node.Parent; } - // ACASEY: Using node.Parent here to maintain existing behavior, - // but I have no idea why. - return GetBinder(node.Parent, position); + return GetBinder(node, position, memberDeclarationOpt, memberOpt); } - internal Binder GetBinder(CSharpSyntaxNode node, int position) + internal Binder GetBinder(CSharpSyntaxNode node, int position, CSharpSyntaxNode memberDeclarationOpt = null, Symbol memberOpt = null) { Debug.Assert(node != null); - Binder result = null; - BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate(); - visitor.Position = position; - result = node.Accept(visitor); + visitor.Initialize(position, memberDeclarationOpt, memberOpt); + Binder result = node.Accept(visitor); _binderFactoryVisitorPool.Free(visitor); return result; @@ -135,7 +139,7 @@ internal InContainerBinder GetImportsBinder(CSharpSyntaxNode unit, bool inUsing case SyntaxKind.NamespaceDeclaration: { BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate(); - visitor.Position = 0; + visitor.Initialize(0, null, null); var result = visitor.VisitNamespaceDeclaration((NamespaceDeclarationSyntax)unit, unit.SpanStart, inBody: true, inUsing: inUsing); _binderFactoryVisitorPool.Free(visitor); return result; @@ -145,7 +149,7 @@ internal InContainerBinder GetImportsBinder(CSharpSyntaxNode unit, bool inUsing // imports are bound by the Script class binder: { BinderFactoryVisitor visitor = _binderFactoryVisitorPool.Allocate(); - visitor.Position = 0; + visitor.Initialize(0, null, null); var result = visitor.VisitCompilationUnit((CompilationUnitSyntax)unit, inUsing: inUsing, inScript: InScript); _binderFactoryVisitorPool.Free(visitor); return result; diff --git a/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs b/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs index 971bc8ad28e399a08bdded05e1b5b21f9e4802ea..adff30f53c7657553b8b1b03104d536ade9d9723 100644 --- a/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs +++ b/src/Compilers/CSharp/Portable/Symbols/BaseTypeAnalysis.cs @@ -1,87 +1,69 @@ // 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.Diagnostics; -using Microsoft.CodeAnalysis.CSharp.Symbols; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis.Collections; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols { internal static class BaseTypeAnalysis { - // let's keep up to 16 hashsets so that we do not need to allocate them over and over. - // 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> s_hsPool = - new ObjectPool>(() => new HashSet(ReferenceEqualityComparer.Instance), 16); - - internal static bool ClassDependsOn(TypeSymbol depends, TypeSymbol on) + internal static bool ClassDependsOn(NamedTypeSymbol depends, NamedTypeSymbol on) { - if ((object)depends == null || (object)on == null) - { - return false; - } + Debug.Assert((object)depends != null); + Debug.Assert((object)on != null); + Debug.Assert(on.IsDefinition); - var hs = s_hsPool.Allocate(); + var hs = PooledHashSet.GetInstance(); ClassDependsClosure(depends, depends.DeclaringCompilation, hs); - var result = hs.Contains(on.OriginalDefinition); - hs.Clear(); - s_hsPool.Free(hs); + var result = hs.Contains(on); + hs.Free(); return result; } - private static void ClassDependsClosure(TypeSymbol type, CSharpCompilation currentCompilation, HashSet partialClosure) + private static void ClassDependsClosure(NamedTypeSymbol type, CSharpCompilation currentCompilation, HashSet partialClosure) { if ((object)type == null) { return; } - var namedType = type.OriginalDefinition as NamedTypeSymbol; - if ((object)namedType != null && partialClosure.Add(namedType)) + type = type.OriginalDefinition; + if (partialClosure.Add(type)) { - ClassDependsClosure(namedType.GetDeclaredBaseType(null), currentCompilation, partialClosure); + ClassDependsClosure(type.GetDeclaredBaseType(null), currentCompilation, partialClosure); // 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) - { - return false; - } + Debug.Assert((object)depends != null); + Debug.Assert((object)on != null); + Debug.Assert(on.IsDefinition); - var hs = s_hsPool.Allocate(); + var hs = PooledHashSet.GetInstance(); StructDependsClosure(depends, hs, on); var result = hs.Contains(on); - hs.Clear(); - s_hsPool.Free(hs); + hs.Free(); return result; } - private static void StructDependsClosure(TypeSymbol type, HashSet partialClosure, NamedTypeSymbol on) + private static void StructDependsClosure(NamedTypeSymbol type, HashSet partialClosure, NamedTypeSymbol on) { - if ((object)type == null) - { - return; - } + Debug.Assert((object)type != null); - var nt = type as NamedTypeSymbol; - if ((object)nt != null && ReferenceEquals(nt.OriginalDefinition, on)) + if ((object)type.OriginalDefinition == on) { // found a possibly expanding cycle, for example // struct X { public T t; } @@ -90,7 +72,8 @@ private static void StructDependsClosure(TypeSymbol type, HashSet partia partialClosure.Add(on); return; } - if ((object)nt != null && partialClosure.Add(nt)) + + if (partialClosure.Add(type)) { foreach (var member in type.GetMembersUnordered()) { @@ -100,7 +83,7 @@ private static void StructDependsClosure(TypeSymbol type, HashSet partia continue; } - StructDependsClosure(field.Type, partialClosure, on); + StructDependsClosure((NamedTypeSymbol)field.Type, partialClosure, on); } } } @@ -134,41 +117,36 @@ internal static bool IsManagedType(NamedTypeSymbol type) } // Otherwise, we have to build and inspect the closure of depended-upon types. - HashSet closure = s_hsPool.Allocate(); - bool result = DependsOnDefinitelyManagedType(type, closure); - closure.Clear(); - s_hsPool.Free(closure); + var hs = PooledHashSet.GetInstance(); + bool result = DependsOnDefinitelyManagedType(type, hs); + hs.Free(); return result; } private static bool DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet partialClosure) { - Debug.Assert(!ReferenceEquals(type, null)); + Debug.Assert((object)type != null); // 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). 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. - if (member.IsStatic) - { - continue; - } - - FieldSymbol field = null; - + FieldSymbol field; switch (member.Kind) { case SymbolKind.Field: 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."); break; case SymbolKind.Event: field = ((EventSymbol)member).AssociatedField; break; + default: + throw ExceptionUtilities.UnexpectedValue(member.Kind); } if ((object)field == null) @@ -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) - { - return false; - } + Debug.Assert((object)depends != null); + Debug.Assert((object)on != null); + Debug.Assert(on.IsDefinition); - var hs = s_hsPool.Allocate(); + var hs = PooledHashSet.GetInstance(); InterfaceDependsClosure(depends, hs); - var result = hs.Contains(on.OriginalDefinition); - hs.Clear(); - s_hsPool.Free(hs); + var result = hs.Contains(on); + hs.Free(); return result; } - private static void InterfaceDependsClosure(TypeSymbol type, HashSet partialClosure) + private static void InterfaceDependsClosure(NamedTypeSymbol type, HashSet partialClosure) { - var nt = type.OriginalDefinition as NamedTypeSymbol; - if ((object)nt != null && partialClosure.Add(nt)) + type = type.OriginalDefinition; + if (partialClosure.Add(type)) { - foreach (var bt in nt.GetDeclaredInterfaces(null)) + foreach (var bt in type.GetDeclaredInterfaces(null)) { InterfaceDependsClosure(bt, partialClosure); // containment is not interesting for interfaces as they cannot nest in C# diff --git a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs index d418e5abc5694383848a52ae45907aba80e63b73..cc0365d5b1b1005079f79d2b6bc7f680c3a1fc8e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/NamedTypeSymbol.cs @@ -561,6 +561,32 @@ internal virtual ImmutableArray GetSimpleNonTypeMembers(string name) /// returns an empty ImmutableArray. Never returns null. public abstract override ImmutableArray GetTypeMembers(string name, int arity); + /// + /// Get all instance field and event members. + /// + /// + /// For source symbols may be called while calculating + /// . + /// + internal virtual IEnumerable GetInstanceFieldsAndEvents() + { + return GetMembersUnordered().Where(IsInstanceFieldOrEvent); + } + + protected static Func IsInstanceFieldOrEvent = symbol => + { + if (!symbol.IsStatic) + { + switch (symbol.Kind) + { + case SymbolKind.Field: + case SymbolKind.Event: + return true; + } + } + return false; + }; + /// /// Get this accessibility that was declared on this symbol. For symbols that do not have /// accessibility declared on them, returns NotApplicable. diff --git a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs index 044ceb244b89d87c956576e39691b997f8fee499..a1505a155b7179bcd8bddcff52fc261e0fd15cc4 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Retargeting/RetargetingNamedTypeSymbol.cs @@ -431,10 +431,6 @@ internal override NamedTypeSymbol BaseTypeNoUseSiteDiagnostics if (ReferenceEquals(_lazyBaseType, ErrorTypeSymbol.UnknownResultType)) { NamedTypeSymbol acyclicBase = GetDeclaredBaseType(null); - if (BaseTypeAnalysis.ClassDependsOn(acyclicBase, this)) - { - return CyclicInheritanceError(this, acyclicBase); - } if ((object)acyclicBase == null) { @@ -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); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index f8099181986b281d3434087fb8cdca405bea0961..8cd981476d9902bca816697610acd2be9eb7ee38 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -1297,6 +1297,12 @@ private MembersAndInitializers GetMembersAndInitializers() return _lazyMembersDictionary; } + internal override IEnumerable GetInstanceFieldsAndEvents() + { + var membersAndInitializers = this.GetMembersAndInitializers(); + return membersAndInitializers.NonTypeNonIndexerMembers.Where(IsInstanceFieldOrEvent); + } + protected void AfterMembersChecks(DiagnosticBag diagnostics) { if (IsInterface) @@ -1769,7 +1775,7 @@ private bool HasStructCircularity(DiagnosticBag diagnostics) var type = field.Type; if (((object)type != null) && (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 { // If this is a backing field, report the error on the associated property. diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index 98750937dc69be5d876cfed627bfbba15b5feb80..d49b764b1ab4b3a01ed6c0eeb07599edd6236f89 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -37,14 +37,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol /// private SourceMemberMethodSymbol _otherPartOfPartial; - /// - /// 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.) - /// - private readonly Binder _constraintClauseBinder; - public static SourceMemberMethodSymbol CreateMethodSymbol( NamedTypeSymbol containingType, Binder bodyBinder, @@ -63,7 +55,7 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol ? MethodKind.Ordinary : 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( @@ -71,7 +63,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol TypeSymbol explicitInterfaceType, string name, Location location, - Binder bodyBinder, MethodDeclarationSyntax syntax, MethodKind methodKind, DiagnosticBag diagnostics) : @@ -103,25 +94,9 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isMetadataVirtualIgnoringModifiers); - // NOTE: by creating a WithMethodTypeParametersBinder, we are effectively duplicating the - // functionality of the BinderFactory. Unfortunately, we cannot use the BinderFactory - // because it depends on having access to the member list of our containing type and - // 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.Empty; - } - else - { - var parameterBinder = new WithMethodTypeParametersBinder(this, bodyBinder); - withTypeParamsBinder = parameterBinder; - _typeParameters = MakeTypeParameters(syntax, diagnostics); - } + _typeParameters = (syntax.Arity == 0) ? + ImmutableArray.Empty : + MakeTypeParameters(syntax, diagnostics); bool hasBlockBody = syntax.Body != null; _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; @@ -136,23 +111,6 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol { 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 @@ -453,7 +411,7 @@ protected sealed override void LazyAsyncMethodChecks(CancellationToken cancellat protected override void MethodChecks(DiagnosticBag diagnostics) { 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); } @@ -512,17 +470,9 @@ private ImmutableArray MakeTypeParameterConstrain } var syntaxTree = syntax.SyntaxTree; - - // If we're binding these constraints before the method has been - // fully constructed (see partial method comment in .ctor), we have - // 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]); - } + var compilation = this.DeclaringCompilation; + var binderFactory = compilation.GetBinderFactory(syntaxTree); + var binder = binderFactory.GetBinder(constraintClauses[0]); // Wrap binder from factory in a generic constraints specific binder // to avoid checking constraints when binding type names. diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 22e59c1c848219e62318620daf8ac48987bf6646..51e58d60545e19522abbdc1ef23d54bac466666e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -3001,6 +3001,19 @@ public unsafe struct 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 #region AddressOf operand kinds diff --git a/src/Debugging/Microsoft.DiaSymReader.PortablePdb/Microsoft.DiaSymReader.PortablePdb.nuspec b/src/Debugging/Microsoft.DiaSymReader.PortablePdb/Microsoft.DiaSymReader.PortablePdb.nuspec index 213608d7c80f5bd3535066cf022643fa47c146bb..5491ef0b34cfe3fb40216923c0b7da52b5b3c3a3 100644 --- a/src/Debugging/Microsoft.DiaSymReader.PortablePdb/Microsoft.DiaSymReader.PortablePdb.nuspec +++ b/src/Debugging/Microsoft.DiaSymReader.PortablePdb/Microsoft.DiaSymReader.PortablePdb.nuspec @@ -14,21 +14,21 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + en-US diff --git a/src/Dependencies/VisualStudio/project.json b/src/Dependencies/VisualStudio/project.json index 296b7fe3aef8674323c5b33baf79d8223665535c..bd5c3ff3d6eb7be824f5cc183464f107e1349c78 100644 --- a/src/Dependencies/VisualStudio/project.json +++ b/src/Dependencies/VisualStudio/project.json @@ -3,6 +3,7 @@ "dependencies": { "Microsoft.VisualStudio.Designer.Interfaces": "1.1.4322", "Microsoft.VisualStudio.Editor": "14.1.24720", + "Microsoft.VisualStudio.Shell.Design": "14.1.24720", "Microsoft.VisualStudio.Shell.14.0": "14.1.24720", "Microsoft.VisualStudio.Shell.Interop.10.0": "10.0.30319", "Microsoft.VisualStudio.Shell.Interop.11.0": "11.0.61030", diff --git a/src/EditorFeatures/Core/Implementation/CodeFixes/CodeFixService.cs b/src/EditorFeatures/Core/Implementation/CodeFixes/CodeFixService.cs index 9ee7cf77869b67371f6040f2ec74782429185a84..c7e17cd056e188d8308f4f0e8722341c3b6fb2c2 100644 --- a/src/EditorFeatures/Core/Implementation/CodeFixes/CodeFixService.cs +++ b/src/EditorFeatures/Core/Implementation/CodeFixes/CodeFixService.cs @@ -287,22 +287,21 @@ public async Task> GetFixesAsync(Document documen // 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); - FixAllProvider fixAllProvider = null; - FixAllContext fixAllContext = null; + FixAllState fixAllState = null; IEnumerable supportedScopes = null; if (fixAllProviderInfo != null) { var codeFixProvider = (fixer as CodeFixProvider) ?? new WrapperCodeFixProvider((ISuppressionFixProvider)fixer, diagnostics.Select(d => d.Id)); - fixAllProvider = fixAllProviderInfo.FixAllProvider; - fixAllContext = FixAllContext.Create( + fixAllState = FixAllState.Create( + fixAllProviderInfo.FixAllProvider, document, fixAllProviderInfo, codeFixProvider, diagnostics, - this.GetDocumentDiagnosticsAsync, this.GetProjectDiagnosticsAsync, cancellationToken); + this.GetDocumentDiagnosticsAsync, this.GetProjectDiagnosticsAsync); supportedScopes = fixAllProviderInfo.SupportedScopes; } result = result ?? new List(); var codeFix = new CodeFixCollection( - fixer, span, fixes, fixAllProvider, fixAllContext, + fixer, span, fixes, fixAllState, supportedScopes, diagnostics.First()); result.Add(codeFix); } diff --git a/src/EditorFeatures/Core/Implementation/Suggestions/CodeFixSuggestedAction.cs b/src/EditorFeatures/Core/Implementation/Suggestions/CodeFixSuggestedAction.cs index cd5d1c397ec8cd9dac83aa62e1d58583a1f326be..fb719b352776e73ef2876aa9c6b648180f9ff4e6 100644 --- a/src/EditorFeatures/Core/Implementation/Suggestions/CodeFixSuggestedAction.cs +++ b/src/EditorFeatures/Core/Implementation/Suggestions/CodeFixSuggestedAction.cs @@ -46,8 +46,7 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi internal static SuggestedActionSet GetFixAllSuggestedActionSet( CodeAction action, int actionCount, - FixAllProvider fixAllProvider, - FixAllContext fixAllCodeActionContext, + FixAllState fixAllState, IEnumerable supportedScopes, Diagnostic firstDiagnostic, Workspace workspace, @@ -56,7 +55,7 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi IWaitIndicator waitIndicator, IAsynchronousOperationListener operationListener) { - if (fixAllCodeActionContext == null) + if (fixAllState == null) { return null; } @@ -69,11 +68,11 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi var fixAllSuggestedActions = ImmutableArray.CreateBuilder(); foreach (var scope in supportedScopes) { - var fixAllContext = fixAllCodeActionContext.GetContextForScopeAndActionId(scope, action.EquivalenceKey); - var fixAllAction = new FixAllCodeAction(fixAllContext, fixAllProvider, showPreviewChangesDialog: true); + var fixAllStateForScope = fixAllState.WithScopeAndEquivalenceKey(scope, action.EquivalenceKey); + var fixAllAction = new FixAllCodeAction(fixAllStateForScope, showPreviewChangesDialog: true); var fixAllSuggestedAction = new FixAllSuggestedAction( workspace, subjectBuffer, editHandler, waitIndicator, fixAllAction, - fixAllProvider, firstDiagnostic, operationListener); + fixAllStateForScope.FixAllProvider, firstDiagnostic, operationListener); fixAllSuggestedActions.Add(fixAllSuggestedAction); } diff --git a/src/EditorFeatures/Core/Implementation/Suggestions/FixAllGetFixesService.cs b/src/EditorFeatures/Core/Implementation/Suggestions/FixAllGetFixesService.cs index e11943f58cccab4a3d705bc4f3605a5930efeb62..b90287d77cc354dc8f7df89faa5e661006f7d714 100644 --- a/src/EditorFeatures/Core/Implementation/Suggestions/FixAllGetFixesService.cs +++ b/src/EditorFeatures/Core/Implementation/Suggestions/FixAllGetFixesService.cs @@ -30,9 +30,9 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) return this; } - public async Task GetFixAllChangedSolutionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) + public async Task GetFixAllChangedSolutionAsync(FixAllContext fixAllContext) { - var codeAction = await GetFixAllCodeActionAsync(fixAllProvider, fixAllContext).ConfigureAwait(false); + var codeAction = await GetFixAllCodeActionAsync(fixAllContext).ConfigureAwait(false); if (codeAction == null) { return fixAllContext.Solution; @@ -42,25 +42,27 @@ public async Task GetFixAllChangedSolutionAsync(FixAllProvider fixAllP return await codeAction.GetChangedSolutionInternalAsync(cancellationToken: fixAllContext.CancellationToken).ConfigureAwait(false); } - public async Task> GetFixAllOperationsAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext, bool showPreviewChangesDialog) + public async Task> GetFixAllOperationsAsync( + FixAllContext fixAllContext, bool showPreviewChangesDialog) { - var codeAction = await GetFixAllCodeActionAsync(fixAllProvider, fixAllContext).ConfigureAwait(false); + var codeAction = await GetFixAllCodeActionAsync(fixAllContext).ConfigureAwait(false); if (codeAction == 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 GetFixAllCodeActionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) + private async Task GetFixAllCodeActionAsync(FixAllContext fixAllContext) { using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken)) { CodeAction action = null; try { - action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); + action = await fixAllContext.FixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -82,13 +84,14 @@ private async Task GetFixAllCodeActionAsync(FixAllProvider fixAllPro } } - private async Task> GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext, bool showPreviewChangesDialog) + private async Task> GetFixAllOperationsAsync( + CodeAction codeAction, bool showPreviewChangesDialog, + FixAllState fixAllState, CancellationToken cancellationToken) { // We have computed the fix all occurrences code fix. // Now fetch the new solution with applied fix and bring up the Preview changes dialog. - var cancellationToken = fixAllContext.CancellationToken; - var workspace = fixAllContext.Project.Solution.Workspace; + var workspace = fixAllState.Project.Solution.Workspace; cancellationToken.ThrowIfCancellationRequested(); var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false); @@ -103,11 +106,11 @@ private async Task> GetFixAllOperationsAsync(Co if (showPreviewChangesDialog) { newSolution = PreviewChanges( - fixAllContext.Project.Solution, + fixAllState.Project.Solution, newSolution, FeaturesResources.FixAllOccurrences, codeAction.Title, - fixAllContext.Project.Language, + fixAllState.Project.Language, workspace, cancellationToken); if (newSolution == null) diff --git a/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleOccurrencesService.cs b/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleOccurrencesService.cs index 0e32ce25862915a233ac10ff8e112caec9105f86..bf4c14f6ffc8de77d43d79a474fb6e06bdc3b003 100644 --- a/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleOccurrencesService.cs +++ b/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleOccurrencesService.cs @@ -50,10 +50,10 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) string waitDialogMessage, 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 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); } @@ -67,25 +67,26 @@ public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) string waitDialogMessage, 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 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); } private FixMultipleSuggestedAction GetSuggestedAction( - FixAllContext fixAllContext, + FixAllState fixAllState, Diagnostic triggerDiagnostic, Workspace workspace, - FixAllProvider fixAllProvider, string title, string waitDialogMessage, bool showPreviewChangesDialog, CancellationToken cancellationToken) { - var fixMultipleCodeAction = new FixMultipleCodeAction(fixAllContext, triggerDiagnostic, fixAllProvider, title, waitDialogMessage, showPreviewChangesDialog); - return new FixMultipleSuggestedAction(_listener, workspace, _editHandler, _waitIndicator, fixMultipleCodeAction, fixAllProvider); + var fixMultipleCodeAction = new FixMultipleCodeAction(fixAllState, triggerDiagnostic, title, waitDialogMessage, showPreviewChangesDialog); + return new FixMultipleSuggestedAction( + _listener, workspace, _editHandler, _waitIndicator, + fixMultipleCodeAction, fixAllState.FixAllProvider); } } } diff --git a/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleSuggestedAction.cs b/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleSuggestedAction.cs index 1c05f95053a4878b714449716eb55c463c8659ac..b9108df7250aa0c66851e2de12d5f738ad27eb59 100644 --- a/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleSuggestedAction.cs +++ b/src/EditorFeatures/Core/Implementation/Suggestions/FixMultipleSuggestedAction.cs @@ -33,9 +33,9 @@ internal class FixMultipleSuggestedAction : FixAllSuggestedAction ITextBuffer subjectBufferOpt = null) : 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 diagnosticIds) diff --git a/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSourceProvider.cs b/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSourceProvider.cs index 9a91272527da7125430dadd519974cbb234bcc4d..8f99ed0207f3fd2a5cbd19a2f5f626d51dfce646 100644 --- a/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSourceProvider.cs +++ b/src/EditorFeatures/Core/Implementation/Suggestions/SuggestedActionsSourceProvider.cs @@ -285,7 +285,7 @@ private List FilterOnUIThread(List collect : applicableFixes.Count == collection.Fixes.Length ? collection : new CodeFixCollection(collection.Provider, collection.TextSpan, applicableFixes, - collection.FixAllProvider, collection.FixAllContext, + collection.FixAllState, collection.SupportedScopes, collection.FirstDiagnostic); } @@ -350,10 +350,10 @@ private IEnumerable OrganizeFixes(Workspace workspace, IEnum Func getFixAllSuggestedActionSet = codeAction => CodeFixSuggestedAction.GetFixAllSuggestedActionSet( - codeAction, fixCount, fixCollection.FixAllProvider, - fixCollection.FixAllContext, fixCollection.SupportedScopes, - fixCollection.FirstDiagnostic, workspace, _subjectBuffer, - _owner._editHandler, _owner._waitIndicator, _owner._listener); + codeAction, fixCount, fixCollection.FixAllState, + fixCollection.SupportedScopes, fixCollection.FirstDiagnostic, + workspace, _subjectBuffer, _owner._editHandler, + _owner._waitIndicator, _owner._listener); foreach (var fix in fixes) { diff --git a/src/EditorFeatures/Test/Diagnostics/AbstractUserDiagnosticTest.cs b/src/EditorFeatures/Test/Diagnostics/AbstractUserDiagnosticTest.cs index 4b7e26feff431a1ec938916aa27ef282398984d1..f68453d68860f4819d49862624771623f1434a5b 100644 --- a/src/EditorFeatures/Test/Diagnostics/AbstractUserDiagnosticTest.cs +++ b/src/EditorFeatures/Test/Diagnostics/AbstractUserDiagnosticTest.cs @@ -144,7 +144,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri { var codeFix = new CodeFixCollection( 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)); } } @@ -155,7 +155,8 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri var fixAllProvider = fixer.GetFixAllProvider(); 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); if (fixAllFix != null) { @@ -165,7 +166,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri var diagnosticSpan = diagnostic.Location.IsInSource ? diagnostic.Location.SourceSpan : default(TextSpan); var codeFix = new CodeFixCollection( 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)); } } @@ -174,7 +175,8 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri return result; } - private static FixAllContext GetFixAllContext( + private static FixAllState GetFixAllState( + FixAllProvider fixAllProvider, IEnumerable diagnostics, DiagnosticAnalyzer provider, CodeFixProvider fixer, @@ -189,7 +191,7 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri { // Bulk fixing diagnostics in selected scope. 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(); @@ -213,10 +215,10 @@ protected Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, out stri }; 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 - ? new FixAllContext(document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider, CancellationToken.None) - : new FixAllContext(document.Project, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider, CancellationToken.None); + ? new FixAllState(fixAllProvider, document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider) + : new FixAllState(fixAllProvider, document.Project, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider); } protected async Task TestEquivalenceKeyAsync(string initialMarkup, string equivalenceKey) diff --git a/src/EditorFeatures/Test2/Diagnostics/AbstractCrossLanguageUserDiagnosticTest.vb b/src/EditorFeatures/Test2/Diagnostics/AbstractCrossLanguageUserDiagnosticTest.vb index 86cb5ddd5077c8d68e4a2bfad65b68076f3642f9..8a04beec8bb5ddd55dba8d1b493698f712ad1e87 100644 --- a/src/EditorFeatures/Test2/Diagnostics/AbstractCrossLanguageUserDiagnosticTest.vb +++ b/src/EditorFeatures/Test2/Diagnostics/AbstractCrossLanguageUserDiagnosticTest.vb @@ -114,8 +114,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics If fixes.Any() Then result.Add(Tuple.Create(diagnostic, New CodeFixCollection( fixer, diagnostic.Location.SourceSpan, fixes, - fixAllProvider:=Nothing, fixAllContext:=Nothing, - supportedScopes:=Nothing, firstDiagnostic:=Nothing))) + fixAllState:=Nothing, supportedScopes:=Nothing, firstDiagnostic:=Nothing))) End If Next diff --git a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb index 0086c35ec7a058e18ce3cf2bf765b16bd6a261c1..3ad2f9a182a2179eeee7ef78a0df208a7ef2da13 100644 --- a/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb +++ b/src/EditorFeatures/Test2/Diagnostics/DiagnosticServiceTests.vb @@ -1918,7 +1918,6 @@ class MyClass Using workspace = TestWorkspace.CreateWorkspace(test) - ' set csharp closed diagnostic option on workspace.Options = workspace.Options.WithChangedOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, LanguageNames.CSharp, True) Dim project = workspace.CurrentSolution.Projects.Single() diff --git a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb index c775afc622f49bab22e1fe9c0050e59ae9c9200a..14c7fabc3ccfc9579341d0310f6c042898a9e6b5 100644 --- a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb @@ -7073,6 +7073,80 @@ End Module Await VerifyItemExistsAsync(text, "Length") End Function + + + Public Async Function LocalInForLoop() As Task + Dim text = +.Value + Await VerifyItemExistsAsync(text, "x") + End Function + + + + Public Async Function ExcludeConstLocalInForLoop() As Task + Dim text = +.Value + Await VerifyItemIsAbsentAsync(text, "x") + End Function + + + + Public Async Function ExcludeConstFieldInForLoop() As Task + Dim text = +.Value + Await VerifyItemIsAbsentAsync(text, "x") + End Function + + + + Public Async Function ExcludeReadOnlyFieldInForLoop() As Task + Dim text = +.Value + Await VerifyItemIsAbsentAsync(text, "x") + End Function + + + + Public Async Function FieldInForLoop() As Task + Dim text = +.Value + Await VerifyItemExistsAsync(text, "x") + End Function End Class End Namespace diff --git a/src/ExpressionEvaluator/Package/ExpressionEvaluatorPackage.csproj b/src/ExpressionEvaluator/Package/ExpressionEvaluatorPackage.csproj index 4f0f12a7522d02b61735a6f2b59b945c54afa180..609f5de219392996e2cd536edd8a0172d093823a 100644 --- a/src/ExpressionEvaluator/Package/ExpressionEvaluatorPackage.csproj +++ b/src/ExpressionEvaluator/Package/ExpressionEvaluatorPackage.csproj @@ -32,6 +32,11 @@ v4.6 + + {8da861d8-0cce-4334-b6c0-01a846c881ec} + VisualStudio + False + {201EC5B7-F91E-45E5-B9F2-67A266CCE6FC} VisualStudioSetup @@ -86,16 +91,10 @@ - - false - $(DevEnvDir)\PrivateAssemblies\Microsoft.VisualStudio.Shell.14.0.dll - - - false - + Designer @@ -109,4 +108,4 @@ - + \ No newline at end of file diff --git a/src/ExpressionEvaluator/Package/project.json b/src/ExpressionEvaluator/Package/project.json new file mode 100644 index 0000000000000000000000000000000000000000..2a1dd2816adc82d430b838dff6a359096548c29f --- /dev/null +++ b/src/ExpressionEvaluator/Package/project.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + }, + "frameworks": { + "net46": { } + }, + "runtimes": { + "win7": { }, + "win7-anycpu": { } + } +} diff --git a/src/Features/Core/Portable/CodeFixes/CodeFixCollection.cs b/src/Features/Core/Portable/CodeFixes/CodeFixCollection.cs index fd943d346c9d19e4e339893ded80fc59dc59a365..f89db8cdc5768116e1277ebd1f496ee7c9b4d364 100644 --- a/src/Features/Core/Portable/CodeFixes/CodeFixCollection.cs +++ b/src/Features/Core/Portable/CodeFixes/CodeFixCollection.cs @@ -20,8 +20,7 @@ internal class CodeFixCollection /// /// Optional fix all context, which is non-null if the given supports fix all occurrences code fix. /// - public FixAllProvider FixAllProvider { get; } - public FixAllContext FixAllContext { get; } + public FixAllState FixAllState { get; } public IEnumerable SupportedScopes { get; } public Diagnostic FirstDiagnostic { get; } @@ -29,11 +28,10 @@ internal class CodeFixCollection object provider, TextSpan span, IEnumerable fixes, - FixAllProvider fixAllProvider, - FixAllContext fixAllContext, + FixAllState fixAllState, IEnumerable supportedScopes, 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 object provider, TextSpan span, ImmutableArray fixes, - FixAllProvider fixAllProvider, - FixAllContext fixAllContext, + FixAllState fixAllState, IEnumerable supportedScopes, Diagnostic firstDiagnostic) { this.Provider = provider; this.TextSpan = span; this.Fixes = fixes; - this.FixAllProvider = fixAllProvider; - this.FixAllContext = fixAllContext; + this.FixAllState = fixAllState; this.SupportedScopes = supportedScopes; this.FirstDiagnostic = firstDiagnostic; } diff --git a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixAllCodeAction.cs b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixAllCodeAction.cs index e506081e6e00893c608bb08cca2a85a329a84946..f7b293b1000e8d6932ce95585016b8be38823416 100644 --- a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixAllCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixAllCodeAction.cs @@ -15,15 +15,14 @@ namespace Microsoft.CodeAnalysis.CodeFixes /// internal partial class FixAllCodeAction : CodeAction { - private readonly FixAllContext _fixAllContext; - private readonly FixAllProvider _fixAllProvider; + private readonly FixAllState _fixAllState; private readonly bool _showPreviewChangesDialog; private static readonly HashSet s_predefinedCodeFixProviderNames = GetPredefinedCodeFixProviderNames(); - internal FixAllCodeAction(FixAllContext fixAllContext, FixAllProvider fixAllProvider, bool showPreviewChangesDialog) + internal FixAllCodeAction( + FixAllState fixAllState, bool showPreviewChangesDialog) { - _fixAllContext = fixAllContext; - _fixAllProvider = fixAllProvider; + _fixAllState = fixAllState; _showPreviewChangesDialog = showPreviewChangesDialog; } @@ -31,7 +30,7 @@ public override string Title { get { - switch (_fixAllContext.Scope) + switch (_fixAllState.Scope) { case FixAllScope.Document: return FeaturesResources.FixAllTitle_Document; @@ -47,28 +46,31 @@ public override string Title internal override string Message => FeaturesResources.ComputingFixAllOccurrences; - public FixAllContext FixAllContext => _fixAllContext; + public FixAllState FixAllState => _fixAllState; protected override async Task> ComputeOperationsAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - FixAllLogger.LogContext(_fixAllContext, IsInternalCodeFixProvider(_fixAllContext.CodeFixProvider)); + FixAllLogger.LogState(_fixAllState, IsInternalCodeFixProvider(_fixAllState.CodeFixProvider)); - var service = _fixAllContext.Project.Solution.Workspace.Services.GetService(); + var service = _fixAllState.Project.Solution.Workspace.Services.GetService(); // 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 GetChangedSolutionAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - FixAllLogger.LogContext(_fixAllContext, IsInternalCodeFixProvider(_fixAllContext.CodeFixProvider)); + FixAllLogger.LogState(_fixAllState, IsInternalCodeFixProvider(_fixAllState.CodeFixProvider)); - var service = _fixAllContext.Project.Solution.Workspace.Services.GetService(); + var service = _fixAllState.Project.Solution.Workspace.Services.GetService(); // 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) diff --git a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixMultipleCodeAction.cs b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixMultipleCodeAction.cs index 865714e0e7ba4078455cc523beb616a66cc2e58d..5e9de696edf04e283be345ae1b7553e781c688ca 100644 --- a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixMultipleCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/FixMultipleCodeAction.cs @@ -12,13 +12,12 @@ internal partial class FixMultipleCodeAction : FixAllCodeAction private readonly string _computingFixWaitDialogMessage; internal FixMultipleCodeAction( - FixAllContext fixAllContext, + FixAllState fixAllState, Diagnostic triggerDiagnostic, - FixAllProvider fixAllProvider, string title, string computingFixWaitDialogMessage, bool showPreviewChangesDialog) - : base(fixAllContext, fixAllProvider, showPreviewChangesDialog) + : base(fixAllState, showPreviewChangesDialog) { _triggerDiagnostic = triggerDiagnostic; _title = title; diff --git a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixAllGetFixesService.cs b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixAllGetFixesService.cs index a538df67e2b6f777a009575ae02c8be39aa6286d..f054b4cfd328fcc09910c33a4810ef3ab069a890 100644 --- a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixAllGetFixesService.cs +++ b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixAllGetFixesService.cs @@ -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 /// returns the code action operations corresponding to the fix. /// - Task> GetFixAllOperationsAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext, bool showPreviewChangesDialog); + Task> GetFixAllOperationsAsync(FixAllContext fixAllContext, bool showPreviewChangesDialog); /// /// Computes the fix all occurrences code fix and returns the changed solution. /// - Task GetFixAllChangedSolutionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext); + Task GetFixAllChangedSolutionAsync(FixAllContext fixAllContext); } } diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs index 962a98ca973575bcccaf0ec09770bb877fb325c3..32df28eea42000c8b225fa2a211c225157207c20 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.FixAllProvider.cs @@ -37,18 +37,20 @@ public async override Task GetFixAsync(FixAllContext fixAllContext) var documentsAndDiagnosticsToFixMap = await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false); - return !isGlobalSuppression ? - await batchFixer.GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) : - GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap); + return !isGlobalSuppression + ? await batchFixer.GetFixAsync( + documentsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false) + : GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap); } else { var projectsAndDiagnosticsToFixMap = await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false); - return !isGlobalSuppression ? - await batchFixer.GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) : - GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap); + return !isGlobalSuppression + ? await batchFixer.GetFixAsync( + projectsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false) + : GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap); } } } diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs index 98588246c82d0456469680eaa5b82cf88e3322ec..aaafa2092c4feea08e3e25dee0feea312ddc4da9 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaBatchFixHelpers.cs @@ -25,15 +25,16 @@ private static class PragmaBatchFixHelpers Document document, ImmutableArray pragmaActions, ImmutableArray pragmaDiagnostics, - FixAllContext fixAllContext) + FixAllState fixAllState, + CancellationToken cancellationToken) { // 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 return CodeAction.Create( ((CodeAction)pragmaActions[0]).Title, createChangedDocument: ct => - BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllContext.CancellationToken), - equivalenceKey: fixAllContext.CodeActionEquivalenceKey); + BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, cancellationToken), + equivalenceKey: fixAllState.CodeActionEquivalenceKey); #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction } diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs index 3e1f8c2a29770981051e5a8d766ed82f9ae3c9a0..4ba662824a7fbbc03356ad13844e25387a2b940f 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.PragmaWarningBatchFixAllProvider.cs @@ -26,7 +26,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr _suppressionFixProvider = suppressionFixProvider; } - public override async Task AddDocumentFixesAsync(Document document, ImmutableArray diagnostics, Action addFix, FixAllContext fixAllContext) + public override async Task AddDocumentFixesAsync( + Document document, ImmutableArray diagnostics, Action addFix, + FixAllState fixAllState, CancellationToken cancellationToken) { var pragmaActionsBuilder = ImmutableArray.CreateBuilder(); var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder(); @@ -34,11 +36,12 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed)) { 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(); if (pragmaSuppression != null) { - if (fixAllContext.IsFixMultiple) + if (fixAllState.IsFixMultiple) { pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext(); } @@ -51,8 +54,10 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr // Get the pragma batch fix. if (pragmaActionsBuilder.Count > 0) { - var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document, - pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext); + var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix( + _suppressionFixProvider, document, + pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), + fixAllState, cancellationToken); addFix(pragmaBatchFix); } diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs index ef4c6e422f1af9b077cddcd62d6dc6f5234610ad..51ac9e6128739509ed597949a5965dbe22627b7c 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction.BatchFixer.cs @@ -32,7 +32,9 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) _suppressionFixProvider = suppressionFixProvider; } - public override async Task AddDocumentFixesAsync(Document document, ImmutableArray diagnostics, Action addFix, FixAllContext fixAllContext) + public override async Task AddDocumentFixesAsync( + Document document, ImmutableArray diagnostics, Action addFix, + FixAllState fixAllState, CancellationToken cancellationToken) { // Batch all the pragma remove suppression fixes by executing them sequentially for the document. var pragmaActionsBuilder = ImmutableArray.CreateBuilder(); @@ -40,14 +42,15 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && d.IsSuppressed)) { 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(); if (removeSuppressionFix != null) { var codeAction = removeSuppressionFix.Action as RemoveSuppressionCodeAction; if (codeAction != null) { - if (fixAllContext.IsFixMultiple) + if (fixAllState.IsFixMultiple) { codeAction = codeAction.CloneForFixMultipleContext(); } @@ -69,22 +72,27 @@ public override async Task AddDocumentFixesAsync(Document document, ImmutableArr // Get the pragma batch fix. if (pragmaActionsBuilder.Count > 0) { - var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document, - pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext); + var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix( + _suppressionFixProvider, document, + pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), + fixAllState, cancellationToken); addFix(pragmaBatchFix); } } - public async override Task AddProjectFixesAsync(Project project, ImmutableArray diagnostics, Action addFix, FixAllContext fixAllContext) + public async override Task AddProjectFixesAsync( + Project project, ImmutableArray diagnostics, Action addFix, + FixAllState fixAllState, CancellationToken cancellationToken) { 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; if (removeSuppressionCodeAction != null) { - if (fixAllContext.IsFixMultiple) + if (fixAllState.IsFixMultiple) { removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext(); } @@ -94,14 +102,14 @@ public async override Task AddProjectFixesAsync(Project project, ImmutableArray< } } - public override async Task TryGetMergedFixAsync(IEnumerable batchOfFixes, FixAllContext fixAllContext) + public override async Task TryGetMergedFixAsync( + IEnumerable batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken) { // Batch all the attribute removal fixes into a single fix. // 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. - var cancellationToken = fixAllContext.CancellationToken; - var oldSolution = fixAllContext.Project.Solution; + var oldSolution = fixAllState.Project.Solution; var currentSolution = oldSolution; var attributeRemoveFixes = new List(); @@ -139,13 +147,13 @@ public override async Task TryGetMergedFixAsync(IEnumerable Task.FromResult(currentSolution), - equivalenceKey: fixAllContext.CodeActionEquivalenceKey); + equivalenceKey: fixAllState.CodeActionEquivalenceKey); #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction 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> GetAttributeNodesToFixAsync(ImmutableArray attributeRemoveFixes, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/Diagnostics/EngineV1/DiagnosticIncrementalAnalyzer.cs b/src/Features/Core/Portable/Diagnostics/EngineV1/DiagnosticIncrementalAnalyzer.cs index d98a31d09538d80ec4cb3e40f8c32dcd21530319..cf87ee75ee2cd818d2aebb23803d1de82af0f41d 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV1/DiagnosticIncrementalAnalyzer.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV1/DiagnosticIncrementalAnalyzer.cs @@ -143,7 +143,7 @@ private Task ClearOnlyDocumentStates(Document document) private bool CheckOptions(Project project, bool forceAnalysis) { var workspace = project.Solution.Workspace; - if (workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, project.Language) && + if (ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(workspace, project.Language) && workspace.Options.GetOption(RuntimeOptions.FullSolutionAnalysis)) { return true; diff --git a/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptions.cs b/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptions.cs index 2611ec985411679274fc969cbe59c63d178f0054..6898a9c22edb47b193133dc488183fe3061fc83c 100644 --- a/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptions.cs +++ b/src/Features/Core/Portable/Shared/Options/ServiceFeatureOnOffOptions.cs @@ -1,6 +1,5 @@ // 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; namespace Microsoft.CodeAnalysis.Shared.Options @@ -9,12 +8,33 @@ internal static class ServiceFeatureOnOffOptions { public const string OptionName = "ServiceFeaturesOnOff"; + private const bool CSharpClosedFileDiagnosticsEnabledByDefault = false; + private const bool DefaultClosedFileDiagnosticsEnabledByDefault = true; + /// /// 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, /// rather it means we will only show diagnostics that are cheap to calculate for small scope such as opened files. /// - public static readonly PerLanguageOption ClosedFileDiagnostic = new PerLanguageOption( - OptionName, "Closed File Diagnostic", defaultValue: true, perLanguageDefaults: ImmutableDictionary.Empty.Add(LanguageNames.CSharp, false)); + public static readonly PerLanguageOption ClosedFileDiagnostic = new PerLanguageOption(OptionName, "Closed File Diagnostic", defaultValue: null); + + public static bool IsClosedFileDiagnosticsEnabled(Workspace workspace, string language) + { + var optionsService = workspace.Services.GetService(); + 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; + } } } diff --git a/src/NuGet/Microsoft.CodeAnalysis.Common.nuspec b/src/NuGet/Microsoft.CodeAnalysis.Common.nuspec index 2a9cef0efe6c307e6ba2e34f9cef21ee6e0e98e5..f86dd72d09d054324a82234cf621fe31e94ad9cf 100644 --- a/src/NuGet/Microsoft.CodeAnalysis.Common.nuspec +++ b/src/NuGet/Microsoft.CodeAnalysis.Common.nuspec @@ -21,44 +21,44 @@ Supported Platforms: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/NuGet/Microsoft.CodeAnalysis.Scripting.Common.nuspec b/src/NuGet/Microsoft.CodeAnalysis.Scripting.Common.nuspec index 4af0e0658a46d116f46e78e86cabdc36f6e4bbcc..3497216a7a5a1dbfc7410abccd31c013cbbcce9d 100644 --- a/src/NuGet/Microsoft.CodeAnalysis.Scripting.Common.nuspec +++ b/src/NuGet/Microsoft.CodeAnalysis.Scripting.Common.nuspec @@ -18,25 +18,25 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/NuGet/Microsoft.Net.CSharp.Interactive.netcore.nuspec b/src/NuGet/Microsoft.Net.CSharp.Interactive.netcore.nuspec index 639dcdf1bab4ba4833ebea6a369d566870d0a38f..63334c77a84c03fa5707a54c852e4c2fdbd12852 100644 --- a/src/NuGet/Microsoft.Net.CSharp.Interactive.netcore.nuspec +++ b/src/NuGet/Microsoft.Net.CSharp.Interactive.netcore.nuspec @@ -19,30 +19,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/src/NuGet/Microsoft.Net.Compilers.netcore.nuspec b/src/NuGet/Microsoft.Net.Compilers.netcore.nuspec index ebc3f68d8e414c60bf96517681e8be358fc4abfe..521c2cb2ff0621d16ee17e49de26e39527a1c152 100644 --- a/src/NuGet/Microsoft.Net.Compilers.netcore.nuspec +++ b/src/NuGet/Microsoft.Net.Compilers.netcore.nuspec @@ -18,44 +18,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Samples/CSharp/ConvertToAutoProperty/ConvertToAutoPropertyCS.csproj b/src/Samples/CSharp/ConvertToAutoProperty/ConvertToAutoPropertyCS.csproj index 992f9af79b8d3547b80325825fc49db6e52623db..471eea586533db6cd0c48b415517c1b202c5b096 100644 --- a/src/Samples/CSharp/ConvertToAutoProperty/ConvertToAutoPropertyCS.csproj +++ b/src/Samples/CSharp/ConvertToAutoProperty/ConvertToAutoPropertyCS.csproj @@ -70,9 +70,6 @@ - - false - diff --git a/src/Samples/CSharp/CopyPasteWithUsing/CopyPasteWithUsing.csproj b/src/Samples/CSharp/CopyPasteWithUsing/CopyPasteWithUsing.csproj index 9116350aeff595c362ac84bd7226f769676935e1..63d694cbe367a9f849dc962d7baf3802752994b5 100644 --- a/src/Samples/CSharp/CopyPasteWithUsing/CopyPasteWithUsing.csproj +++ b/src/Samples/CSharp/CopyPasteWithUsing/CopyPasteWithUsing.csproj @@ -43,6 +43,11 @@ Composition False + + {8da861d8-0cce-4334-b6c0-01a846c881ec} + VisualStudio + False + Debug @@ -84,28 +89,6 @@ - - false - - - false - - - false - - - - false - - - false - - - false - - - false - diff --git a/src/Samples/CSharp/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedCS.csproj b/src/Samples/CSharp/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedCS.csproj index ab052e3afa4601ce1623c274201ba23adba7b345..1f34c79c3fb87d951271748b633be7bcfe1b1167 100644 --- a/src/Samples/CSharp/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedCS.csproj +++ b/src/Samples/CSharp/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedCS.csproj @@ -39,6 +39,16 @@ Composition False + + {c25768b3-2fe1-4d6d-8c17-a6acd56f8389} + VisualStudioText + False + + + {8da861d8-0cce-4334-b6c0-01a846c881ec} + VisualStudio + False + true @@ -80,46 +90,6 @@ false - - false - - - false - - - false - - - - false - - - false - - - True - - - false - - - false - - - false - - - false - - - false - - - false - - - false - diff --git a/src/Samples/Samples.sln b/src/Samples/Samples.sln index 17ab1cf23eae8201199e0c90ac347ad3e879bfb7..2fb8bfe7e14f3a6a7f5bd184a0ba99ab19dbee01 100644 --- a/src/Samples/Samples.sln +++ b/src/Samples/Samples.sln @@ -130,6 +130,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moq.net", "..\Dependencies\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Composition", "..\Dependencies\Composition\Composition.csproj", "{A57DDFE5-AB0E-4371-98E5-11B9218DF11C}" 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 GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -556,6 +560,30 @@ Global {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.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 GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -616,5 +644,7 @@ Global {8635CB8F-D210-41ED-B4FF-71502CDB475C} = {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} + {8DA861D8-0CCE-4334-B6C0-01A846C881EC} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2} + {C25768B3-2FE1-4D6D-8C17-A6ACD56F8389} = {D14160E0-ACA0-4D2D-A670-CB72A57225F2} EndGlobalSection EndGlobal diff --git a/src/Samples/VisualBasic/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedVB.vbproj b/src/Samples/VisualBasic/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedVB.vbproj index 5e4f4a8d969ce4957abec0a7543b83e0b8f4d81d..1292ae3f44b1d18f4013ecf90b12044cd119ce94 100644 --- a/src/Samples/VisualBasic/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedVB.vbproj +++ b/src/Samples/VisualBasic/ImplementNotifyPropertyChanged/Impl/ImplementNotifyPropertyChangedVB.vbproj @@ -30,6 +30,16 @@ Composition False + + {c25768b3-2fe1-4d6d-8c17-a6acd56f8389} + VisualStudioText + False + + + {8da861d8-0cce-4334-b6c0-01a846c881ec} + VisualStudio + False + true @@ -74,46 +84,6 @@ false - - false - - - false - - - false - - - - false - - - false - - - True - - - false - - - false - - - false - - - false - - - false - - - false - - - false - diff --git a/src/Scripting/Core/Scripting.csproj b/src/Scripting/Core/Scripting.csproj index c71de3ddbb74bab5edffc65797afaf6e5357251d..c739236cb830641f87639b88159062623cb928ff 100644 --- a/src/Scripting/Core/Scripting.csproj +++ b/src/Scripting/Core/Scripting.csproj @@ -39,7 +39,7 @@ - + False diff --git a/src/Test/Perf/runner.csx b/src/Test/Perf/runner.csx index 912e721a7104c3df2c46dbde00163935fae1ee78..a5e133aafe773de77f9e0ed318bc5778d7e7b2c4 100644 --- a/src/Test/Perf/runner.csx +++ b/src/Test/Perf/runner.csx @@ -41,13 +41,22 @@ foreach (dynamic test in testInstances) for (int i = 0; i < iterations; i++) { - traceManager.StartScenarios(); traceManager.Start(); - traceManager.StartScenario(test.Name + i, test.MeasuredProc); - traceManager.StartEvent(); - test.Test(); - traceManager.EndEvent(); - traceManager.EndScenario(); + traceManager.StartScenarios(); + + if (test.ProvidesScenarios) + { + 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.WriteScenariosFileToDisk(); diff --git a/src/Test/Perf/tests/csharp/csharp_compiler.csx b/src/Test/Perf/tests/csharp/csharp_compiler.csx index cd03bed1a4945201c922231677e269abf7f299ae..0b98e8c862a1a4ace2e1c923f4a97f057c7f814c 100644 --- a/src/Test/Perf/tests/csharp/csharp_compiler.csx +++ b/src/Test/Perf/tests/csharp/csharp_compiler.csx @@ -30,6 +30,11 @@ class CSharpCompilerTest: PerfTest public override int Iterations => 2; public override string Name => "csharp " + _rspFile; public override string MeasuredProc => "csc"; + public override bool ProvidesScenarios => false; + public override string[] GetScenarios() + { + throw new System.NotImplementedException(); + } } TestThisPlease( diff --git a/src/Test/Perf/tests/helloworld/hello_world.csx b/src/Test/Perf/tests/helloworld/hello_world.csx index be1a29a405a5838cff7791ae745593fee1d5b2c9..89353eed5b61c9e9de0fc53d5b4512c336a44488 100644 --- a/src/Test/Perf/tests/helloworld/hello_world.csx +++ b/src/Test/Perf/tests/helloworld/hello_world.csx @@ -24,6 +24,11 @@ class HelloWorldTest: PerfTest public override int Iterations => 2; public override string Name => "hello world"; public override string MeasuredProc => "csc"; + public override bool ProvidesScenarios => false; + public override string[] GetScenarios() + { + throw new System.NotImplementedException(); + } } TestThisPlease(new HelloWorldTest()); diff --git a/src/Test/Perf/util/scenario_generator_util.csx b/src/Test/Perf/util/scenario_generator_util.csx index 08b5739a140b3f804d01d30a7151cacc12a8864c..c1497ec40e8000b913b690c6dbfc01389af59d2c 100644 --- a/src/Test/Perf/util/scenario_generator_util.csx +++ b/src/Test/Perf/util/scenario_generator_util.csx @@ -51,7 +51,7 @@ public class ScenarioGenerator public void AddStartEvent(int absoluteInstance) { - WriteToBuffer($@""); + WriteToBuffer($@""); } public void AddEndEvent() @@ -63,6 +63,11 @@ public class ScenarioGenerator { WriteToBuffer($@""); } + + public void AddLine(string line) + { + WriteToBuffer(line); + } public void WriteToDisk() { diff --git a/src/Test/Perf/util/test_util.csx b/src/Test/Perf/util/test_util.csx index aaa54b1267125afdf7437433c3224454f800aca0..5d7da4df71c5a30150554ee461cbc548cfa32eda 100644 --- a/src/Test/Perf/util/test_util.csx +++ b/src/Test/Perf/util/test_util.csx @@ -138,6 +138,8 @@ abstract class PerfTest: RelativeDirectory { Log(description + ": " + value.ToString()); } + public abstract bool ProvidesScenarios { get; } + public abstract string[] GetScenarios(); public abstract void Setup(); public abstract void Test(); public abstract int Iterations { get; } diff --git a/src/Test/Perf/util/trace_manager_util.csx b/src/Test/Perf/util/trace_manager_util.csx index 987c0bb4ca02610de970355d7d80852c038f8018..38d6693b60813e92f169c35a7a6b01d9fe663d65 100644 --- a/src/Test/Perf/util/trace_manager_util.csx +++ b/src/Test/Perf/util/trace_manager_util.csx @@ -21,6 +21,7 @@ interface ITraceManager void StartScenario(string scenarioName, string processName); void StartScenarios(); void Stop(); + void WriteScenarios(string[] scenarios); void WriteScenariosFileToDisk(); } @@ -106,6 +107,10 @@ class NoOpTraceManager : ITraceManager { } + public void WriteScenarios(string[] scenarios) + { + } + public void WriteScenariosFileToDisk() { } @@ -209,6 +214,14 @@ class TraceManager: ITraceManager { _scenarioGenerator.AddScenariosFileEnd(); } + + public void WriteScenarios(string[] scenarios) + { + foreach (var line in scenarios) + { + _scenarioGenerator.AddLine(line); + } + } public void WriteScenariosFileToDisk() { diff --git a/src/Tools/CommonNetCoreReferences/project.json b/src/Tools/CommonNetCoreReferences/project.json index 0c542625662458ea639de59953037122ff9eaa99..4732a3cd84e74d72d6be32c6855dc3daba3b3ccc 100644 --- a/src/Tools/CommonNetCoreReferences/project.json +++ b/src/Tools/CommonNetCoreReferences/project.json @@ -1,56 +1,56 @@ { "dependencies": { - "Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-23931", - "Microsoft.NETCore.Platforms": "1.0.1-rc2-23931", - "Microsoft.NETCore.Runtime.CoreCLR": "1.0.2-rc2-23931", - "Microsoft.NETCore.TestHost": "1.0.0-rc2-23931", - "System.AppContext": "4.1.0-rc2-23931", - "System.Collections": "4.0.11-rc2-23931", - "System.Collections.Concurrent": "4.0.12-rc2-23931", - "System.Collections.Immutable": "1.2.0-rc2-23931", - "System.Console": "4.0.0-rc2-23931", - "System.Diagnostics.Debug": "4.0.11-rc2-23931", - "System.Diagnostics.FileVersionInfo": "4.0.0-rc2-23931", - "System.Diagnostics.Process": "4.1.0-rc2-23931", - "System.Diagnostics.StackTrace": "4.0.1-rc2-23931", - "System.Diagnostics.Tools": "4.0.1-rc2-23931", - "System.Dynamic.Runtime": "4.0.11-rc2-23931", - "System.Globalization": "4.0.11-rc2-23931", - "System.IO.FileSystem": "4.0.1-rc2-23931", - "System.IO.FileSystem.Primitives": "4.0.1-rc2-23931", - "System.IO.FileSystem.Watcher": "4.0.0-rc2-23931", - "System.IO.Pipes": "4.0.0-rc2-23931", - "System.Linq": "4.1.0-rc2-23931", - "System.Linq.Expressions": "4.0.11-rc2-23931", - "System.Net.NameResolution": "4.0.0-rc2-23931", - "System.Net.Sockets": "4.1.0-rc2-23931", - "System.Reflection": "4.1.0-rc2-23931", - "System.Reflection.Primitives": "4.0.1-rc2-23931", - "System.Resources.ResourceManager": "4.0.1-rc2-23931", - "System.Runtime": "4.1.0-rc2-23931", - "System.Runtime.Extensions": "4.1.0-rc2-23931", - "System.Runtime.Handles": "4.0.1-rc2-23931", - "System.Runtime.InteropServices": "4.1.0-rc2-23931", - "System.Runtime.Loader": "4.0.0-rc2-23931", - "System.Runtime.Numerics": "4.0.1-rc2-23931", - "System.Security.Cryptography.Algorithms": "4.1.0-rc2-23931", - "System.Security.Cryptography.Encoding": "4.0.0-rc2-23931", - "System.Security.Cryptography.X509Certificates": "4.1.0-rc2-23931", - "System.Text.Encoding": "4.0.11-rc2-23931", - "System.Text.Encoding.CodePages": "4.0.1-rc2-23931", - "System.Text.Encoding.Extensions": "4.0.11-rc2-23931", - "System.Threading": "4.0.11-rc2-23931", - "System.Threading.Tasks": "4.0.11-rc2-23931", - "System.Threading.Tasks.Parallel": "4.0.1-rc2-23931", - "System.Threading.Thread": "4.0.0-rc2-23931", - "System.Xml.ReaderWriter": "4.0.11-rc2-23931", - "System.Xml.XDocument": "4.0.11-rc2-23931", - "System.Xml.XmlDocument": "4.0.1-rc2-23931", - "System.Xml.XPath.XDocument": "4.0.1-rc2-23931" + "Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24022", + "Microsoft.NETCore.Platforms": "1.0.1-rc2-24022", + "Microsoft.NETCore.Runtime.CoreCLR": "1.0.2-rc2-24022", + "Microsoft.NETCore.TestHost": "1.0.0-rc2-24022", + "System.AppContext": "4.1.0-rc2-24022", + "System.Collections": "4.0.11-rc2-24022", + "System.Collections.Concurrent": "4.0.12-rc2-24022", + "System.Collections.Immutable": "1.2.0-rc2-24022", + "System.Console": "4.0.0-rc2-24022", + "System.Diagnostics.Debug": "4.0.11-rc2-24022", + "System.Diagnostics.FileVersionInfo": "4.0.0-rc2-24022", + "System.Diagnostics.Process": "4.1.0-rc2-24022", + "System.Diagnostics.StackTrace": "4.0.1-rc2-24022", + "System.Diagnostics.Tools": "4.0.1-rc2-24022", + "System.Dynamic.Runtime": "4.0.11-rc2-24022", + "System.Globalization": "4.0.11-rc2-24022", + "System.IO.FileSystem": "4.0.1-rc2-24022", + "System.IO.FileSystem.Primitives": "4.0.1-rc2-24022", + "System.IO.FileSystem.Watcher": "4.0.0-rc2-24022", + "System.IO.Pipes": "4.0.0-rc2-24022", + "System.Linq": "4.1.0-rc2-24022", + "System.Linq.Expressions": "4.0.11-rc2-24022", + "System.Net.NameResolution": "4.0.0-rc2-24022", + "System.Net.Sockets": "4.1.0-rc2-24022", + "System.Reflection": "4.1.0-rc2-24022", + "System.Reflection.Primitives": "4.0.1-rc2-24022", + "System.Resources.ResourceManager": "4.0.1-rc2-24022", + "System.Runtime": "4.1.0-rc2-24022", + "System.Runtime.Extensions": "4.1.0-rc2-24022", + "System.Runtime.Handles": "4.0.1-rc2-24022", + "System.Runtime.InteropServices": "4.1.0-rc2-24022", + "System.Runtime.Loader": "4.0.0-rc2-24022", + "System.Runtime.Numerics": "4.0.1-rc2-24022", + "System.Security.Cryptography.Algorithms": "4.1.0-rc2-24022", + "System.Security.Cryptography.Encoding": "4.0.0-rc2-24022", + "System.Security.Cryptography.X509Certificates": "4.1.0-rc2-24022", + "System.Text.Encoding": "4.0.11-rc2-24022", + "System.Text.Encoding.CodePages": "4.0.1-rc2-24022", + "System.Text.Encoding.Extensions": "4.0.11-rc2-24022", + "System.Threading": "4.0.11-rc2-24022", + "System.Threading.Tasks": "4.0.11-rc2-24022", + "System.Threading.Tasks.Parallel": "4.0.1-rc2-24022", + "System.Threading.Thread": "4.0.0-rc2-24022", + "System.Xml.ReaderWriter": "4.0.11-rc2-24022", + "System.Xml.XDocument": "4.0.11-rc2-24022", + "System.Xml.XmlDocument": "4.0.1-rc2-24022", + "System.Xml.XPath.XDocument": "4.0.1-rc2-24022" }, "frameworks": { "dnxcore50": { "imports": "portable-net452" } } -} \ No newline at end of file +} diff --git a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs index c3ed821ff3c5c4be1759dc166bf3e0a8a389f926..adeb8b09aac610f95b611c943f41f0e172195fe5 100644 --- a/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs +++ b/src/VisualStudio/CSharp/Impl/Options/AutomationObject.cs @@ -1,5 +1,6 @@ // 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 Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Completion; @@ -36,7 +37,22 @@ public int BringUpOnIdentifier set { SetBooleanOption(CompletionOptions.TriggerOnTypingLetters, value); } } + [Obsolete("This SettingStore option has now been deprecated in favor of CSharpClosedFileDiagnostics")] 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); } set { SetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, value); } @@ -520,5 +536,24 @@ private void SetBooleanOption(PerLanguageOption key, int value) optionSet = optionSet.WithChangedOption(key, LanguageNames.CSharp, value != 0); _optionService.SetOptions(optionSet); } + + private int GetBooleanOption(PerLanguageOption key) + { + var option = _optionService.GetOption(key, LanguageNames.CSharp); + if (!option.HasValue) + { + return -1; + } + + return option.Value ? 1 : 0; + } + + private void SetBooleanOption(PerLanguageOption 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); + } } } diff --git a/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs b/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs index d37da72bee279afa1179e70efb206e782876ba24..0c3a53cf24695353051d8f0e4c285fe247ba1bc0 100644 --- a/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs +++ b/src/VisualStudio/CSharp/Impl/Options/CSharpSettingsManagerOptionSerializer.cs @@ -103,6 +103,20 @@ private bool ShouldIncludeOnOffOption(FieldInfo fieldInfo) 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) { if (option == OrganizerOptions.PlaceSystemNamespaceFirst || diff --git a/src/VisualStudio/Core/Def/Implementation/Diagnostics/MiscellaneousDiagnosticAnalyzerService.cs b/src/VisualStudio/Core/Def/Implementation/Diagnostics/MiscellaneousDiagnosticAnalyzerService.cs index 90c211ddaed244a5b4f14beb8a0e715100557e53..b8811b5938ff9f41b7427789a5c4c231f7a30e57 100644 --- a/src/VisualStudio/Core/Def/Implementation/Diagnostics/MiscellaneousDiagnosticAnalyzerService.cs +++ b/src/VisualStudio/Core/Def/Implementation/Diagnostics/MiscellaneousDiagnosticAnalyzerService.cs @@ -152,7 +152,7 @@ public void RemoveProject(ProjectId projectId) 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)) { return true; diff --git a/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj b/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj index 7e17ed665ac4bdabed8585a58c72c85777033c28..5f32a6db0a9b5bdd24aeee259fc3b614ec1fa713 100644 --- a/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj +++ b/src/VisualStudio/Core/Def/ServicesVisualStudio.csproj @@ -251,9 +251,6 @@ $(DevEnvDir)\PrivateAssemblies\Microsoft.VisualStudio.ExtensionManager.dll - - $(DevEnvDir)\Microsoft.VisualStudio.Shell.Design.dll - diff --git a/src/VisualStudio/Core/Impl/Options/AbstractSettingStoreOptionSerializer.cs b/src/VisualStudio/Core/Impl/Options/AbstractSettingStoreOptionSerializer.cs index dc87ba018ab1cb08fb284f5674a6c54e28176a09..bcd282f6fe838993a08b3db1b944d224c0ad6b44 100644 --- a/src/VisualStudio/Core/Impl/Options/AbstractSettingStoreOptionSerializer.cs +++ b/src/VisualStudio/Core/Impl/Options/AbstractSettingStoreOptionSerializer.cs @@ -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)); } - protected bool TryFetch(OptionKey optionKey, Func valueGetter, out object value) + protected bool TryFetch(OptionKey optionKey, Func valueGetter, out object value) { if (this.RegistryKey == null) { @@ -58,7 +58,7 @@ protected bool TryFetch(OptionKey optionKey, Func _fullSolutionAnalysis; - private readonly PerLanguageOption _closedFileDiagnostics; + private readonly PerLanguageOption _closedFileDiagnostics; public FullSolutionAnalysisOptionBinding(IOptionService optionService, string languageName) { @@ -26,7 +26,7 @@ public bool Value { get { - return _optionService.GetOption(_closedFileDiagnostics, _languageName) && + return ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_optionService, _languageName) && _optionService.GetOption(_fullSolutionAnalysis); } diff --git a/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject.vb b/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject.vb index d3d4c61b1dec32591ba2205f91efd0c08c1942c3..21018ded2105e457aa827e317ea11f21fea85fc5 100644 --- a/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject.vb +++ b/src/VisualStudio/VisualBasic/Impl/Options/AutomationObject.vb @@ -44,11 +44,25 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options End Set End Property + Public Property ClosedFileDiagnostics As Boolean Get - Return GetBooleanOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic) + Return ServiceFeatureOnOffOptions.IsClosedFileDiagnosticsEnabled(_optionService, LanguageNames.VisualBasic) End Get 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) End Set End Property @@ -171,5 +185,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options optionSet = optionSet.WithChangedOption(key, LanguageNames.VisualBasic, value) _optionService.SetOptions(optionSet) 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 Namespace diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs index eab6417dee76981c11f8aecd9e28dbda38bfc463..fd7dbecbe87096dd2388e800c56fd3e4ebdd484b 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs @@ -31,12 +31,12 @@ public override async Task GetFixAsync(FixAllContext fixAllContext) if (fixAllContext.Document != null) { 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 { 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 GetFixAsync(FixAllContext fixAllContext) internal override async Task GetFixAsync( ImmutableDictionary> documentsAndDiagnosticsToFixMap, - FixAllContext fixAllContext) + FixAllState fixAllState, CancellationToken cancellationToken) { if (documentsAndDiagnosticsToFixMap != null && documentsAndDiagnosticsToFixMap.Any()) { @@ -52,22 +52,22 @@ public override async Task GetFixAsync(FixAllContext fixAllContext) var fixesBag = new ConcurrentBag(); - 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 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(); await Task.WhenAll(tasks).ConfigureAwait(false); } if (fixesBag.Any()) { - using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, fixAllContext.CancellationToken)) + using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, cancellationToken)) { 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 GetFixAsync(FixAllContext fixAllContext) return null; } - public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArray diagnostics, Action addFix, FixAllContext fixAllContext) + public async virtual Task AddDocumentFixesAsync( + Document document, ImmutableArray diagnostics, Action addFix, + FixAllState fixAllState, CancellationToken cancellationToken) { Debug.Assert(!diagnostics.IsDefault); - var cancellationToken = fixAllContext.CancellationToken; cancellationToken.ThrowIfCancellationRequested(); var fixerTasks = new Task[diagnostics.Length]; @@ -105,13 +106,13 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra // TODO: Wrap call to ComputeFixesAsync() below in IExtensionManager.PerformFunctionAsync() so that // 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); foreach (var fix in fixes) { cancellationToken.ThrowIfCancellationRequested(); - if (fix != null && fix.EquivalenceKey == fixAllContext.CodeActionEquivalenceKey) + if (fix != null && fix.EquivalenceKey == fixAllState.CodeActionEquivalenceKey) { addFix(fix); } @@ -124,7 +125,7 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra internal override async Task GetFixAsync( ImmutableDictionary> projectsAndDiagnosticsToFixMap, - FixAllContext fixAllContext) + FixAllState fixAllState, CancellationToken cancellationToken) { if (projectsAndDiagnosticsToFixMap != null && projectsAndDiagnosticsToFixMap.Any()) { @@ -132,20 +133,20 @@ public async virtual Task AddDocumentFixesAsync(Document document, ImmutableArra var fixesBag = new ConcurrentBag(); - using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, fixAllContext.CancellationToken)) + using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Fixes, cancellationToken)) { 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(); await Task.WhenAll(tasks).ConfigureAwait(false); } if (fixesBag.Any()) { - using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, fixAllContext.CancellationToken)) + using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, cancellationToken)) { 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 return null; } - public virtual async Task AddProjectFixesAsync(Project project, ImmutableArray diagnostics, Action addFix, FixAllContext fixAllContext) + public virtual async Task AddProjectFixesAsync( + Project project, ImmutableArray diagnostics, Action addFix, + FixAllState fixAllState, CancellationToken cancellationToken) { Debug.Assert(!diagnostics.IsDefault); - var cancellationToken = fixAllContext.CancellationToken; cancellationToken.ThrowIfCancellationRequested(); var fixes = new List(); @@ -175,39 +177,39 @@ public virtual async Task AddProjectFixesAsync(Project project, ImmutableArray TryGetMergedFixAsync(IEnumerable batchOfFixes, FixAllContext fixAllContext) + public virtual async Task TryGetMergedFixAsync( + IEnumerable batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken) { Contract.ThrowIfNull(batchOfFixes); Contract.ThrowIfFalse(batchOfFixes.Any()); - var solution = fixAllContext.Solution; - var cancellationToken = fixAllContext.CancellationToken; + var solution = fixAllState.Solution; var newSolution = await TryMergeFixesAsync(solution, batchOfFixes, cancellationToken).ConfigureAwait(false); if (newSolution != null && newSolution != solution) { - var title = GetFixAllTitle(fixAllContext); + var title = GetFixAllTitle(fixAllState); return new CodeAction.SolutionChangeAction(title, _ => Task.FromResult(newSolution)); } return null; } - public virtual string GetFixAllTitle(FixAllContext fixAllContext) + public virtual string GetFixAllTitle(FixAllState fixAllState) { - var diagnosticIds = fixAllContext.DiagnosticIds; + var diagnosticIds = fixAllState.DiagnosticIds; string diagnosticId; if (diagnosticIds.Count() == 1) { @@ -218,17 +220,17 @@ public virtual string GetFixAllTitle(FixAllContext fixAllContext) diagnosticId = string.Join(",", diagnosticIds.ToArray()); } - switch (fixAllContext.Scope) + switch (fixAllState.Scope) { case FixAllScope.Custom: return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnostic, diagnosticId); case FixAllScope.Document: - var document = fixAllContext.Document; + var document = fixAllState.Document; return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, document.Name); case FixAllScope.Project: - var project = fixAllContext.Project; + var project = fixAllState.Project; return string.Format(WorkspacesResources.FixAllOccurrencesOfDiagnosticInScope, diagnosticId, project.Name); case FixAllScope.Solution: diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchSimplificationFixAllProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchSimplificationFixAllProvider.cs index db37f75193204cec7e440c98a63ed7351f5de71b..119f226dee7e124c5119e39bc73aa4e35ed98b4d 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchSimplificationFixAllProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchSimplificationFixAllProvider.cs @@ -23,10 +23,13 @@ internal class BatchSimplificationFixAllProvider : BatchFixAllProvider protected BatchSimplificationFixAllProvider() { } - public override async Task AddDocumentFixesAsync(Document document, ImmutableArray diagnostics, Action addFix, FixAllContext fixAllContext) + public override async Task AddDocumentFixesAsync( + Document document, ImmutableArray diagnostics, Action addFix, + FixAllState fixAllState, CancellationToken cancellationToken) { - var changedDocument = await AddSimplifierAnnotationsAsync(document, diagnostics, fixAllContext).ConfigureAwait(false); - var title = GetFixAllTitle(fixAllContext); + var changedDocument = await AddSimplifierAnnotationsAsync( + document, diagnostics, fixAllState, cancellationToken).ConfigureAwait(false); + var title = GetFixAllTitle(fixAllState); var codeAction = new MyCodeAction(title, (c) => Task.FromResult(changedDocument)); addFix(codeAction); } @@ -52,19 +55,20 @@ protected virtual Task AddSimplifyAnnotationsAsync(Document document, } /// - /// By default, this property returns false and will just add to each node to simplify + /// By default, this property returns false and will just add to each node to simplify /// returned by . /// /// 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. - /// will end up invoking for each node to simplify. + /// will end up invoking for each node to simplify. /// Ensure that you override method when this property returns true. /// protected virtual bool NeedsParentFixup { get { return false; } } - private async Task AddSimplifierAnnotationsAsync(Document document, ImmutableArray diagnostics, FixAllContext fixAllContext) + private async Task AddSimplifierAnnotationsAsync( + Document document, ImmutableArray diagnostics, + FixAllState fixAllState, CancellationToken cancellationToken) { - var cancellationToken = fixAllContext.CancellationToken; var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -73,8 +77,8 @@ private async Task AddSimplifierAnnotationsAsync(Document document, Im foreach (var diagnostic in diagnostics) { string codeActionEquivalenceKey; - var node = GetNodeToSimplify(root, model, diagnostic, fixAllContext.Solution.Workspace, out codeActionEquivalenceKey, cancellationToken); - if (node != null && fixAllContext.CodeActionEquivalenceKey == codeActionEquivalenceKey) + var node = GetNodeToSimplify(root, model, diagnostic, fixAllState.Solution.Workspace, out codeActionEquivalenceKey, cancellationToken); + if (node != null && fixAllState.CodeActionEquivalenceKey == codeActionEquivalenceKey) { nodesToSimplify.Add(node); } diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.DiagnosticProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.DiagnosticProvider.cs index 23219b554b2343abbfb403b14764aad6550e5720..1cb9b6cb30bbf763b4b57ac00e525a470c75de29 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.DiagnosticProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.DiagnosticProvider.cs @@ -160,7 +160,8 @@ private static Document GetReportedDocument(Diagnostic diagnostic, ImmutableDict return null; } - internal virtual async Task>> GetProjectDiagnosticsToFixAsync(FixAllContext fixAllContext) + internal virtual async Task>> GetProjectDiagnosticsToFixAsync( + FixAllContext fixAllContext) { using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken)) { diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs index e907e786c9fd1768f6d054405ae2ecbeecc87d23..85e91e8b8929769d3fb36077fc8250a0a2143ab0 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs @@ -16,45 +16,47 @@ namespace Microsoft.CodeAnalysis.CodeFixes /// public sealed partial class FixAllContext { - private readonly DiagnosticProvider _diagnosticProvider; + internal FixAllState State { get; } + + internal FixAllProvider FixAllProvider => State.FixAllProvider; /// /// Solution to fix all occurrences. /// - public Solution Solution { get { return this.Project.Solution; } } + public Solution Solution => State.Solution; /// /// Project within which fix all occurrences was triggered. /// - public Project Project { get; } + public Project Project => State.Project; /// /// Document within which fix all occurrences was triggered. /// Can be null if the context was created using . /// - public Document Document { get; } + public Document Document => State.Document; /// /// Underlying which triggered this fix all. /// - public CodeFixProvider CodeFixProvider { get; } + public CodeFixProvider CodeFixProvider => State.CodeFixProvider; /// /// to fix all occurrences. /// - public FixAllScope Scope { get; } + public FixAllScope Scope => State.Scope; /// /// Diagnostic Ids to fix. /// Note that , and methods /// return only diagnostics whose IDs are contained in this set of Ids. /// - public ImmutableHashSet DiagnosticIds { get; } + public ImmutableHashSet DiagnosticIds => State.DiagnosticIds; /// /// The value expected of a participating in this fix all. /// - public string CodeActionEquivalenceKey { get; } + public string CodeActionEquivalenceKey => State.CodeActionEquivalenceKey; /// /// CancellationToken for fix all session. @@ -82,7 +84,7 @@ public sealed partial class FixAllContext IEnumerable diagnosticIds, DiagnosticProvider fixAllDiagnosticProvider, 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) { @@ -111,7 +113,7 @@ public sealed partial class FixAllContext IEnumerable diagnosticIds, DiagnosticProvider fixAllDiagnosticProvider, 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) { @@ -119,71 +121,14 @@ public sealed partial class FixAllContext } } - private FixAllContext( - Document document, - Project project, - CodeFixProvider codeFixProvider, - FixAllScope scope, - string codeActionEquivalenceKey, - IEnumerable diagnosticIds, - DiagnosticProvider fixAllDiagnosticProvider, + internal FixAllContext( + FixAllState state, CancellationToken cancellationToken) { - 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.Document = document; - this.Project = project; - this.CodeFixProvider = codeFixProvider; - this.Scope = scope; - this.CodeActionEquivalenceKey = codeActionEquivalenceKey; - this.DiagnosticIds = ImmutableHashSet.CreateRange(diagnosticIds); - _diagnosticProvider = fixAllDiagnosticProvider; + State = state; this.CancellationToken = cancellationToken; } - internal bool IsFixMultiple => _diagnosticProvider.IsFixMultiple; - - /// - /// Transforms this context into the public to be used for invocation. - /// - 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); - } - /// /// Gets all the diagnostics in the given document filtered by . /// @@ -199,7 +144,7 @@ public async Task> GetDocumentDiagnosticsAsync(Docume return ImmutableArray.Empty; } - var getDiagnosticsTask = _diagnosticProvider.GetDocumentDiagnosticsAsync(document, this.CancellationToken); + var getDiagnosticsTask = State.DiagnosticProvider.GetDocumentDiagnosticsAsync(document, this.CancellationToken); return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false); } @@ -258,9 +203,9 @@ private async Task> GetProjectDiagnosticsAsync(Projec return ImmutableArray.Empty; } - var getDiagnosticsTask = includeAllDocumentDiagnostics ? - _diagnosticProvider.GetAllDiagnosticsAsync(project, CancellationToken) : - _diagnosticProvider.GetProjectDiagnosticsAsync(project, CancellationToken); + var getDiagnosticsTask = includeAllDocumentDiagnostics + ? State.DiagnosticProvider.GetAllDiagnosticsAsync(project, CancellationToken) + : State.DiagnosticProvider.GetProjectDiagnosticsAsync(project, CancellationToken); return await GetFilteredDiagnosticsAsync(getDiagnosticsTask, this.DiagnosticIds).ConfigureAwait(false); } @@ -275,132 +220,17 @@ public FixAllContext WithCancellationToken(CancellationToken cancellationToken) return this; } - return new FixAllContext( - 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 originalFixDiagnostics, - Func, CancellationToken, Task>> getDocumentDiagnosticsAsync, - Func, CancellationToken, Task>> 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 originalFixDiagnostics, - Func, CancellationToken, Task>> getDocumentDiagnosticsAsync, - Func, CancellationToken, Task>> 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 GetFixAllDiagnosticIds(FixAllProviderInfo fixAllProviderInfo, IEnumerable originalFixDiagnostics) - { - return originalFixDiagnostics - .Where(fixAllProviderInfo.CanBeFixed) - .Select(d => d.Id); - } - - #region FixMultiple - - /// - /// Creates a new . - /// Use this overload when applying fix multiple diagnostics with a source location. - /// - /// Specific set of diagnostics to fix. Must be a non-empty set. - /// Underlying which triggered this fix all. - /// The value expected of a participating in this fix all. - /// Cancellation token for fix all computation. - internal static FixAllContext Create( - ImmutableDictionary> 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); - } - - /// - /// Creates a new . - /// Use this overload when applying fix multiple diagnostics with no source location. - /// - /// Specific set of diagnostics to fix. Must be a non-empty set. - /// Underlying which triggered this fix all. - /// The value expected of a participating in this fix all. - /// Cancellation token for fix all computation. - internal static FixAllContext Create( - ImmutableDictionary> 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 GetDiagnosticsIds(IEnumerable> diagnosticsCollection) - { - var uniqueIds = ImmutableHashSet.CreateBuilder(); - foreach (var diagnostics in diagnosticsCollection) - { - foreach (var diagnostic in diagnostics) - { - uniqueIds.Add(diagnostic.Id); - } - } - - return uniqueIds.ToImmutable(); + return new FixAllContext(State, cancellationToken); } - #endregion - internal Task>> GetDocumentDiagnosticsToFixAsync() { - return _diagnosticProvider.GetDocumentDiagnosticsToFixAsync(this); + return State.DiagnosticProvider.GetDocumentDiagnosticsToFixAsync(this); } internal Task>> GetProjectDiagnosticsToFixAsync() { - return _diagnosticProvider.GetProjectDiagnosticsToFixAsync(this); + return State.DiagnosticProvider.GetProjectDiagnosticsToFixAsync(this); } } -} +} \ No newline at end of file diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllLogger.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllLogger.cs index ccf7b19d24401bb9a2debd554029409586a301d4..adc6b00b07554961571c15296aa4737c1d0d6d35 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllLogger.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllLogger.cs @@ -35,32 +35,32 @@ internal static class FixAllLogger private static readonly string s_totalDiagnosticsToFix = "TotalDiagnosticsToFix"; 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 => { if (isInternalCodeFixProvider) { - m[s_codeFixProvider] = fixAllContext.CodeFixProvider.GetType().FullName; - m[s_codeActionEquivalenceKey] = fixAllContext.CodeActionEquivalenceKey; - m[s_languageName] = fixAllContext.Project.Language; + m[s_codeFixProvider] = fixAllState.CodeFixProvider.GetType().FullName; + m[s_codeActionEquivalenceKey] = fixAllState.CodeActionEquivalenceKey; + m[s_languageName] = fixAllState.Project.Language; } else { - m[s_codeFixProvider] = fixAllContext.CodeFixProvider.GetType().FullName.GetHashCode().ToString(); - m[s_codeActionEquivalenceKey] = fixAllContext.CodeActionEquivalenceKey != null ? fixAllContext.CodeActionEquivalenceKey.GetHashCode().ToString() : null; - m[s_languageName] = fixAllContext.Project.Language.GetHashCode().ToString(); + m[s_codeFixProvider] = fixAllState.CodeFixProvider.GetType().FullName.GetHashCode().ToString(); + m[s_codeActionEquivalenceKey] = fixAllState.CodeActionEquivalenceKey != null ? fixAllState.CodeActionEquivalenceKey.GetHashCode().ToString() : null; + m[s_languageName] = fixAllState.Project.Language.GetHashCode().ToString(); } - m[s_fixAllScope] = fixAllContext.Scope.ToString(); - switch (fixAllContext.Scope) + m[s_fixAllScope] = fixAllState.Scope.ToString(); + switch (fixAllState.Scope) { case CodeFixes.FixAllScope.Project: - m[s_documentCount] = fixAllContext.Project.DocumentIds.Count; + m[s_documentCount] = fixAllState.Project.DocumentIds.Count; break; 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; } })); diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllProvider.cs index 03940da6c7c31c5ef9f68afd1b6228009fb57dec..57c0de17677c49a42064457250456cafa0b9dd25 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllProvider.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; @@ -42,14 +43,14 @@ public virtual IEnumerable GetSupportedFixAllDiagnosticIds(CodeFixProvid internal virtual Task GetFixAsync( ImmutableDictionary> documentsAndDiagnosticsToFixMap, - FixAllContext fixAllContext) + FixAllState fixAllState, CancellationToken cancellationToken) { return Task.FromResult(null); } internal virtual Task GetFixAsync( ImmutableDictionary> projectsAndDiagnosticsToFixMap, - FixAllContext fixAllContext) + FixAllState fixAllState, CancellationToken cancellationToken) { return Task.FromResult(null); } diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.FixAllDiagnosticProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.FixAllDiagnosticProvider.cs similarity index 98% rename from src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.FixAllDiagnosticProvider.cs rename to src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.FixAllDiagnosticProvider.cs index e1956973bad6b4b05b2e8f345f6b55935a5e435b..d5483f4e1a320fde3c0cd9c999fa065df7df070e 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.FixAllDiagnosticProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.FixAllDiagnosticProvider.cs @@ -6,7 +6,7 @@ namespace Microsoft.CodeAnalysis.CodeFixes { - public partial class FixAllContext + internal partial class FixAllState { // Internal for testing purposes. internal class FixAllDiagnosticProvider : FixAllContext.DiagnosticProvider diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.FixMultipleDiagnosticProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.FixMultipleDiagnosticProvider.cs similarity index 99% rename from src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.FixMultipleDiagnosticProvider.cs rename to src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.FixMultipleDiagnosticProvider.cs index d7252e56ae95e9e81cae89593ede0958ae0c9e6d..fcd7d8f66086030f3e8f1adc6e9f12812774675e 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.FixMultipleDiagnosticProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.FixMultipleDiagnosticProvider.cs @@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.CodeFixes { - public partial class FixAllContext + internal partial class FixAllState { /// /// Diagnostic provider to fetch document/project diagnostics to fix in a . diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.cs new file mode 100644 index 0000000000000000000000000000000000000000..bd575af31813fbbfa6f758e7f8c1233f189a508d --- /dev/null +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllState.cs @@ -0,0 +1,217 @@ +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 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 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 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 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 originalFixDiagnostics, + Func, CancellationToken, Task>> getDocumentDiagnosticsAsync, + Func, CancellationToken, Task>> 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 originalFixDiagnostics, + Func, CancellationToken, Task>> getDocumentDiagnosticsAsync, + Func, CancellationToken, Task>> 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 GetFixAllDiagnosticIds(FixAllProviderInfo fixAllProviderInfo, IEnumerable originalFixDiagnostics) + { + return originalFixDiagnostics + .Where(fixAllProviderInfo.CanBeFixed) + .Select(d => d.Id); + } + + #region FixMultiple + + internal static FixAllState Create( + FixAllProvider fixAllProvider, + ImmutableDictionary> 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> 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 GetDiagnosticsIds(IEnumerable> diagnosticsCollection) + { + var uniqueIds = ImmutableHashSet.CreateBuilder(); + foreach (var diagnostics in diagnosticsCollection) + { + foreach (var diagnostic in diagnostics) + { + uniqueIds.Add(diagnostic.Id); + } + } + + return uniqueIds.ToImmutable(); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs index eda9ced94e7fb637614db5def55e4a5b6ef9bb7a..c940857bb51c4a6662d91791ccc9f9cc386c6b84 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs @@ -278,7 +278,12 @@ private int BinarySearch(string name) 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) { return null; @@ -293,12 +298,15 @@ private int BinarySearch(string name) { 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( - 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( - 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) { @@ -306,7 +314,8 @@ private int BinarySearch(string name) } var list = new List(); - GenerateNodes(assembly.GlobalNamespace, list); + var lookup = includeInternal ? s_getMembersNoPrivate : s_getMembersNoPrivateOrInternal; + GenerateNodes(assembly.GlobalNamespace, list, lookup); var sortedNodes = SortNodes(list); var createSpellCheckerTask = GetSpellCheckerTask(solution, version, assembly, filePath, sortedNodes); @@ -387,44 +396,65 @@ private static int CompareNodes(Node x, Node y, IReadOnlyList nodeList) } // generate nodes for the global namespace an all descendants - private static void GenerateNodes(INamespaceSymbol globalNamespace, List list) + private static void GenerateNodes( + INamespaceSymbol globalNamespace, + List list, + Func> lookup) { var node = new Node(globalNamespace.Name, Node.RootNodeParentIndex); list.Add(node); // 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) { - 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 s_useSymbol = + private static readonly Func s_useSymbolNoPrivate = s => s.CanBeReferencedByName && s.DeclaredAccessibility != Accessibility.Private; + private static readonly Func 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 - private static void GenerateNodes(string name, int parentIndex, IEnumerable symbolsWithSameName, List list) + private static void GenerateNodes( + string name, + int parentIndex, + IEnumerable symbolsWithSameName, + List list, + Func> lookup) { var node = new Node(name, parentIndex); var nodeIndex = list.Count; list.Add(node); // 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) { - GenerateNodes(grouping.Key, nodeIndex, grouping, list); + GenerateNodes(grouping.Key, nodeIndex, grouping, list, lookup); } } - private static Func> s_getMembers = symbol => + private static Func> s_getMembersNoPrivate = symbol => + { + var nt = symbol as INamespaceOrTypeSymbol; + return nt != null + ? nt.GetMembers().Where(s_useSymbolNoPrivate) + : SpecializedCollections.EmptyEnumerable(); + }; + + private static Func> s_getMembersNoPrivateOrInternal = symbol => { var nt = symbol as INamespaceOrTypeSymbol; return nt != null - ? nt.GetMembers().Where(s_useSymbol) + ? nt.GetMembers().Where(s_useSymbolNoPrivateOrInternal) : SpecializedCollections.EmptyEnumerable(); }; diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs index 5886199038960173a2be56e7afb40435791b6b76..222c1f1b97b02eaf79298f7f003a12ab77adeae7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo_Serialization.cs @@ -26,6 +26,7 @@ internal partial class SymbolTreeInfo : IObjectWritable IAssemblySymbol assembly, string filePath, bool loadOnly, + bool includeInternal, CancellationToken cancellationToken) { return LoadOrCreateAsync( @@ -33,7 +34,7 @@ internal partial class SymbolTreeInfo : IObjectWritable assembly, filePath, loadOnly, - create: version => CreateSymbolTreeInfo(solution, version, assembly, filePath, cancellationToken), + create: version => CreateSymbolTreeInfo(solution, version, assembly, filePath, includeInternal, cancellationToken), keySuffix: "", getVersion: info => info._version, readObject: reader => ReadSymbolTreeInfo(reader, (version, nodes) => GetSpellCheckerTask(solution, version, assembly, filePath, nodes)), diff --git a/src/Workspaces/Core/Portable/Options/IOption2.cs b/src/Workspaces/Core/Portable/Options/IOption2.cs deleted file mode 100644 index 857604f38d947640f5e59feccf0fe3b663427b35..0000000000000000000000000000000000000000 --- a/src/Workspaces/Core/Portable/Options/IOption2.cs +++ /dev/null @@ -1,9 +0,0 @@ -// 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); - } -} diff --git a/src/Workspaces/Core/Portable/Options/OptionKey.cs b/src/Workspaces/Core/Portable/Options/OptionKey.cs index 8300af2f144d147d09b91103c8d1bd27454742e7..f4956d401678a46cb31935d1e92d07fda4aa359a 100644 --- a/src/Workspaces/Core/Portable/Options/OptionKey.cs +++ b/src/Workspaces/Core/Portable/Options/OptionKey.cs @@ -10,8 +10,6 @@ public struct OptionKey : IEquatable public IOption Option { get; } public string Language { get; } - internal object DefaultValue => ((IOption2)Option).GetDefaultValue(Language); - public OptionKey(IOption option, string language = null) { if (option == null) diff --git a/src/Workspaces/Core/Portable/Options/OptionService.cs b/src/Workspaces/Core/Portable/Options/OptionService.cs index c6a30107eff9d131de505d2a36d9fb2ca0d8817e..de73f3c956e4eb536fea71fa10a7f035017e27b6 100644 --- a/src/Workspaces/Core/Portable/Options/OptionService.cs +++ b/src/Workspaces/Core/Portable/Options/OptionService.cs @@ -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 // over and over. - return optionKey.DefaultValue; + return optionKey.Option.DefaultValue; } } diff --git a/src/Workspaces/Core/Portable/Options/OptionSet.cs b/src/Workspaces/Core/Portable/Options/OptionSet.cs index 2c9acd7f0f939061ccef1cb6a7fca9c5d1e5d279..eac193bb2ec29be8dcef1b7dc6fe855628b5c90f 100644 --- a/src/Workspaces/Core/Portable/Options/OptionSet.cs +++ b/src/Workspaces/Core/Portable/Options/OptionSet.cs @@ -51,7 +51,7 @@ public object GetOption(OptionKey optionKey) 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); } diff --git a/src/Workspaces/Core/Portable/Options/Option`1.cs b/src/Workspaces/Core/Portable/Options/Option`1.cs index 521c7414f3fa01ad702a85d5e2f4979f89390295..5c8bea66b814e9cd5c1ff65170cc6dc3f96e2e6f 100644 --- a/src/Workspaces/Core/Portable/Options/Option`1.cs +++ b/src/Workspaces/Core/Portable/Options/Option`1.cs @@ -7,7 +7,7 @@ namespace Microsoft.CodeAnalysis.Options /// /// An global option. An instance of this class can be used to access an option value from an OptionSet. /// - public class Option : IOption2, IOption + public class Option : IOption { /// /// Feature this option is associated with. @@ -22,7 +22,10 @@ public class Option : IOption2, IOption /// /// The type of the option value. /// - public Type Type => typeof(T); + public Type Type + { + get { return typeof(T); } + } /// /// The default value of the option. @@ -46,13 +49,19 @@ public Option(string feature, string name, T defaultValue = default(T)) this.DefaultValue = defaultValue; } - Type IOption.Type => typeof(T); - object IOption.DefaultValue => this.DefaultValue; - bool IOption.IsPerLanguage => false; + Type IOption.Type + { + 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() diff --git a/src/Workspaces/Core/Portable/Options/PerLanguageOption.cs b/src/Workspaces/Core/Portable/Options/PerLanguageOption.cs index ae04592fb490fe3b2c18eb0ab82955f426a83f5a..23398e14ad9820611e827aab1571fd9e26d1e0e9 100644 --- a/src/Workspaces/Core/Portable/Options/PerLanguageOption.cs +++ b/src/Workspaces/Core/Portable/Options/PerLanguageOption.cs @@ -1,8 +1,6 @@ // 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.Immutable; namespace Microsoft.CodeAnalysis.Options { @@ -10,13 +8,8 @@ namespace Microsoft.CodeAnalysis.Options /// An option that can be specified once per language. /// /// - public class PerLanguageOption : IOption2, IOption + public class PerLanguageOption : IOption { - /// - /// Save per language defaults - /// - private readonly IImmutableDictionary _perLanguageDefaults; - /// /// Feature this option is associated with. /// @@ -40,32 +33,7 @@ public Type Type /// public T DefaultValue { get; } - /// - /// The default option value of specific language - /// - 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.Empty) - { - } - - internal PerLanguageOption( - string feature, string name, T defaultValue, IDictionary perLanguageDefaults) + public PerLanguageOption(string feature, string name, T defaultValue) { if (string.IsNullOrWhiteSpace(feature)) { @@ -77,18 +45,9 @@ internal T GetDefaultValue(string language) throw new ArgumentException(nameof(name)); } - if (perLanguageDefaults == null) - { - throw new ArgumentNullException(nameof(perLanguageDefaults)); - } - this.Feature = feature; this.Name = name; this.DefaultValue = defaultValue; - - this._perLanguageDefaults = - (perLanguageDefaults as IImmutableDictionary) ?? - ImmutableDictionary.CreateRange(perLanguageDefaults); } Type IOption.Type @@ -106,11 +65,6 @@ bool IOption.IsPerLanguage get { return true; } } - object IOption2.GetDefaultValue(string language) - { - return this.GetDefaultValue(language); - } - public override string ToString() { return string.Format("{0} - {1}", this.Feature, this.Name); diff --git a/src/Workspaces/Core/Portable/Utilities/BKTree.cs b/src/Workspaces/Core/Portable/Utilities/BKTree.cs index 30f5ba29b8f8db0425502b5871edcf0bcca4d5ed..0db3a8c9fcd2ff3b938eaf5882ada61d4e24c87b 100644 --- a/src/Workspaces/Core/Portable/Utilities/BKTree.cs +++ b/src/Workspaces/Core/Portable/Utilities/BKTree.cs @@ -88,7 +88,7 @@ public IList Find(string value, int? threshold = null) threshold = threshold ?? WordSimilarityChecker.GetThreshold(value); var result = new List(); - Lookup(_nodes[0], lowerCaseCharacters, value.Length, threshold.Value, result); + Lookup(_nodes[0], lowerCaseCharacters, value.Length, threshold.Value, result, recursionCount: 0); return result; } finally @@ -97,8 +97,28 @@ public IList Find(string value, int? threshold = null) } } - private void Lookup(Node currentNode, char[] queryCharacters, int queryLength, int threshold, List result) + private void Lookup( + Node currentNode, + char[] queryCharacters, + int queryLength, + int threshold, + List 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 // because we need that edit distance to appropriately determine which edges to walk // in the tree. @@ -124,7 +144,8 @@ private void Lookup(Node currentNode, char[] queryCharacters, int queryLength, i if (min <= childEditDistance && childEditDistance <= max) { Lookup(_nodes[_edges[i].ChildNodeIndex], - queryCharacters, queryLength, threshold, result); + queryCharacters, queryLength, threshold, result, + recursionCount + 1); } } } diff --git a/src/Workspaces/Core/Portable/Utilities/SpellChecker.cs b/src/Workspaces/Core/Portable/Utilities/SpellChecker.cs index 062966bc86098b1ee8657ea3e4094283257c4b6d..aa2f0ba4b29a5f34eb6139ce74948735597dc901 100644 --- a/src/Workspaces/Core/Portable/Utilities/SpellChecker.cs +++ b/src/Workspaces/Core/Portable/Utilities/SpellChecker.cs @@ -11,7 +11,7 @@ namespace Roslyn.Utilities { internal class SpellChecker { - private const string SerializationFormat = "1"; + private const string SerializationFormat = "2"; public VersionStamp Version { get; } private readonly BKTree _bkTree; diff --git a/src/Workspaces/Core/Portable/Workspaces.csproj b/src/Workspaces/Core/Portable/Workspaces.csproj index 7ff73bd714e732c67fd62ba6e3bd94645e75451b..150c62218e1dcd0a64c7eb2e1a6575ddf5201f33 100644 --- a/src/Workspaces/Core/Portable/Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Workspaces.csproj @@ -310,11 +310,12 @@ - + - + + @@ -393,7 +394,6 @@ - @@ -978,4 +978,4 @@ - \ No newline at end of file + diff --git a/src/Workspaces/CoreTest/FindAllDeclarationsTests.cs b/src/Workspaces/CoreTest/FindAllDeclarationsTests.cs index 3622422bdaf60a7ef0bef42aca2e391148201f9d..8abfaca157dcba7c2099eb79f9e9059277bab9bd 100644 --- a/src/Workspaces/CoreTest/FindAllDeclarationsTests.cs +++ b/src/Workspaces/CoreTest/FindAllDeclarationsTests.cs @@ -577,7 +577,8 @@ public static async Task TestSymbolTreeInfoSerialization() // create symbol tree info from assembly 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()) { diff --git a/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb b/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb index 6275160268bc4169d2a3a91bc565a5eb35980645..1a4d0448146a213a3a083c4653c0291235c52288 100644 --- a/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb +++ b/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb @@ -68,11 +68,29 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Recommendations Return GetUnqualifiedSymbolsForLabelContext(context, cancellationToken) ElseIf context.SyntaxTree.IsRaiseEventContext(context.Position, context.TargetToken, cancellationToken) Then Return GetUnqualifiedSymbolsForRaiseEvent(context, cancellationToken) + ElseIf context.TargetToken.IsKind(SyntaxKind.ForKeyword) Then + Dim symbols = GetUnqualifiedSymbolsForExpressionOrStatementContext(context, filterOutOfScopeLocals, cancellationToken) _ + .Where(AddressOf IsWritableFieldOrLocal) + Return symbols End If Return SpecializedCollections.EmptyEnumerable(Of ISymbol)() 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( context As VisualBasicSyntaxContext, cancellationToken As CancellationToken