コード例 #1
0
        private bool FindCloseChar(SnapshotPoint start, string kind, out SnapshotPoint end)
        {
            ParseTree.Builder.Node root = ParseTree.Tree.Root();
            int  startPos  = start.Position;
            int  endPos    = startPos;
            bool haveFound = false;

            void Traverse(ParseTree.Builder.Node node)
            {
                if (node.children == null)
                {
                    return;
                }

                if (node.name == kind && node.begin == startPos && node.children.Exists(x => x.name == "']'" || x.name == "'}'" || x.name == "')'"))
                {
                    endPos    = node.end - 1;
                    haveFound = true;
                }

                foreach (var child in node.children)
                {
                    if (!haveFound && child.begin <= startPos && child.end > startPos)
                    {
                        Traverse(child);
                    }
                }
            }

            Traverse(root);

            end = new SnapshotPoint(start.Snapshot, endPos);
            return(haveFound);
        }
コード例 #2
0
        private bool FindOpenChar(SnapshotPoint end, string kind, out SnapshotPoint start)
        {
            ParseTree.Builder.Node root = ParseTree.Tree.Root();
            int  endPos    = end.Position;
            int  startPos  = endPos;
            bool haveFound = false;

            void Traverse(ParseTree.Builder.Node node)
            {
                if (node.children == null)
                {
                    return;
                }

                if (node.name == kind && node.end - 1 == endPos)
                {
                    startPos  = node.begin;
                    haveFound = true;
                }

                foreach (var child in node.children)
                {
                    if (!haveFound)
                    {
                        Traverse(child);
                    }
                }
            }

            Traverse(root);

            start = new SnapshotPoint(end.Snapshot, startPos);
            return(haveFound);
        }
コード例 #3
0
 public static OriginAndTree FromNode(ParseTree.Builder.Node node, string input, string file)
 {
     return(new OriginAndTree {
         File = file,
         Input = input,
         Root = node
     });
 }
コード例 #4
0
        public static string Text(ParseTree.Builder.Node node, string source)
        {
            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }
            if (string.IsNullOrEmpty(source))
            {
                throw new ArgumentException($"'{nameof(source)}' cannot be null or empty.", nameof(source));
            }

            return(source.Substring(node.begin, node.end - node.begin));
        }
コード例 #5
0
        public static IEnumerable <ParseTree.Builder.Node> Flatten(ParseTree.Builder.Node node)
        {
            IEnumerable <ParseTree.Builder.Node> empty = Array.Empty <ParseTree.Builder.Node>();

            if (node is null)
            {
                return(empty);
            }

            var payload = empty.Append(node);

            return
                (node.children is object
                 ?payload.Concat(node.children.SelectMany(a => Flatten(a)))
                     : payload);
        }
コード例 #6
0
        private bool findDefinition()
        {
            ParseTree.Builder.Node root = ParseTree.Tree.Root();
            bool definitionFound        = false;

            void Traverse(Builder.Node node)
            {
                if (node.children == null)
                {
                    return;
                }

                if ((node.name == "Code" || node.name == "Object" || node.name == "List") && node.end < selectionEnd)
                {
                    return;
                }

                if (node.name == "Label")
                {
                    Builder.Node child = node.children[0];
                    currName = TextView.TextBuffer.CurrentSnapshot.GetText(child.begin, child.end - child.begin);
                    if (currName == selectedName)
                    {
                        definitionBegin = child.begin;
                        definitionEnd   = child.end;
                        definitionFound = true;
                    }
                }

                foreach (var child in node.children)
                {
                    if (child.begin < selectionEnd)
                    {
                        Traverse(child);
                    }
                }
            }

            Traverse(root);

            return(definitionFound);
        }
