Пример #1
0
        private CustomAttributeBuilder CreateCustomAttributeBuilder(Cci.ICustomAttribute attribute)
        {
            // TODO (tomat): Use CCI to build the blob?
            // TODO (tomat): The CustomAttributeBuilder has problems with application of an attribute on itself 
            // and other dependencies on unbaked types.
            // e.g. [My]class MyAttribute : Attribute { }

            var ctor = ResolveConstructor(attribute.Constructor(_context));
            var attributeType = ctor.DeclaringType;

            object[] argValues = new object[attribute.ArgumentCount];
            ArrayBuilder<object> propertyValues = null;
            ArrayBuilder<object> fieldValues = null;
            ArrayBuilder<FieldInfo> fields = null;
            ArrayBuilder<PropertyInfo> properties = null;
            try
            {
                int i = 0;
                foreach (Cci.IMetadataExpression arg in attribute.GetArguments(_context))
                {
                    argValues[i++] = GetMetadataExpressionValue(arg);
                }

                foreach (Cci.IMetadataNamedArgument namedArg in attribute.GetNamedArguments(_context))
                {
                    object value = GetMetadataExpressionValue(namedArg.ArgumentValue);
                    string name = namedArg.ArgumentName;

                    Type type = ResolveType(namedArg.Type);

                    if (namedArg.IsField)
                    {
                        if (fields == null)
                        {
                            fields = ArrayBuilder<FieldInfo>.GetInstance();
                            fieldValues = ArrayBuilder<object>.GetInstance();
                        }

                        var field = new FieldRef(attributeType, name, type);
                        fields.Add(field);
                        fieldValues.Add(value);
                    }
                    else
                    {
                        if (properties == null)
                        {
                            properties = ArrayBuilder<PropertyInfo>.GetInstance();
                            propertyValues = ArrayBuilder<object>.GetInstance();
                        }

                        var property = new CustomAttributeProperty(attributeType, name, type);
                        properties.Add(property);
                        propertyValues.Add(value);
                    }
                }

                try
                {
                    return new CustomAttributeBuilder(
                        ctor as ConstructorInfo ?? new ConstructorRef(ctor),
                        argValues,
                        (properties != null) ? properties.ToArray() : SpecializedCollections.EmptyArray<PropertyInfo>(),
                        (properties != null) ? propertyValues.ToArray() : SpecializedCollections.EmptyArray<object>(),
                        (fields != null) ? fields.ToArray() : SpecializedCollections.EmptyArray<FieldInfo>(),
                        (fields != null) ? fieldValues.ToArray() : SpecializedCollections.EmptyArray<object>());
                }
                catch (ArgumentException)
                {
                    throw new NotSupportedException("Ref.Emit limitation");
                }
            }
            finally
            {
                if (properties != null)
                {
                    properties.Free();
                    propertyValues.Free();
                }

                if (fields != null)
                {
                    fields.Free();
                    fieldValues.Free();
                }
            }
        }