Skip to content

Commit

Permalink
Merge pull request #284 from gureedo/master
Browse files Browse the repository at this point in the history
any attribute is not rendered if complex type extends other complex type
  • Loading branch information
mganss authored Sep 8, 2021
2 parents c7f5dcd + bb89889 commit 74feff9
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 19 deletions.
3 changes: 2 additions & 1 deletion XmlSchemaClassGenerator.Tests/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ public static Assembly GenerateFiles(string name, IEnumerable<string> files, Gen
CompactTypeNames = generatorPrototype.CompactTypeNames,
UniqueTypeNamesAcrossNamespaces = generatorPrototype.UniqueTypeNamesAcrossNamespaces,
CreateGeneratedCodeAttributeVersion = generatorPrototype.CreateGeneratedCodeAttributeVersion,
NetCoreSpecificCode = generatorPrototype.NetCoreSpecificCode
NetCoreSpecificCode = generatorPrototype.NetCoreSpecificCode,
NamingScheme = generatorPrototype.NamingScheme
};

gen.CommentLanguages.Clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Glob.cs" Version="5.1.766" />
<PackageReference Include="Microsoft.Net.Compilers.netcore" Version="1.3.2" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="System.CodeDom" Version="5.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
Expand Down
27 changes: 21 additions & 6 deletions XmlSchemaClassGenerator.Tests/XmlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,24 @@ public void TestListWithPublicPropertySettersWithoutConstructorsSpecified()
}
}

public static IEnumerable<object[]> TestSimpleData() {
foreach (var referenceMode in new[]
{ CodeTypeReferenceOptions.GlobalReference, /*CodeTypeReferenceOptions.GenericTypeParameter*/ })
foreach (var namingScheme in new[] { NamingScheme.Direct, NamingScheme.PascalCase })
foreach (var collectionType in new[] { typeof(Collection<>), /*typeof(Array)*/ })
{
yield return new object[] { referenceMode, namingScheme, collectionType };
}
}

[Fact, TestPriority(1)]

