File: Symbols\EETypeParameterSymbol.cs
Web Access
Project: ..\..\..\src\ExpressionEvaluator\CSharp\Source\ExpressionCompiler\Microsoft.CodeAnalysis.CSharp.ExpressionCompiler.csproj (Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ExpressionCompiler)
// 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;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
    internal sealed class EETypeParameterSymbol : TypeParameterSymbol
    {
        private readonly Symbol _container;
        private readonly TypeParameterSymbol _sourceTypeParameter;
        private readonly int _ordinal;
        private readonly Func<TypeMap> _getTypeMap;
        private TypeMap _lazyTypeMap;
 
        public EETypeParameterSymbol(
            Symbol container,
            TypeParameterSymbol sourceTypeParameter,
            int ordinal,
            Func<TypeMap> getTypeMap)
        {
            Debug.Assert((container.Kind == SymbolKind.NamedType) || (container.Kind == SymbolKind.Method));
            _container = container;
            _sourceTypeParameter = sourceTypeParameter;
            _ordinal = ordinal;
            _getTypeMap = getTypeMap;
        }
 
        public override Symbol ContainingSymbol
        {
            get { return _container; }
        }
 
        public override string Name
        {
            get { return _sourceTypeParameter.Name; }
        }
 
        public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
        {
            get { throw ExceptionUtilities.Unreachable(); }
        }
 
        public override bool HasConstructorConstraint
        {
            get { return _sourceTypeParameter.HasConstructorConstraint; }
        }
 
        public override bool HasReferenceTypeConstraint
        {
            get { return _sourceTypeParameter.HasReferenceTypeConstraint; }
        }
 
        public override bool IsReferenceTypeFromConstraintTypes
        {
            get
            {
                return _sourceTypeParameter.IsReferenceTypeFromConstraintTypes || CalculateIsReferenceTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics);
            }
        }
 
        internal override bool? ReferenceTypeConstraintIsNullable
        {
            get { return _sourceTypeParameter.ReferenceTypeConstraintIsNullable; }
        }
 
        public override bool HasNotNullConstraint
        {
            get { return _sourceTypeParameter.HasNotNullConstraint; }
        }
 
        internal override bool? IsNotNullable
        {
            get
            {
                if (_sourceTypeParameter.ConstraintTypesNoUseSiteDiagnostics.IsEmpty)
                {
                    return _sourceTypeParameter.IsNotNullable;
                }
 
                return CalculateIsNotNullable();
            }
        }
 
        public override bool HasValueTypeConstraint
        {
            get { return _sourceTypeParameter.HasValueTypeConstraint; }
        }
 
        public override bool IsValueTypeFromConstraintTypes
        {
            get
            {
                return _sourceTypeParameter.IsValueTypeFromConstraintTypes || CalculateIsValueTypeFromConstraintTypes(ConstraintTypesNoUseSiteDiagnostics);
            }
        }
 
        public override bool HasUnmanagedTypeConstraint
        {
            get { return _sourceTypeParameter.HasUnmanagedTypeConstraint; }
        }
 
        public override ImmutableArray<Location> Locations
        {
            get { throw ExceptionUtilities.Unreachable(); }
        }
 
        public override int Ordinal
        {
            get { return _ordinal; }
        }
 
        public override TypeParameterKind TypeParameterKind
        {
            get { throw ExceptionUtilities.Unreachable(); }
        }
 
        public override VarianceKind Variance
        {
            get { return _sourceTypeParameter.Variance; }
        }
 
        public override bool IsImplicitlyDeclared
        {
            get { return true; }
        }
 
        internal override void EnsureAllConstraintsAreResolved()
        {
            _sourceTypeParameter.EnsureAllConstraintsAreResolved();
        }
 
        internal override ImmutableArray<TypeWithAnnotations> GetConstraintTypes(ConsList<TypeParameterSymbol> inProgress)
        {
            var constraintTypes = _sourceTypeParameter.GetConstraintTypes(inProgress);
 
            if (constraintTypes.IsEmpty)
            {
                return constraintTypes;
            }
 
            // Remap constraints from sourceTypeParameter since constraints
            // may be defined in terms of other type parameters.
            return this.TypeMap.SubstituteTypes(constraintTypes);
        }
 
        internal override TypeSymbol GetDeducedBaseType(ConsList<TypeParameterSymbol> inProgress)
        {
            var type = _sourceTypeParameter.GetDeducedBaseType(inProgress);
            return this.TypeMap.SubstituteType(type).AsTypeSymbolOnly();
        }
 
        internal override NamedTypeSymbol GetEffectiveBaseClass(ConsList<TypeParameterSymbol> inProgress)
        {
            var type = _sourceTypeParameter.GetEffectiveBaseClass(inProgress);
            return this.TypeMap.SubstituteNamedType(type);
        }
 
        internal override ImmutableArray<NamedTypeSymbol> GetInterfaces(ConsList<TypeParameterSymbol> inProgress)
        {
            var interfaces = _sourceTypeParameter.GetInterfaces(inProgress);
            return this.TypeMap.SubstituteNamedTypes(interfaces);
        }
 
        private TypeMap TypeMap
        {
            get
            {
                if (_lazyTypeMap == null)
                {
                    Interlocked.CompareExchange(ref _lazyTypeMap, _getTypeMap(), null);
                }
                return _lazyTypeMap;
            }
        }
    }
}