簡體   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