2013-12-08 50 views
13

我從roslyn的語法樹中獲得了ClassDeclarationSyntax。 我讀到這樣的:從Roslyn ClassDeclarationSyntax獲取類FullName(包括名稱空間)

var tree = SyntaxTree.ParseText(sourceCode); 
var root = (CompilationUnitSyntax)tree.GetRoot(); 

var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>(); 

標識符只包含類的名字,但沒有關於命名空間信息,所以fullType缺少名稱。像「MyClass的」,但NOCH「Namespace1.MyClass」

什麼是推薦的方式來獲得命名空間/語法FulltypeName?

+2

據我所知,這些信息來自於語義樹。 – SLaks

+0

我擔心你的權利與您的信息,我發現:http://social.msdn.microsoft.com/Forums/vstudio/en-US/bbb8c695-7555-4d27-b6ef-442f3f0492a5/getting-fulltypename-from-classdeclarationsyntax但是,對我來說似乎很醜陋。在我的情況下,如果壯舉這將花費大量的performacne的:-( –

+1

由於有提到的,你可以通過遞歸地尋找空間聲明自己來建立。當心嵌套泛型類。 – SLaks

回答

0

以下是我如何獲取名稱空間。你必須稍微修改我的代碼,你的情況:

NamespaceDeclarationSyntax namespaceDeclarationSyntax = null; 
if (!SyntaxNodeHelper.TryGetParentSyntax(classDeclarationSyntax, out namespaceDeclarationSyntax)) 
{ 
    return; // or whatever you want to do in this scenario 
} 

var namespaceName = namespaceDeclarationSyntax.Name.ToString(); 
var fullClassName = namespaceName + "." + classDeclarationSyntax.Identifier.ToString(); 

和助手:

 public static async Task<NamespaceDeclarationSyntax> GetNamespaceAsync(this Document document, CancellationToken cancellationToken = default(CancellationToken)) 
     { 
      SyntaxNode documentRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); 
      var rootCompUnit = (CompilationUnitSyntax)documentRoot; 
      return (NamespaceDeclarationSyntax)rootCompUnit.Members.Where(m => m.IsKind(SyntaxKind.NamespaceDeclaration)).Single(); 
     } 
+3

我認爲這只是?故事的一半如果命名空間是嵌套我會建議往上走,直到你達到年初 –

4

您可以使用輔助類我寫這樣做

static class SyntaxNodeHelper 
{ 
    public static bool TryGetParentSyntax<T>(SyntaxNode syntaxNode, out T result) 
     where T : SyntaxNode 
    { 
     // set defaults 
     result = null; 

     if (syntaxNode == null) 
     { 
      return false; 
     } 

     try 
     { 
      syntaxNode = syntaxNode.Parent; 

      if (syntaxNode == null) 
      { 
       return false; 
      } 

      if (syntaxNode.GetType() == typeof (T)) 
      { 
       result = syntaxNode as T; 
       return true; 
      } 

      return TryGetParentSyntax<T>(syntaxNode, out result); 
     } 
     catch 
     { 
      return false; 
     } 
    } 
} 

沒有什麼在這裏過於複雜......這是有道理的,命名空間將「在語法樹上」(因爲該類包含在命名空間中),所以你只需要向上「移動」語法樹直到找到命名空間追加到ClassDeclarationSyntax的標識符。

+0

你爲什麼不只是變種命名空間= root.DescendantNodes()OfType (); –

+0

不知道這個現在可行,但我認爲這在當時是不被支持的 - 自從我和R一起工作已經有一段時間了oslyn – Jordan

0

試試這個代碼

public static string GetFullName(NamespaceDeclarationSyntax node) 
{ 
    if (node.Parent is NamespaceDeclarationSyntax) 
     return String.Format("{0}.{1}", 
      GetFullName((NamespaceDeclarationSyntax)node.Parent), 
      ((IdentifierNameSyntax)node.Name).Identifier.ToString()); 
    else 
     return ((IdentifierNameSyntax)node.Name).Identifier.ToString(); 
} 
+0

你爲什麼在NamespaceDeclarationSyntax考慮,而不僅僅是一個syntaxnode –

+0

這是CSharpSyntaxWalker後裔與owerriden VisitNamespaceDeclaration(NamespaceDeclarationSyntax節點)的一部分。 – Arci

相關問題