From 21db02dcb8d307a968fdbbb7fb5cb6033097c2ec Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 11:21:34 -0700 Subject: [PATCH 01/10] Simplify --- .../Core/Portable/FindSymbols/SymbolFinder.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs index 89ac7f1794849..339c8ca10d36d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -188,22 +189,13 @@ public static async Task FindSymbolAtPositionAsync( var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var result = symbolId.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken: cancellationToken); - if (result.Symbol != null && InSource(result.Symbol)) - { - return result.Symbol; - } - else - { - return result.CandidateSymbols.FirstOrDefault(InSource); - } + return InSource(result.Symbol) ? result.Symbol : result.CandidateSymbols.FirstOrDefault(InSource); } return null; - } - private static bool InSource(ISymbol symbol) - { - return symbol.Locations.Any(static loc => loc.IsInSource); + static bool InSource([NotNullWhen(true)] ISymbol? symbol) + => symbol != null && symbol.Locations.Any(static loc => loc.IsInSource); } /// From 979d3e84311d656048412a992b17be7ac6de486e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 11:33:00 -0700 Subject: [PATCH 02/10] Remove async from FindReferencesInDocument --- .../DelegateInvokeMethodReferenceFinder.cs | 5 ++- .../FindReferencesSearchEngine.cs | 11 ++++--- ...sSearchEngine_FindReferencesInDocuments.cs | 4 +-- .../AbstractMemberScopedReferenceFinder.cs | 4 +-- .../Finders/AbstractReferenceFinder.cs | 11 +++---- ...tractTypeParameterSymbolReferenceFinder.cs | 4 +-- ...tructorInitializerSymbolReferenceFinder.cs | 4 +-- .../ConstructorSymbolReferenceFinder.cs | 6 ++-- .../DestructorSymbolReferenceFinder.cs | 3 +- .../Finders/EventSymbolReferenceFinder.cs | 5 ++- ...ExplicitConversionSymbolReferenceFinder.cs | 3 +- .../ExplicitInterfaceMethodReferenceFinder.cs | 3 +- .../Finders/FieldSymbolReferenceFinder.cs | 3 +- .../Finders/IReferenceFinder.cs | 2 +- .../Finders/LabelSymbolReferenceFinder.cs | 2 -- .../Finders/NamedTypeSymbolReferenceFinder.cs | 4 +-- .../Finders/NamespaceSymbolReferenceFinder.cs | 6 ++-- .../Finders/OperatorSymbolReferenceFinder.cs | 3 +- .../Finders/OrdinaryMethodReferenceFinder.cs | 4 +-- .../Finders/ParameterSymbolReferenceFinder.cs | 3 +- .../PropertyAccessorSymbolReferenceFinder.cs | 6 ++-- .../Finders/PropertySymbolReferenceFinder.cs | 3 +- .../Core/Portable/FindSymbols/SymbolFinder.cs | 33 ++++++++++--------- 23 files changed, 57 insertions(+), 75 deletions(-) diff --git a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs index fab481046098c..b4b4f86be28c1 100644 --- a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs +++ b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs @@ -76,7 +76,7 @@ protected override Task DetermineDocumentsToSearchAsync( return Task.CompletedTask; } - protected override async ValueTask FindReferencesInDocumentAsync( + protected override async void FindReferencesInDocument( IMethodSymbol methodSymbol, FindReferencesDocumentState state, Action processResult, @@ -105,8 +105,7 @@ protected override async ValueTask FindReferencesInDocumentAsync( var convertedType = (ISymbol?)state.SemanticModel.GetTypeInfo(node, cancellationToken).ConvertedType; if (convertedType != null) { - convertedType = await SymbolFinder.FindSourceDefinitionAsync(convertedType, state.Solution, cancellationToken).ConfigureAwait(false) - ?? convertedType; + convertedType = SymbolFinder.FindSourceDefinition(convertedType, state.Solution, cancellationToken) ?? convertedType; } if (convertedType == methodSymbol.ContainingType) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs index a80669feb1155..451eae0b79cd0 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine.cs @@ -290,19 +290,20 @@ private async ValueTask ProcessDocumentAsync( await RoslynParallel.ForEachAsync( symbols, GetParallelOptions(cancellationToken), - async (symbol, cancellationToken) => + (symbol, cancellationToken) => { // symbolToGlobalAliases is safe to read in parallel. It is created fully before this point and is no // longer mutated. var state = new FindReferencesDocumentState( cache, TryGet(symbolToGlobalAliases, symbol)); - await ProcessDocumentAsync(symbol, state, onReferenceFound).ConfigureAwait(false); + ProcessDocument(symbol, state, onReferenceFound); + return ValueTaskFactory.CompletedTask; }).ConfigureAwait(false); return; - async Task ProcessDocumentAsync( + void ProcessDocument( ISymbol symbol, FindReferencesDocumentState state, Action onReferenceFound) { cancellationToken.ThrowIfCancellationRequested(); @@ -318,12 +319,12 @@ async Task ProcessDocumentAsync( // and only do interesting work on the single relevant one. foreach (var finder in _finders) { - await finder.FindReferencesInDocumentAsync( + finder.FindReferencesInDocument( symbol, state, static (loc, tuple) => tuple.onReferenceFound((tuple.group, tuple.symbol, loc.Location)), (group, symbol, onReferenceFound), _options, - cancellationToken).ConfigureAwait(false); + cancellationToken); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs index 0666734493488..1c3de836deb31 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs @@ -113,8 +113,8 @@ async ValueTask DirectSymbolSearchAsync(ISymbol symbol, FindReferencesDocumentSt using var _ = ArrayBuilder.GetInstance(out var referencesForFinder); foreach (var finder in _finders) { - await finder.FindReferencesInDocumentAsync( - symbol, state, StandardCallbacks.AddToArrayBuilder, referencesForFinder, _options, cancellationToken).ConfigureAwait(false); + finder.FindReferencesInDocument( + symbol, state, StandardCallbacks.AddToArrayBuilder, referencesForFinder, _options, cancellationToken); } if (referencesForFinder.Count > 0) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMemberScopedReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMemberScopedReferenceFinder.cs index bc902b6dde014..1c194904c1ca4 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMemberScopedReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractMemberScopedReferenceFinder.cs @@ -49,7 +49,7 @@ protected sealed override Task DetermineDocumentsToSearchAsync( return Task.CompletedTask; } - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( TSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -67,8 +67,6 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( var tokens = FindMatchingIdentifierTokens(state, symbol.Name, cancellationToken); FindReferencesInTokens(symbol, state, tokens, processResult, processResultData, cancellationToken); } - - return ValueTaskFactory.CompletedTask; } private static ISymbol? GetContainer(ISymbol symbol) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs index 99787ba6b637f..3d5f8e9c504e5 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs @@ -33,7 +33,7 @@ public abstract ValueTask> DetermineCascadedSymbolsAsync public abstract Task DetermineDocumentsToSearchAsync( ISymbol symbol, HashSet? globalAliases, Project project, IImmutableSet? documents, Action processResult, TData processResultData, FindReferencesSearchOptions options, CancellationToken cancellationToken); - public abstract ValueTask FindReferencesInDocumentAsync( + public abstract void FindReferencesInDocument( ISymbol symbol, FindReferencesDocumentState state, Action processResult, TData processResultData, FindReferencesSearchOptions options, CancellationToken cancellationToken); private static (bool matched, CandidateReason reason) SymbolsMatch( @@ -848,7 +848,7 @@ protected abstract Task DetermineDocumentsToSearchAsync( Action processResult, TData processResultData, FindReferencesSearchOptions options, CancellationToken cancellationToken); - protected abstract ValueTask FindReferencesInDocumentAsync( + protected abstract void FindReferencesInDocument( TSymbol symbol, FindReferencesDocumentState state, Action processResult, TData processResultData, FindReferencesSearchOptions options, CancellationToken cancellationToken); @@ -878,12 +878,11 @@ public sealed override Task DetermineDocumentsToSearchAsync( return Task.CompletedTask; } - public sealed override ValueTask FindReferencesInDocumentAsync( + public sealed override void FindReferencesInDocument( ISymbol symbol, FindReferencesDocumentState state, Action processResult, TData processResultData, FindReferencesSearchOptions options, CancellationToken cancellationToken) { - return symbol is TSymbol typedSymbol && CanFind(typedSymbol) - ? FindReferencesInDocumentAsync(typedSymbol, state, processResult, processResultData, options, cancellationToken) - : ValueTaskFactory.CompletedTask; + if (symbol is TSymbol typedSymbol && CanFind(typedSymbol)) + FindReferencesInDocument(typedSymbol, state, processResult, processResultData, options, cancellationToken); } public sealed override ValueTask> DetermineCascadedSymbolsAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractTypeParameterSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractTypeParameterSymbolReferenceFinder.cs index b84e1bd7abaf1..8bb2cecb9ffba 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractTypeParameterSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractTypeParameterSymbolReferenceFinder.cs @@ -13,7 +13,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; internal abstract class AbstractTypeParameterSymbolReferenceFinder : AbstractReferenceFinder { - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( ITypeParameterSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -43,7 +43,7 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( processResult, processResultData); - return ValueTaskFactory.CompletedTask; + return; static bool IsObjectCreationToken(SyntaxToken token, FindReferencesDocumentState state) { diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs index 3ee5b2f3a72e4..b15a9593de89c 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs @@ -51,7 +51,7 @@ protected override Task DetermineDocumentsToSearchAsync( }, symbol.ContainingType.Name, processResult, processResultData, cancellationToken); } - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( IMethodSymbol methodSymbol, FindReferencesDocumentState state, Action processResult, @@ -68,7 +68,7 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( (state, methodSymbol, cancellationToken)); FindReferencesInTokens(methodSymbol, state, totalTokens, processResult, processResultData, cancellationToken); - return ValueTaskFactory.CompletedTask; + return; // local functions static bool TokensMatch( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs index 9e0d20f947dfd..6d77c275ac4fe 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs @@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; -internal class ConstructorSymbolReferenceFinder : AbstractReferenceFinder +internal sealed class ConstructorSymbolReferenceFinder : AbstractReferenceFinder { public static readonly ConstructorSymbolReferenceFinder Instance = new(); @@ -90,7 +90,7 @@ private static bool IsPotentialReference(PredefinedType predefinedType, ISyntaxF => syntaxFacts.TryGetPredefinedType(token, out var actualType) && predefinedType == actualType; - protected override ValueTask FindReferencesInDocumentAsync( + protected override void FindReferencesInDocument( IMethodSymbol methodSymbol, FindReferencesDocumentState state, Action processResult, @@ -126,8 +126,6 @@ protected override ValueTask FindReferencesInDocumentAsync( FindReferencesInDocumentInsideGlobalSuppressions( methodSymbol, state, processResult, processResultData, cancellationToken); - - return ValueTaskFactory.CompletedTask; } /// diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs index a6c1623d5ba95..f7185806276a0 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/DestructorSymbolReferenceFinder.cs @@ -29,7 +29,7 @@ protected override Task DetermineDocumentsToSearchAsync( return Task.CompletedTask; } - protected override ValueTask FindReferencesInDocumentAsync( + protected override void FindReferencesInDocument( IMethodSymbol methodSymbol, FindReferencesDocumentState state, Action processResult, @@ -37,6 +37,5 @@ protected override ValueTask FindReferencesInDocumentAsync( FindReferencesSearchOptions options, CancellationToken cancellationToken) { - return ValueTaskFactory.CompletedTask; } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs index 7b5870acdbde7..d0347dca087c1 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/EventSymbolReferenceFinder.cs @@ -12,7 +12,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; -internal class EventSymbolReferenceFinder : AbstractMethodOrPropertyOrEventSymbolReferenceFinder +internal sealed class EventSymbolReferenceFinder : AbstractMethodOrPropertyOrEventSymbolReferenceFinder { protected override bool CanFind(IEventSymbol symbol) => true; @@ -49,7 +49,7 @@ protected sealed override async Task DetermineDocumentsToSearchAsync( await FindDocumentsWithGlobalSuppressMessageAttributeAsync(project, documents, processResult, processResultData, cancellationToken).ConfigureAwait(false); } - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( IEventSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -58,6 +58,5 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( CancellationToken cancellationToken) { FindReferencesInDocumentUsingSymbolName(symbol, state, processResult, processResultData, cancellationToken); - return ValueTaskFactory.CompletedTask; } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitConversionSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitConversionSymbolReferenceFinder.cs index dfed302b16041..647a4cb6565e2 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitConversionSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitConversionSymbolReferenceFinder.cs @@ -59,7 +59,7 @@ protected sealed override async Task DetermineDocumentsToSearchAsync( } } - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( IMethodSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -74,7 +74,6 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( state); FindReferencesInTokens(symbol, state, tokens, processResult, processResultData, cancellationToken); - return ValueTaskFactory.CompletedTask; } private static bool IsPotentialReference( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs index a92e4f0ca1eba..a1a9accd9b03b 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ExplicitInterfaceMethodReferenceFinder.cs @@ -30,7 +30,7 @@ protected sealed override Task DetermineDocumentsToSearchAsync( return Task.CompletedTask; } - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( IMethodSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -39,6 +39,5 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( CancellationToken cancellationToken) { // An explicit method can't be referenced anywhere. - return ValueTaskFactory.CompletedTask; } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs index 4377ecd8bb5b5..de2f29401c9ad 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/FieldSymbolReferenceFinder.cs @@ -41,7 +41,7 @@ protected override async Task DetermineDocumentsToSearchAsync( await FindDocumentsWithGlobalSuppressMessageAttributeAsync(project, documents, processResult, processResultData, cancellationToken).ConfigureAwait(false); } - protected override ValueTask FindReferencesInDocumentAsync( + protected override void FindReferencesInDocument( IFieldSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -53,6 +53,5 @@ protected override ValueTask FindReferencesInDocumentAsync( symbol, state, processResult, processResultData, cancellationToken); FindReferencesInDocumentInsideGlobalSuppressions( symbol, state, processResult, processResultData, cancellationToken); - return ValueTaskFactory.CompletedTask; } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs index f5b717542dc20..cb77de6a8bed9 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/IReferenceFinder.cs @@ -63,7 +63,7 @@ Task DetermineDocumentsToSearchAsync( /// /// Implementations of this method must be thread-safe. /// - ValueTask FindReferencesInDocumentAsync( + void FindReferencesInDocument( ISymbol symbol, FindReferencesDocumentState state, Action processResult, diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LabelSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LabelSymbolReferenceFinder.cs index f88a6830cb41e..b25a8d8b00da4 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LabelSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/LabelSymbolReferenceFinder.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Threading; - namespace Microsoft.CodeAnalysis.FindSymbols.Finders; internal sealed class LabelSymbolReferenceFinder : AbstractMemberScopedReferenceFinder diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs index 0b2e5e08bb88c..458bb779a494e 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs @@ -105,7 +105,7 @@ private static bool IsPotentialReference( predefinedType == actualType; } - protected override ValueTask FindReferencesInDocumentAsync( + protected override void FindReferencesInDocument( INamedTypeSymbol namedType, FindReferencesDocumentState state, Action processResult, @@ -135,8 +135,6 @@ protected override ValueTask FindReferencesInDocumentAsync( FindReferencesInDocumentInsideGlobalSuppressions( namedType, state, processResult, processResultData, cancellationToken); - - return ValueTaskFactory.CompletedTask; } internal static void AddReferencesToTypeOrGlobalAliasToIt( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs index 3ca848269ce6a..1a0d59c5b103a 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs @@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; -internal class NamespaceSymbolReferenceFinder : AbstractReferenceFinder +internal sealed class NamespaceSymbolReferenceFinder : AbstractReferenceFinder { protected override bool CanFind(INamespaceSymbol symbol) => true; @@ -51,7 +51,7 @@ await FindDocumentsAsync( await FindDocumentsWithGlobalSuppressMessageAttributeAsync(project, documents, processResult, processResultData, cancellationToken).ConfigureAwait(false); } - protected override ValueTask FindReferencesInDocumentAsync( + protected override void FindReferencesInDocument( INamespaceSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -94,8 +94,6 @@ protected override ValueTask FindReferencesInDocumentAsync( FindReferencesInDocumentInsideGlobalSuppressions( symbol, state, processResult, processResultData, cancellationToken); } - - return ValueTaskFactory.CompletedTask; } /// diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OperatorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OperatorSymbolReferenceFinder.cs index a6d5cb8b80c0c..869ff256c1691 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OperatorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OperatorSymbolReferenceFinder.cs @@ -48,7 +48,7 @@ private static Task FindDocumentsAsync( project, documents, static (index, op) => index.ContainsPredefinedOperator(op), op, processResult, processResultData, cancellationToken); } - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( IMethodSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -67,7 +67,6 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( symbol, state, tokens, processResult, processResultData, cancellationToken); FindReferencesInDocumentInsideGlobalSuppressions( symbol, state, processResult, processResultData, cancellationToken); - return ValueTaskFactory.CompletedTask; } private static bool IsPotentialReference( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs index bb1dbb697400a..491bff6bfc5a3 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/OrdinaryMethodReferenceFinder.cs @@ -109,7 +109,7 @@ private static bool IsGetAwaiterMethod(IMethodSymbol methodSymbol) private static bool IsAddMethod(IMethodSymbol methodSymbol) => methodSymbol.Name == WellKnownMemberNames.CollectionInitializerAddMethodName; - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( IMethodSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -134,7 +134,5 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( if (IsAddMethod(symbol)) FindReferencesInCollectionInitializer(symbol, state, processResult, processResultData, cancellationToken); - - return ValueTaskFactory.CompletedTask; } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs index adef39983674b..5cffb6d4ca570 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs @@ -39,7 +39,7 @@ protected override Task DetermineDocumentsToSearchAsync( return FindDocumentsAsync(project, documents, processResult, processResultData, cancellationToken, symbol.Name); } - protected override ValueTask FindReferencesInDocumentAsync( + protected override void FindReferencesInDocument( IParameterSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -48,7 +48,6 @@ protected override ValueTask FindReferencesInDocumentAsync( CancellationToken cancellationToken) { FindReferencesInDocumentUsingIdentifier(symbol, symbol.Name, state, processResult, processResultData, cancellationToken); - return ValueTaskFactory.CompletedTask; } protected override async ValueTask> DetermineCascadedSymbolsAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs index cf0a657769c89..b7fee3ebaac87 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs @@ -60,7 +60,7 @@ await ReferenceFinders.Property.DetermineDocumentsToSearchAsync( await FindDocumentsWithGlobalSuppressMessageAttributeAsync(project, documents, processResult, processResultData, cancellationToken).ConfigureAwait(false); } - protected override async ValueTask FindReferencesInDocumentAsync( + protected override async void FindReferencesInDocument( IMethodSymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -77,7 +77,7 @@ protected override async ValueTask FindReferencesInDocumentAsync( return; } - await ReferenceFinders.Property.FindReferencesInDocumentAsync( + ReferenceFinders.Property.FindReferencesInDocument( property, state, static (loc, data) => @@ -89,6 +89,6 @@ await ReferenceFinders.Property.FindReferencesInDocumentAsync( }, (property, symbol, state, processResult, processResultData, cancellationToken), options with { AssociatePropertyReferencesWithSpecificAccessor = false }, - cancellationToken).ConfigureAwait(false); + cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs index d5fed2c94c5aa..39e52cfa2fe73 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs @@ -119,7 +119,7 @@ protected sealed override async Task DetermineDocumentsToSearchAsync( private static bool IsForEachProperty(IPropertySymbol symbol) => symbol.Name == WellKnownMemberNames.CurrentPropertyName; - protected sealed override ValueTask FindReferencesInDocumentAsync( + protected sealed override void FindReferencesInDocument( IPropertySymbol symbol, FindReferencesDocumentState state, Action processResult, @@ -157,7 +157,6 @@ protected sealed override ValueTask FindReferencesInDocumentAsync( FindReferencesInDocumentInsideGlobalSuppressions( symbol, state, processResult, processResultData, cancellationToken); - return ValueTaskFactory.CompletedTask; } private static Task FindDocumentWithExplicitOrImplicitElementAccessExpressionsAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs index 339c8ca10d36d..5424f98041207 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs @@ -119,8 +119,12 @@ public static async Task FindSymbolAtPositionAsync( /// Finds the definition symbol declared in source code for a corresponding reference symbol. /// Returns null if no such symbol can be found in the specified solution. /// - public static Task FindSourceDefinitionAsync( - ISymbol? symbol, Solution solution, CancellationToken cancellationToken = default) + public static Task FindSourceDefinitionAsync(ISymbol? symbol, Solution solution, CancellationToken cancellationToken = default) + => Task.FromResult(FindSourceDefinition(symbol, solution, cancellationToken)); + + /// + internal static ISymbol? FindSourceDefinition( + ISymbol? symbol, Solution solution, CancellationToken cancellationToken) { if (symbol != null) { @@ -136,14 +140,14 @@ public static async Task FindSymbolAtPositionAsync( case SymbolKind.Property: case SymbolKind.TypeParameter: case SymbolKind.Namespace: - return FindSourceDefinitionWorkerAsync(symbol, solution, cancellationToken); + return FindSourceDefinitionWorker(symbol, solution, cancellationToken); } } - return SpecializedTasks.Null(); + return null; } - private static async Task FindSourceDefinitionWorkerAsync( + private static ISymbol? FindSourceDefinitionWorker( ISymbol symbol, Solution solution, CancellationToken cancellationToken) @@ -154,9 +158,7 @@ public static async Task FindSymbolAtPositionAsync( // If our symbol doesn't have a containing assembly, there's nothing better we can do to map this // symbol somewhere else. The common case for this is a merged INamespaceSymbol that spans assemblies. if (symbol.ContainingAssembly == null) - { return symbol; - } // Just because it's a source symbol doesn't mean we have the final symbol we actually want. In retargeting cases, // the retargeted symbol is from "source" but isn't equal to the actual source definition in the other project. Thus, @@ -167,12 +169,10 @@ public static async Task FindSymbolAtPositionAsync( // If our symbol is actually a "regular" source symbol, then we know the compilation is holding the symbol alive // and thus TryGetCompilation is sufficient. For another example of this pattern, see Solution.GetProject(IAssemblySymbol) // which we happen to call below. - if (sourceProject.TryGetCompilation(out var compilation)) + if (sourceProject.TryGetCompilation(out var compilation) && + symbol.ContainingAssembly.Equals(compilation.Assembly)) { - if (symbol.ContainingAssembly.Equals(compilation.Assembly)) - { - return symbol; - } + return symbol; } } } @@ -183,11 +183,14 @@ public static async Task FindSymbolAtPositionAsync( } var project = solution.GetProject(symbol.ContainingAssembly, cancellationToken); - if (project != null && project.SupportsCompilation) + + // Note: if the assembly came from a particular project, then we should be able to get the compilation without + // building it. That's because once we create the compilation, we'll hold onto it for the lifetime of the + // project, to avoid unnecessary recomputation. + if (project?.TryGetCompilation(out var projectCompilation) is true) { var symbolId = symbol.GetSymbolKey(cancellationToken); - var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - var result = symbolId.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken: cancellationToken); + var result = symbolId.Resolve(projectCompilation, ignoreAssemblyKey: true, cancellationToken: cancellationToken); return InSource(result.Symbol) ? result.Symbol : result.CandidateSymbols.FirstOrDefault(InSource); } From d9e7f1d4fbe45b2afb86f701637b3a6b56b654fd Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 11:33:40 -0700 Subject: [PATCH 03/10] Async void --- .../ChangeSignature/DelegateInvokeMethodReferenceFinder.cs | 2 +- .../Finders/PropertyAccessorSymbolReferenceFinder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs index b4b4f86be28c1..cde2fbfd02852 100644 --- a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs +++ b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs @@ -76,7 +76,7 @@ protected override Task DetermineDocumentsToSearchAsync( return Task.CompletedTask; } - protected override async void FindReferencesInDocument( + protected override void FindReferencesInDocument( IMethodSymbol methodSymbol, FindReferencesDocumentState state, Action processResult, diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs index b7fee3ebaac87..7f0b4d9d1ca81 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs @@ -60,7 +60,7 @@ await ReferenceFinders.Property.DetermineDocumentsToSearchAsync( await FindDocumentsWithGlobalSuppressMessageAttributeAsync(project, documents, processResult, processResultData, cancellationToken).ConfigureAwait(false); } - protected override async void FindReferencesInDocument( + protected override void FindReferencesInDocument( IMethodSymbol symbol, FindReferencesDocumentState state, Action processResult, From e7743d102ca8d39a50773c38f02918e4ff7860c8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 11:34:23 -0700 Subject: [PATCH 04/10] Make sealed --- .../ChangeSignature/DelegateInvokeMethodReferenceFinder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs index cde2fbfd02852..e04a40ba71f1d 100644 --- a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs +++ b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs @@ -26,7 +26,7 @@ namespace Microsoft.CodeAnalysis.ChangeSignature; /// /// TODO: Rewrite this to track backward through references instead of binding everything /// -internal class DelegateInvokeMethodReferenceFinder : AbstractReferenceFinder +internal sealed class DelegateInvokeMethodReferenceFinder : AbstractReferenceFinder { public static readonly IReferenceFinder DelegateInvokeMethod = new DelegateInvokeMethodReferenceFinder(); From 6930a3ffcfaa4069df6d65be7243012c777d92d9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 11:38:25 -0700 Subject: [PATCH 05/10] Simplify --- .../AbstractChangeSignatureService.cs | 2 +- .../DelegateInvokeMethodReferenceFinder.cs | 6 ++- .../Finders/ReferenceFinders.cs | 54 +++++++++---------- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index fc9ea2a994409..44ad3f2409885 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -236,7 +236,7 @@ private static async Task> FindChangeSignatureR var engine = new FindReferencesSearchEngine( solution, documents: null, - ReferenceFinders.DefaultReferenceFinders.Add(DelegateInvokeMethodReferenceFinder.DelegateInvokeMethod), + [.. ReferenceFinders.DefaultReferenceFinders, DelegateInvokeMethodReferenceFinder.Instance], streamingProgress, FindReferencesSearchOptions.Default); diff --git a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs index e04a40ba71f1d..ceefcf6a65088 100644 --- a/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs +++ b/src/Features/Core/Portable/ChangeSignature/DelegateInvokeMethodReferenceFinder.cs @@ -28,7 +28,11 @@ namespace Microsoft.CodeAnalysis.ChangeSignature; /// internal sealed class DelegateInvokeMethodReferenceFinder : AbstractReferenceFinder { - public static readonly IReferenceFinder DelegateInvokeMethod = new DelegateInvokeMethodReferenceFinder(); + public static readonly DelegateInvokeMethodReferenceFinder Instance = new(); + + private DelegateInvokeMethodReferenceFinder() + { + } protected override bool CanFind(IMethodSymbol symbol) => symbol.MethodKind == MethodKind.DelegateInvoke; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs index 305357b92a34d..6dd48c5bbeadf 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs @@ -8,37 +8,32 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; internal static class ReferenceFinders { - public static readonly IReferenceFinder Constructor = ConstructorSymbolReferenceFinder.Instance; - public static readonly IReferenceFinder ConstructorInitializer = new ConstructorInitializerSymbolReferenceFinder(); - public static readonly IReferenceFinder Destructor = new DestructorSymbolReferenceFinder(); - public static readonly IReferenceFinder ExplicitConversion = new ExplicitConversionSymbolReferenceFinder(); - public static readonly IReferenceFinder ExplicitInterfaceMethod = new ExplicitInterfaceMethodReferenceFinder(); - public static readonly IReferenceFinder Event = new EventSymbolReferenceFinder(); - public static readonly IReferenceFinder Field = new FieldSymbolReferenceFinder(); - public static readonly IReferenceFinder Label = new LabelSymbolReferenceFinder(); - public static readonly IReferenceFinder Local = new LocalSymbolReferenceFinder(); - public static readonly IReferenceFinder MethodTypeParameter = new MethodTypeParameterSymbolReferenceFinder(); - public static readonly IReferenceFinder NamedType = new NamedTypeSymbolReferenceFinder(); - public static readonly IReferenceFinder Namespace = new NamespaceSymbolReferenceFinder(); - public static readonly IReferenceFinder Operator = new OperatorSymbolReferenceFinder(); - public static readonly IReferenceFinder OrdinaryMethod = new OrdinaryMethodReferenceFinder(); - public static readonly IReferenceFinder Parameter = new ParameterSymbolReferenceFinder(); - public static readonly IReferenceFinder Property = new PropertySymbolReferenceFinder(); - public static readonly IReferenceFinder PropertyAccessor = new PropertyAccessorSymbolReferenceFinder(); - public static readonly IReferenceFinder RangeVariable = new RangeVariableSymbolReferenceFinder(); - public static readonly IReferenceFinder TypeParameter = new TypeParameterSymbolReferenceFinder(); + private static readonly IReferenceFinder Constructor = ConstructorSymbolReferenceFinder.Instance; + private static readonly IReferenceFinder ConstructorInitializer = new ConstructorInitializerSymbolReferenceFinder(); + private static readonly IReferenceFinder Destructor = new DestructorSymbolReferenceFinder(); + private static readonly IReferenceFinder ExplicitConversion = new ExplicitConversionSymbolReferenceFinder(); + private static readonly IReferenceFinder ExplicitInterfaceMethod = new ExplicitInterfaceMethodReferenceFinder(); + private static readonly IReferenceFinder Event = new EventSymbolReferenceFinder(); + private static readonly IReferenceFinder Field = new FieldSymbolReferenceFinder(); + private static readonly IReferenceFinder Label = new LabelSymbolReferenceFinder(); + private static readonly IReferenceFinder Local = new LocalSymbolReferenceFinder(); + private static readonly IReferenceFinder MethodTypeParameter = new MethodTypeParameterSymbolReferenceFinder(); + private static readonly IReferenceFinder NamedType = new NamedTypeSymbolReferenceFinder(); + private static readonly IReferenceFinder Namespace = new NamespaceSymbolReferenceFinder(); + private static readonly IReferenceFinder Operator = new OperatorSymbolReferenceFinder(); + private static readonly IReferenceFinder OrdinaryMethod = new OrdinaryMethodReferenceFinder(); + private static readonly IReferenceFinder Parameter = new ParameterSymbolReferenceFinder(); + private static readonly IReferenceFinder PropertyAccessor = new PropertyAccessorSymbolReferenceFinder(); + private static readonly IReferenceFinder RangeVariable = new RangeVariableSymbolReferenceFinder(); + private static readonly IReferenceFinder TypeParameter = new TypeParameterSymbolReferenceFinder(); /// - /// The list of common reference finders. + /// Public as it is used recursively from within the . /// - public static readonly ImmutableArray DefaultReferenceFinders; + public static readonly IReferenceFinder Property = new PropertySymbolReferenceFinder(); // Rename does not need to include base/this constructor initializer calls - internal static readonly ImmutableArray DefaultRenameReferenceFinders; - - static ReferenceFinders() - { - DefaultRenameReferenceFinders = + public static readonly ImmutableArray DefaultRenameReferenceFinders = [ Constructor, Destructor, @@ -59,6 +54,9 @@ static ReferenceFinders() RangeVariable, TypeParameter, ]; - DefaultReferenceFinders = DefaultRenameReferenceFinders.Add(ConstructorInitializer); - } + + /// + /// The list of common reference finders. + /// + internal static readonly ImmutableArray DefaultReferenceFinders = [.. DefaultRenameReferenceFinders, ConstructorInitializer]; } From 31f4e584cff031288be8e2e699c8d81874176186 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 11:39:43 -0700 Subject: [PATCH 06/10] Simplify --- .../Finders/PropertyAccessorSymbolReferenceFinder.cs | 4 ++-- .../FindReferences/Finders/PropertySymbolReferenceFinder.cs | 6 ++++++ .../FindSymbols/FindReferences/Finders/ReferenceFinders.cs | 6 +----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs index 7f0b4d9d1ca81..9dad8f072eb4d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertyAccessorSymbolReferenceFinder.cs @@ -50,7 +50,7 @@ protected override async Task DetermineDocumentsToSearchAsync( // we want to associate normal property references with the specific accessor being // referenced. So we also need to include documents with our property's name. Just // defer to the Property finder to find these docs and combine them with the result. - await ReferenceFinders.Property.DetermineDocumentsToSearchAsync( + await PropertySymbolReferenceFinder.Instance.DetermineDocumentsToSearchAsync( property, globalAliases, project, documents, processResult, processResultData, options with { AssociatePropertyReferencesWithSpecificAccessor = false }, @@ -77,7 +77,7 @@ protected override void FindReferencesInDocument( return; } - ReferenceFinders.Property.FindReferencesInDocument( + PropertySymbolReferenceFinder.Instance.FindReferencesInDocument( property, state, static (loc, data) => diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs index 39e52cfa2fe73..60ec567348984 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs @@ -19,6 +19,12 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; internal sealed class PropertySymbolReferenceFinder : AbstractMethodOrPropertyOrEventSymbolReferenceFinder { + public static readonly PropertyAccessorSymbolReferenceFinder Instance = new(); + + private PropertySymbolReferenceFinder() + { + } + protected override bool CanFind(IPropertySymbol symbol) => true; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs index 6dd48c5bbeadf..af6aad4f7cb3d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs @@ -23,15 +23,11 @@ internal static class ReferenceFinders private static readonly IReferenceFinder Operator = new OperatorSymbolReferenceFinder(); private static readonly IReferenceFinder OrdinaryMethod = new OrdinaryMethodReferenceFinder(); private static readonly IReferenceFinder Parameter = new ParameterSymbolReferenceFinder(); + private static readonly IReferenceFinder Property = PropertySymbolReferenceFinder.Instance; private static readonly IReferenceFinder PropertyAccessor = new PropertyAccessorSymbolReferenceFinder(); private static readonly IReferenceFinder RangeVariable = new RangeVariableSymbolReferenceFinder(); private static readonly IReferenceFinder TypeParameter = new TypeParameterSymbolReferenceFinder(); - /// - /// Public as it is used recursively from within the . - /// - public static readonly IReferenceFinder Property = new PropertySymbolReferenceFinder(); - // Rename does not need to include base/this constructor initializer calls public static readonly ImmutableArray DefaultRenameReferenceFinders = [ From cc030ed29e7fcdf5b420a3c3742cf7bfa0eb5ac1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 11:41:32 -0700 Subject: [PATCH 07/10] Simplify --- .../Finders/ReferenceFinders.cs | 58 ++++++------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs index af6aad4f7cb3d..58488bb4b9668 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ReferenceFinders.cs @@ -8,51 +8,31 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; internal static class ReferenceFinders { - private static readonly IReferenceFinder Constructor = ConstructorSymbolReferenceFinder.Instance; - private static readonly IReferenceFinder ConstructorInitializer = new ConstructorInitializerSymbolReferenceFinder(); - private static readonly IReferenceFinder Destructor = new DestructorSymbolReferenceFinder(); - private static readonly IReferenceFinder ExplicitConversion = new ExplicitConversionSymbolReferenceFinder(); - private static readonly IReferenceFinder ExplicitInterfaceMethod = new ExplicitInterfaceMethodReferenceFinder(); - private static readonly IReferenceFinder Event = new EventSymbolReferenceFinder(); - private static readonly IReferenceFinder Field = new FieldSymbolReferenceFinder(); - private static readonly IReferenceFinder Label = new LabelSymbolReferenceFinder(); - private static readonly IReferenceFinder Local = new LocalSymbolReferenceFinder(); - private static readonly IReferenceFinder MethodTypeParameter = new MethodTypeParameterSymbolReferenceFinder(); - private static readonly IReferenceFinder NamedType = new NamedTypeSymbolReferenceFinder(); - private static readonly IReferenceFinder Namespace = new NamespaceSymbolReferenceFinder(); - private static readonly IReferenceFinder Operator = new OperatorSymbolReferenceFinder(); - private static readonly IReferenceFinder OrdinaryMethod = new OrdinaryMethodReferenceFinder(); - private static readonly IReferenceFinder Parameter = new ParameterSymbolReferenceFinder(); - private static readonly IReferenceFinder Property = PropertySymbolReferenceFinder.Instance; - private static readonly IReferenceFinder PropertyAccessor = new PropertyAccessorSymbolReferenceFinder(); - private static readonly IReferenceFinder RangeVariable = new RangeVariableSymbolReferenceFinder(); - private static readonly IReferenceFinder TypeParameter = new TypeParameterSymbolReferenceFinder(); - // Rename does not need to include base/this constructor initializer calls public static readonly ImmutableArray DefaultRenameReferenceFinders = [ - Constructor, - Destructor, - Event, - ExplicitConversion, - ExplicitInterfaceMethod, - Field, - Label, - Local, - MethodTypeParameter, - NamedType, - Namespace, - Operator, - OrdinaryMethod, - Parameter, - Property, - PropertyAccessor, - RangeVariable, - TypeParameter, + ConstructorSymbolReferenceFinder.Instance, + PropertySymbolReferenceFinder.Instance, + new DestructorSymbolReferenceFinder(), + new EventSymbolReferenceFinder(), + new ExplicitConversionSymbolReferenceFinder(), + new ExplicitInterfaceMethodReferenceFinder(), + new FieldSymbolReferenceFinder(), + new LabelSymbolReferenceFinder(), + new LocalSymbolReferenceFinder(), + new MethodTypeParameterSymbolReferenceFinder(), + new NamedTypeSymbolReferenceFinder(), + new NamespaceSymbolReferenceFinder(), + new OperatorSymbolReferenceFinder(), + new OrdinaryMethodReferenceFinder(), + new ParameterSymbolReferenceFinder(), + new PropertyAccessorSymbolReferenceFinder(), + new RangeVariableSymbolReferenceFinder(), + new TypeParameterSymbolReferenceFinder(), ]; /// /// The list of common reference finders. /// - internal static readonly ImmutableArray DefaultReferenceFinders = [.. DefaultRenameReferenceFinders, ConstructorInitializer]; + internal static readonly ImmutableArray DefaultReferenceFinders = [.. DefaultRenameReferenceFinders, new ConstructorInitializerSymbolReferenceFinder()]; } From fbba45560a8c34cfaa47b37b0a0b046f77f9c4c3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 12:53:11 -0700 Subject: [PATCH 08/10] Fix --- .../FindReferences/Finders/PropertySymbolReferenceFinder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs index 60ec567348984..e4a29e82e255c 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/PropertySymbolReferenceFinder.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols.Finders; internal sealed class PropertySymbolReferenceFinder : AbstractMethodOrPropertyOrEventSymbolReferenceFinder { - public static readonly PropertyAccessorSymbolReferenceFinder Instance = new(); + public static readonly PropertySymbolReferenceFinder Instance = new(); private PropertySymbolReferenceFinder() { From db627303383b2ffef3b0697239c417a714436462 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 14:13:27 -0700 Subject: [PATCH 09/10] Fix move static members --- .../MoveStaticMembersWithDialogCodeAction.cs | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs b/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs index 230248be794f6..75357e8a52523 100644 --- a/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs @@ -13,7 +13,9 @@ using Microsoft.CodeAnalysis.CodeRefactorings.PullMemberUp; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.FindSymbols; +using Microsoft.CodeAnalysis.ForEachCast; using Microsoft.CodeAnalysis.LanguageService; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Simplification; @@ -66,7 +68,7 @@ protected override async Task> ComputeOperation // we already have our destination type, but we need to find the document it is in // When it is an existing type, "FileName" points to a full path rather than just the name // There should be no two docs that have the same file path - var destinationDocId = _document.Project.Solution.GetDocumentIdsWithFilePath(moveOptions.FileName).Single(); + var destinationDocId = sourceDoc.Project.Solution.GetDocumentIdsWithFilePath(moveOptions.FileName).Single(); var fixedSolution = await RefactorAndMoveAsync( moveOptions.SelectedMembers, memberNodes, @@ -77,7 +79,7 @@ protected override async Task> ComputeOperation sourceDoc.Id, destinationDocId, cancellationToken).ConfigureAwait(false); - return new CodeActionOperation[] { new ApplyChangesOperation(fixedSolution) }; + return [new ApplyChangesOperation(fixedSolution)]; } // otherwise, we need to create a destination ourselves @@ -100,10 +102,10 @@ protected override async Task> ComputeOperation sourceDoc.Project.Solution, moveOptions.NamespaceDisplay, moveOptions.FileName, - _document.Project.Id, - _document.Folders, + sourceDoc.Project.Id, + sourceDoc.Folders, newType, - _document, + sourceDoc, _fallbackOptions, cancellationToken).ConfigureAwait(false); @@ -113,7 +115,7 @@ protected override async Task> ComputeOperation newType = (INamedTypeSymbol)destSemanticModel.GetRequiredDeclaredSymbol(destRoot.GetAnnotatedNodes(annotation).Single(), cancellationToken); // refactor references across the entire solution - var memberReferenceLocations = await FindMemberReferencesAsync(moveOptions.SelectedMembers, newDoc.Project.Solution, cancellationToken).ConfigureAwait(false); + var memberReferenceLocations = await FindMemberReferencesAsync(newDoc.Project.Solution, newDoc.Project.Id, moveOptions.SelectedMembers, cancellationToken).ConfigureAwait(false); var projectToLocations = memberReferenceLocations.ToLookup(loc => loc.location.Document.Project.Id); var solutionWithFixedReferences = await RefactorReferencesAsync(projectToLocations, newDoc.Project.Solution, newType, typeArgIndices, cancellationToken).ConfigureAwait(false); @@ -130,7 +132,7 @@ protected override async Task> ComputeOperation var pullMembersUpOptions = PullMembersUpOptionsBuilder.BuildPullMembersUpOptions(newType, members); var movedSolution = await MembersPuller.PullMembersUpAsync(sourceDoc, pullMembersUpOptions, _fallbackOptions, cancellationToken).ConfigureAwait(false); - return new CodeActionOperation[] { new ApplyChangesOperation(movedSolution) }; + return [new ApplyChangesOperation(movedSolution)]; } /// @@ -174,7 +176,8 @@ private async Task RefactorAndMoveAsync( oldSolution = newTypeDoc.WithSyntaxRoot(newTypeRoot).Project.Solution; // refactor references across the entire solution - var memberReferenceLocations = await FindMemberReferencesAsync(selectedMembers, oldSolution, cancellationToken).ConfigureAwait(false); + var memberReferenceLocations = await FindMemberReferencesAsync( + oldSolution, sourceDocId.ProjectId, selectedMembers, cancellationToken).ConfigureAwait(false); var projectToLocations = memberReferenceLocations.ToLookup(loc => loc.location.Document.Project.Id); var solutionWithFixedReferences = await RefactorReferencesAsync(projectToLocations, oldSolution, newType, typeArgIndices, cancellationToken).ConfigureAwait(false); @@ -326,11 +329,27 @@ private static async Task FixReferencesSingleDocumentAsync( } private static async Task> FindMemberReferencesAsync( - ImmutableArray members, Solution solution, + ProjectId projectId, + ImmutableArray members, CancellationToken cancellationToken) { - var tasks = members.Select(symbol => SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken)); + var project = solution.GetRequiredProject(projectId); + var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); + + using var _ = ArrayBuilder>>.GetInstance(out var tasks); + foreach (var member in members) + { + tasks.Add(Task.Run(async () => + { + var symbolKey = member.GetSymbolKey(cancellationToken); + var resolvedMember = symbolKey.Resolve(compilation, ignoreAssemblyKey: false, cancellationToken).GetAnySymbol(); + return resolvedMember is null + ? [] + : await SymbolFinder.FindReferencesAsync(resolvedMember, solution, cancellationToken).ConfigureAwait(false); + })); + } + var symbolRefs = await Task.WhenAll(tasks).ConfigureAwait(false); return symbolRefs .Flatten() From 151e653a96f70c84c6147e813b0e0583d8b0b000 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 16 May 2024 14:14:03 -0700 Subject: [PATCH 10/10] Cleanup --- .../MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs b/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs index 75357e8a52523..c10091e28b5c3 100644 --- a/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs +++ b/src/Features/Core/Portable/MoveStaticMembers/MoveStaticMembersWithDialogCodeAction.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.CodeRefactorings.PullMemberUp; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.FindSymbols; -using Microsoft.CodeAnalysis.ForEachCast; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions;