Пример #1
0
        public void GetElementsEnclosingRangeTest()
        {
            AstRoot ast = RParser.Parse(new TextStream(" x <- a123+b"));

            IAstNode     startNode, endNode;
            PositionType startPositionType, endPositionType;

            ast.GetElementsEnclosingRange(2, 5, out startNode, out startPositionType, out endNode, out endPositionType);

            startNode.Should().BeAssignableTo <IOperator>();
            endNode.Should().BeOfType <Variable>();

            startPositionType.Should().Be(PositionType.Node);
            endPositionType.Should().Be(PositionType.Token);

            ((Variable)endNode).Name.Should().Be("a123");
        }
Пример #2
0
        /// <summary>
        /// Processes a single text change incrementally. Enqueues resulting
        /// tree changes in the supplied queue. Does not modify the tree.
        /// Changes are to be sent to the main thread and applied from there.
        /// Caller is responsible for the tree read lock acquisition.
        /// </summary>
        /// <param name="start">Start position of the change</param>
        /// <param name="oldLength">Length of the original text (0 if insertion)</param>
        /// <param name="newLength">Length of the new text (0 if deletion)</param>
        /// <param name="oldSnapshot">Text snapshot before the change</param>
        /// <param name="newSnapshot">Text snapshot after the change</param>
        /// <param name="treeChanges">Collection of tree changes to apply
        /// from the main thread</param>
        public void ProcessChange(TextChange textChange, EditorTreeChangeCollection treeChanges)
        {
            IAstNode     startNode = null, endNode = null;
            PositionType startPositionType = PositionType.Undefined;
            PositionType endPositionType   = PositionType.Undefined;
            IAstNode     commonParent      = null;

            int start     = textChange.OldRange.Start;
            int oldLength = textChange.OldRange.Length;
            int newLength = textChange.NewRange.Length;
            int offset    = newLength - oldLength;

            ITextProvider oldSnapshot = textChange.OldTextProvider;
            ITextProvider newSnapshot = textChange.NewTextProvider;

            // Find position type and the enclosing element node. Note that element
            // positions have been adjusted already (it happens immediately in OnTextChange)
            // so we should be looking at the new range even that tree hasn't
            // been fully updated yet. For example,if we delete a node, subsequent
            // elements were already shifted up and damaged nodes have been removed
            // so current node positions reflect text buffer state after the change.

            _astRoot.GetElementsEnclosingRange(start, newLength, out startNode,
                                               out startPositionType, out endNode, out endPositionType);

            if (startNode is AstRoot)
            {
                commonParent = _astRoot;
            }
            else if (startNode == endNode)
            {
                if (startPositionType == PositionType.Token)
                {
                    // Change in comment or string content.
                    commonParent = OnTokenNodeChange(startNode as TokenNode, start, oldLength, newLength);
                }
            }
            else
            {
                //if (commonParent == null)
                //{
                //    // Find parent that still has well formed curly braces.
                //    commonParent = FindWellFormedOuterScope(startNode);
                //}

                if (commonParent == null)
                {
                    commonParent = _astRoot;
                }
            }

            if (IsCancellationRequested())
            {
                return;
            }

            if (!(commonParent is AstRoot))
            {
                Debug.Assert(commonParent is IScope);
                AstRoot subTree = RParser.Parse(newSnapshot, commonParent);
                return;
            }

            AstRoot newTree = RParser.Parse(newSnapshot);

            treeChanges.ChangeQueue.Enqueue(new EditorTreeChange_NewTree(newTree));
        }