-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Share more data in the SyntaxTreeIndex #54057
Conversation
} | ||
} | ||
|
||
private static void AddExtensionMethodInfo( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this moved into the IDeclaredSYmbolInfoService
{ | ||
private const string GenericTypeNameManglingString = "`"; | ||
private static readonly string[] s_aritySuffixesOneToNine = { "`1", "`2", "`3", "`4", "`5", "`6", "`7", "`8", "`9" }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these moved to another (non-generic) helper type.
Dim item = (Await _aggregator.GetItemsAsync("M")).Single | ||
VerifyNavigateToResultItem(item, "M", "[|M|]()", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, additionalInfo:=String.Format(FeaturesResources.in_0_project_1, "A", "Test")) | ||
End Function) | ||
End Function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
abstract methods never worked in VB navigate to. who knew.
GetContainerDisplayName(node.Parent), | ||
GetFullyQualifiedContainerName(node.Parent), | ||
containerDisplayName, | ||
fullyQualifiedContainerName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these values are computed once per container and passed in.
@@ -108,6 +111,9 @@ public static async ValueTask<SyntaxTreeIndex> GetRequiredIndexAsync(Document do | |||
bool loadOnly, | |||
CancellationToken cancellationToken) | |||
{ | |||
if (!document.SupportsSyntaxTree) | |||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adding these checks simplified CreateIndexAsync later on.
src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs
Outdated
Show resolved
Hide resolved
bool TryGetAliasesFromUsingDirective(SyntaxNode node, out ImmutableArray<(string aliasName, string name)> aliases); | ||
|
||
string GetRootNamespace(CompilationOptions compilationOptions); | ||
void AddDeclaredSymbolInfos(Document document, SyntaxNode root, ArrayBuilder<DeclaredSymbolInfo> declaredSymbolInfos, Dictionary<string, ArrayBuilder<int>> extensionMethodInfo, CancellationToken cancellationToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all the above methods still exist, but are only used int he impl of AddDeclaredSymbolInfos, so they dont' need be exposed externally.
var stringTable = GetStringTable(project); | ||
Contract.ThrowIfFalse(document.SupportsSyntaxTree); | ||
|
||
var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pulled this await up, and put everything else in a synchronous method to prevent pooled collections from being used across awaits (As per @sharwell ).
@@ -123,69 +113,6 @@ internal sealed partial class SyntaxTreeIndex | |||
containsImplicitObjectCreation = containsImplicitObjectCreation || syntaxFacts.IsImplicitObjectCreationExpression(node); | |||
containsGlobalAttributes = containsGlobalAttributes || syntaxFacts.IsGlobalAttribute(node); | |||
containsConversion = containsConversion || syntaxFacts.IsConversionExpression(node); | |||
|
|||
if (syntaxFacts.IsUsingAliasDirective(node) && infoFactory.TryGetAliasesFromUsingDirective(node, out var aliases)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aliases were used only inside the 'DeclaredSymbolInfo' computation. so all this moved into the other type.
protected abstract SyntaxList<TMemberDeclarationSyntax> GetChildren(TCompilationUnitSyntax node); | ||
protected abstract SyntaxList<TMemberDeclarationSyntax> GetChildren(TNamespaceDeclarationSyntax node); | ||
protected abstract SyntaxList<TMemberDeclarationSyntax> GetChildren(TTypeDeclarationSyntax node); | ||
protected abstract IEnumerable<TMemberDeclarationSyntax> GetChildren(TEnumDeclarationSyntax node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enums are a SeparatedSyntaxList in C#, and a SyntaxList in VB. so we need an IEnumerable here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i considered making this generic and adding TEnumMemberDeclarationListSyntax ... where TEnumMemberDeclarationListSyntax : IEnumerable<TMemberDeclarationSyntax>
. However, that doesn't help as foreaching will still allocate the IEnumerator. We'd need to have abstracts for the count/indexing to avoid any allocations here, and it just seemed to overwrought to be worth it.
{ | ||
if (this.TryGetAliasesFromUsingDirective(usingAlias, out var current)) | ||
AddAliases(aliases, current); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this logic is incorrect (but was incorrect originally as well). If you have multiple nested namespaces (possibly as symbols) one namespace's aliases with bleed into the others. HOwever, this is probably very rare in practice (certainly no one has reported an issue there), so it hasn't been an issue.
cancellationToken); | ||
} | ||
|
||
protected void AddExtensionMethodInfo( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this moved unchanged.
arrayBuilder.Add(declaredSymbolInfoIndex); | ||
} | ||
|
||
private static void AddAliases(Dictionary<string, string> allAliases, ImmutableArray<(string aliasName, string name)> aliases) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this moved unchanged.
Debug.Assert(arity > 0); | ||
return (arity <= s_aritySuffixesOneToNine.Length) | ||
? s_aritySuffixesOneToNine[arity - 1] | ||
: string.Concat(GenericTypeNameManglingString, arity.ToString(CultureInfo.InvariantCulture)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this moved into ArityUtilities
Dictionary<string, string> aliases, | ||
Dictionary<string, ArrayBuilder<int>> extensionMethodInfo, | ||
string containerDisplayName, | ||
string fullyQualifiedContainerName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a core change is that these two strings are now computed by teh caller and passed into all children, saving 5% of allocs in NavTo as reported by @sharwell .
@@ -147,7 +154,16 @@ private static void ProcessUsings(List<Dictionary<string, string>> aliasMaps, Sy | |||
} | |||
} | |||
|
|||
public override bool TryGetDeclaredSymbolInfo(StringTable stringTable, SyntaxNode node, string rootNamespace, out DeclaredSymbolInfo declaredSymbolInfo) | |||
protected override void AddDeclaredSymbolInfosWorker( | |||
SyntaxNode container, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by passing in the container, we save a lot of ugly computation in the VB side trying to figure out waht the container is for any particular member/type.
case SyntaxKind.FieldDeclaration: | ||
case SyntaxKind.EventFieldDeclaration: | ||
var fieldDeclaration = (BaseFieldDeclarationSyntax)node; | ||
foreach (var variableDeclarator in fieldDeclaration.Declaration.Variables) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this logic got much simpler as we don't have to hit every vardecl in the file (which might be everywhere) and then filter to the subset that are fields/events. instead we know if we've hit a field/event and can just process its vardecls directly.
ElseIf node.Kind() = SyntaxKind.EventBlock Then | ||
node = DirectCast(node, EventBlockSyntax).EventStatement | ||
ElseIf TypeOf node Is MethodBlockBaseSyntax Then | ||
node = DirectCast(node, MethodBlockBaseSyntax).BlockStatement | ||
End If |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the additional of MethodBlockBaseSyntax here is new. We effectively did not support abstract VB method before in navto. i fixed that as part of this change.
typeBlock.BlockStatement.Modifiers.Any(SyntaxKind.PartialKeyword), | ||
If(kind = SyntaxKind.ClassBlock, DeclaredSymbolInfoKind.Class, | ||
If(kind = SyntaxKind.InterfaceBlock, DeclaredSymbolInfoKind.Interface, | ||
If(kind = SyntaxKind.ModuleBlock, DeclaredSymbolInfoKind.Module, | ||
DeclaredSymbolInfoKind.Struct))), | ||
GetAccessibility(typeBlock, typeBlock.BlockStatement.Modifiers), | ||
GetAccessibility(container, typeBlock, typeBlock.BlockStatement.Modifiers), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
passing the container in greatly simplified accessibility logic in several of these blocks.
End Function | ||
|
||
Protected Overrides Function GetUsingAliases(node As NamespaceBlockSyntax) As SyntaxList(Of ImportsStatementSyntax) | ||
Return Nothing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will doc that VB does not have imports inside a namespace.
I recommend reviewing this one commit at a time. The two main changes are: