收集源代码变更列表,然后将其应用于Roslyn

本文关键字:然后 应用于 Roslyn 列表 源代码 | 更新日期: 2023-09-27 18:02:58

我正在用Roslyn实现不同的源代码转换。(代码上下文将是一个独立的命令行util和而不是一个VS CodeAction)

要做到这一点,最简单的方法是使用CSharpSyntaxRewriter实现,当访问特定节点时,在 上应用更改。然而,这种方法可能会或可能不会产生副作用,导致不稳定的结果。当改变树的时候,我们也改变了语义模型,所以之前得到的语义模型可能会失效。不深入细节,这有点类似于在枚举时更改List而不通知枚举器

(是的,我知道树是不可变的,但这就是重点:当重载方法返回一个替换节点而不是原始节点时,访问者更改它。)

所以我有了这个想法:我们必须在两步中完成转换:第一步收集更改,第二步实际应用更改。

  • 第一次传递显然是CSharpSyntaxRewriter(访问者)实际上并不重写任何只是产生一个更改列表。(也许一些较低的基本访客类会比重写器做得更好,因为实际上在这一阶段不会重写任何东西)
  • 第二个步骤是变更列表应用程序,它应用第一个步骤中收集的变更。

下一个有趣的想法是,第二次传递不必操作树本身:它可以直接操作原始源文本(第一次传递可以构建具有精确源代码位置的更改列表,因为Span信息可用于每个节点和令牌)

很抱歉解释这么长,现在的问题是:

我不想重新发明轮子:是否有任何源代码操作基础设施已经在Roslyn中实现(有一个更改列表,(例如基于span)并应用(…)它在源代码上?

提前致谢

收集源代码变更列表,然后将其应用于Roslyn

完全符合描述:

SourceText类有一个WithChanges(…)方法,它通过应用的更改返回新的SourceText实例。这些更改是以TextChange列表的形式出现的,它基本上是TextSpan的一个薄包装,包含了span本身和替换文本。

感谢任何花时间在这上面的人。