Example #1
0
        /// <summary>
        /// Adds an entry to the map and propagates the substitution through
        /// all other entries in the type map.
        /// </summary>
        internal void AddAndPropagate(TypeParameterSymbol key, TypeWithModifiers value)
        {
            // @MattWindsor91 (Concept-C# 2017)
            //
            // This is an attempt to make TypeUnification perform a proper
            // unification where no mapping is dependent on another mapping.
            //
            // This is important for using unification for concepts, but less
            // so elsewhere.

            Debug.Assert(!Mapping.ContainsKey(key), "should not map the same type twice");

            // CONSIDER: performance
            var tmp = new MutableTypeMap();

            tmp.Add(key, value);

            var ms = Mapping.AsImmutable();

            foreach (var m in ms)
            {
                Mapping[m.Key] = m.Value.SubstituteType(tmp);
            }

            Add(key, value);
        }
Example #2
0
        private NamedTypeSymbol ApplyGenericArguments(NamedTypeSymbol symbol, Type[] typeArguments, ref int currentTypeArgument, bool includeReferences)
        {
            int remainingTypeArguments = typeArguments.Length - currentTypeArgument;

            // in case we are specializing a nested generic definition we might have more arguments than the current symbol:
            Debug.Assert(remainingTypeArguments >= symbol.Arity);

            if (remainingTypeArguments == 0)
            {
                return(symbol);
            }

            var typeArgumentSymbols = new TypeWithModifiers[symbol.TypeArgumentsNoUseSiteDiagnostics.Length];

            for (int i = 0; i < typeArgumentSymbols.Length; i++)
            {
                var argSymbol = GetTypeByReflectionType(typeArguments[currentTypeArgument++], includeReferences);
                if ((object)argSymbol == null)
                {
                    return(null);
                }
                typeArgumentSymbols[i] = new TypeWithModifiers(argSymbol);
            }

            return(symbol.ConstructIfGeneric(typeArgumentSymbols.AsImmutableOrNull()));
        }
Example #3
0
        /// <summary>
        /// Adds a mapping to this unification, creating a new unification.
        /// </summary>
        /// <param name="key">
        /// The key of the mapping to add.
        /// </param>
        /// <param name="value">
        /// The value of the mapping to add.
        /// </param>
        /// <returns>
        /// The result of adding, which will ignore this mapping if there is
        /// already a present mapping for <paramref name="key"/>.
        /// </returns>

        internal ImmutableTypeMap Add(TypeParameterSymbol key, TypeWithModifiers value)
        {
            var sd = new SmallDictionary <TypeParameterSymbol, TypeWithModifiers>();

            sd.Add(key, value);
            return(ComposeDict(sd));
        }
Example #4
0
        internal override TypeWithModifiers Substitute(AbstractTypeMap typeMap)
        {
            TypeWithModifiers substitutedReferencedType = typeMap.SubstituteType(_referencedType);

            return(substitutedReferencedType.Is(_referencedType) ?
                   new TypeWithModifiers(this) :
                   new TypeWithModifiers(new ByRefReturnErrorTypeSymbol(substitutedReferencedType.Type, _countOfCustomModifiersPrecedingByRef),
                                         substitutedReferencedType.CustomModifiers));
        }
        private PointerTypeSymbol SubstitutePointerType(PointerTypeSymbol t)
        {
            var oldPointedAtType            = new TypeWithModifiers(t.PointedAtType, t.CustomModifiers);
            TypeWithModifiers pointedAtType = oldPointedAtType.SubstituteType(this);

            if (pointedAtType == oldPointedAtType)
            {
                return(t);
            }

            return(new PointerTypeSymbol(pointedAtType.Type, pointedAtType.CustomModifiers));
        }
Example #6
0
 internal TypeMap(NamedTypeSymbol containingType, ImmutableArray <TypeParameterSymbol> typeParameters, ImmutableArray <TypeWithModifiers> typeArguments)
     : base(ForType(containingType))
 {
     for (int i = 0; i < typeParameters.Length; i++)
     {
         TypeParameterSymbol tp = typeParameters[i];
         TypeWithModifiers   ta = typeArguments[i];
         if (!ta.Is(tp))
         {
             Mapping.Add(tp, ta);
         }
     }
 }
