我正在编写一个类生成器Microsoft.CodeAnalysis,它使用一个现有类(即ITypeSymbol实例)作为输入,并应该生成一个NamespaceDeclarationSyntax包含的新类ClassDeclarationSyntax。本质上,生成的类是源类的外观。就是说,在生成的代码中需要相同的usings集和相同的namespace名称,以使生成的Facade类正确编译。
我正在使用自定义CSharpSyntaxRewriter后代来处理源代码。从该VisitClassDeclaration方法调用外观生成逻辑。我SemanticModel.GetDeclaredSymbol用来检索对应的ITypeSymbol。
为了构建所有适用的usings的列表,并构建完全限定的名称空间名称,我想执行以下操作:
// collect usings and construct namespace name
SyntaxList<UsingDirectiveSyntax> allUsings = SyntaxFactory.List<UsingDirectiveSyntax>();
var nmspace = ClassSymbol.ContainingNamespace;
string namespaceName = null;
while (nmspace != null)
{
if (!nmspace.IsGlobalNamespace)
{
if (namespaceName == null)
namespaceName = nmspace.Name;
else
namespaceName = nmspace.Name + "." + namespaceName;
}
// here nmspace.DeclaringSyntaxReferences contains all occurrences in the given assembly
var syntax = nmspace.DeclaringSyntaxReferences.First().GetSyntax();
if (syntax is NamespaceDeclarationSyntax)
allUsings = allUsings.AddRange(((NamespaceDeclarationSyntax) syntax).Usings);
else if (syntax is CompilationUnitSyntax)
allUsings = allUsings.AddRange(((CompilationUnitSyntax) syntax).Usings);
nmspace = nmspace.ContainingNamespace;
}
问题是(1)我看不到一种简单的方法来将语法树从给定遍历SyntaxNode到根,以及(2)甚至如何检索一个精确地NamespaceDeclarationSyntax包围给定的ClassDeclarationSyntax。
最后,我想构建一个新的NamespaceDeclarationSyntax像这样:
return SyntaxFactory.NamespaceDeclaration(
SyntaxFactory.ParseName(namespaceName),
SyntaxFactory.List<ExternAliasDirectiveSyntax>(),
allUsings,
SyntaxFactory.List(new[] {(MemberDeclarationSyntax) generatedClass}));
问题:有了给定的条件后SyntaxNode,如何遍历树回到CompilationUnitSyntax根节点?
暮色呼如
相关分类