From c60cc6e44d1e4aa20a44d44558a4fa9f0319f4c3 Mon Sep 17 00:00:00 2001 From: Michael Ganss Date: Tue, 18 Jul 2023 17:55:59 +0200 Subject: [PATCH] Add union configuration option (see #397) --- XmlSchemaClassGenerator.Console/Program.cs | 3 +++ XmlSchemaClassGenerator.Tests/Compiler.cs | 1 + XmlSchemaClassGenerator.Tests/XmlTests.cs | 8 +++++++- XmlSchemaClassGenerator/CodeUtilities.cs | 2 +- XmlSchemaClassGenerator/Generator.cs | 6 ++++++ XmlSchemaClassGenerator/GeneratorConfiguration.cs | 8 +++++++- 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/XmlSchemaClassGenerator.Console/Program.cs b/XmlSchemaClassGenerator.Console/Program.cs index ae8034fa..20cdd6e0 100644 --- a/XmlSchemaClassGenerator.Console/Program.cs +++ b/XmlSchemaClassGenerator.Console/Program.cs @@ -62,6 +62,7 @@ static void Main(string[] args) var enumAsString = false; var namespaceFiles = new List(); var nameSubstituteFiles = new List(); + var unionCommonType = false; var options = new OptionSet { { "h|help", "show this message and exit", v => showHelp = v != null }, @@ -148,6 +149,7 @@ A file name may be given by appending a pipe sign (|) followed by a file name (l { "ar|useArrayItemAttribute", "use ArrayItemAttribute for sequences with single elements (default is true)", v => useArrayItemAttribute = v != null }, { "es|enumAsString", "Use string instead of enum for enumeration", v => enumAsString = v != null }, { "ca|commandArgs", "generate a comment with the exact command line arguments that were used to generate the source code (default is true)", v => generateCommandLineArgs = v != null }, + { "uc|unionCommonType", "generate a common type for unions if possible (default is false)", v => unionCommonType = v != null }, }; var globsAndUris = options.Parse(args); @@ -232,6 +234,7 @@ A file name may be given by appending a pipe sign (|) followed by a file name (l GenerateCommandLineArgumentsComment = generateCommandLineArgs, UseArrayItemAttribute = useArrayItemAttribute, EnumAsString = enumAsString, + MapUnionToWidestCommonType = unionCommonType }; if (nameSubstituteMap.Any()) diff --git a/XmlSchemaClassGenerator.Tests/Compiler.cs b/XmlSchemaClassGenerator.Tests/Compiler.cs index 3566cee7..2f200a31 100644 --- a/XmlSchemaClassGenerator.Tests/Compiler.cs +++ b/XmlSchemaClassGenerator.Tests/Compiler.cs @@ -117,6 +117,7 @@ public static Assembly GenerateFiles(string name, IEnumerable files, Gen NamingScheme = generatorPrototype.NamingScheme, UseArrayItemAttribute = generatorPrototype.UseArrayItemAttribute, EnumAsString = generatorPrototype.EnumAsString, + MapUnionToWidestCommonType = generatorPrototype.MapUnionToWidestCommonType }; gen.CommentLanguages.Clear(); diff --git a/XmlSchemaClassGenerator.Tests/XmlTests.cs b/XmlSchemaClassGenerator.Tests/XmlTests.cs index 1f314f54..8256882c 100644 --- a/XmlSchemaClassGenerator.Tests/XmlTests.cs +++ b/XmlSchemaClassGenerator.Tests/XmlTests.cs @@ -160,7 +160,13 @@ public void TestClient() [UseCulture("en-US")] public void TestUnion() { - var assembly = Compiler.Generate("Union", UnionPattern); + var assembly = Compiler.Generate("Union", UnionPattern, new Generator + { + NamespacePrefix = "Union", + IntegerDataType = typeof(int), + MapUnionToWidestCommonType = true + }); + Assert.NotNull(assembly); SharedTestFunctions.TestSamples(Output, "Union", UnionPattern); diff --git a/XmlSchemaClassGenerator/CodeUtilities.cs b/XmlSchemaClassGenerator/CodeUtilities.cs index 06fd8acd..9e0b79c2 100644 --- a/XmlSchemaClassGenerator/CodeUtilities.cs +++ b/XmlSchemaClassGenerator/CodeUtilities.cs @@ -103,7 +103,7 @@ public static Type GetEffectiveType(this XmlSchemaDatatype type, GeneratorConfig { var resultType = type.TypeCode switch { - XmlTypeCode.AnyAtomicType => GetUnionType(configuration, schemaType, attribute), // union + XmlTypeCode.AnyAtomicType => configuration.MapUnionToWidestCommonType ? GetUnionType(configuration, schemaType, attribute) : typeof(string), // union XmlTypeCode.AnyUri or XmlTypeCode.GDay or XmlTypeCode.GMonth or XmlTypeCode.GMonthDay or XmlTypeCode.GYear or XmlTypeCode.GYearMonth => typeof(string), XmlTypeCode.Duration => configuration.NetCoreSpecificCode ? type.ValueType : typeof(string), XmlTypeCode.Time => typeof(DateTime), diff --git a/XmlSchemaClassGenerator/Generator.cs b/XmlSchemaClassGenerator/Generator.cs index 54e4146f..2c754b40 100644 --- a/XmlSchemaClassGenerator/Generator.cs +++ b/XmlSchemaClassGenerator/Generator.cs @@ -318,6 +318,12 @@ public CommandLineArgumentsProvider CommandLineArgumentsProvider set { _configuration.CommandLineArgumentsProvider = value; } } + public bool MapUnionToWidestCommonType + { + get { return _configuration.MapUnionToWidestCommonType; } + set { _configuration.MapUnionToWidestCommonType = value; } + } + static Generator() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); diff --git a/XmlSchemaClassGenerator/GeneratorConfiguration.cs b/XmlSchemaClassGenerator/GeneratorConfiguration.cs index 7167d884..ba677484 100644 --- a/XmlSchemaClassGenerator/GeneratorConfiguration.cs +++ b/XmlSchemaClassGenerator/GeneratorConfiguration.cs @@ -208,7 +208,7 @@ public void WriteLog(string message) public Action TypeVisitor { get; set; } /// - /// Provides options to customize Elementnamens with own logik + /// Provides options to customize Elementnamens with own logic /// public INamingProvider NamingProvider { get; set; } @@ -328,5 +328,11 @@ public void WriteLog(string message) /// for sequences with single elements. Default is true. /// public bool UseArrayItemAttribute { get; set; } = true; + + /// + /// Tries to determine a common specific type for union member types, e.g. if a union has member types that are all integers + /// a numeric C# type is generated. If this is disabled, a union's type will default to string. Default is false. + /// + public bool MapUnionToWidestCommonType { get; set; } } }