/// <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");
            }
        }
Exemple #2
0
        /// <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");
            }
        }
Exemple #3
0
        /// <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));
        }