- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想一次对 Roslyn 语法树进行多项修改,都围绕同一代码区域
tree = tree.ReplaceNodes(oldNode, newNode).RemoveNode(toRemove);
但是,只有第一次修改成功。似乎第一个更改更改了它周围的所有节点,因此 RemoveNodes
方法不再在生成的树中找到 toRemove
。我真的非常不想重新计算新树中的 toRemove
并使用单个 SyntaxRewriter 执行所有工作(覆盖 DefaultVisit
方法)慢得离谱。
我怎样才能做我想做的事?
最佳答案
在我提供一些替代方案之前,您对 SyntaxRewriter“慢得离谱”的评论有点令人惊讶。当您说“慢”时,您的意思是“要编写很多代码”还是“它的性能非常糟糕”?这是执行多个替换的最快(执行时间明智)方式,并且 ReplaceNodes 和 RemoveNode 都在内部使用重写器。如果您遇到性能问题,请确保在实现 DefaultVisit 时仅在您感兴趣的节点位于调用它的节点下时才访问子类型。简单的技巧是比较跨度并确保传递的节点的跨度与您正在处理的节点相交。
无论如何,SyntaxAnnotations 提供了一种有用的方法来在修改后定位树中的节点。您可以只创建该类型的实例,然后使用 WithAdditionalAnnotations 扩展方法将其附加到节点。您可以使用 GetAnnotatedNodesOrTokens 方法再次定位该节点。
因此,解决您的问题的一种方法是注释您的 toRemove,然后当您调用 ReplaceNodes 时,在同一调用中执行两次替换——一次执行旧节点 -> 新节点替换,然后一次执行 toRemove -> toRemoveWithAnnotation替代品。然后在结果树中找到带注释的节点并调用 RemoveNode。
如果您知道 oldNode 和 toRemove 不是彼此的祖先(即它们位于树的不相关部分),另一种选择是颠倒顺序。获取 toRemove 的父节点(称为 oldNodeParent)并调用 RemoveNode,这意味着您将获得更新的父节点(称为 oldNodeParentRewritten)。然后,调用 ReplaceNodes 进行两次替换:oldNode -> newNode 和 oldNodeParent -> oldNodeParentRewritten。无需注释。
关于c# - 一次对 SyntaxTree 进行多项修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13435168/
我正在 Unity 2019.2.3f1 中开发。我正在尝试编写一个可以 Customize project files created by VSTU 的脚本.如果链接被删除,我已经包含了一个与链接
我正在尝试在解决方案中查找某个类型的所有引用。我的起点是文件内的一个跨度(当前光标位置),例如 110:116。查看 Roslyn 附带的示例,我发现我需要 SymbolFinder.FindRefe
我想一次对 Roslyn 语法树进行多项修改,都围绕同一代码区域 tree = tree.ReplaceNodes(oldNode, newNode).RemoveNode(toRemove); 但是
免责声明 我很确定我遗漏了一些明显的东西,但即使阅读了官方文档,我也不清楚 Roslyn 如何创建语法树。 例子 考虑以下简单代码: using System; using System.Collec
有没有一种简单的方法可以到达定义了特定 TypeSyntax 的文档的 SyntaxTree? 每当 TypeSyntax 为 IdentifierNameSyntax 时,我都可以获得 Identi
我想在给定位置(lineNumber)的情况下获取一行的 SyntaxNode。下面的代码应该是不言自明的,但如有任何问题,请告诉我。 static void Main() {
我写了我的类 MonitorSyntaxRewriter,它继承自 CSharpSyntaxRewriter。通过这个类(class),我改变了我的 SyntaxTree。但是,我怎样才能将这个修改过
我正在寻找将 C# 转换为 XML 并再次反序列化回 C# 的选项。任何人都知道任何现有的解决方案吗?我假设 Roslyn SyntaxTree 不是 Xml 可序列化的。我还假设为语法树制作一个 x
我正在使用 Roslyn 更改代码,但是,在更改后生成了一个新的 SyntaxNode,但我无法找到执行此新代码的方法。我发现的唯一方法是从新的 Root 获取 ToString 并使用新字符串调用
我正在尝试替换 Roslyn 语法树中的节点,这只是为了工作,但有一种烦恼,感觉它不应该是一个问题。 语法树是从脚本生成的,我希望结果也是基于脚本的语法树——但出于某种原因,替换树中的一个节点会创建一
我已经使用 Install-Package Microsoft.CodeAnalysis -Pre 为 Roslyn 安装了 nuget,但我仍然无法获取方法 SyntaxTree.ParseFile
我是一名优秀的程序员,十分优秀!