public virtual SyntaxToken VisitToken(SyntaxToken token) { // PERF: This is a hot method, so it has been written to minimize the following: // 1. Virtual method calls // 2. Copying of structs // 3. Repeated null checks // PERF: Avoid testing node for null more than once var node = token.Node; if (node == null) { return(token); } // PERF: Make one virtual method call each to get the leading and trailing trivia var leadingTrivia = node.GetLeadingTriviaCore(); var trailingTrivia = node.GetTrailingTriviaCore(); // Trivia is either null or a non-empty list (there's no such thing as an empty green list) Debug.Assert(leadingTrivia == null || !leadingTrivia.IsList || leadingTrivia.SlotCount > 0); Debug.Assert(trailingTrivia == null || !trailingTrivia.IsList || trailingTrivia.SlotCount > 0); if (leadingTrivia != null) { // PERF: Expand token.LeadingTrivia when node is not null. var leading = this.VisitList(new SyntaxTriviaList(token, leadingTrivia)); if (trailingTrivia != null) { // Both leading and trailing trivia // PERF: Expand token.TrailingTrivia when node is not null and leadingTrivia is not null. // Also avoid node.Width because it makes a virtual call to GetText. Instead use node.FullWidth - trailingTrivia.FullWidth. var index = leadingTrivia.IsList ? leadingTrivia.SlotCount : 1; var trailing = this.VisitList(new SyntaxTriviaList(token, trailingTrivia, token.Position + node.FullWidth - trailingTrivia.FullWidth, index)); if (leading.Node != leadingTrivia) { token = token.WithLeadingTrivia(leading); } return(trailing.Node != trailingTrivia?token.WithTrailingTrivia(trailing) : token); } else { // Leading trivia only return(leading.Node != leadingTrivia?token.WithLeadingTrivia(leading) : token); } } else if (trailingTrivia != null) { // Trailing trivia only // PERF: Expand token.TrailingTrivia when node is not null and leading is null. // Also avoid node.Width because it makes a virtual call to GetText. Instead use node.FullWidth - trailingTrivia.FullWidth. var trailing = this.VisitList(new SyntaxTriviaList(token, trailingTrivia, token.Position + node.FullWidth - trailingTrivia.FullWidth, index: 0)); return(trailing.Node != trailingTrivia?token.WithTrailingTrivia(trailing) : token); } else { // No trivia return(token); } }