如何使用Roslyn修改源代码?我无法创建SyntaxNode并在SyntaxTree中插入。 或者使用替代品(Antrl,NRefactory或其他)?
答案 0 :(得分:5)
svick如何回答您 - 您无法修改现有语法树。 Sytnax树是不可变的,但您可以基于现有树创建另一个树。为此,您必须创建节点并替换现有节点。下面你可以举一个简单的例子(改变使用):
var name = Syntax.QualifiedName(Syntax.IdentifierName("System"), Syntax.IdentifierName("Collections"));
name = Syntax.QualifiedName(name, Syntax.IdentifierName("Generic"));
SyntaxTree tree = SyntaxTree.ParseText(
@"using System;
using System.Collections;
using System.Linq;
using System.Text;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(""Hello, World!"");
}
}
}");
var root = (CompilationUnitSyntax)tree.GetRoot();
var oldUsing = root.Usings[1];
var newUsing = oldUsing.WithName(name);
root = root.ReplaceNode(oldUsing, newUsing);
Console.WriteLine(root.GetText());
如果是不可变的,请参阅入门文档中的注释:
Roslyn API的基本原则是不变性。由于不可变数据结构在创建后无法更改,因此可以由多个使用者同时安全地共享和分析它们,而不会有一种工具以不可预测的方式影响另一个工具。不需要锁或其他并发措施。这适用于Roslyn API中的语法树,编译,符号,语义模型和所有其他数据结构。而不是修改,新对象是根据与旧对象的指定差异创建的。您将此概念应用于语法树以创建树转换!
答案 1 :(得分:4)
您可以使用SyntaxNode
创建SyntaxFactory
。
您无法修改现有语法树(因为它是不可变的),但您可以创建一个包含您的节点的新语法树。查看With-
和Add-
方法,ReplaceNode
和CSharpSyntaxVisitor
。很难说哪一种最符合您的需求。