private List <CustomAttribute> HandleCustomAttributes(Cts.Ecma.EcmaModule module, Ecma.CustomAttributeHandleCollection attributes)
        {
            List <CustomAttribute> customAttributes = new List <CustomAttribute>(attributes.Count);

            var attributeTypeProvider = new Cts.Ecma.CustomAttributeTypeProvider(module);

            foreach (var attributeHandle in attributes)
            {
                Ecma.MetadataReader  reader    = module.MetadataReader;
                Ecma.CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle);

                // TODO-NICE: We can intern the attributes based on the CA constructor and blob bytes

                Cts.MethodDesc constructor  = module.GetMethod(attribute.Constructor);
                var            decodedValue = attribute.DecodeValue(attributeTypeProvider);

                if (IsBlockedCustomAttribute(constructor, decodedValue))
                {
                    continue;
                }

                customAttributes.Add(HandleCustomAttribute(constructor, decodedValue));
            }

            return(customAttributes);
        }
Exemple #2
0
        private void InitializeTypeForwarder(ForwarderKey key, TypeForwarder record)
        {
            Cts.Ecma.EcmaModule module       = key.Module;
            Ecma.MetadataReader reader       = module.MetadataReader;
            Ecma.ExportedType   exportedType = reader.GetExportedType(key.ExportedType);

            record.Name = HandleString(reader.GetString(exportedType.Name));

            switch (exportedType.Implementation.Kind)
            {
            case Ecma.HandleKind.AssemblyReference:
            {
                string ns = reader.GetString(exportedType.Namespace);
                NamespaceDefinition namespaceDefinition = HandleNamespaceDefinition(module, ns);

                Ecma.AssemblyReference assemblyRef = reader.GetAssemblyReference((Ecma.AssemblyReferenceHandle)exportedType.Implementation);
                AssemblyName           refName     = new AssemblyName
                {
                    ContentType = (AssemblyContentType)((int)(assemblyRef.Flags & AssemblyFlags.ContentTypeMask) >> 9),
                    Flags       = (AssemblyNameFlags)(assemblyRef.Flags & ~AssemblyFlags.ContentTypeMask),
                    CultureName = reader.GetString(assemblyRef.Culture),
                    Name        = reader.GetString(assemblyRef.Name),
                    Version     = assemblyRef.Version,
                };

                if ((assemblyRef.Flags & AssemblyFlags.PublicKey) != 0)
                {
                    refName.SetPublicKey(reader.GetBlobBytes(assemblyRef.PublicKeyOrToken));
                }
                else
                {
                    refName.SetPublicKeyToken(reader.GetBlobBytes(assemblyRef.PublicKeyOrToken));
                }

                record.Scope = HandleScopeReference(refName);

                namespaceDefinition.TypeForwarders.Add(record);
            }
            break;

            case Ecma.HandleKind.ExportedType:
            {
                TypeForwarder scope = HandleTypeForwarder(module, (Ecma.ExportedTypeHandle)exportedType.Implementation);

                record.Scope = scope.Scope;

                scope.NestedTypes.Add(record);
            }
            break;

            default:
                throw new BadImageFormatException();
            }
        }
Exemple #3
0
        private TypeForwarder HandleTypeForwarder(Cts.Ecma.EcmaModule module, Ecma.ExportedType exportedType)
        {
            Ecma.MetadataReader reader = module.MetadataReader;
            string        name         = reader.GetString(exportedType.Name);
            TypeForwarder result;

            switch (exportedType.Implementation.Kind)
            {
            case Ecma.HandleKind.AssemblyReference:
            {
                string ns = reader.GetString(exportedType.Namespace);
                NamespaceDefinition namespaceDefinition = HandleNamespaceDefinition(module, ns);

                Ecma.AssemblyReference assemblyRef = reader.GetAssemblyReference((Ecma.AssemblyReferenceHandle)exportedType.Implementation);
                AssemblyName           refName     = new AssemblyName
                {
                    ContentType = (AssemblyContentType)((int)(assemblyRef.Flags & AssemblyFlags.ContentTypeMask) >> 9),
                    Flags       = (AssemblyNameFlags)(assemblyRef.Flags & ~AssemblyFlags.ContentTypeMask),
                    CultureName = reader.GetString(assemblyRef.Culture),
                    Name        = reader.GetString(assemblyRef.Name),
                    Version     = assemblyRef.Version,
                };

                result = new TypeForwarder
                {
                    Name  = HandleString(name),
                    Scope = HandleScopeReference(refName),
                };

                namespaceDefinition.TypeForwarders.Add(result);
            }
            break;

            case Ecma.HandleKind.ExportedType:
            {
                TypeForwarder scope = HandleTypeForwarder(module, reader.GetExportedType((Ecma.ExportedTypeHandle)exportedType.Implementation));

                result = new TypeForwarder
                {
                    Name  = HandleString(name),
                    Scope = scope.Scope,
                };

                scope.NestedTypes.Add(result);
            }
            break;

            default:
                throw new BadImageFormatException();
            }

            return(result);
        }
