Roslyn:检测 IdentifierName 是否为 属性?

Roslyn : detect if IdentifierName is a property?

在以下示例中,使用 Roslyn 如何知道 IdentifierName SyntaxNode 是否引用 属性:

using System;
namespace test
{
    public class Base {
        public int Data { get {return Data;} set {Data = value;} }
        public int Normal;
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Base b = new Base();
            int x = b.Data;
            int y = b.Normal;
        }
    }
}

当我打印 SyntaxNode 树时,最后两个赋值表达式看起来是一样的。我怎么知道 b.Data 的 IdentifierName 节点是 属性?我已经检查了 ISymbol、ITypeSymbol,但无论如何都看不到这样做。

这是我打印出来的 SyntaxNode 树的一部分。

    node[4][1]=LocalDeclarationStatement,declsymbol=null,symbol=null,type=null
      node[5][0]=VariableDeclaration,declsymbol=null,symbol=null,type=null
        node[6][0]=PredefinedType,declsymbol=null,symbol=int,name=Int32,static=False,type=int,static=False,type.Kind=NamedType,type.TypeKind=Struct
        node[6][1]=VariableDeclarator,declsymbol=x,symbol=null,type=null
          node[7][0]=EqualsValueClause,declsymbol=null,symbol=null,type=null
            node[8][0]=SimpleMemberAccessExpression,declsymbol=null,symbol=test.Base.Data,name=Data,static=False,type=int,static=False,type.Kind=NamedType,type.TypeKind=Struct
              node[9][0]=IdentifierName,declsymbol=null,symbol=b,name=b,static=False,type=test.Base,static=False,type.Kind=NamedType,type.TypeKind=Class
              node[9][1]=IdentifierName,declsymbol=null,symbol=test.Base.Data,name=Data,static=False,type=int,static=False,type.Kind=NamedType,type.TypeKind=Struct
    node[4][2]=LocalDeclarationStatement,declsymbol=null,symbol=null,type=null
      node[5][0]=VariableDeclaration,declsymbol=null,symbol=null,type=null
        node[6][0]=PredefinedType,declsymbol=null,symbol=int,name=Int32,static=False,type=int,static=False,type.Kind=NamedType,type.TypeKind=Struct
        node[6][1]=VariableDeclarator,declsymbol=y,symbol=null,type=null
          node[7][0]=EqualsValueClause,declsymbol=null,symbol=null,type=null
            node[8][0]=SimpleMemberAccessExpression,declsymbol=null,symbol=test.Base.Normal,name=Normal,static=False,type=int,static=False,type.Kind=NamedType,type.TypeKind=Struct
              node[9][0]=IdentifierName,declsymbol=null,symbol=b,name=b,static=False,type=test.Base,static=False,type.Kind=NamedType,type.TypeKind=Class
              node[9][1]=IdentifierName,declsymbol=null,symbol=test.Base.Normal,name=Normal,static=False,type=int,static=False,type.Kind=NamedType,type.TypeKind=Struct

您可以看到 Data 和 Normal 的 IdentifierName 节点看起来是一样的。

谢谢。

您需要检查从 SemannticModel.GetSymbolInfo 返回的 ISymbol 是否是 IFieldSymbol or an IPropertySymbol

那是因为语法节点只告诉你语法。语法树是在没有引用的情况下构建的;它既不知道也不关心名称是什么(甚至根本不关心它们是否存在)。

相反,您需要来自编译的语义模型。

获取 IdentifierName 的符号,然后检查其 KindProperty 还是 Field

如果符号为 null,则可能存在编译错误。