protected void AdjustFlagsAndWidth(GreenNode node) { Debug.Assert(node != null, "PERF: caller must ensure that node!=null, we do not want to re-check that here."); this.flags |= (node.flags & NodeFlags.InheritMask); _fullWidth += node._fullWidth; }
/// <summary> /// Used by structured trivia which has "parent == null", and therefore must know its /// SyntaxTree explicitly when created. /// </summary> internal SyntaxNode(GreenNode green, int position, SyntaxTree syntaxTree) : this(green, null, position) { this._syntaxTree = syntaxTree; }
private static GreenNode GetGreenNodeAt(GreenNode node, int i) { Debug.Assert(node.IsList || (i == 0 && !node.IsList)); return(node.IsList ? node.GetSlot(i) : node); }
public virtual GreenNode WithTrailingTrivia(GreenNode trivia) { return(this); }
internal bool IsCacheEquivalent(int kind, NodeFlags flags, GreenNode child1, GreenNode child2, GreenNode child3) { Debug.Assert(this.IsCacheable); return(this.RawKind == kind && this.flags == flags && this.GetSlot(0) == child1 && this.GetSlot(1) == child2 && this.GetSlot(2) == child3); }
internal SyntaxToken(GreenNode token) : this() { Debug.Assert(token == null || token.IsToken, "token must be a token"); Node = token; }
private static int Occupancy(GreenNode green) { return(green.IsList ? green.SlotCount : 1); }
/// <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)); var green = node.Green; var position = node.Position; var 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) { var 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) var 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)); }
/// <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)); }