我想在VS2013中的C#(.NET 4.5)脚本中进行简单的代码替换。每个@GetIt
调用都应该重写,以便将其封装在lambda函数中:
new MyClass(@GetInt("a") * @GetInt("b"));
成为
new MyClass( x => (x.GetInt("a") * x.GetInt("b")) )
我安装了Roslyn的CodeAnalysis来解析脚本。我使用以下调用获取具有@GetInt
标识符的所有令牌:
var getters = CSharpSyntaxTree.ParseText("new MyClass(@GetInt("a") * @GetInt("b"));")
.GetRoot().DescendantTokens().OfType<SyntaxToken>()
.Where(x => x.Text.Equals("@GetInt"));
对于@GetInt
作为MyClass
构造函数的简单参数,它工作正常,并且使用getters[i].Parent.Parent.Parent.Parent
我正确地到达了构造函数的MethodDeclarationSyntax
节点。
但是,像上面的示例中那样添加乘法,第二个@GetInt
的标记声明* GetInt("b")
作为其父代(但是它已经是MethodDeclarationSyntax
,而不是参数节点)并遍历回其父代导致CompilationUnitSyntax
成为根!
这样,我就没有第二个@GetInt
在语法树中的位置的信息。因此,如果缺少缺少的信息,将无法进行替换。
我已经检查过这种情况,没有使用前缀@
,但是结果是相同的。有人可以告诉我我做错了什么吗?
SOLUTION:在NuGet包中禁用脚本的代码分析之前,我必须使用一种解决方法。首先,我将string script = "..."
并装饰为
var decoratedScript = "class MYCLASS { void METHOD() {\n" + script + "\n} }";
@GetInt
的重写完成后,我删除了添加的装饰。
默认情况下,ParseText()
希望您传递典型的C#文档。 (包括使用语句,名称空间,类型等的内容。)