Beispiel #1
0
        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;
 }
Beispiel #3
0
        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];
            }
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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;
                            }
                        }
                    }
                }
            }
Beispiel #9
0
        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);
        }