ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 通过SyntaxFactory构建NameOf表达式(Roslyn)

2019-05-22 19:53:21  阅读:468  来源: 互联网

标签:c roslyn roslyn-code-analysis


尝试使用C#SyntaxFactory从头开始构造表达式. Roslyn无法将我的InvocationExpressionSyntax识别为关键字的上下文名称,并在Emit命令时抛出错误诊断.

试图给Roslyn有效的代码解析,希望我能找到我的语法结构和“正确解析的”之间的差异.我能够跟踪差异到“nameof”标识符令牌,但那是我被卡住的地方.我发现我的令牌和已解析的令牌之间没有任何区别,但它们仍然有些不同.

当我使用“已解析的”时,一切正常,Emit按预期工作,没有错误.另一方面,当我使用自己的令牌时,它无法编译,Emit会抛出错误诊断.

我正在测试代码:

var CODE = "class X { void Q() { var q = nameof(Q); } }";

var correctSyntaxTree = CSharpSyntaxTree.ParseText(CODE);
var correctRoot = correctSyntaxTree.GetRoot();
var correctNameOf = correctRoot.DescendantNodes().OfType<InvocationExpressionSyntax>().First();

var correctExpression = (IdentifierNameSyntax)correctNameOf.Expression;

var myNameOf = SyntaxFactory.InvocationExpression (
    correctExpression, //Works
    //SyntaxFactory.IdentifierName("nameof"), //Doesn't work
    //SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.NameOfKeyword)), //System.ArgumentException: 'identifier'

    //SyntaxFactory.IdentifierName(correctExpression.Identifier), //Works
    //SyntaxFactory.IdentifierName(correctExpression.Identifier.ValueText), //Doesn't work

    //correctExpression.WithIdentifier(SyntaxFactory.Identifier("nameof")), //Doesn't work
    //correctExpression.WithIdentifier(SyntaxFactory.Identifier(correctExpression.Identifier.ValueText)), //Doesn't work

    //SyntaxFactory.IdentifierName("nameof").WithTriviaFrom(correctExpression), //Doesn't work
    //correctExpression.CopyAnnotationsTo(SyntaxFactory.IdentifierName("nameof")), //Doesn't work
    //SyntaxFactory.IdentifierName(correctExpression.Identifier.WithoutAnnotations().WithoutTrivia()), //Works

    SyntaxFactory.ArgumentList (
        SyntaxFactory.SingletonSeparatedList (
            SyntaxFactory.Argument (
                SyntaxFactory.IdentifierName("Q")
            )
        )
    )
);

var newRoot = correctRoot.ReplaceNode(correctNameOf, myNameOf);
var newTree = CSharpSyntaxTree.Create((CSharpSyntaxNode)newRoot);

var compilation = CSharpCompilation.Create (
    "Compilation",
    new[] { newTree },
    references: MsCorLib,
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);

var compilationResult = compilation.Emit(new MemoryStream());

任何人都可以指出解析的令牌和我的令牌之间的任何区别,这导致Roslyn(正确)无法将nameof表达式绑定到任何“in-code”符号,但不将其视为上下文关键字?

编译错误:(1,30):错误CS0103:当前上下文中不存在名称“nameof”

编译#LanguageVersion:CSharp7

Roslyn版本:( Nuget最新)Microsoft.CodeAnalysis.CSharp v2.3.2

解决方法:

如果您查看Identifier的非私有成员,您将看到有属性RawContextualKind.当您从代码中解析nameof时,您将获得此上下文类型:
enter image description here

但是如果你使用SyntaxFactory.IdentifierName(“nameof”)创建标识符,你会得到:
enter image description here

在第二种情况下,nameof被视为普通标识符,这就是您收到错误的原因.您应该使用SyntaxFactory.Identifier()重载,它允许您指定上下文类型:

SyntaxFactory.IdentifierName(
    SyntaxFactory.Identifier(
        SyntaxFactory.TriviaList(),
        SyntaxKind.NameOfKeyword,
        "nameof",
        "nameof",
        SyntaxFactory.TriviaList()))

标签:c,roslyn,roslyn-code-analysis
来源: https://codeday.me/bug/20190522/1153684.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有