From 08929cdb477f7e0ba3b4cd5fe9220bb726fee9cb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 14 Jun 2024 18:11:26 -0700 Subject: [PATCH 1/5] separate indices --- .../Shared/AbstractSyntaxIndex_Persistence.cs | 8 ++- .../FindSymbols/SyntaxTree/SyntaxTreeIndex.cs | 3 + .../SyntaxTree/SyntaxTreeIndex_Create.cs | 6 +- .../SyntaxTree/SyntaxTreeIndex_Persistence.cs | 60 +++++++++++-------- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs b/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs index d17056acb7686..aaec84b363045 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/Shared/AbstractSyntaxIndex_Persistence.cs @@ -17,7 +17,13 @@ namespace Microsoft.CodeAnalysis.FindSymbols; internal partial class AbstractSyntaxIndex { private static readonly string s_persistenceName = typeof(TIndex).Name; - private static readonly Checksum s_serializationFormatChecksum = CodeAnalysis.Checksum.Create("39"); + + /// + /// Increment this whenever the data format of the changes. This ensures + /// that we will not try to read previously cached data from a prior version of roslyn with a different format and + /// will instead regenerate all the indices with the new format. + /// + private static readonly Checksum s_serializationFormatChecksum = CodeAnalysis.Checksum.Create("40"); /// /// Cache of ParseOptions to a checksum for the contained diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs index 904beb0748f02..2f2e914b183e7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs @@ -14,6 +14,7 @@ internal sealed partial class SyntaxTreeIndex : AbstractSyntaxIndex? _aliasInfo; private readonly HashSet<(string alias, string name, int arity)>? _globalAliasInfo; private SyntaxTreeIndex( @@ -21,12 +22,14 @@ private SyntaxTreeIndex( LiteralInfo literalInfo, IdentifierInfo identifierInfo, ContextInfo contextInfo, + HashSet<(string alias, string name, int arity)>? aliasInfo, HashSet<(string alias, string name, int arity)>? globalAliasInfo) : base(checksum) { _literalInfo = literalInfo; _identifierInfo = identifierInfo; _contextInfo = contextInfo; + _aliasInfo = aliasInfo; _globalAliasInfo = globalAliasInfo; } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs index 6c40ce8a69abc..5025e9187b92d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs @@ -48,6 +48,7 @@ private static SyntaxTreeIndex CreateIndex( var longLiterals = LongLiteralHashSetPool.Allocate(); HashSet<(string alias, string name, int arity)>? globalAliasInfo = null; + var isCSharp = project.Language == LanguageNames.CSharp; try { @@ -98,7 +99,8 @@ private static SyntaxTreeIndex CreateIndex( containsConversion = containsConversion || syntaxFacts.IsConversionExpression(node); containsCollectionInitializer = containsCollectionInitializer || syntaxFacts.IsObjectCollectionInitializer(node); - TryAddGlobalAliasInfo(syntaxFacts, ref globalAliasInfo, node); + if (isCSharp) + TryAddGlobalAliasInfo(syntaxFacts, ref globalAliasInfo, node); } else { @@ -228,7 +230,7 @@ private static void TryAddGlobalAliasInfo( return; syntaxFacts.GetPartsOfUsingAliasDirective(node, out var globalToken, out var alias, out var usingTarget); - if (globalToken.IsMissing) + if (globalToken == default) return; // if we have `global using X = Y.Z` then walk down the rhs to pull out 'Z'. diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs index 9a6c08ffca80a..f71eddf9e1cc2 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs @@ -25,18 +25,20 @@ public override void WriteTo(ObjectWriter writer) _identifierInfo.WriteTo(writer); _contextInfo.WriteTo(writer); - if (_globalAliasInfo == null) - { - writer.WriteInt32(0); - } - else + WriteTo(writer, _aliasInfo); + WriteTo(writer, _globalAliasInfo); + + static void WriteTo(ObjectWriter writer, HashSet<(string alias, string name, int arity)>? aliasInfo) { - writer.WriteInt32(_globalAliasInfo.Count); - foreach (var (alias, name, arity) in _globalAliasInfo) + writer.WriteInt32(aliasInfo?.Count ?? 0); + if (aliasInfo != null) { - writer.WriteString(alias); - writer.WriteString(name); - writer.WriteInt32(arity); + foreach (var (alias, name, arity) in aliasInfo) + { + writer.WriteString(alias); + writer.WriteString(name); + writer.WriteInt32(arity); + } } } } @@ -51,27 +53,33 @@ public override void WriteTo(ObjectWriter writer) if (literalInfo == null || identifierInfo == null || contextInfo == null) return null; - var globalAliasInfoCount = reader.ReadInt32(); - HashSet<(string alias, string name, int arity)>? globalAliasInfo = null; + return new SyntaxTreeIndex( + checksum, + literalInfo.Value, + identifierInfo.Value, + contextInfo.Value, + ReadAliasInfo(reader), + ReadAliasInfo(reader)); - if (globalAliasInfoCount > 0) + static HashSet<(string alias, string name, int arity)>? ReadAliasInfo(ObjectReader reader) { - globalAliasInfo = []; + var aliasInfoCount = reader.ReadInt32(); + HashSet<(string alias, string name, int arity)>? aliasInfo = null; - for (var i = 0; i < globalAliasInfoCount; i++) + if (aliasInfoCount > 0) { - var alias = reader.ReadRequiredString(); - var name = reader.ReadRequiredString(); - var arity = reader.ReadInt32(); - globalAliasInfo.Add((alias, name, arity)); + aliasInfo = []; + + for (var i = 0; i < aliasInfoCount; i++) + { + var alias = reader.ReadRequiredString(); + var name = reader.ReadRequiredString(); + var arity = reader.ReadInt32(); + aliasInfo.Add((alias, name, arity)); + } } - } - return new SyntaxTreeIndex( - checksum, - literalInfo.Value, - identifierInfo.Value, - contextInfo.Value, - globalAliasInfo); + return aliasInfo; + } } } From d473c81366afb2f0c0265fa32999d9eabd5ff3cd Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 14 Jun 2024 18:13:21 -0700 Subject: [PATCH 2/5] Sets --- .../SyntaxTree/SyntaxTreeIndex_Create.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs index 5025e9187b92d..d9f9f4e4ae2a9 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs @@ -47,8 +47,8 @@ private static SyntaxTreeIndex CreateIndex( var stringLiterals = StringLiteralHashSetPool.Allocate(); var longLiterals = LongLiteralHashSetPool.Allocate(); + HashSet<(string alias, string name, int arity)>? aliasInfo = null; HashSet<(string alias, string name, int arity)>? globalAliasInfo = null; - var isCSharp = project.Language == LanguageNames.CSharp; try { @@ -99,8 +99,7 @@ private static SyntaxTreeIndex CreateIndex( containsConversion = containsConversion || syntaxFacts.IsConversionExpression(node); containsCollectionInitializer = containsCollectionInitializer || syntaxFacts.IsObjectCollectionInitializer(node); - if (isCSharp) - TryAddGlobalAliasInfo(syntaxFacts, ref globalAliasInfo, node); + TryAddAliasInfo(syntaxFacts, ref aliasInfo, ref globalAliasInfo, node); } else { @@ -188,6 +187,7 @@ private static SyntaxTreeIndex CreateIndex( containsConversion, containsGlobalKeyword, containsCollectionInitializer), + aliasInfo, globalAliasInfo); } finally @@ -221,8 +221,9 @@ private static bool IsGlobalSuppressMessageAttribute(ISyntaxFactsService syntaxF syntaxFacts.StringComparer.Equals(identifierName, nameof(SuppressMessageAttribute)); } - private static void TryAddGlobalAliasInfo( + private static void TryAddAliasInfo( ISyntaxFactsService syntaxFacts, + ref HashSet<(string alias, string name, int arity)>? aliasInfo, ref HashSet<(string alias, string name, int arity)>? globalAliasInfo, SyntaxNode node) { @@ -230,8 +231,6 @@ private static void TryAddGlobalAliasInfo( return; syntaxFacts.GetPartsOfUsingAliasDirective(node, out var globalToken, out var alias, out var usingTarget); - if (globalToken == default) - return; // if we have `global using X = Y.Z` then walk down the rhs to pull out 'Z'. if (syntaxFacts.IsQualifiedName(usingTarget)) @@ -244,8 +243,13 @@ private static void TryAddGlobalAliasInfo( if (syntaxFacts.IsSimpleName(usingTarget)) { syntaxFacts.GetNameAndArityOfSimpleName(usingTarget, out var name, out var arity); - globalAliasInfo ??= []; - globalAliasInfo.Add((alias.ValueText, name, arity)); + + ref var set = ref globalToken == default + ? ref aliasInfo + : ref globalAliasInfo; + + set ??= []; + set.Add((alias.ValueText, name, arity)); } } From a67c3f84ff2a071ee2498b0cab029c6be3d8ba4e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 14 Jun 2024 18:25:00 -0700 Subject: [PATCH 3/5] Fix lookup --- ...sSearchEngine_FindReferencesInDocuments.cs | 4 +-- .../ConstructorSymbolReferenceFinder.cs | 30 ++++++++++++------- .../Finders/NamedTypeSymbolReferenceFinder.cs | 27 ++++++++++------- .../Finders/NamespaceSymbolReferenceFinder.cs | 27 ++++++++++------- .../SyntaxTree/SyntaxTreeIndex_Forwarders.cs | 12 ++++++-- 5 files changed, 64 insertions(+), 36 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs index e17a6dae28e09..59c4e65dcbddd 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs @@ -94,9 +94,7 @@ async ValueTask PerformSearchInDocumentAsync( foreach (var symbol in symbols) { - var state = new FindReferencesDocumentState( - cache, TryGet(symbolToGlobalAliases, symbol)); - + var state = new FindReferencesDocumentState(cache, TryGet(symbolToGlobalAliases, symbol)); await PerformSearchInDocumentWorkerAsync(symbol, state).ConfigureAwait(false); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs index 155e4ac7b6039..05dcd0c0dc731 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs @@ -98,22 +98,17 @@ protected override void FindReferencesInDocument( CancellationToken cancellationToken) { // First just look for this normal constructor references using the name of it's containing type. - var name = methodSymbol.ContainingType.Name; + var containingType = methodSymbol.ContainingType; + var containingTypeName = containingType.Name; AddReferencesInDocumentWorker( - methodSymbol, name, state, processResult, processResultData, cancellationToken); + methodSymbol, containingTypeName, state, processResult, processResultData, cancellationToken); // Next, look for constructor references through a global alias to our containing type. foreach (var globalAlias in state.GlobalAliases) - { - // ignore the cases where the global alias might match the type name (i.e. - // global alias Console = System.Console). We'll already find those references - // above. - if (state.SyntaxFacts.StringComparer.Equals(name, globalAlias)) - continue; + FindReferenceToAlias(methodSymbol, state, processResult, processResultData, containingTypeName, globalAlias, cancellationToken); - AddReferencesInDocumentWorker( - methodSymbol, globalAlias, state, processResult, processResultData, cancellationToken); - } + foreach (var localAlias in state.Cache.SyntaxTreeIndex.GetAliases(containingTypeName, containingType.Arity)) + FindReferenceToAlias(methodSymbol, state, processResult, processResultData, containingTypeName, localAlias, cancellationToken); // Finally, look for constructor references to predefined types (like `new int()`), // implicit object references, and inside global suppression attributes. @@ -127,6 +122,19 @@ protected override void FindReferencesInDocument( methodSymbol, state, processResult, processResultData, cancellationToken); } + private static void FindReferenceToAlias( + IMethodSymbol methodSymbol, FindReferencesDocumentState state, Action processResult, TData processResultData, string name, string alias, CancellationToken cancellationToken) + { + // ignore the cases where the global alias might match the type name (i.e. + // global alias Console = System.Console). We'll already find those references + // above. + if (state.SyntaxFacts.StringComparer.Equals(name, alias)) + return; + + AddReferencesInDocumentWorker( + methodSymbol, alias, state, processResult, processResultData, cancellationToken); + } + /// /// Finds references to in this , but only if it referenced /// though (which might be the actual name of the type, or a global alias to it). diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs index b31c93e3911e6..96d55fd773a1e 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamedTypeSymbolReferenceFinder.cs @@ -147,16 +147,23 @@ internal static void AddReferencesToTypeOrGlobalAliasToIt( namedType, namedType.Name, state, processResult, processResultData, cancellationToken); foreach (var globalAlias in state.GlobalAliases) - { - // ignore the cases where the global alias might match the type name (i.e. - // global alias Console = System.Console). We'll already find those references - // above. - if (state.SyntaxFacts.StringComparer.Equals(namedType.Name, globalAlias)) - continue; - - AddNonAliasReferences( - namedType, globalAlias, state, processResult, processResultData, cancellationToken); - } + FindReferenceToAlias(namedType, state, processResult, processResultData, globalAlias, cancellationToken); + + foreach (var localAlias in state.Cache.SyntaxTreeIndex.GetAliases(namedType.Name, namedType.Arity)) + FindReferenceToAlias(namedType, state, processResult, processResultData, localAlias, cancellationToken); + } + + private static void FindReferenceToAlias( + INamedTypeSymbol namedType, FindReferencesDocumentState state, Action processResult, TData processResultData, string alias, CancellationToken cancellationToken) + { + // ignore the cases where the global alias might match the type name (i.e. + // global alias Console = System.Console). We'll already find those references + // above. + if (state.SyntaxFacts.StringComparer.Equals(namedType.Name, alias)) + return; + + AddNonAliasReferences( + namedType, alias, state, processResult, processResultData, cancellationToken); } /// diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs index e7ae12e6af02d..a37a5aa784526 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/NamespaceSymbolReferenceFinder.cs @@ -72,16 +72,10 @@ protected override void FindReferencesInDocument( symbol, namespaceName, state, StandardCallbacks.AddToArrayBuilder, initialReferences, cancellationToken); foreach (var globalAlias in state.GlobalAliases) - { - // ignore the cases where the global alias might match the namespace name (i.e. - // global alias Collections = System.Collections). We'll already find those references - // above. - if (state.SyntaxFacts.StringComparer.Equals(namespaceName, globalAlias)) - continue; - - AddNamedReferences( - symbol, globalAlias, state, StandardCallbacks.AddToArrayBuilder, initialReferences, cancellationToken); - } + FindReferenceToAlias(symbol, state, initialReferences, namespaceName, globalAlias, cancellationToken); + + foreach (var localAlias in state.Cache.SyntaxTreeIndex.GetAliases(symbol.Name, arity: 0)) + FindReferenceToAlias(symbol, state, initialReferences, namespaceName, localAlias, cancellationToken); // The items in initialReferences need to be both reported and used later to calculate additional results. foreach (var location in initialReferences) @@ -95,6 +89,19 @@ protected override void FindReferencesInDocument( } } + private static void FindReferenceToAlias( + INamespaceSymbol symbol, FindReferencesDocumentState state, ArrayBuilder initialReferences, string namespaceName, string alias, CancellationToken cancellationToken) + { + // ignore the cases where the global alias might match the namespace name (i.e. + // global alias Collections = System.Collections). We'll already find those references + // above. + if (state.SyntaxFacts.StringComparer.Equals(namespaceName, alias)) + return; + + AddNamedReferences( + symbol, alias, state, StandardCallbacks.AddToArrayBuilder, initialReferences, cancellationToken); + } + /// /// Finds references to in this , but only if it referenced /// though (which might be the actual name of the type, or a global alias to it). diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs index 9bd7ec22026ca..615dc9a735ea2 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs @@ -2,6 +2,7 @@ // 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.Collections.Generic; using System.Collections.Immutable; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Collections; @@ -42,13 +43,20 @@ internal sealed partial class SyntaxTreeIndex /// name="C" and arity=1 will return X. /// public ImmutableArray GetGlobalAliases(string name, int arity) + => GetAliasesWorker(name, arity, _globalAliasInfo); + + public ImmutableArray GetAliases(string name, int arity) + => GetAliasesWorker(name, arity, _aliasInfo); + + private static ImmutableArray GetAliasesWorker( + string name, int arity, HashSet<(string alias, string name, int arity)>? aliases) { - if (_globalAliasInfo == null) + if (aliases == null) return []; using var result = TemporaryArray.Empty; - foreach (var (alias, aliasName, aliasArity) in _globalAliasInfo) + foreach (var (alias, aliasName, aliasArity) in aliases) { if (aliasName == name && aliasArity == arity) result.Add(alias); From bad3b0be8e0f118e827357d8ff705db6ca6fefd1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 14 Jun 2024 18:33:26 -0700 Subject: [PATCH 4/5] Simplify --- .../FindSymbols/SyntaxTree/SyntaxTreeIndex.cs | 7 +-- .../SyntaxTree/SyntaxTreeIndex_Create.cs | 19 ++---- .../SyntaxTree/SyntaxTreeIndex_Forwarders.cs | 15 +++-- .../SyntaxTree/SyntaxTreeIndex_Persistence.cs | 58 ++++++++----------- 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs index 2f2e914b183e7..c84e77f077d74 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.cs @@ -14,23 +14,20 @@ internal sealed partial class SyntaxTreeIndex : AbstractSyntaxIndex? _aliasInfo; - private readonly HashSet<(string alias, string name, int arity)>? _globalAliasInfo; + private readonly HashSet<(string alias, string name, int arity, bool isGlobal)>? _aliasInfo; private SyntaxTreeIndex( Checksum? checksum, LiteralInfo literalInfo, IdentifierInfo identifierInfo, ContextInfo contextInfo, - HashSet<(string alias, string name, int arity)>? aliasInfo, - HashSet<(string alias, string name, int arity)>? globalAliasInfo) + HashSet<(string alias, string name, int arity, bool isGlobal)>? aliasInfo) : base(checksum) { _literalInfo = literalInfo; _identifierInfo = identifierInfo; _contextInfo = contextInfo; _aliasInfo = aliasInfo; - _globalAliasInfo = globalAliasInfo; } public static ValueTask GetRequiredIndexAsync(Document document, CancellationToken cancellationToken) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs index d9f9f4e4ae2a9..317788f2e468c 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs @@ -47,8 +47,7 @@ private static SyntaxTreeIndex CreateIndex( var stringLiterals = StringLiteralHashSetPool.Allocate(); var longLiterals = LongLiteralHashSetPool.Allocate(); - HashSet<(string alias, string name, int arity)>? aliasInfo = null; - HashSet<(string alias, string name, int arity)>? globalAliasInfo = null; + HashSet<(string alias, string name, int arity, bool isGlobal)>? aliasInfo = null; try { @@ -99,7 +98,7 @@ private static SyntaxTreeIndex CreateIndex( containsConversion = containsConversion || syntaxFacts.IsConversionExpression(node); containsCollectionInitializer = containsCollectionInitializer || syntaxFacts.IsObjectCollectionInitializer(node); - TryAddAliasInfo(syntaxFacts, ref aliasInfo, ref globalAliasInfo, node); + TryAddAliasInfo(syntaxFacts, ref aliasInfo, node); } else { @@ -187,8 +186,7 @@ private static SyntaxTreeIndex CreateIndex( containsConversion, containsGlobalKeyword, containsCollectionInitializer), - aliasInfo, - globalAliasInfo); + aliasInfo); } finally { @@ -223,8 +221,7 @@ private static bool IsGlobalSuppressMessageAttribute(ISyntaxFactsService syntaxF private static void TryAddAliasInfo( ISyntaxFactsService syntaxFacts, - ref HashSet<(string alias, string name, int arity)>? aliasInfo, - ref HashSet<(string alias, string name, int arity)>? globalAliasInfo, + ref HashSet<(string alias, string name, int arity, bool isGlobal)>? aliasInfo, SyntaxNode node) { if (!syntaxFacts.IsUsingAliasDirective(node)) @@ -244,12 +241,8 @@ private static void TryAddAliasInfo( { syntaxFacts.GetNameAndArityOfSimpleName(usingTarget, out var name, out var arity); - ref var set = ref globalToken == default - ? ref aliasInfo - : ref globalAliasInfo; - - set ??= []; - set.Add((alias.ValueText, name, arity)); + aliasInfo ??= []; + aliasInfo.Add((alias.ValueText, name, arity, isGlobal: globalToken != default)); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs index 615dc9a735ea2..787df4cc554e7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs @@ -2,7 +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.Collections.Generic; using System.Collections.Immutable; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Collections; @@ -43,22 +42,22 @@ internal sealed partial class SyntaxTreeIndex /// name="C" and arity=1 will return X. /// public ImmutableArray GetGlobalAliases(string name, int arity) - => GetAliasesWorker(name, arity, _globalAliasInfo); + => GetAliasesWorker(name, arity, isGlobal: true); public ImmutableArray GetAliases(string name, int arity) - => GetAliasesWorker(name, arity, _aliasInfo); + => GetAliasesWorker(name, arity, isGlobal: false); - private static ImmutableArray GetAliasesWorker( - string name, int arity, HashSet<(string alias, string name, int arity)>? aliases) + private ImmutableArray GetAliasesWorker( + string name, int arity, bool isGlobal) { - if (aliases == null) + if (_aliasInfo == null) return []; using var result = TemporaryArray.Empty; - foreach (var (alias, aliasName, aliasArity) in aliases) + foreach (var (alias, aliasName, aliasArity, aliasIsGlobal) in _aliasInfo) { - if (aliasName == name && aliasArity == arity) + if (aliasIsGlobal == isGlobal && aliasArity == arity && aliasName == name) result.Add(alias); } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs index f71eddf9e1cc2..162867421cee7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs @@ -25,20 +25,15 @@ public override void WriteTo(ObjectWriter writer) _identifierInfo.WriteTo(writer); _contextInfo.WriteTo(writer); - WriteTo(writer, _aliasInfo); - WriteTo(writer, _globalAliasInfo); - - static void WriteTo(ObjectWriter writer, HashSet<(string alias, string name, int arity)>? aliasInfo) + writer.WriteInt32(_aliasInfo?.Count ?? 0); + if (_aliasInfo != null) { - writer.WriteInt32(aliasInfo?.Count ?? 0); - if (aliasInfo != null) + foreach (var (alias, name, arity, isGlobal) in _aliasInfo) { - foreach (var (alias, name, arity) in aliasInfo) - { - writer.WriteString(alias); - writer.WriteString(name); - writer.WriteInt32(arity); - } + writer.WriteString(alias); + writer.WriteString(name); + writer.WriteInt32(arity); + writer.WriteBoolean(isGlobal); } } } @@ -53,33 +48,28 @@ static void WriteTo(ObjectWriter writer, HashSet<(string alias, string name, int if (literalInfo == null || identifierInfo == null || contextInfo == null) return null; - return new SyntaxTreeIndex( - checksum, - literalInfo.Value, - identifierInfo.Value, - contextInfo.Value, - ReadAliasInfo(reader), - ReadAliasInfo(reader)); + var aliasInfoCount = reader.ReadInt32(); + HashSet<(string alias, string name, int arity, bool isGlobal)>? aliasInfo = null; - static HashSet<(string alias, string name, int arity)>? ReadAliasInfo(ObjectReader reader) + if (aliasInfoCount > 0) { - var aliasInfoCount = reader.ReadInt32(); - HashSet<(string alias, string name, int arity)>? aliasInfo = null; + aliasInfo = []; - if (aliasInfoCount > 0) + for (var i = 0; i < aliasInfoCount; i++) { - aliasInfo = []; - - for (var i = 0; i < aliasInfoCount; i++) - { - var alias = reader.ReadRequiredString(); - var name = reader.ReadRequiredString(); - var arity = reader.ReadInt32(); - aliasInfo.Add((alias, name, arity)); - } + aliasInfo.Add(( + reader.ReadRequiredString(), + reader.ReadRequiredString(), + reader.ReadInt32(), + reader.ReadBoolean())); } - - return aliasInfo; } + + return new SyntaxTreeIndex( + checksum, + literalInfo.Value, + identifierInfo.Value, + contextInfo.Value, + aliasInfo); } } From f7d3357cf182e1d992fd3814708831054e8d9c3e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 14 Jun 2024 18:35:59 -0700 Subject: [PATCH 5/5] revert --- .../FindReferencesSearchEngine_FindReferencesInDocuments.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs index 59c4e65dcbddd..e17a6dae28e09 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferencesSearchEngine_FindReferencesInDocuments.cs @@ -94,7 +94,9 @@ async ValueTask PerformSearchInDocumentAsync( foreach (var symbol in symbols) { - var state = new FindReferencesDocumentState(cache, TryGet(symbolToGlobalAliases, symbol)); + var state = new FindReferencesDocumentState( + cache, TryGet(symbolToGlobalAliases, symbol)); + await PerformSearchInDocumentWorkerAsync(symbol, state).ConfigureAwait(false); } }