예제 #1
0
        /// <summary>
        /// Creates a new list with the specified nodes inserted at the index.
        /// </summary>
        /// <param name="index">The index to insert at.</param>
        /// <param name="nodes">The nodes to insert.</param>
        public SeparatedSyntaxList <TNode> InsertRange(int index, IEnumerable <TNode> nodes)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException(nameof(nodes));
            }

            if (index < 0 || index > this.Count)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            SyntaxNodeOrTokenList nodesWithSeps = this.GetWithSeparators();
            int insertionIndex = index < this.Count ? nodesWithSeps.IndexOf(this[index]) : nodesWithSeps.Count;

            // determine how to deal with separators (commas)
            if (insertionIndex > 0 && insertionIndex < nodesWithSeps.Count)
            {
                SyntaxNodeOrToken previous = nodesWithSeps[insertionIndex - 1];
                if (previous.IsToken && !KeepSeparatorWithPreviousNode(previous.AsToken()))
                {
                    // pull back so item in inserted before separator
                    insertionIndex--;
                }
            }

            List <SyntaxNodeOrToken> nodesToInsertWithSeparators = new List <SyntaxNodeOrToken>();

            foreach (TNode item in nodes)
            {
                if (item != null)
                {
                    // if item before insertion point is a node, add a separator
                    if (nodesToInsertWithSeparators.Count > 0 || (insertionIndex > 0 && nodesWithSeps[insertionIndex - 1].IsNode))
                    {
                        nodesToInsertWithSeparators.Add(item.Green.CreateSeparator <TNode>(item));
                    }

                    nodesToInsertWithSeparators.Add(item);
                }
            }

            // if item after last inserted node is a node, add separator
            if (insertionIndex < nodesWithSeps.Count && nodesWithSeps[insertionIndex].IsNode)
            {
                SyntaxNode node = nodesWithSeps[insertionIndex].AsNode();
                nodesToInsertWithSeparators.Add(node.Green.CreateSeparator <TNode>(node)); // separator
            }

            return(new SeparatedSyntaxList <TNode>(nodesWithSeps.InsertRange(insertionIndex, nodesToInsertWithSeparators)));
        }
예제 #2
0
        internal SyntaxToken GetLastToken(SyntaxNode current, Func <SyntaxToken, bool> predicate, Func <SyntaxTrivia, bool> stepInto)
        {
            Stack <ChildSyntaxList.Reversed.Enumerator> stack = s_childReversedEnumeratorStackPool.Allocate();

            try
            {
                stack.Push(current.ChildNodesAndTokens().Reverse().GetEnumerator());

                while (stack.Count > 0)
                {
                    ChildSyntaxList.Reversed.Enumerator en = stack.Pop();

                    if (en.MoveNext())
                    {
                        SyntaxNodeOrToken child = en.Current;

                        if (child.IsToken)
                        {
                            SyntaxToken token = GetLastToken(child.AsToken(), predicate, stepInto);
                            if (token.RawKind != None)
                            {
                                return(token);
                            }
                        }

                        // push this enumerator back, not done yet
                        stack.Push(en);

                        if (child.IsNode)
                        {
                            stack.Push(child.AsNode().ChildNodesAndTokens().Reverse().GetEnumerator());
                        }
                    }
                }

                return(default(SyntaxToken));
            }
            finally
            {
                stack.Clear();
                s_childReversedEnumeratorStackPool.Free(stack);
            }
        }