| File: Symbols\Metadata\PE\SymbolFactory.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE { internal sealed class SymbolFactory : SymbolFactory<PEModuleSymbol, TypeSymbol> { internal static readonly SymbolFactory Instance = new SymbolFactory(); internal override TypeSymbol GetMDArrayTypeSymbol(PEModuleSymbol moduleSymbol, int rank, TypeSymbol elementType, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers, ImmutableArray<int> sizes, ImmutableArray<int> lowerBounds) { if (elementType is UnsupportedMetadataTypeSymbol) { return elementType; } return ArrayTypeSymbol.CreateMDArray(moduleSymbol.ContainingAssembly, CreateType(elementType, customModifiers), rank, sizes, lowerBounds); } internal override TypeSymbol GetSpecialType(PEModuleSymbol moduleSymbol, SpecialType specialType) { return moduleSymbol.ContainingAssembly.GetSpecialType(specialType); } internal override TypeSymbol GetSystemTypeSymbol(PEModuleSymbol moduleSymbol) { return moduleSymbol.SystemTypeSymbol; } internal override TypeSymbol MakePointerTypeSymbol(PEModuleSymbol moduleSymbol, TypeSymbol type, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers) { if (type is UnsupportedMetadataTypeSymbol) { return type; } return new PointerTypeSymbol(CreateType(type, customModifiers)); } internal override TypeSymbol MakeFunctionPointerTypeSymbol(PEModuleSymbol moduleSymbol, Cci.CallingConvention callingConvention, ImmutableArray<ParamInfo<TypeSymbol>> retAndParamTypes) { return FunctionPointerTypeSymbol.CreateFromMetadata(moduleSymbol, callingConvention, retAndParamTypes); } internal override TypeSymbol GetEnumUnderlyingType(PEModuleSymbol moduleSymbol, TypeSymbol type) { return type.GetEnumUnderlyingType(); } internal override Cci.PrimitiveTypeCode GetPrimitiveTypeCode(PEModuleSymbol moduleSymbol, TypeSymbol type) { return type.PrimitiveTypeCode; } internal override TypeSymbol GetSZArrayTypeSymbol(PEModuleSymbol moduleSymbol, TypeSymbol elementType, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers) { if (elementType is UnsupportedMetadataTypeSymbol) { return elementType; } return ArrayTypeSymbol.CreateSZArray(moduleSymbol.ContainingAssembly, CreateType(elementType, customModifiers)); } internal override TypeSymbol GetUnsupportedMetadataTypeSymbol(PEModuleSymbol moduleSymbol, BadImageFormatException exception) { return new UnsupportedMetadataTypeSymbol(exception); } 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; } internal override TypeSymbol MakeUnboundIfGeneric(PEModuleSymbol moduleSymbol, TypeSymbol type) { var namedType = type as NamedTypeSymbol; return ((object)namedType != null && namedType.IsGenericType) ? namedType.AsUnboundGenericType() : type; } private static TypeWithAnnotations CreateType(TypeSymbol type, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers) { // The actual annotation will be set when these types are transformed by the caller. return TypeWithAnnotations.Create(type, NullableAnnotation.Oblivious, CSharpCustomModifier.Convert(customModifiers)); } } }