[Theory, TestPriority(1)]
[MemberData(nameof(TestSimpleData))]
[UseCulture("en-US")]
public void TestSimple()
public void TestSimple(CodeTypeReferenceOptions referenceMode, NamingScheme namingScheme, Type collectionType)
{
Compiler.Generate("Simple", SimplePattern, new Generator
var name = $"Simple_{referenceMode}_{namingScheme}_{collectionType}";
Compiler.Generate(name, SimplePattern, new Generator
{
GenerateNullables = true,
IntegerDataType = typeof(int),
Expand All @@ -316,10 +328,13 @@ public void TestSimple()
GenerateInterfaces = true,
NamespacePrefix = "Simple",
GenerateDescriptionAttribute = true,
CodeTypeReferenceOptions = CodeTypeReferenceOptions.GlobalReference,
NetCoreSpecificCode = true
CodeTypeReferenceOptions = referenceMode,
NetCoreSpecificCode = true,
NamingScheme = namingScheme,
CollectionType = collectionType,
CollectionSettersMode = CollectionSettersMode.Public
});
TestSamples("Simple", SimplePattern);
TestSamples(name, SimplePattern);
}

[Fact, TestPriority(1)]
Expand Down
37 changes: 37 additions & 0 deletions XmlSchemaClassGenerator.Tests/xsd/simple/any.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>

<xs:schema id="default"
targetNamespace="http://tempuri.org/default.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/default.xsd"
xmlns:mstns="http://tempuri.org/default.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="AnyTest_ExtendedString">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:anyAttribute namespace="##any" processContents="lax"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

<xs:complexType name="AnyTest_Type">
<xs:sequence/>
<xs:anyAttribute namespace="##any" processContents="lax"/>
</xs:complexType>

<xs:complexType name="AnyTest_ExtendedTypeWithAnyAttr">
<xs:complexContent>
<xs:extension base="AnyTest_Type">
<xs:anyAttribute namespace="##any" processContents="lax"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>

<xs:complexType name="AnyTest_ExtendedTypeWithoutAnyAttr">
<xs:complexContent>
<xs:extension base="AnyTest_Type" />
</xs:complexContent>
</xs:complexType>

</xs:schema>
29 changes: 29 additions & 0 deletions XmlSchemaClassGenerator.Tests/xsd/simple/fields_ambiguity.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>

<xs:schema id="default"
targetNamespace="http://tempuri.org/default.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/default.xsd"
xmlns:mstns="http://tempuri.org/default.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="AmbiguityTest_Type">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Property">
<xs:complexType>
<xs:sequence>
<xs:element name="Value" type="AmbiguityTest_NestedType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="value" type="xs:string" use="optional" default="" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>

<xs:complexType name="AmbiguityTest_NestedType">
<xs:attribute name="NestedItem" type="xs:string" use="required" />
</xs:complexType>

</xs:schema>
24 changes: 24 additions & 0 deletions XmlSchemaClassGenerator.Tests/xsd/simple/nested_type.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>

<xs:schema id="default"
targetNamespace="http://tempuri.org/default.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/default.xsd"
xmlns:mstns="http://tempuri.org/default.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

<xs:complexType name="NestedTest_NestedType">
<xs:sequence>
<xs:element name="TestField" type="xs:string" />
</xs:sequence>
</xs:complexType>

<xs:complexType name="NestedTest_Type">
<xs:sequence>
<xs:element name="TestField" type="NestedTest_NestedType" minOccurs="0" maxOccurs="1" />
<xs:element name="TestCollectionField" type="NestedTest_NestedType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>

</xs:schema>
20 changes: 14 additions & 6 deletions XmlSchemaClassGenerator/CodeUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,6 @@ public static string GetUniqueFieldName(this TypeModel typeModel, PropertyModel
var i = 0;
foreach (var prop in classModel.Properties)
{
if (!classModel.Configuration.EnableDataBinding && !(prop.Type is SimpleModel))
{
continue;
}

if (propertyModel == prop)
{
i += 1;
Expand Down Expand Up @@ -399,7 +394,20 @@ public static CodeTypeReference CreateTypeReference(Type t, GeneratorConfigurati
return typeRef;
}
else
return new CodeTypeReference(t, conf.CodeTypeReferenceOptions);
{
var typeRef = new CodeTypeReference(t, conf.CodeTypeReferenceOptions);

foreach (var typeArg in typeRef.TypeArguments)
{
if (typeArg is CodeTypeReference typeArgRef)
{
typeArgRef.Options = conf.CodeTypeReferenceOptions;
}
}

return typeRef;
}

}

public static CodeTypeReference CreateTypeReference(string namespaceName, string typeName, GeneratorConfiguration conf)
Expand Down
25 changes: 24 additions & 1 deletion XmlSchemaClassGenerator/ModelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace XmlSchemaClassGenerator
{
Expand Down Expand Up @@ -577,7 +578,29 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaComplexType complexType,
}
}

XmlSchemaAnyAttribute anyAttribute = null;
if (complexType.AnyAttribute != null)
anyAttribute = complexType.AnyAttribute;
else if (complexType.AttributeWildcard != null)
{
var hasAnyAttribute = true;
for (var baseType = complexType.BaseXmlSchemaType; baseType != null; baseType = baseType.BaseXmlSchemaType)
{
if (baseType is not XmlSchemaComplexType baseComplexType)
continue;

if (baseComplexType.AttributeWildcard != null)
{
hasAnyAttribute = false;
break;
}
}

if (hasAnyAttribute)
anyAttribute = complexType.AttributeWildcard;
}

if (anyAttribute != null)
{
var property = new PropertyModel(_configuration)
{
Expand All @@ -589,7 +612,7 @@ private TypeModel CreateTypeModel(Uri source, XmlSchemaComplexType complexType,
IsAny = true
};

var attributeDocs = GetDocumentation(complexType.AnyAttribute);
var attributeDocs = GetDocumentation(anyAttribute);
property.Documentation.AddRange(attributeDocs);

classModel.Properties.Add(property);
Expand Down
25 changes: 21 additions & 4 deletions XmlSchemaClassGenerator/TypeModel.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
Expand Down Expand Up @@ -172,17 +171,32 @@ protected void GenerateSerializableAttribute(CodeTypeDeclaration typeDeclaration
public virtual CodeTypeReference GetReferenceFor(NamespaceModel referencingNamespace, bool collection = false, bool forInit = false, bool attribute = false)
{
string name;
var referencingOptions = Configuration.CodeTypeReferenceOptions;
if (referencingNamespace == Namespace)
{
name = Name;
referencingOptions = CodeTypeReferenceOptions.GenericTypeParameter;
}
else if ((referencingNamespace ?? Namespace).IsAmbiguous)
{
name = string.Format("global::{0}.{1}", Namespace.Name, Name);
referencingOptions = CodeTypeReferenceOptions.GenericTypeParameter;
}
else
name = string.Format("{2}{0}.{1}", Namespace.Name, Name, ((referencingNamespace ?? Namespace).IsAmbiguous ? "global::" : string.Empty));
{
name = string.Format("{0}.{1}", Namespace.Name, Name);
}

if (collection)
{
name = forInit ? SimpleModel.GetCollectionImplementationName(name, Configuration) : SimpleModel.GetCollectionDefinitionName(name, Configuration);
if (Configuration.CollectionType == typeof(System.Array))
referencingOptions = CodeTypeReferenceOptions.GenericTypeParameter;
else
referencingOptions = Configuration.CodeTypeReferenceOptions;
}

return new CodeTypeReference(name, Configuration.CodeTypeReferenceOptions);
return new CodeTypeReference(name, referencingOptions);
}

public virtual CodeExpression GetDefaultValueFor(string defaultString, bool attribute)
Expand Down Expand Up @@ -1411,7 +1425,10 @@ private static string GetFullTypeName(string typeName, CodeTypeReference typeRef
typeRef.ArrayElementType = new CodeTypeReference(typeName);
typeRef.ArrayRank = 1;
}
var typeOfExpr = new CodeTypeOfExpression(typeRef);
var typeOfExpr = new CodeTypeOfExpression(typeRef)
{
Type = { Options = CodeTypeReferenceOptions.GenericTypeParameter }
};
var writer = new System.IO.StringWriter();
CSharpProvider.GenerateCodeFromExpression(typeOfExpr, writer, new CodeGeneratorOptions());
var fullTypeName = writer.ToString();
Expand Down

0 comments on commit 74feff9

Please sign in to comment.