Skip to content

Commit 269889d

Browse files
committed
wip: array nullable reference type
1 parent 44234f6 commit 269889d

3 files changed

Lines changed: 81 additions & 3 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Xml.Schema;
7+
using Xunit;
8+
using Xunit.Abstractions;
9+
10+
namespace XmlSchemaClassGenerator.Tests;
11+
12+
public class NullableElementReferenceListTest(ITestOutputHelper testOutputHelper)
13+
{
14+
[Fact]
15+
public void Test()
16+
{
17+
var mow = new MemoryOutputWriter();
18+
var gen = new Generator()
19+
{
20+
OutputWriter = mow,
21+
Log = testOutputHelper.WriteLine,
22+
GenerateNullables = true,
23+
EnableNullableReferenceAttributes = true,
24+
GenerateInterfaces = false,
25+
CompactTypeNames = true,
26+
CollectionType = typeof(Array),
27+
CollectionSettersMode = CollectionSettersMode.PublicWithoutConstructorInitialization,
28+
UseShouldSerializePattern = true,
29+
SerializeEmptyCollections = true
30+
};
31+
gen.Generate(GetXmlSchemaSet(Schema));
32+
33+
// log generated code
34+
foreach (var line in mow.Content.SelectMany(l => l.Split(Environment.NewLine))) testOutputHelper.WriteLine(line);
35+
36+
var assembly = Compiler.Compile(nameof(Test), mow.Content.ToArray());
37+
void assertNullable(string typename, bool nullable)
38+
{
39+
Type c = assembly.GetType(typename);
40+
var property = c.GetProperty("Text");
41+
var setParameter = property.SetMethod.GetParameters();
42+
var getReturnParameter = property.GetMethod.ReturnParameter;
43+
var allowNullableAttribute = setParameter.Single().CustomAttributes.SingleOrDefault(a => a.AttributeType == typeof(AllowNullAttribute));
44+
var maybeNullAttribute = getReturnParameter.CustomAttributes.SingleOrDefault(a => a.AttributeType == typeof(MaybeNullAttribute));
45+
var hasAllowNullAttribute = allowNullableAttribute != null;
46+
var hasMaybeNullAttribute = maybeNullAttribute != null;
47+
Assert.Equal(nullable, hasAllowNullAttribute);
48+
Assert.Equal(nullable, hasMaybeNullAttribute);
49+
}
50+
assertNullable("SampleNamespace.ElementReferenceList", true);
51+
}
52+
53+
const string Schema = """
54+
<?xml version="1.0" encoding="UTF-8"?>
55+
<xs:schema xmlns="SampleNamespace" targetNamespace="SampleNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
56+
<xs:element name="ElementReferenceList">
57+
<xs:complexType>
58+
<xs:sequence>
59+
<xs:element name="Text" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
60+
<xs:element name="Todo" type="xs:string" minOccurs="0"/>
61+
</xs:sequence>
62+
</xs:complexType>
63+
</xs:element>
64+
</xs:schema>
65+
""";
66+
67+
private XmlSchemaSet GetXmlSchemaSet(string xsd)
68+
{
69+
var ms = new MemoryStream(Encoding.UTF8.GetBytes(xsd));
70+
var schema = XmlSchema.Read(ms, null)!;
71+
var set = new XmlSchemaSet();
72+
set.Add(schema);
73+
return set;
74+
}
75+
}

XmlSchemaClassGenerator.Tests/XmlTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2688,7 +2688,7 @@ void assertNullable(string typename, bool nullable)
26882688
Assert.Equal(nullable, hasMaybeNullAttribute);
26892689
}
26902690
assertNullable("Test.ElementReferenceNullable", true);
2691-
assertNullable("Test.ElementReferenceList", false);
2691+
assertNullable("Test.ElementReferenceList", false); // fails
26922692
assertNullable("Test.ElementReferenceNonNullable", false);
26932693
assertNullable("Test.AttributeReferenceNullable", true);
26942694
assertNullable("Test.AttributeReferenceNonNullable", false);

XmlSchemaClassGenerator/TypeModel.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.CodeDom;
33
using System.CodeDom.Compiler;
44
using System.Collections.Generic;
@@ -606,7 +606,10 @@ string checkEquality()
606606

607607
private bool IsNullableValueType => IsNullable && IsValueType;
608608

609-
private bool IsNullableReferenceType => IsNullable && (PropertyType is ClassModel || (PropertyType is SimpleModel model && !model.ValueType.IsValueType));
609+
// IsNullable excludes enumerables
610+
// private bool IsNullableReferenceType => IsNullable && (PropertyType is ClassModel || (PropertyType is SimpleModel model && !model.ValueType.IsValueType));
611+
612+
private bool IsNullableReferenceType => DefaultValue == null && !IsRequired && (PropertyType is ClassModel || (PropertyType is SimpleModel model && !model.ValueType.IsValueType));
610613

611614
private bool IsNillableValueType => IsNillable && !IsEnumerable && IsValueType;
612615

0 commit comments

Comments
 (0)