【问题标题】:Accessing SymbolInfo from modified SyntaxNode in Roslyn SyntaxRewriter从 Roslyn SyntaxRewriter 中修改的 SyntaxNode 访问 SymbolInfo
【发布时间】:2015-02-14 12:12:16
【问题描述】:

我正在创建一个 SyntaxRewriter,如果该类继承自某种类型,则它将类标记为部分,方法标记为虚拟

为此,我正在从重写器中的语义模型中查找 SymbolInfo,我遇到的问题是,一旦我修改语法树以使类部分化,我已经使 SemanticModel 无效并且无法使用它获取方法的 SymbolInfo。

下面是重写器的一个粗略示例,.InheritsFrom() 是一个扩展方法,它只是遍历继承以查找特定类型的用法,我只是将 IDisposable 作为示例插入,但这并不重要类型是什么。 .WithPartialModifier() 再次只是将部分添加到类语法节点修饰符的扩展方法。

我可能需要切换方法或使用新的语法树更新编译,但我不确定如何继续。

public class RewriterPartial : CSharpSyntaxRewriter
{
    private readonly CSharpCompilation _compiler;

    public RewriterPartial(CSharpCompilation compiler)
    {
        this._compiler = compiler;
    }

    public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
    {
        var symbol = _compiler.GetSemanticModel(node.SyntaxTree).GetDeclaredSymbol(node);
        if (symbol.InheritsFrom<System.IDisposable>())
        {
            if (!node.Modifiers.Any(SyntaxKind.PartialKeyword))
            {
                node = node.WithPartialModifier();
            }
        }

        return base.VisitClassDeclaration(node);
    }

    public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
    {
        var model = _compiler.GetSemanticModel(node.SyntaxTree);
        // fails above here as the node modified above 
        // and its SyntaxTree have no CompilationUnit
        // and I need to repeat the .InheritsFrom<T> call
        // to check if the method comes from a class in the syntaxtree
        // that inherits from the specific type
        return node;
    }
}

【问题讨论】:

    标签: c# roslyn


    【解决方案1】:

    在修改树之前,您可以先调用base.VisitClassDeclaration(node);访问和修改最深的节点。

    尝试以下方法:

    public class RewriterPartial : CSharpSyntaxRewriter
    {
        private readonly CSharpCompilation _compilation;
        public RewriterPartial(CSharpCompilation compilation, SemanticModel model)
        {
            this._compilation = compilation;
        }
    
        public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node)
        {
            //Visit the deepest nodes before modifying the tree.
            var newNode = (ClassDeclarationSyntax)base.VisitClassDeclaration(node);
            if (!newNode.Modifiers.Any(SyntaxKind.PartialKeyword))
            {
                newNode = newNode.WithModifiers(
                    SyntaxFactory.TokenList(
                        SyntaxFactory.Token(SyntaxKind.PartialKeyword)));
            }
            return newNode;
        }
    
        public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
        {
            var model = _compilation.GetSemanticModel(node.SyntaxTree);
            var symbol = model.GetDeclaredSymbol(node);
            //Do whatever you need to here
            return node;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-28
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多