File: src\roslyn\src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\CodeGeneration\Symbols\CodeGenerationConstructorInfo.cs
Web Access
Project: src\roslyn\src\RoslynAnalyzers\Tools\GenerateDocumentationAndConfigFiles\GenerateDocumentationAndConfigFiles.csproj (GenerateDocumentationAndConfigFiles)
// 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.Collections.Immutable;
using System.Runtime.CompilerServices;

namespace Microsoft.CodeAnalysis.CodeGeneration;

internal sealed class CodeGenerationConstructorInfo
{
    private static readonly ConditionalWeakTable<IMethodSymbol, CodeGenerationConstructorInfo> s_constructorToInfoMap = new();

    private readonly bool _isPrimaryConstructor;
    private readonly bool _isUnsafe;
    private readonly string _typeName;
    private readonly ImmutableArray<SyntaxNode> _baseConstructorArguments;
    private readonly ImmutableArray<SyntaxNode> _thisConstructorArguments;
    private readonly ImmutableArray<SyntaxNode> _statements;

    private CodeGenerationConstructorInfo(
        bool isPrimaryConstructor,
        bool isUnsafe,
        string typeName,
        ImmutableArray<SyntaxNode> statements,
        ImmutableArray<SyntaxNode> baseConstructorArguments,
        ImmutableArray<SyntaxNode> thisConstructorArguments)
    {
        _isPrimaryConstructor = isPrimaryConstructor;
        _isUnsafe = isUnsafe;
        _typeName = typeName;
        _statements = statements;
        _baseConstructorArguments = baseConstructorArguments;
        _thisConstructorArguments = thisConstructorArguments;
    }

    public static void Attach(
        IMethodSymbol constructor,
        bool isPrimaryConstructor,
        bool isUnsafe,
        string typeName,
        ImmutableArray<SyntaxNode> statements,
        ImmutableArray<SyntaxNode> baseConstructorArguments,
        ImmutableArray<SyntaxNode> thisConstructorArguments)
    {
        var info = new CodeGenerationConstructorInfo(isPrimaryConstructor, isUnsafe, typeName, statements, baseConstructorArguments, thisConstructorArguments);
        s_constructorToInfoMap.Add(constructor, info);
    }

    private static CodeGenerationConstructorInfo? GetInfo(IMethodSymbol method)
    {
        s_constructorToInfoMap.TryGetValue(method, out var info);
        return info;
    }

    public static ImmutableArray<SyntaxNode> GetThisConstructorArgumentsOpt(IMethodSymbol constructor)
        => GetThisConstructorArgumentsOpt(GetInfo(constructor));

    public static ImmutableArray<SyntaxNode> GetBaseConstructorArgumentsOpt(IMethodSymbol constructor)
        => GetBaseConstructorArgumentsOpt(GetInfo(constructor));

    public static ImmutableArray<SyntaxNode> GetStatements(IMethodSymbol constructor)
        => GetStatements(GetInfo(constructor));

    public static string GetTypeName(IMethodSymbol constructor)
        => GetTypeName(GetInfo(constructor), constructor);

    public static bool GetIsUnsafe(IMethodSymbol constructor)
        => GetIsUnsafe(GetInfo(constructor));

    public static bool GetIsPrimaryConstructor(IMethodSymbol constructor)
        => GetIsPrimaryConstructor(GetInfo(constructor));

    private static ImmutableArray<SyntaxNode> GetThisConstructorArgumentsOpt(CodeGenerationConstructorInfo? info)
        => info?._thisConstructorArguments ?? default;

    private static ImmutableArray<SyntaxNode> GetBaseConstructorArgumentsOpt(CodeGenerationConstructorInfo? info)
        => info?._baseConstructorArguments ?? default;

    private static ImmutableArray<SyntaxNode> GetStatements(CodeGenerationConstructorInfo? info)
        => info?._statements ?? default;

    private static string GetTypeName(CodeGenerationConstructorInfo? info, IMethodSymbol constructor)
        => info == null ? constructor.ContainingType.Name : info._typeName;

    private static bool GetIsUnsafe(CodeGenerationConstructorInfo? info)
        => info?._isUnsafe ?? false;

    private static bool GetIsPrimaryConstructor(CodeGenerationConstructorInfo? info)
        => info?._isPrimaryConstructor ?? false;
}