File: CodeModel\AbstractCodeModelService.AbstractNodeNameGenerator.cs
Web Access
Project: ..\..\..\src\VisualStudio\Core\Impl\Microsoft.VisualStudio.LanguageServices.Implementation_zmmkbl53_wpftmp.csproj (Microsoft.VisualStudio.LanguageServices.Implementation)
// 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 System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
 
namespace Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel
{
    internal partial class AbstractCodeModelService : ICodeModelService
    {
        protected abstract AbstractNodeNameGenerator CreateNodeNameGenerator();
 
        protected abstract class AbstractNodeNameGenerator
        {
            protected abstract bool IsNameableNode(SyntaxNode node);
            protected abstract void AppendNodeName(StringBuilder builder, SyntaxNode node);
 
            protected static void AppendDotIfNeeded(StringBuilder builder)
            {
                if (builder.Length > 0 &&
                    char.IsLetterOrDigit(builder[builder.Length - 1]))
                {
                    builder.Append('.');
                }
            }
 
            protected static void AppendArity(StringBuilder builder, int arity)
            {
                if (arity > 0)
                {
                    builder.Append("`" + arity);
                }
            }
 
            public string GenerateName(SyntaxNode node)
            {
                Debug.Assert(IsNameableNode(node));
 
                var builder = new StringBuilder();
 
                var ancestors = node.Ancestors().ToArray();
                for (var i = ancestors.Length - 1; i >= 0; i--)
                {
                    var ancestor = ancestors[i];
 
                    // We skip "unnameable" nodes to ensure that we don't add empty names
                    // for nodes like the compilation unit or field declarations.
                    if (IsNameableNode(ancestor))
                    {
                        AppendNodeName(builder, ancestor);
                    }
                }
 
                AppendNodeName(builder, node);
 
                return builder.ToString();
            }
        }
    }
}