/// <summary> /// Gets the token at the specified index. /// </summary> /// <param name="index">The zero-based index of the token to get.</param> /// <returns>The token at the specified index.</returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="index" /> is less than 0.-or-<paramref name="index" /> is equal to or greater than <see cref="SyntaxTokenList.Count" />. </exception> public SyntaxToken this[int index] { get { if (node != null) { if (node.IsList) { if (unchecked ((uint)index < (uint)node.SlotCount)) { return(new SyntaxToken(this.parent, node.GetSlot(index), this.position + node.GetSlotOffset(index), this.index + index)); } } else if (index == 0) { return(new SyntaxToken(this.parent, this.node, this.position, this.index)); } } throw new ArgumentOutOfRangeException("index"); } }
/// <summary> /// Gets the trivia at the specified index. /// </summary> /// <param name="index">The zero-based index of the trivia to get.</param> /// <returns>The token at the specified index.</returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="index" /> is less than 0.-or-<paramref name="index" /> is equal to or greater than <see cref="SyntaxTriviaList.Count" />. </exception> public SyntaxTrivia this[int index] { get { if (_node != null) { if (_node.IsList) { if (unchecked ((uint)index < (uint)_node.SlotCount)) { return(new SyntaxTrivia(_token, _node.GetSlot(index), _position + _node.GetSlotOffset(index), _index + index)); } } else if (index == 0) { return(new SyntaxTrivia(_token, _node, _position, _index)); } } throw new ArgumentOutOfRangeException("index"); } }
/// <summary> /// Locate the node or token that is a child of the given <see cref="SyntaxNode"/> and contains the given position. /// </summary> /// <param name="node">The <see cref="SyntaxNode"/> to search.</param> /// <param name="targetPosition">The position.</param> /// <returns>The node or token that spans the given position.</returns> /// <remarks> /// Assumes that <paramref name="targetPosition"/> is within the span of <paramref name="node"/>. /// </remarks> internal static SyntaxNodeOrToken ChildThatContainsPosition(SyntaxNode node, int targetPosition) { // The targetPosition must already be within this node Debug.Assert(node.FullSpan.Contains(targetPosition)); GreenNode green = node.Green; int position = node.Position; int index = 0; Debug.Assert(!green.IsList); // Find the green node that spans the target position. // We will be skipping whole slots here so we will not loop for long // The max possible number of slots is 11 (TypeDeclarationSyntax) // and typically much less than that int slot; for (slot = 0; ; slot++) { GreenNode greenChild = green.GetSlot(slot); if (greenChild != null) { int endPosition = position + greenChild.FullWidth; if (targetPosition < endPosition) { // Descend into the child element green = greenChild; break; } position = endPosition; index += Occupancy(greenChild); } } // Realize the red node (if any) SyntaxNode red = node.GetNodeSlot(slot); if (!green.IsList) { // This is a single node or token. // If it is a node, we are done. if (red != null) { return(red); } // Otherwise will have to make a token with current green and position } else { slot = green.FindSlotIndexContainingOffset(targetPosition - position); // Realize the red node (if any) if (red != null) { // It is a red list of nodes (separated or not) red = red.GetNodeSlot(slot); if (red != null) { return(red); } // Must be a separator } // Otherwise we have a token. position += green.GetSlotOffset(slot); green = green.GetSlot(slot); // Since we can't have "lists of lists", the Occupancy calculation for // child elements in a list is simple. index += slot; } // Make a token with current child and position. return(new SyntaxNodeOrToken(node, green, position, index)); }