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。 :-) –