/// <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 static void AppendMapping(MutableTypeMap customTypeSubstitution, NamedTypeSymbol namedTypeSymbol, bool invert = false) { for (var i = 0; i < namedTypeSymbol.TypeParameters.Length; i++) { var typeParameterSymbol = namedTypeSymbol.TypeParameters[i]; var typeArgument = namedTypeSymbol.TypeArguments[i]; if (!ReferenceEquals(typeParameterSymbol, typeArgument)) { if (invert) { Debug.Assert(typeArgument is TypeParameterSymbol, "TypeParameterSymbol is required"); customTypeSubstitution.Add(typeArgument as TypeParameterSymbol, customTypeSubstitution.SubstituteType(typeParameterSymbol)); } else { customTypeSubstitution.Add(typeParameterSymbol, typeArgument); } } } }
private static void AppendMethodDirectMapping(MutableTypeMap customTypeSubstitution, MethodSymbol methodSymbolSpec, MethodSymbol methodSymbolDef) { for (var i = 0; i < methodSymbolSpec.TypeParameters.Length; i++) { var typeParameterSymbol = methodSymbolDef.TypeParameters[i]; var typeArgument = methodSymbolSpec.TypeArguments[i]; if (!ReferenceEquals(typeParameterSymbol, typeArgument)) { customTypeSubstitution.Add(typeParameterSymbol, typeArgument); } } }