Exemple #4
0
        private void InitializeScopeDefinition(Cts.ModuleDesc module, ScopeDefinition scopeDefinition)
        {
            // Make sure we're expected to create a scope definition here. If the assert fires, the metadata
            // policy should have directed us to create a scope reference (or the list of inputs was incomplete).
            Debug.Assert(_modulesToTransform.Contains(module), "Incomplete list of input modules with respect to metadata policy");

            var assemblyDesc = module as Cts.IAssemblyDesc;

            if (assemblyDesc != null)
            {
                var assemblyName = assemblyDesc.GetName();

                scopeDefinition.Name = HandleString(assemblyName.Name);
#if NETFX_45
                // With NET 4.5 contract System.Reflection 4.0.0.0 EcmaModule has no way
                // to set Culture in its AssemblyName.
                scopeDefinition.Culture = HandleString(assemblyName.CultureName ?? "");
#else
                scopeDefinition.Culture = HandleString(assemblyName.CultureName);
#endif
                scopeDefinition.MajorVersion   = checked ((ushort)assemblyName.Version.Major);
                scopeDefinition.MinorVersion   = checked ((ushort)assemblyName.Version.Minor);
                scopeDefinition.BuildNumber    = checked ((ushort)assemblyName.Version.Build);
                scopeDefinition.RevisionNumber = checked ((ushort)assemblyName.Version.Revision);

                Debug.Assert((int)AssemblyFlags.PublicKey == (int)AssemblyNameFlags.PublicKey);
                Debug.Assert((int)AssemblyFlags.Retargetable == (int)AssemblyNameFlags.Retargetable);
                scopeDefinition.Flags = (AssemblyFlags)assemblyName.Flags;

                if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime)
                {
                    scopeDefinition.Flags |= (AssemblyFlags)((int)AssemblyContentType.WindowsRuntime << 9);
                }

                scopeDefinition.PublicKey = assemblyName.GetPublicKey();

                Cts.Ecma.EcmaModule ecmaModule = module as Cts.Ecma.EcmaModule;
                if (ecmaModule != null)
                {
                    Ecma.CustomAttributeHandleCollection customAttributes = ecmaModule.AssemblyDefinition.GetCustomAttributes();
                    if (customAttributes.Count > 0)
                    {
                        scopeDefinition.CustomAttributes = HandleCustomAttributes(ecmaModule, customAttributes);
                    }
                }
            }
            else
            {
                throw new NotSupportedException("Multi-module assemblies");
            }
        }
 private void HandleTypeForwarders(Cts.Ecma.EcmaModule module)
 {
     foreach (var exportedTypeHandle in module.MetadataReader.ExportedTypes)
     {
         Ecma.ExportedType exportedType = module.MetadataReader.GetExportedType(exportedTypeHandle);
         if (exportedType.IsForwarder || exportedType.Implementation.Kind == Ecma.HandleKind.ExportedType)
         {
             HandleTypeForwarder(module, exportedType);
         }
         else
         {
             Debug.Assert(false, "Multi-module assemblies");
         }
     }
 }
