2017-05-05 1 views
0

現在、私はc#とroslynで単純なコードを分析しています。私は1つのソリューションの中のすべてのプロジェクトのすべてのドキュメントを解析し、このドキュメントの中で宣言されたクラスを取得する必要があります。RoslynはObjectCreationExpressionSyntaxでIdentifierNameを取得します

から例えば

:私はProgramFooを使用して取得したい

class Program 
{ 
    static void Main(string[] args) 
    { 
     var foo = new Foo(); 
    } 
} 

私はすでにすべてのドキュメントを解析し、内部で宣言されたクラスを取得します。

// all projects in solution 
foreach (var project in _solution.Projects) 
{ 
    // all documents inside project 
    foreach (var document in project.Documents) 
    { 
     var syntaxRoot = await document.GetSyntaxRootAsync(); 
     var model = await document.GetSemanticModelAsync(); 
     var classes = syntaxRoot.DescendantNodes().OfType<ClassDeclarationSyntax>(); 
     // all classes inside document 
     foreach (var classDeclarationSyntax in classes) 
     { 
      var symbol = model.GetDeclaredSymbol(classDeclarationSyntax); 
      var objectCreationExpressionSyntaxs = classDeclarationSyntax.DescendantNodes().OfType<ObjectCreationExpressionSyntax>(); 
      // all object creations inside document 
      foreach (var objectCreationExpressionSyntax in objectCreationExpressionSyntaxs) 
      { 
       // TODO: Get the identifier value 
      } 
     } 
    } 
} 

問題がIdentifierName Fooを取得することです。 debuggerを使用して、objectCreationExpressionSyntax.Typeを取得しました。Identifier.Textが必要な値を取得しましたが、objectCreationExpressionSyntax.Type.Identifierはプライベートであるようです。

SymbolFinderを使用して、ソリューション内のクラスのすべての参照を見つけることができます。私はすでにすべてのドキュメントを解析する必要があるので、そのドキュメントは必要なくすべきです。

多分私は間違った経路にいるでしょうか?識別子値を取得するには?

答えて

1

さまざまなタイプのTypeSyntaxを処理する必要があります。ここをクリックしてください:http://source.roslyn.io/#Microsoft.CodeAnalysis.CSharp/Syntax/TypeSyntax.cs,29171ac4ad60a546,references

デバッガで表示される内容はSimpleNameSyntaxです。公開されているのはIdentifierです。

更新

var ns = objectCreationExpressionSyntax.Type as NameSyntax; 
if (ns != null) 
{ 
    return ns.Identifier.ToString(); 
} 

var pts = objectCreationExpressionSyntax.Type as PredefinedTypeSyntax; 
if (pts != null) 
{ 
    return pts.Keyword.ToString(); 
} 

... 

他のすべてのサブタイプが渡される必要があります。 ArrayType.ElementTypeTypeSyntaxであるため、このメソッドを再帰的にする必要があります。

+0

これはどのようにするのですか?あなたのリンクは、私がこれを理解するのに本当に役立たなかった。もっと説明したり、コードを使ってください。 –

+0

更新された回答が役立つことを願っています。 – Tamas

+0

はい、ありがとうございます。おそらく、@Crowcoderが投稿したものと同じ優れたソリューションです。魔女の1つが私の必要性に合っているとわかるでしょう。ありがとう! –

0

あなたは構文のTypeプロパティから識別子を取得することができます。

foreach (var objectCreationExpressionSyntax in objectCreationExpressionSyntaxs) 
{ 
    IdentifierNameSyntax ins = (IdentifierNameSyntax)objectCreationExpressionSyntax.Type; 
    var id = ins.Identifier; 
    Console.WriteLine(id.ValueText); 
} 
+0

ありがとう、それは私が必要としたものでした。私はこれを前に持っていましたが、 'IdentifierNameSyntax'にキャストする必要があることを知りませんでした –

0

文字列は誤解を招くことができます。

表現がnew SomeClass()で、文字列「SomeClass」が表示されているとします。それがNamespace1.SomeClassまたはNamespace2.SomeClassを参照しているかどうかをどのように知っていますか? using SomeClass = Namespace3.SomeOtherType;宣言が使用されている場合はどうなりますか?

幸いにも、この分析を自分で行う必要はありません。コンパイラは、ObjectCreationExpressionSyntaxをシンボルにバインドできます。あなたはセマンティックモデルを持っています。

foreach (var oce in objectCreationExpressionSyntaxs) 
{ 
    ITypeSymbol typeSymbol = model.GetTypeInfo(oce).Type; 
    // ... 
} 

あなたはちょうどあなたがEquals方法、ない==演算子を使用してください、あなたはmodel.GetDeclaredSymbol(classDeclarationSyntax)から取得シンボルと、このシンボルを比較することができます。

関連する問題