internal MetadataModule(ICompilation compilation, Metadata.PEFile peFile, TypeSystemOptions options) { this.Compilation = compilation; this.PEFile = peFile; this.metadata = peFile.Metadata; this.options = options; this.TypeProvider = new TypeProvider(this); // assembly metadata if (metadata.IsAssembly) { var asmdef = metadata.GetAssemblyDefinition(); this.AssemblyName = metadata.GetString(asmdef.Name); this.FullAssemblyName = metadata.GetFullAssemblyName(); } else { var moddef = metadata.GetModuleDefinition(); this.AssemblyName = metadata.GetString(moddef.Name); this.FullAssemblyName = this.AssemblyName; } this.rootNamespace = new MetadataNamespace(this, null, string.Empty, metadata.GetNamespaceDefinitionRoot()); if (!options.HasFlag(TypeSystemOptions.Uncached)) { // create arrays for resolved entities, indexed by row index this.typeDefs = new MetadataTypeDefinition[metadata.TypeDefinitions.Count + 1]; this.fieldDefs = new MetadataField[metadata.FieldDefinitions.Count + 1]; this.methodDefs = new MetadataMethod[metadata.MethodDefinitions.Count + 1]; this.propertyDefs = new MetadataProperty[metadata.PropertyDefinitions.Count + 1]; this.eventDefs = new MetadataEvent[metadata.EventDefinitions.Count + 1]; } }
private ApplyAttributeTypeVisitor(ICompilation compilation, bool hasDynamicAttribute, bool[] dynamicAttributeData, TypeSystemOptions options, string[] tupleElementNames) { this.compilation = compilation ?? throw new ArgumentNullException(nameof(compilation)); this.hasDynamicAttribute = hasDynamicAttribute; this.dynamicAttributeData = dynamicAttributeData; this.options = options; this.tupleElementNames = tupleElementNames; }
internal MetadataModule(ICompilation compilation, Metadata.PEFile peFile, TypeSystemOptions options) { this.Compilation = compilation; this.PEFile = peFile; this.metadata = peFile.Metadata; this.options = options; this.TypeProvider = new TypeProvider(this); // assembly metadata if (metadata.IsAssembly) { var asmdef = metadata.GetAssemblyDefinition(); try { this.AssemblyName = metadata.GetString(asmdef.Name); this.AssemblyVersion = asmdef.Version; this.FullAssemblyName = metadata.GetFullAssemblyName(); } catch (BadImageFormatException) { this.AssemblyName = "<ERR: invalid assembly name>"; this.FullAssemblyName = "<ERR: invalid assembly name>"; } } else { try { var moddef = metadata.GetModuleDefinition(); this.AssemblyName = metadata.GetString(moddef.Name); } catch (BadImageFormatException) { this.AssemblyName = "<ERR: invalid assembly name>"; } this.FullAssemblyName = this.AssemblyName; } var customAttrs = metadata.GetModuleDefinition().GetCustomAttributes(); this.NullableContext = customAttrs.GetNullableContext(metadata) ?? Nullability.Oblivious; this.minAccessibilityForNRT = FindMinimumAccessibilityForNRT(metadata, customAttrs); this.rootNamespace = new MetadataNamespace(this, null, string.Empty, metadata.GetNamespaceDefinitionRoot()); if (!options.HasFlag(TypeSystemOptions.Uncached)) { // create arrays for resolved entities, indexed by row index this.typeDefs = new MetadataTypeDefinition[metadata.TypeDefinitions.Count + 1]; this.fieldDefs = new MetadataField[metadata.FieldDefinitions.Count + 1]; this.methodDefs = new MetadataMethod[metadata.MethodDefinitions.Count + 1]; this.propertyDefs = new MetadataProperty[metadata.PropertyDefinitions.Count + 1]; this.eventDefs = new MetadataEvent[metadata.EventDefinitions.Count + 1]; this.referencedAssemblies = new IModule[metadata.AssemblyReferences.Count + 1]; } }
public ICompilation GetTypeSystemOrNull(TypeSystemOptions options) { if (typeSystemWithOptions != null && options == currentTypeSystemOptions) { return(typeSystemWithOptions); } var module = GetPEFileOrNull(); if (module == null) { return(null); } currentTypeSystemOptions = options; return(typeSystemWithOptions = new SimpleCompilation( module.WithOptions(options | TypeSystemOptions.Uncached | TypeSystemOptions.KeepModifiers), MinimalCorlib.Instance)); }
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); }
public static async Task <DecompilerTypeSystem> CreateAsync(PEFile mainModule, IAssemblyResolver assemblyResolver, TypeSystemOptions typeSystemOptions) { if (mainModule == null) { throw new ArgumentNullException(nameof(mainModule)); } if (assemblyResolver == null) { throw new ArgumentNullException(nameof(assemblyResolver)); } var ts = new DecompilerTypeSystem(); await ts.InitializeAsync(mainModule, assemblyResolver, typeSystemOptions) .ConfigureAwait(false); return(ts); }
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); } }
public static IType ApplyAttributesToType( IType inputType, ICompilation compilation, SRM.CustomAttributeHandleCollection?attributes, SRM.MetadataReader metadata, TypeSystemOptions options, Nullability nullableContext, bool typeChildrenOnly = false) { bool hasDynamicAttribute = false; bool[] dynamicAttributeData = null; bool hasNativeIntegersAttribute = false; bool[] nativeIntegersAttributeData = null; string[] tupleElementNames = null; Nullability nullability; Nullability[] nullableAttributeData = null; if ((options & TypeSystemOptions.NullabilityAnnotations) != 0) { nullability = nullableContext; } else { nullability = Nullability.Oblivious; } const TypeSystemOptions relevantOptions = TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple | TypeSystemOptions.NullabilityAnnotations | TypeSystemOptions.NativeIntegers; if (attributes != null && (options & relevantOptions) != 0) { foreach (var attrHandle in attributes.Value) { var attr = metadata.GetCustomAttribute(attrHandle); var attrType = attr.GetAttributeType(metadata); if ((options & TypeSystemOptions.Dynamic) != 0 && 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 ((options & TypeSystemOptions.NativeIntegers) != 0 && attrType.IsKnownType(metadata, KnownAttribute.NativeInteger)) { hasNativeIntegersAttribute = 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)) { nativeIntegersAttributeData = values.SelectArray(v => (bool)v.Value); } } } else if ((options & TypeSystemOptions.Tuple) != 0 && 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); } } } else if ((options & TypeSystemOptions.NullabilityAnnotations) != 0 && attrType.IsKnownType(metadata, KnownAttribute.Nullable)) { 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 byte b && b <= 2)) { nullableAttributeData = values.SelectArray(v => (Nullability)(byte)v.Value); } else if (arg.Value is byte b && b <= 2) { nullability = (Nullability)b; } } } } }
internal static (IType returnType, IParameter[] parameters, ModifiedType returnTypeModifier) DecodeSignature( MetadataModule module, IParameterizedMember owner, MethodSignature <IType> signature, ParameterHandleCollection?parameterHandles, Nullability nullableContext, TypeSystemOptions typeSystemOptions, CustomAttributeHandleCollection?returnTypeAttributes = null) { var metadata = module.metadata; int i = 0; IParameter[] parameters = new IParameter[signature.RequiredParameterCount + (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs ? 1 : 0)]; IType parameterType; if (parameterHandles != null) { foreach (var parameterHandle in parameterHandles) { var par = metadata.GetParameter(parameterHandle); if (par.SequenceNumber == 0) { // "parameter" holds return type attributes. // Note: for properties, the attributes normally stored on a method's return type // are instead stored as normal attributes on the property. // So MetadataProperty provides a non-null value for returnTypeAttributes, // which then should be preferred over the attributes on the accessor's parameters. if (returnTypeAttributes == null) { returnTypeAttributes = par.GetCustomAttributes(); } } else if (par.SequenceNumber > 0 && i < signature.RequiredParameterCount) { // "Successive rows of the Param table that are owned by the same method shall be // ordered by increasing Sequence value - although gaps in the sequence are allowed" Debug.Assert(i < par.SequenceNumber); // Fill gaps in the sequence with non-metadata parameters: while (i < par.SequenceNumber - 1) { parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType( signature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext); parameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner, referenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None); i++; } parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType( signature.ParameterTypes[i], module.Compilation, par.GetCustomAttributes(), metadata, typeSystemOptions, nullableContext); parameters[i] = new MetadataParameter(module, owner, parameterType, parameterHandle); i++; } } } while (i < signature.RequiredParameterCount) { parameterType = ApplyAttributeTypeVisitor.ApplyAttributesToType( signature.ParameterTypes[i], module.Compilation, null, metadata, typeSystemOptions, nullableContext); parameters[i] = new DefaultParameter(parameterType, name: string.Empty, owner, referenceKind: parameterType.Kind == TypeKind.ByReference ? ReferenceKind.Ref : ReferenceKind.None); i++; } if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { parameters[i] = new DefaultParameter(SpecialType.ArgList, name: string.Empty, owner); i++; } Debug.Assert(i == parameters.Length); var returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType(signature.ReturnType, module.Compilation, returnTypeAttributes, metadata, typeSystemOptions, nullableContext); return(returnType, parameters, signature.ReturnType as ModifiedType); }