public static Range GetRange(this CommonTree node, ITokenStream tokenStream, IReadOnlyScriptText scriptText) { if (node is CommonErrorNode errorNode) { return(new Range() { Start = scriptText.PositionAt(((CommonToken)tokenStream.Get(errorNode.start.TokenIndex)).StartIndex), End = scriptText.PositionAt(((CommonToken)tokenStream.Get(errorNode.stop.TokenIndex)).StopIndex + 1) }); } if (node.TokenStartIndex == -1 || node.TokenStopIndex == -1) { return(Range.Empty); } return(new Range() { Start = scriptText.PositionAt(((CommonToken)tokenStream.Get(node.TokenStartIndex)).StartIndex), End = scriptText.PositionAt(((CommonToken)tokenStream.Get(node.TokenStopIndex)).StopIndex + 1) }); }
private T CreateNode <T>(SyntaxNode parent, Scanner <CommonTree> parentChildren, Action <T, Scanner <CommonTree> > bindAction = null, bool ignoreExceptions = false) where T : SyntaxNode { var compilerNode = parentChildren.Current; var range = compilerNode.GetRange(_tokenStream, _text); if (compilerNode is CommonErrorNode errorNode) { _diagnostics.Add(errorNode.trappedException.ToDiagnostic(range)); } var text = _text.GetTextInRange(range).TrimEnd(); var node = Activator.CreateInstance <T>(); node.Parent = parent; node.Script = _scriptNode; node.CompilerNode = compilerNode; node.Text = text; node.Range = new Range() { Start = range.Start, End = _text.PositionAt(_text.OffsetAt(range.Start) + text.Length) }; try { bindAction?.Invoke(node, new Scanner <CommonTree>(compilerNode.GetChildren())); } catch (Exception e) { if (!ignoreExceptions) { _diagnostics.Add(new Diagnostic( DiagnosticLevel.Error, e.Message, Range.IsEmpty(node.Range) ? parent.Range : node.Range, e)); } } if (ShouldContractNodeEnd(node)) { var lastChild = node.Children.LastOrDefault(c => c.Range != Range.Empty); node.Range = new Range() { Start = node.Range.Start, End = lastChild != null && lastChild.Range.End < node.Range.End ? lastChild.Range.End : node.Range.End, }; } // Expand parent to contain this child. if (node.Range != Range.Empty) { parent.Range = new Range() { Start = parent.Range.Start > node.Range.Start ? node.Range.Start : parent.Range.Start, End = parent.Range.End < node.Range.End ? node.Range.End : parent.Range.End, }; } var indexInParent = parent.Children.IndexOf(node); if (indexInParent != 0) { var previousPeer = parent.Children[indexInParent - 1]; var leadingRange = new Range() { Start = previousPeer.Range.End, End = node.Range.Start }; node.LeadingText = _text.GetTextInRange(leadingRange); } return(node); }