/// <summary> /// Returns a constructed type given the type it is constructed from and type arguments for its enclosing types and itself. /// </summary> /// <param name="typeArguments">the type arguments that will replace the type parameters, starting with those for enclosing types</param> /// <returns></returns> private static NamedTypeSymbol DeepConstruct(NamedTypeSymbol type, ImmutableArray <TypeSymbol> typeArguments) { Assert.True(type.IsDefinition); var allTypeParameters = ArrayBuilder <TypeParameterSymbol> .GetInstance(); type.GetAllTypeParameters(allTypeParameters); return(new TypeMap(allTypeParameters.ToImmutableAndFree(), typeArguments.SelectAsArray(TypeMap.TypeSymbolAsTypeWithModifiers)).SubstituteNamedType(type)); }
internal override TypeSymbol SubstituteTypeParameters( PEModuleSymbol moduleSymbol, TypeSymbol genericTypeDef, ImmutableArray <KeyValuePair <TypeSymbol, ImmutableArray <ModifierInfo <TypeSymbol> > > > arguments, ImmutableArray <bool> refersToNoPiaLocalType) { if (genericTypeDef is UnsupportedMetadataTypeSymbol) { return(genericTypeDef); } // Let's return unsupported metadata type if any argument is unsupported metadata type foreach (var arg in arguments) { if (arg.Key.Kind == SymbolKind.ErrorType && arg.Key is UnsupportedMetadataTypeSymbol) { return(new UnsupportedMetadataTypeSymbol()); } } NamedTypeSymbol genericType = (NamedTypeSymbol)genericTypeDef; // See if it is or its enclosing type is a non-interface closed over NoPia local types. ImmutableArray <AssemblySymbol> linkedAssemblies = moduleSymbol.ContainingAssembly.GetLinkedReferencedAssemblies(); bool noPiaIllegalGenericInstantiation = false; if (!linkedAssemblies.IsDefaultOrEmpty || moduleSymbol.Module.ContainsNoPiaLocalTypes()) { NamedTypeSymbol typeToCheck = genericType; int argumentIndex = refersToNoPiaLocalType.Length - 1; do { if (!typeToCheck.IsInterface) { break; } else { argumentIndex -= typeToCheck.Arity; } typeToCheck = typeToCheck.ContainingType; }while ((object)typeToCheck != null); for (int i = argumentIndex; i >= 0; i--) { if (refersToNoPiaLocalType[i] || (!linkedAssemblies.IsDefaultOrEmpty && MetadataDecoder.IsOrClosedOverATypeFromAssemblies(arguments[i].Key, linkedAssemblies))) { noPiaIllegalGenericInstantiation = true; break; } } } // Collect generic parameters for the type and its containers in the order // that matches passed in arguments, i.e. sorted by the nesting. ImmutableArray <TypeParameterSymbol> typeParameters = genericType.GetAllTypeParameters(); Debug.Assert(typeParameters.Length > 0); if (typeParameters.Length != arguments.Length) { return(new UnsupportedMetadataTypeSymbol()); } TypeMap substitution = new TypeMap(typeParameters, arguments.SelectAsArray(arg => CreateType(arg.Key, arg.Value))); NamedTypeSymbol constructedType = substitution.SubstituteNamedType(genericType); if (noPiaIllegalGenericInstantiation) { constructedType = new NoPiaIllegalGenericInstantiationSymbol(moduleSymbol, constructedType); } return(constructedType); }