public Cursor MoveToFirstChild() { Debug.Assert(this.CurrentNodeOrToken.IsNode); // Just try to get the first node directly. This is faster than getting the list of // child nodes and tokens (which forces all children to be enumerated for the sake // of counting. It should always be safe to index the 0th element of a node. But // just to make sure that this is not a problem, we verify that the slot count of the // node is greater than 0. var node = CurrentNodeOrToken.AsNode(); // Interpolated strings cannot be scanned or parsed incrementally. Instead they must be // turned into and then reparsed from the single InterpolatedStringToken. We therefore // do not break interpolated string nodes down into their constituent tokens, but // instead replace the whole parsed interpolated string expression with its pre-parsed // interpolated string token. if (node.Kind() == SyntaxKind.InterpolatedStringExpression) { var greenToken = Lexer.RescanInterpolatedString( (InterpolatedStringExpressionSyntax)node.Green ); var redToken = new CodeAnalysis.SyntaxToken( node.Parent, greenToken, node.Position, _indexInParent ); return(new Cursor(redToken, _indexInParent)); } if (node.SlotCount > 0) { var child = Microsoft.CodeAnalysis.ChildSyntaxList.ItemInternal(node, 0); if (IsNonZeroWidthOrIsEndOfFile(child)) { return(new Cursor(child, 0)); } } // Fallback to enumerating all children. int index = 0; foreach (var child in this.CurrentNodeOrToken.ChildNodesAndTokens()) { if (IsNonZeroWidthOrIsEndOfFile(child)) { return(new Cursor(child, index)); } index++; } return(new Cursor()); }
public Cursor MoveToFirstChild() { Debug.Assert(this.CurrentNodeOrToken.IsNode); // Just try to get the first node directly. This is faster than getting the list of // child nodes and tokens (which forces all children to be enumerated for the sake // of counting. It should always be safe to index the 0th element of a node. But // just to make sure that this is not a problem, we verify that the slot count of the // node is greater than 0. var node = CurrentNodeOrToken.AsNode(); // Interpolated strings cannot be scanned or parsed incrementally. Instead they must be // turned into and then reparsed from the single InterpolatedStringToken. We therefore // do not break interpolated string nodes down into their constituent tokens, but // instead replace the whole parsed interpolated string expression with its pre-parsed // interpolated string token. if (node.Kind() == SyntaxKind.InterpolatedStringExpression) { var greenToken = Lexer.RescanInterpolatedString((InterpolatedStringExpressionSyntax)node.Green); var redToken = new CodeAnalysis.SyntaxToken(node.Parent, greenToken, node.Position, _indexInParent); return new Cursor(redToken, _indexInParent); } if (node.SlotCount > 0) { var child = Microsoft.CodeAnalysis.ChildSyntaxList.ItemInternal(node, 0); if (IsNonZeroWidthOrIsEndOfFile(child)) { return new Cursor(child, 0); } } // Fallback to enumerating all children. int index = 0; foreach (var child in this.CurrentNodeOrToken.ChildNodesAndTokens()) { if (IsNonZeroWidthOrIsEndOfFile(child)) { return new Cursor(child, index); } index++; } return new Cursor(); }