public IType ResolveType(EntityHandle typeRefDefSpec, GenericContext context, TypeSystemOptions customOptions, CustomAttributeHandleCollection?typeAttributes = null, Nullability nullableContext = Nullability.Oblivious) { if (typeRefDefSpec.IsNil) { return(SpecialType.UnknownType); } IType ty; switch (typeRefDefSpec.Kind) { case HandleKind.TypeDefinition: ty = TypeProvider.GetTypeFromDefinition(metadata, (TypeDefinitionHandle)typeRefDefSpec, 0); break; case HandleKind.TypeReference: ty = TypeProvider.GetTypeFromReference(metadata, (TypeReferenceHandle)typeRefDefSpec, 0); break; case HandleKind.TypeSpecification: var typeSpec = metadata.GetTypeSpecification((TypeSpecificationHandle)typeRefDefSpec); ty = typeSpec.DecodeSignature(TypeProvider, context); break; case HandleKind.ExportedType: return(ResolveForwardedType(metadata.GetExportedType((ExportedTypeHandle)typeRefDefSpec))); default: throw new BadImageFormatException("Not a type handle"); } ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, typeAttributes, metadata, customOptions, nullableContext); return(ty); }
IType ResolveDeclaringType(EntityHandle declaringTypeReference, GenericContext context) { // resolve without substituting dynamic/tuple types var ty = ResolveType(declaringTypeReference, context, options & ~(TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple | TypeSystemOptions.NullabilityAnnotations)); // but substitute tuple types in type arguments: ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, null, metadata, options, Nullability.Oblivious, typeChildrenOnly: true); return(ty); }
IType IntroduceTupleTypes(IType ty) { // run ApplyAttributeTypeVisitor without attributes, in order to introduce tuple types return(ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, null, metadata, options, Nullability.Oblivious)); }
public static IType ApplyAttributesToType( IType inputType, ICompilation compilation, SRM.CustomAttributeHandleCollection?attributes, SRM.MetadataReader metadata, TypeSystemOptions options, bool typeChildrenOnly = false) { bool useDynamicType = (options & TypeSystemOptions.Dynamic) != 0; bool useTupleTypes = (options & TypeSystemOptions.Tuple) != 0; bool hasDynamicAttribute = false; bool[] dynamicAttributeData = null; string[] tupleElementNames = null; if (attributes != null && (useDynamicType || useTupleTypes)) { foreach (var attrHandle in attributes.Value) { var attr = metadata.GetCustomAttribute(attrHandle); var attrType = attr.GetAttributeType(metadata); if (useDynamicType && attrType.IsKnownType(metadata, KnownAttribute.Dynamic)) { hasDynamicAttribute = true; var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); if (ctor.FixedArguments.Length == 1) { var arg = ctor.FixedArguments[0]; if (arg.Value is ImmutableArray <SRM.CustomAttributeTypedArgument <IType> > values && values.All(v => v.Value is bool)) { dynamicAttributeData = values.SelectArray(v => (bool)v.Value); } } } else if (useTupleTypes && attrType.IsKnownType(metadata, KnownAttribute.TupleElementNames)) { var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); if (ctor.FixedArguments.Length == 1) { var arg = ctor.FixedArguments[0]; if (arg.Value is ImmutableArray <SRM.CustomAttributeTypedArgument <IType> > values && values.All(v => v.Value is string || v.Value == null)) { tupleElementNames = values.SelectArray(v => (string)v.Value); } } } } } if (hasDynamicAttribute || (options & (TypeSystemOptions.Tuple | TypeSystemOptions.KeepModifiers)) != TypeSystemOptions.KeepModifiers) { var visitor = new ApplyAttributeTypeVisitor( compilation, hasDynamicAttribute, dynamicAttributeData, options, tupleElementNames ); if (typeChildrenOnly) { return(inputType.VisitChildren(visitor)); } else { return(inputType.AcceptVisitor(visitor)); } } else { return(inputType); } }