/// <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 SeparatedSyntaxList(SyntaxNodeOrTokenList list) : this() { Validate(list); // calculating counts is very cheap when list interleaves nodes and tokens // so lets just do it here. int allCount = list.Count; _count = (allCount + 1) >> 1; _separatorCount = allCount >> 1; _list = list; }
private static void Validate(SyntaxNodeOrTokenList list) { for (int i = 0; i < list.Count; i++) { var item = list[i]; if ((i & 1) == 0) { Debug.Assert(item.IsNode, "Node missing in separated list."); } else { Debug.Assert(item.IsToken, "Separator token missing in separated list."); } } }
/// <summary> /// Creates a new list with the specified separator token replaced with the new separator. /// </summary> /// <param name="separatorToken">The separator token to be replaced.</param> /// <param name="newSeparator">The new separator token.</param> public SeparatedSyntaxList <TNode> ReplaceSeparator(SyntaxToken separatorToken, SyntaxToken newSeparator) { SyntaxNodeOrTokenList nodesWithSeps = this.GetWithSeparators(); int index = nodesWithSeps.IndexOf(separatorToken); if (index < 0) { throw new ArgumentException("separatorToken"); } if (newSeparator.RawKind != nodesWithSeps[index].RawKind || newSeparator.Language != nodesWithSeps[index].Language) { throw new ArgumentException("newSeparator"); } return(new SeparatedSyntaxList <TNode>(nodesWithSeps.Replace(separatorToken, newSeparator))); }
/// <summary> /// Creates a new list with specified element removed. /// </summary> /// <param name="node">The element to remove.</param> public SeparatedSyntaxList <TNode> Remove(TNode node) { SyntaxNodeOrTokenList nodesWithSeps = this.GetWithSeparators(); int index = nodesWithSeps.IndexOf(node); if (index >= 0 && index <= nodesWithSeps.Count) { nodesWithSeps = nodesWithSeps.RemoveAt(index); // remove separator too if (index < nodesWithSeps.Count && nodesWithSeps[index].IsToken) { nodesWithSeps = nodesWithSeps.RemoveAt(index); } else if (index > 0 && nodesWithSeps[index - 1].IsToken) { nodesWithSeps = nodesWithSeps.RemoveAt(index - 1); } return(new SeparatedSyntaxList <TNode>(nodesWithSeps)); } return(this); }
internal Enumerator(SyntaxNodeOrTokenList list) : this() { _list = list; _index = -1; }