/// <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))); }
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); } }