| File: Syntax\InternalSyntax\SyntaxLastTokenReplacer.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. #nullable disable using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax { internal class SyntaxLastTokenReplacer : CSharpSyntaxRewriter { private readonly SyntaxToken _oldToken; private readonly SyntaxToken _newToken; private int _count = 1; private bool _found; private SyntaxLastTokenReplacer(SyntaxToken oldToken, SyntaxToken newToken) { _oldToken = oldToken; _newToken = newToken; } internal static TRoot Replace<TRoot>(TRoot root, SyntaxToken newToken) where TRoot : CSharpSyntaxNode { var oldToken = root.GetLastToken(); var replacer = new SyntaxLastTokenReplacer(oldToken, newToken); var newRoot = (TRoot)replacer.Visit(root); Debug.Assert(replacer._found); return newRoot; } private static int CountNonNullSlots(CSharpSyntaxNode node) { return node.ChildNodesAndTokens().Count; } public override CSharpSyntaxNode Visit(CSharpSyntaxNode node) { if (node != null && !_found) { _count--; if (_count == 0) { var token = node as SyntaxToken; if (token != null) { Debug.Assert(token == _oldToken); _found = true; return _newToken; } _count += CountNonNullSlots(node); return base.Visit(node); } } return node; } } }