Share more data in the SyntaxTreeIndex#54057
Conversation
| } | ||
| } | ||
|
|
||
| private static void AddExtensionMethodInfo( |
There was a problem hiding this comment.
this moved into the IDeclaredSYmbolInfoService
| where TMemberDeclarationSyntax : SyntaxNode | ||
| { | ||
| 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.
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.
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.
these values are computed once per container and passed in.
| CancellationToken cancellationToken) | ||
| { | ||
| if (!document.SupportsSyntaxTree) | ||
| return null; |
There was a problem hiding this comment.
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.
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.
pulled this await up, and put everything else in a synchronous method to prevent pooled collections from being used across awaits (As per @sharwell ).
| 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.
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.
enums are a SeparatedSyntaxList in C#, and a SyntaxList in VB. so we need an IEnumerable here.
There was a problem hiding this comment.
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.
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.
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.
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.
this moved into ArityUtilities
| Dictionary<string, string> aliases, | ||
| Dictionary<string, ArrayBuilder<int>> extensionMethodInfo, | ||
| string containerDisplayName, | ||
| string fullyQualifiedContainerName, |
There was a problem hiding this comment.
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 .
|
|
||
| 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.
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.
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.
| 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.
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.
| 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.
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.
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: