未验证 提交 4ab355b7 编写于 作者: J Jason Malinowski 提交者: GitHub

Merge pull request #40786 from jasonmalinowski/improve-getdeclaredsymbols-perf

Speed up ISemanticFactsService.GetDeclaredSymbol
......@@ -145,12 +145,30 @@ public string GenerateNameForExpression(SemanticModel semanticModel, SyntaxNode
public ISymbol GetDeclaredSymbol(SemanticModel semanticModel, SyntaxToken token, CancellationToken cancellationToken)
{
var location = token.GetLocation();
var q = from node in token.GetAncestors<SyntaxNode>()
let symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken)
where symbol != null && symbol.Locations.Contains(location)
select symbol;
return q.FirstOrDefault();
foreach (var ancestor in token.GetAncestors<SyntaxNode>())
{
var symbol = semanticModel.GetDeclaredSymbol(ancestor, cancellationToken);
if (symbol != null)
{
if (symbol.Locations.Contains(location))
{
return symbol;
}
// We found some symbol, but it defined something else. We're not going to have a higher node defining _another_ symbol with this token, so we can stop now.
return null;
}
// If we hit an executable statement syntax and didn't find anything yet, we can just stop now -- anything higher would be a member declaration which won't be defined by something inside a statement.
if (SyntaxFactsService.IsExecutableStatement(ancestor))
{
return null;
}
}
return null;
}
public bool LastEnumValueHasInitializer(INamedTypeSymbol namedTypeSymbol)
......
......@@ -145,16 +145,31 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Function GetDeclaredSymbol(semanticModel As SemanticModel, token As SyntaxToken, cancellationToken As CancellationToken) As ISymbol Implements ISemanticFactsService.GetDeclaredSymbol
Dim location = token.GetLocation()
Dim q = From node In token.GetAncestors(Of SyntaxNode)()
Where Not TypeOf node Is AggregationRangeVariableSyntax AndAlso
Not TypeOf node Is CollectionRangeVariableSyntax AndAlso
Not TypeOf node Is ExpressionRangeVariableSyntax AndAlso
Not TypeOf node Is InferredFieldInitializerSyntax
Let symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken)
Where symbol IsNot Nothing AndAlso symbol.Locations.Contains(location)
Select symbol
Return q.FirstOrDefault()
For Each ancestor In token.GetAncestors(Of SyntaxNode)()
If Not TypeOf ancestor Is AggregationRangeVariableSyntax AndAlso
Not TypeOf ancestor Is CollectionRangeVariableSyntax AndAlso
Not TypeOf ancestor Is ExpressionRangeVariableSyntax AndAlso
Not TypeOf ancestor Is InferredFieldInitializerSyntax Then
Dim symbol = semanticModel.GetDeclaredSymbol(ancestor)
If symbol IsNot Nothing Then
If symbol.Locations.Contains(location) Then
Return symbol
End If
' We found some symbol, but it defined something else. We're not going to have a higher node defining _another_ symbol with this token, so we can stop now.
Return Nothing
End If
' If we hit an executable statement syntax and didn't find anything yet, we can just stop now -- anything higher would be a member declaration which won't be defined by something inside a statement.
If SyntaxFactsService.IsExecutableStatement(ancestor) Then
Return Nothing
End If
End If
Next
Return Nothing
End Function
Public Function LastEnumValueHasInitializer(namedTypeSymbol As INamedTypeSymbol) As Boolean Implements ISemanticFactsService.LastEnumValueHasInitializer
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册