| File: Syntax\InternalSyntax\CSharpSyntaxRewriter.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Diagnostics; namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax { using Microsoft.CodeAnalysis.Syntax.InternalSyntax; internal partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor<CSharpSyntaxNode> #nullable disable { protected readonly bool VisitIntoStructuredTrivia; public CSharpSyntaxRewriter(bool visitIntoStructuredTrivia = false) { this.VisitIntoStructuredTrivia = visitIntoStructuredTrivia; } public override CSharpSyntaxNode VisitToken(SyntaxToken token) { var leading = this.VisitList(token.LeadingTrivia); var trailing = this.VisitList(token.TrailingTrivia); if (leading != token.LeadingTrivia || trailing != token.TrailingTrivia) { if (leading != token.LeadingTrivia) { token = token.TokenWithLeadingTrivia(leading.Node); } if (trailing != token.TrailingTrivia) { token = token.TokenWithTrailingTrivia(trailing.Node); } } return token; } public SyntaxList<TNode> VisitList<TNode>(SyntaxList<TNode> list) where TNode : CSharpSyntaxNode { SyntaxListBuilder alternate = null; for (int i = 0, n = list.Count; i < n; i++) { var item = list[i]; var visited = this.Visit(item); if (item != visited && alternate == null) { alternate = new SyntaxListBuilder(n); alternate.AddRange(list, 0, i); } if (alternate != null) { Debug.Assert(visited != null && visited.Kind != SyntaxKind.None, "Cannot remove node using Syntax.InternalSyntax.SyntaxRewriter."); alternate.Add(visited); } } if (alternate != null) { return alternate.ToList(); } return list; } public SeparatedSyntaxList<TNode> VisitList<TNode>(SeparatedSyntaxList<TNode> list) where TNode : CSharpSyntaxNode { // A separated list is filled with C# nodes and C# tokens. Both of which // derive from InternalSyntax.CSharpSyntaxNode. So this cast is appropriately // typesafe. var withSeps = (SyntaxList<CSharpSyntaxNode>)list.GetWithSeparators(); var result = this.VisitList(withSeps); if (result != withSeps) { return result.AsSeparatedList<TNode>(); } return list; } } }