2017-05-05 21 views
0

目前我正在爲roslyn編寫c#的簡單代碼分析。我需要解析一個解決方案中所有項目的所有文檔,並在本文檔中獲取已聲明的使用類。Roslyn在ObjectCreationExpressionSyntax中獲取IdentifierName

例如來自:

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

我想Program使用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 es。看到這裏: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(); 
} 

... 

所有其他亞型將需要遞交。請注意0​​也是TypeSyntax,所以你很可能需要使這個方法遞歸。

+0

好的,該怎麼做?你的鏈接並沒有真正幫助我理解這一點。你能解釋更多還是使用一些代碼? –

+0

希望更新的答案有幫助。 – Tamas

+0

是的,謝謝。也許是一個@Crowcoder發佈的更好的解決方案。會弄清楚巫婆會符合我的需要。謝謝! –

0

你可以從語法的類型屬性的標識符:

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.SomeClassNamespace2.SomeClass?如果使用了using SomeClass = Namespace3.SomeOtherType;聲明怎麼辦?

幸運的是,你不必自己做這個分析。編譯器可以將ObjectCreationExpressionSyntax綁定到一個符號。你有你的語義模型,使用它。

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

你可以比較你從model.GetDeclaredSymbol(classDeclarationSyntax)得到符號這個符號,只是確保你使用Equals方法,而不是==操作。

相關問題