static void PopulateAttributesThatDontAppearInCustomAttributes(ICustomAttributeProvider type, CodeAttributeDeclarationCollection attributes) { if (type is TypeDefinition typeDefinition) { if (typeDefinition.Attributes.HasFlag(Mono.Cecil.TypeAttributes.Serializable)) { var attribute = new CodeAttributeDeclaration("System.SerializableAttribute"); attribute.Name = AttributeNameBuilder.Get(attribute.Name); attributes.Add(attribute); } } }
static CodeAttributeDeclaration GenerateCodeAttributeDeclaration(Func <CodeTypeReference, CodeTypeReference> codeTypeModifier, CustomAttribute customAttribute) { var attribute = new CodeAttributeDeclaration(codeTypeModifier(customAttribute.AttributeType.CreateCodeTypeReference(mode: NullableMode.Disable))); attribute.Name = AttributeNameBuilder.Get(attribute.Name); foreach (var arg in customAttribute.ConstructorArguments) { attribute.Arguments.Add(new CodeAttributeArgument(CreateInitialiserExpression(arg))); } foreach (var field in customAttribute.Fields.OrderBy(f => f.Name, StringComparer.Ordinal)) { attribute.Arguments.Add(new CodeAttributeArgument(field.Name, CreateInitialiserExpression(field.Argument))); } foreach (var property in customAttribute.Properties.OrderBy(p => p.Name, StringComparer.Ordinal)) { attribute.Arguments.Add(new CodeAttributeArgument(property.Name, CreateInitialiserExpression(property.Argument))); } return(attribute); }
static void AddPropertyToTypeDeclaration(CodeTypeDeclaration typeDeclaration, IMemberDefinition typeDeclarationInfo, PropertyDefinition member, AttributeFilter attributeFilter) { var getterAttributes = member.GetMethod?.GetMethodAttributes() ?? 0; var setterAttributes = member.SetMethod?.GetMethodAttributes() ?? 0; var hasGet = ShouldIncludeMember(getterAttributes); var hasSet = ShouldIncludeMember(setterAttributes); if (!(hasGet | hasSet)) { return; } var propertyAttributes = CecilEx.CombineAccessorAttributes(getterAttributes, setterAttributes); var propertyType = member.PropertyType.IsGenericParameter ? new CodeTypeReference(member.PropertyType.Name) : member.PropertyType.CreateCodeTypeReference(member); if (member.PropertyType.IsUnsafeSignatureType()) { propertyType = propertyType.MakeUnsafe(); } var property = new CodeMemberProperty { Name = PropertyNameBuilder.AugmentPropertyNameWithPropertyModifierMarkerTemplate(member, getterAttributes, setterAttributes), Type = propertyType, Attributes = propertyAttributes, CustomAttributes = CreateCustomAttributes(member, attributeFilter), HasGet = hasGet, HasSet = hasSet }; // DefaultMemberAttribute on type gets propagated to IndexerNameAttribute var defaultMemberAttributeValue = typeDeclarationInfo.CustomAttributes.SingleOrDefault(x => x.AttributeType.FullName == "System.Reflection.DefaultMemberAttribute") ?.ConstructorArguments.Select(x => x.Value).OfType <string>().SingleOrDefault(); if (!string.IsNullOrEmpty(defaultMemberAttributeValue) && member.Name == defaultMemberAttributeValue && member.Name != "Item") { property.Name = "Item"; property.CustomAttributes.Add( new CodeAttributeDeclaration( AttributeNameBuilder.Get("System.Runtime.CompilerServices.IndexerNameAttribute")) { Arguments = { new CodeAttributeArgument(new CodePrimitiveExpression(defaultMemberAttributeValue)) } }); } // Here's a nice hack, because hey, guess what, the CodeDOM doesn't support // attributes on getters or setters if (member.GetMethod != null && member.GetMethod.HasCustomAttributes) { PopulateCustomAttributes(member.GetMethod, property.CustomAttributes, type => type.MakeGet(), attributeFilter); } if (member.SetMethod != null && member.SetMethod.HasCustomAttributes) { PopulateCustomAttributes(member.SetMethod, property.CustomAttributes, type => type.MakeSet(), attributeFilter); } foreach (var parameter in member.Parameters) { property.Parameters.Add( new CodeParameterDeclarationExpression(parameter.ParameterType.CreateCodeTypeReference(parameter), parameter.Name)); } // TODO: CodeDOM has no support for different access modifiers for getters and setters // TODO: CodeDOM has no support for attributes on setters or getters - promote to property? typeDeclaration.Members.Add(property); }