SubstitutedTypeParameterSymbol.cs 4.6 KB
Newer Older
1
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2

3 4
//#define DEBUG_ALPHA // turn on DEBUG_ALPHA to help diagnose issues around type parameter alpha-renaming

P
Pilchie 已提交
5 6
using System;
using System.Collections.Immutable;
7
using Microsoft.CodeAnalysis.PooledObjects;
P
Pilchie 已提交
8 9 10 11
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
12
    internal class SubstitutedTypeParameterSymbol : WrappedTypeParameterSymbol
P
Pilchie 已提交
13
    {
14 15
        private readonly Symbol _container;
        private readonly TypeMap _map;
E
Evan Hauck 已提交
16
        private readonly int _ordinal;
P
Pilchie 已提交
17

18 19 20 21 22
#if DEBUG_ALPHA
        private static int _nextSequence = 1;
        private readonly int _mySequence;
#endif

E
Evan Hauck 已提交
23
        internal SubstitutedTypeParameterSymbol(Symbol newContainer, TypeMap map, TypeParameterSymbol substitutedFrom, int ordinal)
D
dotnet-bot 已提交
24
            : base(substitutedFrom)
P
Pilchie 已提交
25
        {
26
            _container = newContainer;
P
Pilchie 已提交
27 28
            // it is important that we don't use the map here in the constructor, as the map is still being filled
            // in by TypeMap.WithAlphaRename.  Instead, we can use the map lazily when yielding the constraints.
29
            _map = map;
E
Evan Hauck 已提交
30
            _ordinal = ordinal;
31 32 33
#if DEBUG_ALPHA
            _mySequence = _nextSequence++;
#endif
P
Pilchie 已提交
34 35 36 37 38 39
        }

        public override Symbol ContainingSymbol
        {
            get
            {
40
                return _container;
P
Pilchie 已提交
41 42 43 44 45 46 47 48 49 50
            }
        }

        public override TypeParameterSymbol OriginalDefinition
        {
            get
            {
                // A substituted type parameter symbol is used as a type parameter of a frame type for lambda-captured
                // variables within a generic method.  In that case the frame's own type parameter is an original.
                return
51 52
                    ContainingSymbol.OriginalDefinition != _underlyingTypeParameter.ContainingSymbol.OriginalDefinition ? this :
                    _underlyingTypeParameter.OriginalDefinition;
P
Pilchie 已提交
53 54 55 56 57 58 59
            }
        }

        public override TypeParameterSymbol ReducedFrom
        {
            get
            {
60
                if (_container.Kind == SymbolKind.Method)
P
Pilchie 已提交
61
                {
62
                    MethodSymbol reducedFrom = ((MethodSymbol)_container).ReducedFrom;
P
Pilchie 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

                    if ((object)reducedFrom != null)
                    {
                        return reducedFrom.TypeParameters[this.Ordinal];
                    }
                }

                return null;
            }
        }

        public override int Ordinal
        {
            get
            {
E
Evan Hauck 已提交
78
                return _ordinal;
P
Pilchie 已提交
79 80 81 82 83 84 85
            }
        }

        public override string Name
        {
            get
            {
86
                return base.Name
87 88
#if DEBUG_ALPHA
                    + "#" + _mySequence
P
Pilchie 已提交
89 90 91 92 93 94 95
#endif
                    ;
            }
        }

        public override ImmutableArray<CSharpAttributeData> GetAttributes()
        {
96
            return _underlyingTypeParameter.GetAttributes();
P
Pilchie 已提交
97 98
        }

99
        internal override ImmutableArray<TypeWithAnnotations> GetConstraintTypes(ConsList<TypeParameterSymbol> inProgress, bool early)
P
Pilchie 已提交
100
        {
101
            var constraintTypes = ArrayBuilder<TypeWithAnnotations>.GetInstance();
C
Charles Stoner 已提交
102
            _map.SubstituteTypesDistinctWithoutModifiers(_underlyingTypeParameter.GetConstraintTypes(inProgress, early), constraintTypes, null);
103
            return constraintTypes.ToImmutableAndFree().WhereAsArray(type => type.SpecialType != SpecialType.System_Object || !type.NullableAnnotation.IsAnnotated());
P
Pilchie 已提交
104 105
        }

106 107 108 109 110 111 112 113 114 115 116 117 118
        internal override bool? IsNotNullableIfReferenceType
        {
            get
            {
                if (_underlyingTypeParameter.ConstraintTypesNoUseSiteDiagnostics.IsEmpty)
                {
                    return _underlyingTypeParameter.IsNotNullableIfReferenceType;
                }

                return CalculateIsNotNullableIfReferenceType();
            }
        }

P
Pilchie 已提交
119 120
        internal override ImmutableArray<NamedTypeSymbol> GetInterfaces(ConsList<TypeParameterSymbol> inProgress)
        {
121
            return _map.SubstituteNamedTypes(_underlyingTypeParameter.GetInterfaces(inProgress));
P
Pilchie 已提交
122 123 124 125
        }

        internal override NamedTypeSymbol GetEffectiveBaseClass(ConsList<TypeParameterSymbol> inProgress)
        {
126
            return _map.SubstituteNamedType(_underlyingTypeParameter.GetEffectiveBaseClass(inProgress));
P
Pilchie 已提交
127 128 129 130
        }

        internal override TypeSymbol GetDeducedBaseType(ConsList<TypeParameterSymbol> inProgress)
        {
131
            return _map.SubstituteType(_underlyingTypeParameter.GetDeducedBaseType(inProgress)).AsTypeSymbolOnly();
P
Pilchie 已提交
132 133
        }
    }
134
}