Source text and positions
editPositions in a tree are offsets in its text, counted in UTF-16 code units from 0. The types of this page turn them into lines and columns, and the other way around.
The text of a tree
SourceText is the text a tree was parsed from: tree.GetText() returns it. You can also create one with SourceText.From and pass it to ParseText. It gives the text with Text or ToString(), a part of it with ToString(span), and its lines with Lines and GetLine(position):
var line = SourceText.From("first\nsecond").Lines[1];
var text = line.Text;
Assert.Equal("second", text);
Assert.Equal(1, line.LineNumber);
Assert.Equal(6, line.Start);A TextLine has its zero-based LineNumber, the Start and End offsets of its text, and its Text, without the line break.
Spans
A TextSpan is a range of characters: a Start and a Length, or End, which is exclusive. Create one from a start and a length, or from two bounds:
var span = new TextSpan(start: 5, length: 3);
var sameSpan = TextSpan.FromBounds(5, 8);
Assert.Equal(span, sameSpan);
Assert.Equal(8, span.End);Contains, OverlapsWith, IntersectsWith, Overlap and Intersection compare spans. Every node, token and trivia has a Span and a FullSpan: see Trivia.
Lines and columns
A Location pairs a span with the text it indexes into, so it can give lines and columns. GetLineSpan() returns a LinePositionSpan, whose Start and End are LinePositions, with a zero-based Line and Character:
var text = "one\ntwo\nthree line here";
var location = new Location(new TextSpan(15, 7), SourceText.From(text));
// Lines and columns are zero-based
Assert.Equal("(2,7)-(2,14)", location.ToString());
Assert.Equal(2, location.GetLineSpan().Start.Line);Add one to both numbers to show them to a person, as editors count lines and columns from 1.
A tree gives the location or the line span of any span with GetLocation(span) and GetLineSpan(span). A Location created without its text, such as Location.None, has no lines: its GetLineSpan() returns default.
Text changes
A TextChange replaces a span with a new text. SourceText.WithChanges applies changes to a text, and a tree's WithChanges applies them and parses the result:
var source = SourceText.From("<root/>");
var updated = source.WithChanges([new TextChange(new TextSpan(1, 4), "item")]);
Assert.Equal("<item/>", updated.Text);
var line = source.GetLine(position: 3);
Assert.Equal(0, line.LineNumber);The spans of the changes refer to the original text, whatever their order: the changes are applied from the end of the text backwards. A change that reaches past the end of the text is ignored.
To get the changes between two versions of a tree, see Get the text changes.