Exemple #6
0
        private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property)
        {
            Ecma.MetadataReader reader = module.MetadataReader;

            Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property);

            Ecma.PropertyAccessors acc          = propDef.GetAccessors();
            Cts.MethodDesc         getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter);
            Cts.MethodDesc         setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter);

            bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod);
            bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod);

            // Policy: If neither the getter nor setter have metadata, property doesn't have metadata
            if (!getterHasMetadata && !setterHasMetadata)
            {
                return(null);
            }

            Ecma.BlobReader       sigBlobReader = reader.GetBlobReader(propDef.Signature);
            Cts.PropertySignature sig           = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader, Cts.NotFoundBehavior.Throw).ParsePropertySignature();

            Property result = new Property
            {
                Name      = HandleString(reader.GetString(propDef.Name)),
                Flags     = propDef.Attributes,
                Signature = new PropertySignature
                {
                    CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis,
                    Type = HandleType(sig.ReturnType)
                },
            };

            result.Signature.Parameters.Capacity = sig.Length;
            for (int i = 0; i < sig.Length; i++)
            {
                result.Signature.Parameters.Add(HandleType(sig[i]));
            }

            if (getterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Getter,
                    Method     = HandleMethodDefinition(getterMethod),
                });
            }

            if (setterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Setter,
                    Method     = HandleMethodDefinition(setterMethod),
                });
            }

            Ecma.ConstantHandle defaultValue = propDef.GetDefaultValue();
            if (!defaultValue.IsNil)
            {
                result.DefaultValue = HandleConstant(module, defaultValue);
            }

            Ecma.CustomAttributeHandleCollection customAttributes = propDef.GetCustomAttributes();
            if (customAttributes.Count > 0)
            {
                result.CustomAttributes = HandleCustomAttributes(module, customAttributes);
            }

            return(result);
        }
Exemple #7
0
        private MetadataRecord HandleConstant(Cts.Ecma.EcmaModule module, Ecma.ConstantHandle constantHandle)
        {
            Ecma.MetadataReader reader   = module.MetadataReader;
            Ecma.Constant       constant = reader.GetConstant(constantHandle);

            Ecma.BlobReader blob = reader.GetBlobReader(constant.Value);

            switch (constant.TypeCode)
            {
            case ConstantTypeCode.Boolean:
                return(new ConstantBooleanValue {
                    Value = blob.ReadBoolean()
                });

            case ConstantTypeCode.Byte:
                return(new ConstantByteValue {
                    Value = blob.ReadByte()
                });

            case ConstantTypeCode.Char:
                return(new ConstantCharValue {
                    Value = blob.ReadChar()
                });

            case ConstantTypeCode.Double:
                return(new ConstantDoubleValue {
                    Value = blob.ReadDouble()
                });

            case ConstantTypeCode.Int16:
                return(new ConstantInt16Value {
                    Value = blob.ReadInt16()
                });

            case ConstantTypeCode.Int32:
                return(new ConstantInt32Value {
                    Value = blob.ReadInt32()
                });

            case ConstantTypeCode.Int64:
                return(new ConstantInt64Value {
                    Value = blob.ReadInt64()
                });

            case ConstantTypeCode.SByte:
                return(new ConstantSByteValue {
                    Value = blob.ReadSByte()
                });

            case ConstantTypeCode.Single:
                return(new ConstantSingleValue {
                    Value = blob.ReadSingle()
                });

            case ConstantTypeCode.String:
                return(HandleString(blob.ReadUTF16(blob.Length)));

            case ConstantTypeCode.UInt16:
                return(new ConstantUInt16Value {
                    Value = blob.ReadUInt16()
                });

            case ConstantTypeCode.UInt32:
                return(new ConstantUInt32Value {
                    Value = blob.ReadUInt32()
                });

            case ConstantTypeCode.UInt64:
                return(new ConstantUInt64Value {
                    Value = blob.ReadUInt64()
                });

            case ConstantTypeCode.NullReference:
                return(new ConstantReferenceValue());

            default:
                throw new BadImageFormatException();
            }
        }
