internal TypeSymbol GetTypeSymbolForSerializedType(string s) { if (string.IsNullOrEmpty(s)) { return(GetUnsupportedMetadataTypeSymbol()); } MetadataHelpers.AssemblyQualifiedTypeName fullName = MetadataHelpers.DecodeTypeName(s); bool refersToNoPiaLocalType; return(GetTypeSymbol(fullName, out refersToNoPiaLocalType)); }
internal TypeSymbol GetTypeSymbol(MetadataHelpers.AssemblyQualifiedTypeName fullName, out bool refersToNoPiaLocalType) { // // Section 23.3 (Custom Attributes) of CLI Spec Partition II: // // If the parameter kind is System.Type, (also, the middle line in above diagram) its value is // stored as a SerString (as defined in the previous paragraph), representing its canonical name. // The canonical name is its full type name, followed optionally by the assembly where it is defined, // its version, culture and public-key-token. If the assembly name is omitted, the CLI looks first // in the current assembly, and then in the system library (mscorlib); in these two special cases, // it is permitted to omit the assembly-name, version, culture and public-key-token. int referencedAssemblyIndex; if (fullName.AssemblyName != null) { AssemblyIdentity identity; if (!AssemblyIdentity.TryParseDisplayName(fullName.AssemblyName, out identity)) { refersToNoPiaLocalType = false; return(GetUnsupportedMetadataTypeSymbol()); } // the assembly name has to be a full name: referencedAssemblyIndex = GetIndexOfReferencedAssembly(identity); if (referencedAssemblyIndex == -1) { // In rare cases (e.g. assemblies emitted by Reflection.Emit) the identity // might be the identity of the containing assembly. The metadata spec doesn't disallow this. if (!this.IsContainingAssembly(identity)) { refersToNoPiaLocalType = false; return(GetUnsupportedMetadataTypeSymbol()); } } } else { // Use this assembly referencedAssemblyIndex = -1; } // Find the top level type Debug.Assert(MetadataHelpers.IsValidMetadataIdentifier(fullName.TopLevelType)); var mdName = MetadataTypeName.FromFullName(fullName.TopLevelType); TypeSymbol container = LookupTopLevelTypeDefSymbol(ref mdName, referencedAssemblyIndex, out refersToNoPiaLocalType); // Process any nested types if (fullName.NestedTypes != null) { if (refersToNoPiaLocalType) { // Types nested into local types are not supported. refersToNoPiaLocalType = false; return(GetUnsupportedMetadataTypeSymbol()); } for (int i = 0; i < fullName.NestedTypes.Length; i++) { Debug.Assert(MetadataHelpers.IsValidMetadataIdentifier(fullName.NestedTypes[i])); mdName = MetadataTypeName.FromTypeName(fullName.NestedTypes[i]); // Find nested type in the container container = LookupNestedTypeDefSymbol(container, ref mdName); } } // Substitute type arguments if any if (fullName.TypeArguments != null) { ImmutableArray <bool> argumentRefersToNoPiaLocalType; var typeArguments = ResolveTypeArguments(fullName.TypeArguments, out argumentRefersToNoPiaLocalType); container = SubstituteTypeParameters(container, typeArguments, argumentRefersToNoPiaLocalType); foreach (bool flag in argumentRefersToNoPiaLocalType) { if (flag) { refersToNoPiaLocalType = true; break; } } } else { container = SubstituteWithUnboundIfGeneric(container); } for (int i = 0; i < fullName.PointerCount; i++) { container = MakePointerTypeSymbol(container, ImmutableArray <ModifierInfo <TypeSymbol> > .Empty); } // Process any array type ranks if (fullName.ArrayRanks != null) { foreach (int rank in fullName.ArrayRanks) { Debug.Assert(rank >= 0); container = rank == 0 ? GetSZArrayTypeSymbol(container, default(ImmutableArray <ModifierInfo <TypeSymbol> >)) : GetMDArrayTypeSymbol(rank, container, default(ImmutableArray <ModifierInfo <TypeSymbol> >), ImmutableArray <int> .Empty, default(ImmutableArray <int>)); } } return(container); }