Ejemplo n.º 1
0
        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);

            Ecma.MetadataReader reader = module.MetadataReader;

            foreach (var attributeHandle in attributes)
            {
                if (!_policy.GeneratesMetadata(module, attributeHandle))
                {
                    continue;
                }

                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);

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

            return(customAttributes);
        }
Ejemplo n.º 2
0
        static decimal?TryDecodeDecimalConstantAttribute(MetadataModule module, System.Reflection.Metadata.CustomAttribute attribute)
        {
            var attrValue = attribute.DecodeValue(module.TypeProvider);

            if (attrValue.FixedArguments.Length != 5)
            {
                return(null);
            }
            // DecimalConstantAttribute has the arguments (byte scale, byte sign, uint hi, uint mid, uint low) or (byte scale, byte sign, int hi, int mid, int low)
            // Both of these invoke the Decimal constructor (int lo, int mid, int hi, bool isNegative, byte scale) with explicit argument conversions if required.
            if (!(attrValue.FixedArguments[0].Value is byte scale && attrValue.FixedArguments[1].Value is byte sign))
            {
                return(null);
            }
            unchecked {
                if (attrValue.FixedArguments[2].Value is uint hi &&
                    attrValue.FixedArguments[3].Value is uint mid &&
                    attrValue.FixedArguments[4].Value is uint lo)
                {
                    return(new decimal((int)lo, (int)mid, (int)hi, sign != 0, scale));
                }
            }
            {
                if (attrValue.FixedArguments[2].Value is int hi &&
                    attrValue.FixedArguments[3].Value is int mid &&
                    attrValue.FixedArguments[4].Value is int lo)
                {
                    return(new decimal(lo, mid, hi, sign != 0, scale));
                }
            }
            return(null);
        }
