/// <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); }
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())); }
/// <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)); }
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)); }
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); } } }
/// <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); }
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)); }
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); }
private static TypeWithModifiers SubstituteType(TypeMap typeMap, TypeWithModifiers typeSymbol) { return(typeMap == null ? typeSymbol : typeSymbol.SubstituteType(typeMap)); }
internal void Add(TypeParameterSymbol key, TypeWithModifiers value) { this.Mapping.Add(key, value); }