Exemple #8
0
        private Event HandleEvent(Cts.Ecma.EcmaModule module, Ecma.EventDefinitionHandle eventHandle)
        {
            Ecma.MetadataReader reader = module.MetadataReader;

            Ecma.EventDefinition eventDef = reader.GetEventDefinition(eventHandle);

            Ecma.EventAccessors acc           = eventDef.GetAccessors();
            Cts.MethodDesc      adderMethod   = acc.Adder.IsNil ? null : module.GetMethod(acc.Adder);
            Cts.MethodDesc      raiserMethod  = acc.Raiser.IsNil ? null : module.GetMethod(acc.Raiser);
            Cts.MethodDesc      removerMethod = acc.Remover.IsNil ? null : module.GetMethod(acc.Remover);

            bool adderHasMetadata   = adderMethod != null && _policy.GeneratesMetadata(adderMethod);
            bool raiserHasMetadata  = raiserMethod != null && _policy.GeneratesMetadata(raiserMethod);
            bool removerHasMetadata = removerMethod != null && _policy.GeneratesMetadata(removerMethod);

            // Policy: If none of the accessors has metadata, event doesn't have metadata
            if (!adderHasMetadata && !raiserHasMetadata && !removerHasMetadata)
            {
                return(null);
            }

            Event result = new Event
            {
                Name  = HandleString(reader.GetString(eventDef.Name)),
                Flags = eventDef.Attributes,
                Type  = HandleType(module.GetType(eventDef.Type)),
            };

            if (adderHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.AddOn,
                    Method     = HandleMethodDefinition(adderMethod),
                });
            }

            if (raiserHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Fire,
                    Method     = HandleMethodDefinition(raiserMethod),
                });
            }

            if (removerHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.RemoveOn,
                    Method     = HandleMethodDefinition(removerMethod),
                });
            }

            Ecma.CustomAttributeHandleCollection customAttributes = eventDef.GetCustomAttributes();
            if (customAttributes.Count > 0)
            {
                result.CustomAttributes = HandleCustomAttributes(module, customAttributes);
            }

            return(result);
        }
        private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property)
        {
            Ecma.MetadataReader reader = module.MetadataReader;

            Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property);

            Ecma.PropertyAccessors acc          = propDef.GetAccessors();
            Cts.MethodDesc         getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter);
            Cts.MethodDesc         setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter);

            bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod);
            bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod);

            // Policy: If neither the getter nor setter have metadata, property doesn't have metadata
            if (!getterHasMetadata && !setterHasMetadata)
            {
                return(null);
            }

            Ecma.BlobReader       sigBlobReader = reader.GetBlobReader(propDef.Signature);
            Cts.PropertySignature sig           = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader).ParsePropertySignature();

            List <ParameterTypeSignature> parameters;

            if (sig.Length == 0)
            {
                parameters = null;
            }
            else
            {
                parameters = new List <ParameterTypeSignature>(sig.Length);
                for (int i = 0; i < parameters.Count; i++)
                {
                    parameters.Add(HandleParameterTypeSignature(sig[i]));
                }
            }

            Property result = new Property
            {
                Name      = HandleString(reader.GetString(propDef.Name)),
                Flags     = propDef.Attributes,
                Signature = new PropertySignature
                {
                    CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis,
                    // TODO: CustomModifiers
                    Type       = HandleType(sig.ReturnType),
                    Parameters = parameters,
                },
            };

            if (getterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Getter,
                    Method     = HandleMethodDefinition(getterMethod),
                });
            }

            if (setterHasMetadata)
            {
                result.MethodSemantics.Add(new MethodSemantics
                {
                    Attributes = MethodSemanticsAttributes.Setter,
                    Method     = HandleMethodDefinition(setterMethod),
                });
            }

            // TODO: DefaultValue
            // TODO: CustomAttributes

            return(result);
        }
Exemple #10
0
 private TypeForwarder HandleTypeForwarder(Cts.Ecma.EcmaModule module, Ecma.ExportedTypeHandle handle)
 {
     return(_forwarders.GetOrCreate(new ForwarderKey(module, handle), _initForwarder ?? (_initForwarder = InitializeTypeForwarder)));
 }
Exemple #11
0
 public ForwarderKey(Cts.Ecma.EcmaModule module, Ecma.ExportedTypeHandle exportedType)
 => (Module, ExportedType) = (module, exportedType);