コード例 #7
0
        private bool findTheName()
        {
            ParseTree.Builder.Node root = ParseTree.Tree.Root();

            int  caretPosition = TextView.Caret.Position.BufferPosition.Position;
            bool foundName     = false;

            void Traverse(Builder.Node node)
            {
                if (node.children == null)
                {
                    if (node.name == "Name")
                    {
                        selectedName = TextView.TextBuffer.CurrentSnapshot.GetText(node.begin, node.end - node.begin);
                        selectionEnd = node.end;
                        foundName    = true;
                    }
                    else if (node.name == "NameWrite" || node.name == "NameRead")
                    {
                        selectedName = TextView.TextBuffer.CurrentSnapshot.GetText(node.begin + 1, node.end - node.begin - 1);
                        selectionEnd = node.end;
                        foundName    = true;
                    }

                    return;
                }

                foreach (var child in node.children)
                {
                    if (child.begin <= caretPosition && child.end >= caretPosition)
                    {
                        Traverse(child);
                    }
                }
            }

            Traverse(root);

            return(foundName);
        }
コード例 #8
0
        private void ReParse()
        {
            ParseTree.Builder.Node root        = ParseTree.Tree.Root();
            ITextSnapshot          newSnapshot = buffer.CurrentSnapshot;
            List <Region>          newRegions  = new List <Region>();
            Stack <char>           brackets    = new Stack <char>();
            Stack <int>            offsets     = new Stack <int>();
            int level = 0;

            //string text = newSnapshot.GetText();

            void Traverse(ParseTree.Builder.Node node)
            {
                if (node.name == "'['" || node.name == "'{'" || node.name == "'('")
                {
                    brackets.Push(node.name[1]);
                    offsets.Push(node.begin);
                    ++level;
                }

                if (brackets.Count != 0 && node.name[1] == bracePairs[brackets.Peek()])
                {
                    int beginLine = newSnapshot.GetLineFromPosition(offsets.Peek()).LineNumber;
                    int endLine   = newSnapshot.GetLineFromPosition(node.begin).LineNumber;
                    if (beginLine != endLine)
                    {
                        if (newRegions.Count != 0 && newRegions.Last().StartOffset == offsets.Peek() + 1 && newRegions.Last().EndOffset == node.begin - 1)
                        {
                            newRegions.Last().Level       = level;
                            newRegions.Last().StartLine   = beginLine;
                            newRegions.Last().EndLine     = endLine;
                            newRegions.Last().StartOffset = offsets.Peek();
                            newRegions.Last().EndOffset   = node.begin;
                            newRegions.Last().Type        = brackets.Peek();
                        }
                        else
                        {
                            newRegions.Add(new Region()
                            {
                                Level       = level,
                                StartLine   = beginLine,
                                EndLine     = endLine,
                                StartOffset = offsets.Peek(),
                                EndOffset   = node.begin,
                                Type        = brackets.Peek()
                            });
                        }
                    }

                    --level;
                    offsets.Pop();
                    brackets.Pop();
                }

                if (node.children == null)
                {
                    return;
                }

                foreach (var child in node.children)
                {
                    Traverse(child);
                }
            }

            Traverse(root);

            List <Span> oldSpans = new List <Span>(this.regions.Select(r => AsSnapshotSpan(r, snapshot)
                                                                       .TranslateTo(newSnapshot, SpanTrackingMode.EdgeExclusive).Span));
            List <Span> newSpans = new List <Span>(newRegions.Select(r => AsSnapshotSpan(r, newSnapshot).Span));

            NormalizedSpanCollection oldSpanCollection = new NormalizedSpanCollection(oldSpans);
            NormalizedSpanCollection newSpanCollection = new NormalizedSpanCollection(newSpans);

            NormalizedSpanCollection removed = NormalizedSpanCollection.Difference(oldSpanCollection, newSpanCollection);

            int changeStart = int.MaxValue;
            int changeEnd   = -1;

            if (removed.Count > 0)
            {
                changeStart = removed[0].Start;
                changeEnd   = removed[removed.Count - 1].End;
            }

            if (newSpans.Count > 0)
            {
                changeStart = Math.Min(changeStart, newSpans[0].Start);
                changeEnd   = Math.Max(changeEnd, newSpans[newSpans.Count - 1].End);
            }

            snapshot = newSnapshot;
            regions  = newRegions;

            if (changeStart <= changeEnd)
            {
                TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(new SnapshotSpan(snapshot, Span.FromBounds(changeStart, changeEnd))));
            }
        }
コード例 #9
0
 public static IEnumerable <ParseTree.Builder.Node> Labels(ParseTree.Builder.Node node) =>
 Flatten(node).Where(a => a.IsLabel());