5

比方说,我有两个SyntaxTree小号一个
其中已经将更改应用到一个生产。罗斯林SyntaxTree DIFF

我想获得以下信息:

  • SyntaxNodes已经从一个去除产生
  • SyntaxNodes已添加到一个到&令牌&令牌生产B

这是否有API?
如果没有,如何有效地计算?

此信息必须可用于Roslyn,
因为在树之间共享不变的GreenNode

我能想到的一个解决方案是使用SyntaxTree.GetChangedSpans()
然后查找相交的标记。
但是,这感觉像一个黑客,我不知道它是否总是准确。
小文本的变化可能对一个SyntaxTree有很大的影响:
(例如用+在表达式替换*可能会改变其顺序/优先级)

+0

如果你真的有两个AST并访问它们,这看起来很简单。列出A的节点,并且B.节点(A)的节点 - 绿色是那些已经被删除的节点。节点(B) - 绿色是已添加的那些节点。所有你需要做的是做一个树行走,建立一些集,并设置减法。我不是Rosyln的用户,但是这很难吗? –

+0

由于技术原因,我认为不可能有效地做到这一点。 (由于节点的“unstable”'GetHashCode()'实现,所以不能使用'HashSets')。平等工作:'SyntaxNode.IsEquivalentTo()'。不过,我想避免将** A **中的每个节点与** B ** bcs O(n^2)中的每个节点进行比较。 – 3dGrabber

+0

因此罗斯林令人失望。 (我建立了一个像Rosyln那样的系统,我建议的方法可以很好地工作;事实上,我们有一个“聪明的区别”,它以更加精确的方式比较树木的更加宏观的比较。生物)。 –

回答

1

我们internally have a differ生活在编译器层,因此使用绿色节点,我们只是没有公开它作为一个API。实际上,这是我们用来驱动GetChangedSpans的。我们故意没有直接暴露绿色节点,因为这是一个实现细节。

没有具体原因,API不能公开。我认为,当这个问题出现时,我们担心人们是如何规定行为是什么的,或者可以从差异中期望什么是最低限度的“善”。那,我们没有一个激励的方案来确保我们的工作是有用的。

+0

这回答了第一个问题:没有公共API。 'SyntaxDiffer'可能会公开吗? (拉请求?)。或者我们可以使用'SyntaxTree.GetChangedSpans'或'SyntaxTree.GetChanges'来解决它吗? – 3dGrabber

+0

另外:我应该在哪里询问有关Roslyn API的问题? SO,GitHub,MSDN? (例如“SyntaxTree.GetChangedSpans'和'SyntaxTree.GetChanges'之间有什么区别”) – 3dGrabber

+0

您可以完全提交拉请求。我首先建议你在GitHub上打开一个bug,这样人们就知道存在一个问题,并且有一些表示你实际上在做这项工作。这也会让人们在公开发表任何他们知道的关于你想要解决的问题的同时参与。也许这个代码实际上是一切都是bug,这就是为什么我们没有公开它。只是因为我们必须维护一个受支持的,经过深思熟虑的,格式良好的API,所以“驱使”拉请求只是将访问修饰符更改为public。 :-) –