Skip to content

Commit

Permalink
Merge pull request #326 from jmatss/fix-attribute-group-interface
Browse files Browse the repository at this point in the history
Fix invalid interface generated for attribute group containing attribute with list type
  • Loading branch information
mganss authored May 18, 2022
2 parents f5c2837 + 4fc5714 commit f18798b
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 4 deletions.
86 changes: 86 additions & 0 deletions XmlSchemaClassGenerator.Tests/XmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2578,5 +2578,91 @@ public void TestArrayItemAttribute()
var optionList = applicationType.GetProperty("OptionList");
Assert.Equal("Test_Generation_Namespace.T_OptionList", optionList.PropertyType.FullName);
}

[Fact]
public void CollectionSetterInAttributeGroupInterfaceIsPrivateIfCollectionSetterModeIsPrivate()
{
const string xsd = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"">
<xs:element name=""Element"">
<xs:complexType>
<xs:attributeGroup ref=""AttrGroup""/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name=""AttrGroup"">
<xs:attribute name=""Attr"">
<xs:simpleType>
<xs:list itemType=""xs:int""/>
</xs:simpleType>
</xs:attribute>
</xs:attributeGroup>
</xs:schema>";

var generator = new Generator
{
NamespaceProvider = new NamespaceProvider
{
GenerateNamespace = key => "Test",
},
GenerateInterfaces = true,
CollectionSettersMode = CollectionSettersMode.Private
};
var contents = ConvertXml(nameof(CollectionSetterInAttributeGroupInterfaceIsPrivateIfCollectionSetterModeIsPrivate), xsd, generator).ToArray();
var assembly = Compiler.Compile(nameof(CollectionSetterInAttributeGroupInterfaceIsPrivateIfCollectionSetterModeIsPrivate), contents);

var interfaceProperty = assembly.GetType("Test.IAttrGroup")?.GetProperty("Attr");
var implementerProperty = assembly.GetType("Test.Element")?.GetProperty("Attr");
Assert.NotNull(interfaceProperty);
Assert.NotNull(implementerProperty);

var interfaceHasPublicSetter = interfaceProperty.GetSetMethod() != null;
var implementerHasPublicSetter = implementerProperty.GetSetMethod() != null;
Assert.False(interfaceHasPublicSetter);
Assert.False(implementerHasPublicSetter);
}

[Fact]
public void CollectionSetterInAttributeGroupInterfaceIsPublicIfCollectionSetterModeIsPublic()
{
const string xsd = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"">
<xs:element name=""Element"">
<xs:complexType>
<xs:attributeGroup ref=""AttrGroup""/>
</xs:complexType>
</xs:element>
<xs:attributeGroup name=""AttrGroup"">
<xs:attribute name=""Attr"">
<xs:simpleType>
<xs:list itemType=""xs:int""/>
</xs:simpleType>
</xs:attribute>
</xs:attributeGroup>
</xs:schema>";

var generator = new Generator
{
NamespaceProvider = new NamespaceProvider
{
GenerateNamespace = key => "Test",
},
GenerateInterfaces = true,
CollectionSettersMode = CollectionSettersMode.Public
};
var contents = ConvertXml(nameof(CollectionSetterInAttributeGroupInterfaceIsPublicIfCollectionSetterModeIsPublic), xsd, generator).ToArray();
var assembly = Compiler.Compile(nameof(CollectionSetterInAttributeGroupInterfaceIsPublicIfCollectionSetterModeIsPublic), contents);

var interfaceProperty = assembly.GetType("Test.IAttrGroup")?.GetProperty("Attr");
var implementerProperty = assembly.GetType("Test.Element")?.GetProperty("Attr");
Assert.NotNull(interfaceProperty);
Assert.NotNull(implementerProperty);

var interfaceHasPublicSetter = interfaceProperty.GetSetMethod() != null;
var implementerHasPublicSetter = implementerProperty.GetSetMethod() != null;
Assert.True(interfaceHasPublicSetter);
Assert.True(implementerHasPublicSetter);
}
}
}
16 changes: 12 additions & 4 deletions XmlSchemaClassGenerator/TypeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,15 @@ private bool IsList
}
}

private bool IsPrivateSetter
{
get
{
return Configuration.CollectionSettersMode == CollectionSettersMode.Private
&& (IsCollection || IsArray || (IsList && IsAttribute));
}
}

private CodeTypeReference TypeReference
{
get
Expand Down Expand Up @@ -825,9 +834,9 @@ public void AddInterfaceMembersTo(CodeTypeDeclaration typeDeclaration)
{
CodeTypeMember member;

var isArray = IsArray;
var propertyType = PropertyType;
var isNullableValueType = IsNullableValueType;
var isPrivateSetter = IsPrivateSetter;
var typeReference = TypeReference;

if (isNullableValueType && Configuration.GenerateNullables)
Expand All @@ -842,7 +851,7 @@ public void AddInterfaceMembersTo(CodeTypeDeclaration typeDeclaration)
Name = Name,
Type = typeReference,
HasGet = true,
HasSet = !IsCollection && !isArray
HasSet = !isPrivateSetter
};

if (DefaultValue != null && IsNullable)
Expand Down Expand Up @@ -872,6 +881,7 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi
var propertyType = PropertyType;
var isNullableValueType = IsNullableValueType;
var isNullableReferenceType = IsNullableReferenceType;
var isPrivateSetter = IsPrivateSetter;
var typeReference = TypeReference;

var requiresBackingField = withDataBinding || DefaultValue != null || IsCollection || isArray;
Expand Down Expand Up @@ -935,8 +945,6 @@ public void AddMembersTo(CodeTypeDeclaration typeDeclaration, bool withDataBindi
else
member = new CodeMemberField(typeReference, propertyName);

var isPrivateSetter = (IsCollection || isArray || (IsList && IsAttribute)) && Configuration.CollectionSettersMode == CollectionSettersMode.Private;

if (requiresBackingField)
{
member.Name += GetAccessors(member.Name, backingField.Name,
Expand Down

0 comments on commit f18798b

Please sign in to comment.