Example #7
0
        /// <summary>
        /// Same as <see cref="SubstituteType"/>, but with special behavior around tuples.
        /// In particular, if substitution makes type tuple compatible, transform it into a tuple type.
        /// </summary>
        internal TypeWithModifiers SubstituteTypeWithTupleUnification(TypeSymbol previous)
        {
            TypeWithModifiers result = SubstituteType(previous);

            // Make it a tuple if it became compatible with one.
            if ((object)result.Type != null && !previous.IsTupleCompatible())
            {
                var possiblyTuple = TupleTypeSymbol.TransformToTupleIfCompatible(result.Type);
                if ((object)result.Type != possiblyTuple)
                {
                    result = new TypeWithModifiers(possiblyTuple, result.CustomModifiers);
                }
            }

            return(result);
        }
Example #8
0
        private TypeSymbol SubstituteNonNullableType(NonNullableReferenceTypeSymbol t)
        {
            var oldUnderlyingType            = new TypeWithModifiers(t.UnderlyingType);
            TypeWithModifiers underlyingType = oldUnderlyingType.SubstituteType(this);

            if (underlyingType == oldUnderlyingType)
            {
                return(t);
            }

            if (underlyingType.Type.IsValueType)
            {
                return(underlyingType.Type);
            }

            return(underlyingType.Type as NonNullableReferenceTypeSymbol ?? NonNullableReferenceTypeSymbol.CreateNonNullableReference(underlyingType.Type));
        }
        private ArrayTypeSymbol SubstituteArrayType(ArrayTypeSymbol t)
        {
            var oldElement            = new TypeWithModifiers(t.ElementType, t.CustomModifiers);
            TypeWithModifiers element = oldElement.SubstituteType(this);

            if (element == oldElement)
            {
                return(t);
            }

            if (t.IsSZArray)
            {
                ImmutableArray <NamedTypeSymbol> interfaces = t.InterfacesNoUseSiteDiagnostics();
                Debug.Assert(0 <= interfaces.Length && interfaces.Length <= 2);

                if (interfaces.Length == 1)
                {
                    Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T>
                    interfaces = ImmutableArray.Create <NamedTypeSymbol>((NamedTypeSymbol)SubstituteType(interfaces[0]).AsTypeSymbolOnly());
                }
                else if (interfaces.Length == 2)
                {
                    Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T>
                    interfaces = ImmutableArray.Create <NamedTypeSymbol>((NamedTypeSymbol)SubstituteType(interfaces[0]).AsTypeSymbolOnly(), (NamedTypeSymbol)SubstituteType(interfaces[1]).AsTypeSymbolOnly());
                }
                else if (interfaces.Length != 0)
                {
                    throw ExceptionUtilities.Unreachable;
                }

                return(ArrayTypeSymbol.CreateSZArray(
                           element.Type,
                           t.BaseTypeNoUseSiteDiagnostics,
                           interfaces,
                           element.CustomModifiers));
            }

            return(ArrayTypeSymbol.CreateMDArray(
                       element.Type,
                       t.Rank,
                       t.Sizes,
                       t.LowerBounds,
                       t.BaseTypeNoUseSiteDiagnostics,
                       element.CustomModifiers));
        }
Example #10
0
        private static SmallDictionary <TypeParameterSymbol, TypeWithModifiers> ConstructMapping(ImmutableArray <TypeParameterSymbol> from, ImmutableArray <TypeWithModifiers> to)
        {
            var mapping = new SmallDictionary <TypeParameterSymbol, TypeWithModifiers>(ReferenceEqualityComparer.Instance);

            Debug.Assert(from.Length == to.Length);

            for (int i = 0; i < from.Length; i++)
            {
                TypeParameterSymbol tp = from[i];
                TypeWithModifiers   ta = to[i];
                if (!ta.Is(tp))
                {
                    mapping.Add(tp, ta);
                }
            }

            return(mapping);
        }
Example #11
0
 private static TypeWithModifiers SubstituteType(TypeMap typeMap, TypeWithModifiers typeSymbol)
 {
     return(typeMap == null ? typeSymbol : typeSymbol.SubstituteType(typeMap));
 }
Example #12
0
 internal void Add(TypeParameterSymbol key, TypeWithModifiers value)
 {
     this.Mapping.Add(key, value);
 }