提交 c6525c9a 编写于 作者: M Martin Strecker

Cherry-pick 7496ec0a: Refactoring/Simplification: Walk language specific...

Cherry-pick 7496ec0a: Refactoring/Simplification: Walk language specific syntax trees directly instead by visitor pattern.
上级 5875cf50
......@@ -9,60 +9,43 @@ namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers
{
internal sealed class InternalsVisibleToCompletionProvider : AbstractInternalsVisibleToCompletionProvider
{
private static readonly AttributeNodeExtractor ExtractAttribute = new AttributeNodeExtractor();
private static readonly AttributeConstructorArgumentExtractor ExtractAttributeConstructorArgument = new AttributeConstructorArgumentExtractor();
protected override IImmutableList<SyntaxNode> GetAssemblyScopedAttributeSyntaxNodesOfDocument(SyntaxNode documentRoot)
{
var result = (documentRoot as CSharpSyntaxNode).Accept(ExtractAttribute);
return result == null
? ImmutableList<SyntaxNode>.Empty
: result.ToImmutableList();
}
protected override SyntaxNode GetConstructorArgumentOfInternalsVisibleToAttribute(SyntaxNode internalsVisibleToAttribute)
=> (internalsVisibleToAttribute as CSharpSyntaxNode).Accept(ExtractAttributeConstructorArgument);
private class AttributeNodeExtractor : CSharpSyntaxVisitor<IEnumerable<SyntaxNode>>
{
public override IEnumerable<SyntaxNode> VisitCompilationUnit(CompilationUnitSyntax node)
var builder = default(ImmutableList<SyntaxNode>.Builder);
if (documentRoot is CompilationUnitSyntax compilationUnit)
{
foreach (var attributeList in node.AttributeLists)
foreach (var attributeList in compilationUnit.AttributeLists)
{
foreach (var attribute in attributeList.Accept(this))
{
yield return attribute;
}
// For most documents the compilationUnit.AttributeLists should be empty.
// Therefore we delay initialization of the builder
builder = builder ?? ImmutableList.CreateBuilder<SyntaxNode>();
builder.AddRange(attributeList.Attributes);
}
}
public override IEnumerable<SyntaxNode> VisitAttributeList(AttributeListSyntax node)
=> node.Attributes;
return builder == null
? ImmutableList<SyntaxNode>.Empty
: builder.ToImmutable();
}
private class AttributeConstructorArgumentExtractor : CSharpSyntaxVisitor<SyntaxNode>
protected override SyntaxNode GetConstructorArgumentOfInternalsVisibleToAttribute(SyntaxNode internalsVisibleToAttribute)
{
public override SyntaxNode VisitAttribute(AttributeSyntax node)
=> node.ArgumentList.Accept(this);
public override SyntaxNode VisitAttributeArgumentList(AttributeArgumentListSyntax node)
if (internalsVisibleToAttribute is AttributeSyntax attributeSyntax)
{
//InternalsVisibleTo has only one constructor argument.
//https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.internalsvisibletoattribute(v=vs.110).aspx
//We can assume that this is the assemblyName argument.
foreach (var argument in node.Arguments)
// InternalsVisibleTo has only one constructor argument.
// https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.internalsvisibletoattribute(v=vs.110).aspx
// We can assume that this is the assemblyName argument.
foreach (var argument in attributeSyntax.ArgumentList.Arguments)
{
if (argument.NameEquals == null) // Ignore attribute properties
{
return argument.Accept(this);
return argument.Expression;
}
}
return default(SyntaxNode);
}
public override SyntaxNode VisitAttributeArgument(AttributeArgumentSyntax node)
=> node.Expression;
return null;
}
}
}
......@@ -10,57 +10,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
Friend NotInheritable Class InternalsVisibleToCompletionProvider
Inherits AbstractInternalsVisibleToCompletionProvider
Private Shared ReadOnly ExtractAttribute As AttributeNodeExtractor = New AttributeNodeExtractor()
Private Shared ReadOnly ExtractAttributeConstructorArgument As AttributeConstructorArgumentExtractor = New AttributeConstructorArgumentExtractor()
Protected Overrides Function GetAssemblyScopedAttributeSyntaxNodesOfDocument(documentRoot As SyntaxNode) As IImmutableList(Of SyntaxNode)
Dim result = TryCast(documentRoot, VisualBasicSyntaxNode).Accept(ExtractAttribute)
Return result.ToImmutableListOrEmpty()
End Function
Protected Overrides Function GetConstructorArgumentOfInternalsVisibleToAttribute(internalsVisibleToAttribute As SyntaxNode) As SyntaxNode
Return TryCast(internalsVisibleToAttribute, VisualBasicSyntaxNode).Accept(ExtractAttributeConstructorArgument)
End Function
Private Class AttributeNodeExtractor
Inherits VisualBasicSyntaxVisitor(Of IEnumerable(Of SyntaxNode))
Public Overrides Iterator Function VisitCompilationUnit(node As CompilationUnitSyntax) As IEnumerable(Of SyntaxNode)
For Each attributeStatement In node.Attributes
For Each attribute In attributeStatement.Accept(Me)
Yield attribute
Next
Next
End Function
Public Overrides Iterator Function VisitAttributesStatement(node As AttributesStatementSyntax) As IEnumerable(Of SyntaxNode)
For Each attributeList In node.AttributeLists
For Each attribute In attributeList.Accept(Me)
Yield attribute
Dim builder As ImmutableList(Of SyntaxNode).Builder = Nothing
Dim compilationUnit = TryCast(documentRoot, CompilationUnitSyntax)
If Not compilationUnit Is Nothing Then
For Each attributeStatement In compilationUnit.Attributes
For Each attributeList In attributeStatement.AttributeLists
builder = If(builder, ImmutableList.CreateBuilder(Of SyntaxNode)())
builder.AddRange(attributeList.Attributes)
Next
Next
End Function
Public Overrides Function VisitAttributeList(node As AttributeListSyntax) As IEnumerable(Of SyntaxNode)
Return node.Attributes
End Function
End Class
Private Class AttributeConstructorArgumentExtractor
Inherits VisualBasicSyntaxVisitor(Of SyntaxNode)
End If
Public Overrides Function VisitAttribute(node As AttributeSyntax) As SyntaxNode
Return node.ArgumentList.Accept(Me)
End Function
Return If(builder Is Nothing, ImmutableList(Of SyntaxNode).Empty, builder.ToImmutable())
End Function
Public Overrides Function VisitArgumentList(node As ArgumentListSyntax) As SyntaxNode
For Each argument In node.Arguments
Protected Overrides Function GetConstructorArgumentOfInternalsVisibleToAttribute(internalsVisibleToAttribute As SyntaxNode) As SyntaxNode
Dim attributeSyntax = TryCast(internalsVisibleToAttribute, AttributeSyntax)
If Not attributeSyntax Is Nothing Then
For Each argument In attributeSyntax.ArgumentList.Arguments
If Not argument.IsNamed Then
Return argument.GetExpression()
End If
Next
Return Nothing
End Function
End Class
End If
Return Nothing
End Function
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册