2017-11-03 6 views
1

でプロパティからタイプを取得します。これが可能か実用的なものなのかどうかはわかりません。私はこのように見えるいくつかのクラスを持ち、それらはすべて基底クラスから派生します。私はこのようになりますいくつかのコードを解釈しようとしているロスリンを使用したロスリン

考えるClassDeclarationSyntaxFooのために、私はこれを行うことができます:

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

または指定をINamedTypeSymbolFooために、私はこれを行うことができます:

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

をしかし、私はどこへ行くかわかりませんそこから。

最後に、さらなる分析のためにMyBarのシンボルを取得したいので、文字列"MyBar"を取得することは、完全修飾ではないので、助けにならないかもしれません。

提案がありますか?

EDIT

は、私はこのようなプロジェクトとコンパイルを取得しています:

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を得るいずれかの方法を私はGetTypeSymbolメソッドを持っていないようですSyntaxTreeSemanticModelで終わります。

答えて

2

Compilation(参照番号&構成)のセマンティックモデルが必要です。

そのノードでGetTypeSymbol()を呼び出して、INamedTypeSymbolにキャストできます。

+0

あなたが少しをしてください手の込んだてもらえますか?私は 'member 'に' GetTypeSymbol'を見つけることができません。 –

+0

@MattBurland:そのメソッドは、 'SemanticModel'にあります。これは' Compilation'か 'Project'に由来します。 – SLaks

+0

私はあなたの助けに感謝しますが、私はまだそれを見ていません。私は、私がやろうとしていることの多くを含めるために少し質問を編集しました。私は 'project.GetCompilationAsync()。Result'からコンパイルを得て、' SemanticModel'を 'compilation 'から得ることができます。GetSemanticModel(tree) 'が返されますが、結果として得られるモデルにはまだ' GetTypeSymbol() 'メソッドがありません –

1

ReturnStatementSyntaxTypeOfExpressionSyntaxを探してください。これには、タイプMyBarが含まれています。 SemanticModelあなたが得ることができる。このようなSymbolInfoで:また、このためSyntaxWalkerを使用することができます

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; 
      } 
     } 
    } 
} 

​​

は使用方法:

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