Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roslyn SyntaxTree Diff

Let's say I have two SyntaxTrees A and B,
where B has been produced by applying changes to A.

I would like to get the following information:

  • SyntaxNodes & Tokens that have been removed from A to produce B
  • SyntaxNodes & Tokens that have been added to A to produce B

Is there an API for this?
If not, how can this be efficiently computed?

This information must be available to Roslyn,
since unchanged GreenNodes are shared between the trees.

One solution I can think of is to use SyntaxTree.GetChangedSpans()
and then lookup the intersecting tokens.
However that feels like a hack and I'm not sure if it is always accurate.
A small text change might have a large impact on a SyntaxTree:
(e.g. replacing * with + in an expression might change its order/precedence)

like image 842
3dGrabber Avatar asked Jan 22 '16 10:01

3dGrabber


1 Answers

We internally have a differ that lives in the compiler layer and thus uses green nodes, we just haven't exposed it as an API. This is what we use to drive GetChangedSpans, actually. We intentionally didn't expose green nodes directly because that's an implementation detail.

There's no specific reason that API couldn't be public. I think when this one came around we were worried about how one actually specs what the behavior is, or what's a minimal "goodness" you can expect from the diff. That, and we didn't have a motivating scenario to actually make sure our work was useful.

like image 173
Jason Malinowski Avatar answered Sep 20 '22 16:09

Jason Malinowski