Ejemplo n.º 3
0
        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

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

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

                    customAttributes.Add(HandleCustomAttribute(constructor, decodedValue));
                }
                catch (Cts.TypeSystemException)
                {
                    // TODO: We should emit unresolvable custom attributes instead of skipping these
                }
            }

            return(customAttributes);
        }
        /// <summary>
        /// This method will return a list of parameter values for the custom attribute.
        /// </summary>
        /// <remarks>
        /// Currently, this only works for string values
        /// </remarks>
        public static ImmutableArray<string> GetParameterValues(this MetadataReader metadataReader, CustomAttribute customAttribute)
        {
            if (customAttribute.Constructor.Kind != HandleKind.MemberReference)
            {
                throw new InvalidOperationException();
            }

            var ctor = metadataReader.GetMemberReference((MemberReferenceHandle)customAttribute.Constructor);
            var signature = SignatureDecoder.DecodeMethodSignature(ctor.Signature, new StringParameterValueTypeProvider(metadataReader, customAttribute.Value));

            return signature.ParameterTypes;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the fixed (required) string arguments of a custom attribute.
        /// Only attributes that have only fixed string arguments.
        /// </summary>
        private static List<string> GetFixedStringArguments(MetadataReader reader, CustomAttribute attribute)
        {
            // TODO: Nick Guerrera ([email protected]) hacked this method for temporary use.
            // There is a blob decoder feature in progress but it won't ship in time for our milestone.
            // Replace this method with the blob decoder feature when later it is availale.

            var signature = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature;
            var signatureReader = reader.GetBlobReader(signature);
            var valueReader = reader.GetBlobReader(attribute.Value);
            var arguments = new List<string>();

            var prolog = valueReader.ReadUInt16();
            if (prolog != 1)
            {
                // Invalid custom attribute prolog
                return arguments;
            }

            var header = signatureReader.ReadSignatureHeader();
            if (header.Kind != SignatureKind.Method || header.IsGeneric)
            {
                // Invalid custom attribute constructor signature
                return arguments;
            }

            int parameterCount;
            if (!signatureReader.TryReadCompressedInteger(out parameterCount))
            {
                // Invalid custom attribute constructor signature
                return arguments;
            }

            var returnType = signatureReader.ReadSignatureTypeCode();
            if (returnType != SignatureTypeCode.Void)
            {
                // Invalid custom attribute constructor signature
                return arguments;
            }

            for (int i = 0; i < parameterCount; i++)
            {
                var signatureTypeCode = signatureReader.ReadSignatureTypeCode();
                if (signatureTypeCode == SignatureTypeCode.String)
                {
                    // Custom attribute constructor must take only strings
                    arguments.Add(valueReader.ReadSerializedString());
                }
            }

            return arguments;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets the type of the attribute.
        /// </summary>
        public static EntityHandle GetAttributeType(this SRM.CustomAttribute attribute, MetadataReader reader)
        {
            switch (attribute.Constructor.Kind)
            {
            case HandleKind.MethodDefinition:
                var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
                return(md.GetDeclaringType());

            case HandleKind.MemberReference:
                var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
                return(mr.Parent);

            default:
                throw new BadImageFormatException("Unexpected token kind for attribute constructor: " + attribute.Constructor.Kind);
            }
        }
Ejemplo n.º 7
0
        public static Handle GetAttributeTypeHandle(this MetadataReader metadataReader, CustomAttribute customAttribute)
        {
            Handle attributeTypeHandle;
            var ctor = customAttribute.Constructor;
            if (ctor.HandleType == HandleType.MemberReference)
            {
                var memberReferenceHandle = (MemberReferenceHandle)ctor;
                var memberReference = metadataReader.GetMemberReference(memberReferenceHandle);
                attributeTypeHandle = memberReference.Parent;
            }
            else
            {
                MethodHandle methodHandle = (MethodHandle)ctor;
                var method = metadataReader.GetMethod(methodHandle);
                attributeTypeHandle = metadataReader.GetDeclaringType(methodHandle);
            }

            return attributeTypeHandle;
        }
        /// <summary>Gets the string argument value of an attribute with a single fixed string argument.</summary>
        /// <param name="reader">The metadata reader.</param>
        /// <param name="attr">The attribute.</param>
        /// <param name="value">The value parsed from the attribute, if it could be retrieved; otherwise, the value is left unmodified.</param>
        private static void GetStringAttributeArgumentValue(MetadataReader reader, CustomAttribute attr, ref string value)
        {
            EntityHandle ctorHandle = attr.Constructor;
            BlobHandle signature;
            switch (ctorHandle.Kind)
            {
                case HandleKind.MemberReference:
                    signature = reader.GetMemberReference((MemberReferenceHandle)ctorHandle).Signature;
                    break;
                case HandleKind.MethodDefinition:
                    signature = reader.GetMethodDefinition((MethodDefinitionHandle)ctorHandle).Signature;
                    break;
                default:
                    // Unusual case, potentially invalid IL
                    return;
            }

            BlobReader signatureReader = reader.GetBlobReader(signature);
            BlobReader valueReader = reader.GetBlobReader(attr.Value);

            const ushort Prolog = 1; // two-byte "prolog" defined by ECMA-335 (II.23.3) to be at the beginning of attribute value blobs
            if (valueReader.ReadUInt16() == Prolog)
            {
                SignatureHeader header = signatureReader.ReadSignatureHeader();
                int parameterCount;
                if (header.Kind == SignatureKind.Method &&                               // attr ctor must be a method
                    !header.IsGeneric &&                                                 // attr ctor must be non-generic
                    signatureReader.TryReadCompressedInteger(out parameterCount) &&      // read parameter count
                    parameterCount == 1 &&                                               // attr ctor must have 1 parameter
                    signatureReader.ReadSignatureTypeCode() == SignatureTypeCode.Void && // attr ctor return type must be void
                    signatureReader.ReadSignatureTypeCode() == SignatureTypeCode.String) // attr ctor first parameter must be string
                {
                    value = valueReader.ReadSerializedString();
                }
            }
        }
        /// <summary>Gets the name of an attribute.</summary>
        /// <param name="reader">The metadata reader.</param>
        /// <param name="attr">The attribute.</param>
        /// <param name="typeNamespaceHandle">The namespace of the attribute.</param>
        /// <param name="typeNameHandle">The name of the attribute.</param>
        /// <returns>true if the name could be retrieved; otherwise, false.</returns>
        private static bool TryGetAttributeName(MetadataReader reader, CustomAttribute attr, out StringHandle typeNamespaceHandle, out StringHandle typeNameHandle)
        {
            EntityHandle ctorHandle = attr.Constructor;
            switch (ctorHandle.Kind)
            {
                case HandleKind.MemberReference:
                    EntityHandle container = reader.GetMemberReference((MemberReferenceHandle)ctorHandle).Parent;
                    if (container.Kind == HandleKind.TypeReference)
                    {
                        TypeReference tr = reader.GetTypeReference((TypeReferenceHandle)container);
                        typeNamespaceHandle = tr.Namespace;
                        typeNameHandle = tr.Name;
                        return true;
                    }
                    break;

                case HandleKind.MethodDefinition:
                    MethodDefinition md = reader.GetMethodDefinition((MethodDefinitionHandle)ctorHandle);
                    TypeDefinition td = reader.GetTypeDefinition(md.GetDeclaringType());
                    typeNamespaceHandle = td.Namespace;
                    typeNameHandle = td.Name;
                    return true;
            }

            // Unusual case, potentially invalid IL
            typeNamespaceHandle = default(StringHandle);
            typeNameHandle = default(StringHandle);
            return false;
        }
Ejemplo n.º 10
0
 internal static bool IsKnownAttribute(this SRM.CustomAttribute attr, MetadataReader metadata,
                                       KnownAttribute attrType)
 {
     return(attr.GetAttributeType(metadata).IsKnownType(metadata, attrType));
 }
Ejemplo n.º 11
0
        private bool TryHandleExportAttribute(CustomAttribute customAttribute, Handle attributeTypeDefinitionHandle)
        {
            bool isInheritedExport = false;
            bool isExport = IsExportAttribute(attributeTypeDefinitionHandle, out isInheritedExport);
            if (!isExport)
            {
                return false;
            }

            var parent = customAttribute.Parent;
            switch (parent.Kind)
            {
                case HandleKind.TypeDefinition:
                    var TypeDefinitionHandle = (TypeDefinitionHandle)parent;
                    TypeInfo exportedTypeInfo = GetOrCreateTypeInfo(TypeDefinitionHandle);
                    if (isInheritedExport)
                    {
                        //this.inheritedExportTypes.Add(TypeDefinitionHandle, true);
                        //this.inheritedExportTypesByName.Add(exportedTypeInfo.FullName);
                        //this.hasInheritedExports = true;
                    }
                    else
                    {
                        exportedTypeInfo.IsExported = true;
                    }

                    break;
                case HandleKind.PropertyDefinition:
                    MemberInfo propertyInfo = GetOrAddPropertyInfo((PropertyDefinitionHandle)parent);
                    this.AddExportedMember(propertyInfo);
                    break;
                case HandleKind.MethodDefinition:
                    MemberInfo methodInfo = GetOrAddMethodInfo((MethodDefinitionHandle)parent);
                    this.AddExportedMember(methodInfo);
                    break;
                case HandleKind.FieldDefinition:
                    MemberInfo exportedFieldInfo = GetOrAddFieldInfo((FieldDefinitionHandle)parent);
                    this.AddExportedMember(exportedFieldInfo);
                    break;
                default:
                    throw new NotImplementedException();
            }

            return true;
        }
Ejemplo n.º 12
0
        private bool TryHandleImportAttribute(CustomAttribute customAttribute, Handle attributeTypeDefinitionHandle)
        {
            bool isImport = IsImportAttribute(attributeTypeDefinitionHandle);
            if (!isImport)
            {
                return false;
            }

            var parent = customAttribute.Parent;
            switch (parent.Kind)
            {
                case HandleKind.PropertyDefinition:
                    MemberInfo propertyInfo = GetOrAddPropertyInfo((PropertyDefinitionHandle)parent);
                    this.AddImportedMember(propertyInfo);
                    break;
                case HandleKind.FieldDefinition:
                    MemberInfo fieldInfo = GetOrAddFieldInfo((FieldDefinitionHandle)parent);
                    this.AddImportedMember(fieldInfo);
                    break;
                case HandleKind.Parameter:
                    // ignore Import attributes on parameters of importing constructors
                    break;
                case HandleKind.MethodDefinition:
                case HandleKind.MethodImplementation:
                case HandleKind.MethodSpecification:
                default:
                    throw new NotImplementedException();
            }

            return true;
        }