繁体   English   中英

使用 Roslyn 从属性中获取类型

[英]Get type from property with Roslyn

使用 Roslyn 我试图解释一些看起来像这样的代码:

public class Foo
{
    public override Type BarType
    {
        get { return typeof(MyBar); }
    }
}

我想做的是获取MyBar然后将该类型作为符号获取,但我不确定这是否可行或可行。 我将有几个看起来像这样的类,它们都派生自一个基类。

鉴于FooClassDeclarationSyntax ,我可以这样做:

var prop = syntax.DescendantNodes().OfType<PropertyDeclarationSyntax>()
              .FirstOrDefault(p => p.Identifier.ToString() == "BarType");

或者给定FooINamedTypeSymbol ,我可以这样做:

var member = symbol.GetMembers("BarType").FirstOrDefault();

但我不知道从那里去哪里。

最终,我希望能够获得MyBar的符号以进行进一步分析,因此即使获得字符串"MyBar"也无济于事,因为它不完全合格。

有什么建议么?

编辑

我得到一个项目和这样的汇编:

var workspace = MSBuildWorkspace.Create();
var project = workspace.OpenProjectAsync(projectPath).Result;
var compilation = project.GetCompilationAsync().Result;

compilation是这里的CSharpCompilation 从那里我做这样的事情:

foreach (var doc in project.Documents)
{
    Console.WriteLine($"Analyzing {doc.Name}");

    //var model = doc.GetSemanticModelAsync().Result;
    var tree = doc.GetSyntaxTreeAsync().Result;
    var root = tree.GetRoot();
    var model = compilation.GetSemanticModel(tree);
    var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();

    foreach (var syntax in classes)
    {
        var symbol = model.GetDeclaredSymbol(syntax);
        //... need to analyze properties in the class here...
    }
}

无论哪种方式,我得到的model我结束了一个SyntaxTreeSemanticModel这似乎不具有GetTypeSymbol方法。

您需要语义模型,它来自Compilation (带有参考和配置)。

然后,您可以在该节点上调用 GetTypeSymbol() GetSymbolInfo()并转换为INamedTypeSymbol

您应该寻找ReturnStatementSyntaxTypeOfExpressionSyntax 这包含类型MyBar 使用SemanticModel您可以像这样获得SymbolInfo

var classDeclarationSyntaxs = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
foreach ( var classDeclarationSyntax in classDeclarationSyntaxs )
{
    var propertyDeclarationSyntaxs = classDeclarationSyntax.Members.OfType<PropertyDeclarationSyntax>();
    var barTypePropertyDeclarationSyntax = propertyDeclarationSyntaxs.FirstOrDefault( p => p.Identifier.Text == "BarType" );
    if ( barTypePropertyDeclarationSyntax != null )
    {
        var returnStatementSyntax = barTypePropertyDeclarationSyntax.DescendantNodes().OfType<ReturnStatementSyntax>().FirstOrDefault();
        if ( returnStatementSyntax != null )
        {
            var typeOfExpressionSyntax = returnStatementSyntax.ChildNodes().OfType<TypeOfExpressionSyntax>().FirstOrDefault();
            if ( typeOfExpressionSyntax != null )
            {
                var symbolInfo = semanticModel.GetSymbolInfo( typeOfExpressionSyntax.Type );
                var symbolInfoSymbol = symbolInfo.Symbol;
            }
        }
    }
}

您还可以为此使用SyntaxWalker

public class TypeOfSyntaxWalker : CSharpSyntaxWalker
{
    private readonly SemanticModel _semanticModel;

    public ISymbol SymbolInfoSymbol { get; private set; }

    public TypeOfSyntaxWalker( SemanticModel semanticModel )
    {
        _semanticModel = semanticModel;
    }

    public override void VisitTypeOfExpression( TypeOfExpressionSyntax typeOfExpressionSyntax )
    {
        var parent = typeOfExpressionSyntax.Parent;
        if ( parent.Kind() == SyntaxKind.ReturnStatement )
        {
            var propertyDeclarationSyntax = parent.FirstAncestorOrSelf<PropertyDeclarationSyntax>();
            if ( propertyDeclarationSyntax != null &&
                    propertyDeclarationSyntax.Identifier.ValueText == "BarType" )
            {
                var symbolInfo = _semanticModel.GetSymbolInfo( typeOfExpressionSyntax.Type );
                SymbolInfoSymbol = symbolInfo.Symbol;
            }
        }
        base.VisitTypeOfExpression( typeOfExpressionSyntax );
    }
}

用法:

var classDeclarationSyntaxs = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
foreach ( var classDeclarationSyntax in classDeclarationSyntaxs )
{
    var typeOfSyntaxWalker = new TypeOfSyntaxWalker( semanticModel );
    typeOfSyntaxWalker.VisitClassDeclaration( classDeclarationSyntax );
    var symbolInfoSymbol = typeOfSyntaxWalker.SymbolInfoSymbol;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM