private static bool EquivalentToInternal(GreenNode node1, GreenNode node2) { if (node1.RawKind != node2.RawKind) { // A single-element list is usually represented as just a single node, // but can be represented as a List node with one child. Move to that // child if necessary. if (node1.IsList && node1.SlotCount == 1) { node1 = node1.GetSlot(0); } if (node2.IsList && node2.SlotCount == 1) { node2 = node2.GetSlot(0); } if (node1.RawKind != node2.RawKind) { return(false); } } if (node1._fullWidth != node2._fullWidth) { return(false); } var n = node1.SlotCount; if (n != node2.SlotCount) { return(false); } for (int i = 0; i < n; i++) { var node1Child = node1.GetSlot(i); var node2Child = node2.GetSlot(i); if (node1Child != null && node2Child != null && !node1Child.IsEquivalentTo(node2Child)) { return(false); } } return(true); }
private static int GetLastNonNullChildIndex(GreenNode node) { int n = node.SlotCount; int lastIndex = n - 1; for (; lastIndex >= 0; lastIndex--) { var child = node.GetSlot(lastIndex); if (child != null) { break; } } return(lastIndex); }
private static int GetFirstNonNullChildIndex(GreenNode node) { int n = node.SlotCount; int firstIndex = 0; for (; firstIndex < n; firstIndex++) { var child = node.GetSlot(firstIndex); if (child != null) { break; } } return(firstIndex); }
/// <summary> /// internal indexer that does not verify index. /// Used when caller has already ensured that index is within bounds. /// </summary> internal static SyntaxNode ItemInternalAsNode(SyntaxNode node, int index) { GreenNode greenChild; GreenNode green = node.Green; int idx = index; int slotIndex = 0; // find a slot that contains the node or its parent list (if node is in a list) // 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 // // at the end of this loop we will have // 1) slot index - slotIdx // 2) if the slot is a list, node index in the list - idx while (true) { greenChild = green.GetSlot(slotIndex); if (greenChild != null) { int currentOccupancy = Occupancy(greenChild); if (idx < currentOccupancy) { break; } idx -= currentOccupancy; } slotIndex++; } // get node that represents this slot SyntaxNode red = node.GetNodeSlot(slotIndex); if (greenChild.IsList && red != null) { // it is a red list of nodes (separated or not), most common case return(red.GetNodeSlot(idx)); } // this is a single node or token return(red); }
internal GreenNode GetLastTerminal() { GreenNode node = this; do { for (int i = node.SlotCount - 1; i >= 0; i--) { var child = node.GetSlot(i); if (child != null) { node = child; break; } } } while (node.slotCount != 0); return(node); }
internal GreenNode GetFirstTerminal() { GreenNode node = this; do { for (int i = 0, n = node.SlotCount; i < n; i++) { var child = node.GetSlot(i); if (child != null) { node = child; break; } } } while (node.slotCount != 0); return(node); }
internal GreenNode GetLastNonmissingTerminal() { GreenNode node = this; do { GreenNode nonmissingChild = null; for (int i = node.SlotCount - 1; i >= 0; i--) { var child = node.GetSlot(i); if (child != null && !child.IsMissing) { nonmissingChild = child; break; } } node = nonmissingChild; }while (node?._slotCount > 0); return(node); }
internal GreenNode GetLastTerminal() { GreenNode node = this; do { GreenNode lastChild = null; for (int i = node.SlotCount - 1; i >= 0; i--) { var child = node.GetSlot(i); if (child != null) { lastChild = child; break; } } node = lastChild; } while (node?._slotCount > 0); return(node); }
internal GreenNode GetFirstTerminal() { GreenNode node = this; do { GreenNode firstChild = null; for (int i = 0, n = node.SlotCount; i < n; i++) { var child = node.GetSlot(i); if (child != null) { firstChild = child; break; } } node = firstChild; } while (node?._slotCount > 0); return(node); }
internal static int CountNodes(GreenNode green) { int n = 0; for (int i = 0, s = green.SlotCount; i < s; i++) { var child = green.GetSlot(i); if (child != null) { if (!child.IsList) { n++; } else { n += child.SlotCount; } } } return(n); }
/// <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> /// 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"); } }
private static GreenNode GetGreenNodeAt(GreenNode node, int i) { Debug.Assert(node.IsList || (i == 0 && !node.IsList)); return(node.IsList ? node.GetSlot(i) : node); }
/// <summary> /// internal indexer that does not verify index. /// Used when caller has already ensured that index is within bounds. /// </summary> internal static SyntaxNodeOrToken ItemInternal(SyntaxNode node, int index) { GreenNode greenChild; GreenNode green = node.Green; int idx = index; int slotIndex = 0; int position = node.Position; // find a slot that contains the node or its parent list (if node is in a list) // 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 // // at the end of this loop we will have // 1) slot index - slotIdx // 2) if the slot is a list, node index in the list - idx // 3) slot position - position while (true) { greenChild = green.GetSlot(slotIndex); if (greenChild != null) { int currentOccupancy = Occupancy(greenChild); if (idx < currentOccupancy) { break; } idx -= currentOccupancy; position += greenChild.FullWidth; } slotIndex++; } // get node that represents this slot SyntaxNode red = node.GetNodeSlot(slotIndex); if (!greenChild.IsList) { // this is a single node or token // if it is a node, we are done // otherwise will have to make a token with current gChild and position if (red != null) { return(red); } } else if (red != null) { // it is a red list of nodes (separated or not), most common case SyntaxNode redChild = red.GetNodeSlot(idx); if (redChild != null) { // this is our node return(redChild); } // must be a separator // update gChild and position and let it be handled as a token greenChild = greenChild.GetSlot(idx); position = red.GetChildPosition(idx); } else { // it is a token from a token list, uncommon case // update gChild and position and let it be handled as a token position += greenChild.GetSlotOffset(idx); greenChild = greenChild.GetSlot(idx); } return(new SyntaxNodeOrToken(node, greenChild, position, 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)); }