【问题标题】:Get constructor declaration from ObjectCreationExpressionSyntax with Roslyn?使用 Roslyn 从 ObjectCreationExpressionSyntax 获取构造函数声明?
【发布时间】:2014-08-02 04:47:58
【问题描述】:

我正在尝试使用 Roslyn 在 C# 源文件中获取对象创建表达式并添加名称所有参数(因此从 new SomeObject("hello")new SomeObject(text: "hello")

我从 SyntaxTree 中获得了 ObjectCreationExpressionSyntax 以及解决方案的 SemanticModel。我正在尝试将GetSymbol/TypeInfo 用于ObjectCreationExpressionSyntax 的类型,但我似乎无法使用它来获取参数名称。

基本上我想要得到的是:

具体是Something.Something的参数。

【问题讨论】:

    标签: c# roslyn


    【解决方案1】:

    SemanticModel 询问您正在访问/重写的节点的SymbolInfo。它返回的符号应该始终是IMethodSymbol,其属性Parameters 包含构造函数的所有参数。

    出于好奇,我写了一个SyntaxRewriter,它完全符合您的要求。当然它还没有经过彻底的测试,我会遗漏一些案例(或者只是省略了,比如已经命名的参数)。

    public class NameAllParametersRewriter : CSharpSyntaxRewriter
    {
        private readonly SemanticModel _semanticModel;
    
        public NameAllParametersRewriter(Document document)
        {
            _semanticModel = document.GetSemanticModelAsync().Result;
        }
    
        public override SyntaxNode VisitObjectCreationExpression(
            ObjectCreationExpressionSyntax node)
        {
            var baseResult = (ObjectCreationExpressionSyntax)
                base.VisitObjectCreationExpression(node);
    
            var ctorSymbol = _semanticModel.GetSymbolInfo(node).Symbol as IMethodSymbol;
            if (ctorSymbol == null)
                return baseResult;
    
            var newArgumentListArguments = new SeparatedSyntaxList<ArgumentSyntax>();
            for (int i = 0; i < baseResult.ArgumentList.Arguments.Count; i++)
            {
                var oldArgumentSyntax = baseResult.ArgumentList.Arguments[i];
                var parameterName = ctorSymbol.Parameters[i].Name;
    
                var identifierSyntax = SyntaxFactory.IdentifierName(parameterName);
                var nameColonSyntax = SyntaxFactory
                    .NameColon(identifierSyntax)
                    .WithTrailingTrivia(SyntaxFactory.Whitespace(" "));
    
                var newArgumentSyntax = SyntaxFactory.Argument(
                    nameColonSyntax, 
                    oldArgumentSyntax.RefOrOutKeyword, 
                    oldArgumentSyntax.Expression);
    
                newArgumentListArguments = newArgumentListArguments.Add(newArgumentSyntax);
            }
    
            return baseResult
                .WithArgumentList(baseResult.ArgumentList
                    .WithArguments(newArgumentListArguments));
        }
    }
    

    【讨论】:

    • 哇,Roslyn 的功能比我预期的要强大得多 :D 我现在无法对此进行测试,但看起来它会起作用。谢谢!
    猜你喜欢
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 2020-09-13
    相关资源
    最近更新 更多