c# - Roslyn:将 using 语句添加到语法树

标签 c# roslyn roslyn-code-analysis

我已经成功创建了一个代码修复程序,如果通用工厂类中缺少工厂方法,它会生成工厂方法。 当我查看修复后的文件时,由于缺少 using 语句,我收到了许多错误。

我已经能够创建一个UsingDirectives 列表,我想将其添加到我的重构文件中。如何将这些用法添加到文件中?

    private async Task<Solution> FixUpFactory(Document document, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken)
        {
...
var factorySyntaxTree = factoryClass.DeclaringSyntaxReferences.Select(x => x.SyntaxTree);
var factoryDocument = document.Project.GetDocument(factorySyntaxTree.FirstOrDefault());
var usingDirectives = FindUsingDirectives(factorySyntaxTree.FirstOrDefault());
var methodUsingDirectives = FindMethodUsingDirectives(createMethods);
var usingDirectivesToAdd = new SyntaxList<UsingDirectiveSyntax>(methodUsingDirectives.Except(usingDirectives).Distinct());
...
//replace 
var factoryTree = await factoryDocument.GetSyntaxTreeAsync();
var compUnitSyntax = factoryTree.GetCompilationUnitRoot();
var newCompUnitSyntax = compUnitSyntax.WithUsings(usingDirectivesToAdd);

var documentRoot = await factoryDocument.GetSyntaxRootAsync().ConfigureAwait(false);
//newRoot comes out the same as the documentRoot
var newRoot= documentRoot.ReplaceNode(compUnitSyntax, newCompUnitSyntax);
var factorySolution = document.Project.Solution.WithDocumentSyntaxRoot(factoryDocument.Id, newRoot);
}

那么,如何让 newRoot 反射(reflect)我想要添加的新 using 指令?

最佳答案

我最终稍微分解了我的代码。 这两种方法都有效:

private SyntaxTree UpdateUsingDirectives(SyntaxTree originalTree, UsingDirectiveSyntax[] newUsings)
{
    var rootNode = originalTree.GetRoot() as CompilationUnitSyntax;
    rootNode = rootNode.AddUsings(newUsings).NormalizeWhitespace();
    return rootNode.SyntaxTree;
}
private SyntaxTree UpdateUsingDirectives(SyntaxTree originalTree, SyntaxList<UsingDirectiveSyntax> newUsings)
{
    var rootNode = originalTree.GetRoot() as CompilationUnitSyntax;
    rootNode = rootNode.WithUsings(newUsings).NormalizeWhitespace();
    return rootNode.SyntaxTree;
}

请注意,第二个替换了 using。

之后,您可以执行以下操作:

var newFactory = UpdateUsingDirectives(factoryTree, newUsings);
var newFactoryRoot = newFactory.GetRoot();

var documentRoot = await factoryDocument.GetSyntaxRootAsync().ConfigureAwait(false);

var newRoot= documentRoot.ReplaceNode(document.getRoot(), newFactoryRoot);
var factorySolution = document.Project.Solution.WithDocumentSyntaxRoot(factoryDocument.Id, newRoot);

关于c# - Roslyn:将 using 语句添加到语法树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63627042/

相关文章:

c# - 通过 OpenXML SDK 插入时如何保持当前样式?

c# - 读取时的 NHibernate 事务

c# - Roslyn - CSharpCompilation 到 CSharpCompilation 引用

c# - Roslyn 分析器未检测 While 表达式

c# - 执行代码修复后如何将插入符号移动到特定位置

c# - 如何在 ViewModel 中设置从模型列表中获取和设置值的属性?

c# - 如何将带有 Unions 的 SQL 查询转换为 LINQ?

c# - 为什么我的一些类名在新的 VS 2015 编译器中返回为 "<>c"?

roslyn - 来自 Roslyn 的扩展方法信息

c# - 使用 Roslyn 查找所有不继承 C# 类并更改为从基础对象继承(类 Java)