예제 #1
0
        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)
            });
        }
예제 #2
0
        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);
        }