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