File: src\roslyn\src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\CodeGeneration\Symbols\CodeGenerationNamedTypeSymbol.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.

#nullable disable

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editing;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CodeGeneration;

internal sealed class CodeGenerationNamedTypeSymbol : CodeGenerationAbstractNamedTypeSymbol
{
    private readonly ImmutableArray<ITypeParameterSymbol> _typeParameters;
    private readonly ImmutableArray<INamedTypeSymbol> _interfaces;
    private readonly ImmutableArray<ISymbol> _members;

    public CodeGenerationNamedTypeSymbol(
        IAssemblySymbol containingAssembly,
        INamedTypeSymbol containingType,
        ImmutableArray<AttributeData> attributes,
        Accessibility declaredAccessibility,
        DeclarationModifiers modifiers,
        bool isRecord,
        TypeKind typeKind,
        string name,
        ImmutableArray<ITypeParameterSymbol> typeParameters,
        INamedTypeSymbol baseType,
        ImmutableArray<INamedTypeSymbol> interfaces,
        SpecialType specialType,
        NullableAnnotation nullableAnnotation,
        ImmutableArray<ISymbol> members,
        ImmutableArray<CodeGenerationAbstractNamedTypeSymbol> typeMembers,
        INamedTypeSymbol enumUnderlyingType)
        : base(containingAssembly, containingType, attributes, declaredAccessibility, modifiers, name, specialType, nullableAnnotation, typeMembers)
    {
        IsRecord = isRecord;
        TypeKind = typeKind;
        _typeParameters = typeParameters.NullToEmpty();
        BaseType = baseType;
        _interfaces = interfaces.NullToEmpty();
        _members = members.NullToEmpty();
        EnumUnderlyingType = enumUnderlyingType;

        this.OriginalDefinition = this;
    }

    protected override CodeGenerationTypeSymbol CloneWithNullableAnnotation(NullableAnnotation nullableAnnotation)
    {
        return new CodeGenerationNamedTypeSymbol(
            this.ContainingAssembly, this.ContainingType, this.GetAttributes(), this.DeclaredAccessibility,
            this.Modifiers, this.IsRecord, this.TypeKind, this.Name, _typeParameters, this.BaseType,
            _interfaces, this.SpecialType, nullableAnnotation, _members, this.TypeMembers,
            this.EnumUnderlyingType);
    }

    public override bool IsRecord { get; }

    public override TypeKind TypeKind { get; }

    public override SymbolKind Kind => SymbolKind.NamedType;

    public override int Arity => this.TypeParameters.Length;

    public override bool IsGenericType
    {
        get
        {
            return this.Arity > 0;
        }
    }

    public override bool IsUnboundGenericType => false;

    public override bool IsScriptClass => false;

    public override bool IsImplicitClass => false;

    public override IEnumerable<string> MemberNames
    {
        get
        {
            return this.GetMembers().Select(m => m.Name).ToList();
        }
    }

    public override IMethodSymbol DelegateInvokeMethod
    {
        get
        {
            return this.TypeKind == TypeKind.Delegate
                ? this.GetMembers(WellKnownMemberNames.DelegateInvokeName).OfType<IMethodSymbol>().FirstOrDefault()
                : null;
        }
    }

    public override INamedTypeSymbol EnumUnderlyingType { get; }

    protected override CodeGenerationNamedTypeSymbol ConstructedFrom
    {
        get
        {
            return this;
        }
    }

    public override INamedTypeSymbol ConstructUnboundGenericType()
        => null;

    public static ImmutableArray<ISymbol> CandidateSymbols
    {
        get
        {
            return [];
        }
    }

    public override ImmutableArray<ITypeSymbol> TypeArguments
    {
        get
        {
            return this.TypeParameters.As<ITypeSymbol>();
        }
    }

    public override ImmutableArray<NullableAnnotation> TypeArgumentNullableAnnotations
    {
        get
        {
            // TODO: what should this be?
            return this.TypeParameters.SelectAsArray(t => NullableAnnotation.NotAnnotated);
        }
    }

    public override ImmutableArray<ITypeParameterSymbol> TypeParameters
    {
        get
        {
            return [.. _typeParameters];
        }
    }

    public override INamedTypeSymbol BaseType { get; }

    public override ImmutableArray<INamedTypeSymbol> Interfaces
    {
        get
        {
            return [.. _interfaces];
        }
    }

    public override ImmutableArray<ISymbol> GetMembers()
        => [.. _members.Concat(this.TypeMembers)];

    public override ImmutableArray<INamedTypeSymbol> GetTypeMembers()
        => [.. this.TypeMembers.Cast<INamedTypeSymbol>()];

    public override ImmutableArray<IMethodSymbol> InstanceConstructors
    {
        get
        {
            // NOTE(cyrusn): remember to Construct the result if we implement this.
            return [.. this.GetMembers().OfType<IMethodSymbol>().Where(m => m.MethodKind == MethodKind.Constructor && !m.IsStatic)];
        }
    }

    public override ImmutableArray<IMethodSymbol> StaticConstructors
    {
        get
        {
            // NOTE(cyrusn): remember to Construct the result if we implement this.
            return [.. this.GetMembers().OfType<IMethodSymbol>().Where(m => m.MethodKind == MethodKind.StaticConstructor && m.IsStatic)];
        }
    }

    public override ImmutableArray<IMethodSymbol> Constructors
    {
        get
        {
            return InstanceConstructors.AddRange(StaticConstructors);
        }
    }
}