我在roslyn的语法树中有一个ClassDeclarationSyntax.我这样看了:
var tree = SyntaxTree.ParseText(sourceCode);
var root = (CompilationUnitSyntax)tree.GetRoot();
var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
Run Code Online (Sandbox Code Playgroud)
标识符仅包含类的名称,但不包含有关命名空间的信息,因此缺少fullType名称.像"MyClass"但是noch"Namespace1.MyClass"
获取语法的名称空间/ FulltypeName的推荐方法是什么?
你可以使用我写的助手类来做到这一点:
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();
Run Code Online (Sandbox Code Playgroud)
和助手:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里没有任何过于复杂的东西......有意义的是命名空间会"升级"语法树(因为类包含在命名空间中)所以你只需要"向上"语法树,直到找到命名空间并将其附加到标识符ClassDeclarationSyntax.
使用模式匹配+递归还有一种优雅的方式:
// method with pattern matching
public static string GetNamespaceFrom(SyntaxNode s) =>
s.Parent switch
{
NamespaceDeclarationSyntax namespaceDeclarationSyntax => namespaceDeclarationSyntax.Name.ToString(),
null => string.Empty, // or whatever you want to do
_ => GetNamespaceFrom(s.Parent)
};
// somewhere call it passing the class declaration syntax:
string ns = GetNamespaceFrom(classDeclarationSyntax);
Run Code Online (Sandbox Code Playgroud)
ITypeSymbol为您的类定义构建一个。
然后获取它的“完整限定名称”
ClassDeclarationSyntax myclass; //your class here
var typeSymbol = context.Compilation.GetSemanticModel(myclass.SyntaxTree).GetDeclaredSymbol(myclass);
typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
//-------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^this
Run Code Online (Sandbox Code Playgroud)
这是我获取命名空间的方法。您必须根据您的情况稍微修改我的代码:
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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5745 次 |
| 最近记录: |