From 5dca2a3dcf813391b9122c187d0e38b32d76bfc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Sun, 22 Aug 2021 14:08:09 +0200 Subject: [PATCH 1/9] add source generator with global namespace setting --- .../Samples/simple_schema.xsd | 25 ++++++ .../SimpleSchemaTests.cs | 18 +++++ ...lassGenerator.SourceGenerator.Tests.csproj | 42 ++++++++++ ...chemaClassGenerator.SourceGenerator.csproj | 71 ++++++++++++++++ ...SchemaClassGenerator.SourceGenerator.props | 5 ++ .../XsdSourceGenerator.cs | 81 +++++++++++++++++++ XmlSchemaClassGenerator.sln | 12 +++ 7 files changed, 254 insertions(+) create mode 100644 XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd create mode 100644 XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs create mode 100644 XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj create mode 100644 XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj create mode 100644 XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props create mode 100644 XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs diff --git a/XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd b/XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd new file mode 100644 index 00000000..f96efc29 --- /dev/null +++ b/XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs b/XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs new file mode 100644 index 00000000..c8780310 --- /dev/null +++ b/XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs @@ -0,0 +1,18 @@ +using System; +using Xunit; + +namespace XmlSchemaClassGenerator.SourceGenerator.Tests +{ + public class SimpleSchemaTests + { + [Fact] + public void Compiles() + { + new Sample.Generated.MyRootElement + { + Child1 = true, + Child2 = "foo" + }; + } + } +} diff --git a/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj b/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj new file mode 100644 index 00000000..52123717 --- /dev/null +++ b/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj @@ -0,0 +1,42 @@ + + + + netcoreapp3.1 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + + Sample.Generated + + + + + PreserveNewest + + + + diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj new file mode 100644 index 00000000..8b409108 --- /dev/null +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj @@ -0,0 +1,71 @@ + + + + netstandard2.0 + false + true + + XmlSchemaClassGenerator.SourceGenerator + Sven Hübner + Source generator for POCOs from XSD schema files, based on XmlSchemaClassGenerator + xml;xsd;Schema;Source Generator;poco;XmlSchemaClassGenerator + https://github.com/mganss/XmlSchemaClassGenerator + Apache-2.0 + git + git://github.com/mganss/XmlSchemaClassGenerator + XmlSchemaClassGenerator + true + true + true + snupkg + + + + + + + + + + + + + + + + + + + + + + + + + $(GetTargetPathDependsOn);GetDependencyTargetPaths + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props new file mode 100644 index 00000000..b8d5f063 --- /dev/null +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props @@ -0,0 +1,5 @@ + + + + + diff --git a/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs new file mode 100644 index 00000000..126d1c09 --- /dev/null +++ b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs @@ -0,0 +1,81 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using System; +using System.CodeDom; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Xml; +using System.Xml.Schema; + +namespace XmlSchemaClassGenerator +{ + [Generator] + public class XsdSourceGenerator : ISourceGenerator + { + internal class MemoryOutputWriter : OutputWriter + { + public string Content { get; set; } + + public override void Write(CodeNamespace cn) + { + var cu = new CodeCompileUnit(); + cu.Namespaces.Add(cn); + + using (var writer = new StringWriter()) + { + Write(writer, cu); + Content = writer.ToString(); + } + } + } + + public void Execute(GeneratorExecutionContext context) + { +#if DEBUG + if (!Debugger.IsAttached) + { + //Debugger.Launch(); + } +#endif + var configurations = GetConfigurations(context); + + foreach (var (schemaFile, @namespace) in configurations) + { + var schemaStr = schemaFile.GetText().ToString(); + var stringReader = new StringReader(schemaStr); + + var schemaSet = new XmlSchemaSet(); + schemaSet.Add(null, XmlReader.Create(stringReader)); + + var generator = new Generator(); + generator.NamespaceProvider.Add(new NamespaceKey(), @namespace); + MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter(); + generator.OutputWriter = memoryOutputWriter; + generator.Generate(schemaSet); + context.AddSource("Pocos", memoryOutputWriter.Content); + } + } + + public void Initialize(GeneratorInitializationContext context) + { + // do nothing + } + + static IEnumerable<(AdditionalText SchemaFile, string Namespace)> GetConfigurations(GeneratorExecutionContext context) + { + if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_Namespace", out var @namespace)) + { + @namespace = "Generated"; + } + + foreach (AdditionalText file in context.AdditionalFiles) + { + if (Path.GetExtension(file.Path).Equals(".xsd", StringComparison.OrdinalIgnoreCase)) + { + yield return (file, @namespace); + } + } + } + } +} diff --git a/XmlSchemaClassGenerator.sln b/XmlSchemaClassGenerator.sln index 23fb93ad..9e36bfda 100644 --- a/XmlSchemaClassGenerator.sln +++ b/XmlSchemaClassGenerator.sln @@ -20,6 +20,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "xscgen-proj", "xscgen-proj\xscgen-proj.csproj", "{2F20FF02-12AB-448B-BC78-DD76DD4C9E66}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlSchemaClassGenerator.SourceGenerator", "XmlSchemaClassGenerator.SourceGenerator\XmlSchemaClassGenerator.SourceGenerator.csproj", "{1A4760D7-7618-41E8-BC97-C68566B7A16C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmlSchemaClassGenerator.SourceGenerator.Tests", "XmlSchemaClassGenerator.SourceGenerator.Tests\XmlSchemaClassGenerator.SourceGenerator.Tests.csproj", "{333F3108-2714-4706-ABA7-4298EFEBFCA7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -50,6 +54,14 @@ Global {2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Debug|Any CPU.Build.0 = Debug|Any CPU {2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Release|Any CPU.ActiveCfg = Release|Any CPU {2F20FF02-12AB-448B-BC78-DD76DD4C9E66}.Release|Any CPU.Build.0 = Release|Any CPU + {1A4760D7-7618-41E8-BC97-C68566B7A16C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A4760D7-7618-41E8-BC97-C68566B7A16C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A4760D7-7618-41E8-BC97-C68566B7A16C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A4760D7-7618-41E8-BC97-C68566B7A16C}.Release|Any CPU.Build.0 = Release|Any CPU + {333F3108-2714-4706-ABA7-4298EFEBFCA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {333F3108-2714-4706-ABA7-4298EFEBFCA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {333F3108-2714-4706-ABA7-4298EFEBFCA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {333F3108-2714-4706-ABA7-4298EFEBFCA7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From ff3feeb9ad5ac3005239a4f1dd939147d6b207ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Mon, 23 Aug 2021 17:12:38 +0200 Subject: [PATCH 2/9] add option to generate separate files --- .../Samples/simple_schema.xsd | 7 ++ .../SimpleSchemaTests.cs | 7 +- ...lassGenerator.SourceGenerator.Tests.csproj | 1 + ...SchemaClassGenerator.SourceGenerator.props | 1 + .../XsdSourceGenerator.cs | 68 ++++++++++++++++--- 5 files changed, 74 insertions(+), 10 deletions(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd b/XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd index f96efc29..c89fcff4 100644 --- a/XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd +++ b/XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd @@ -19,6 +19,13 @@ + + + + + + + diff --git a/XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs b/XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs index c8780310..ff18e144 100644 --- a/XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs +++ b/XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs @@ -1,4 +1,3 @@ -using System; using Xunit; namespace XmlSchemaClassGenerator.SourceGenerator.Tests @@ -11,7 +10,11 @@ public void Compiles() new Sample.Generated.MyRootElement { Child1 = true, - Child2 = "foo" + Child2 = "foo", + ComplexChild1 = new Sample.Generated.MyRootElementComplexChild1 + { + Child11 = null + } }; } } diff --git a/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj b/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj index 52123717..9e241475 100644 --- a/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj +++ b/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj @@ -31,6 +31,7 @@ Sample.Generated + true diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props index b8d5f063..51ba6ba2 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props @@ -1,5 +1,6 @@  + diff --git a/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs index 126d1c09..d8558a5d 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs +++ b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs @@ -5,6 +5,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; +using System.Text.RegularExpressions; using System.Xml; using System.Xml.Schema; @@ -15,19 +17,60 @@ public class XsdSourceGenerator : ISourceGenerator { internal class MemoryOutputWriter : OutputWriter { - public string Content { get; set; } + private readonly bool separateFiles; + + public ICollection<(string Name, string Content)> Contents { get; private set; } = new List<(string, string)>(); + + public MemoryOutputWriter(bool separateFiles) + { + this.separateFiles = separateFiles; + } public override void Write(CodeNamespace cn) { var cu = new CodeCompileUnit(); cu.Namespaces.Add(cn); - using (var writer = new StringWriter()) + if (separateFiles) + { + WriteSeparateFiles(cn); + } + else + { + using (var writer = new StringWriter()) + { + Write(writer, cu); + Contents.Add(("Pocos", writer.ToString())); + } + } + } + + private void WriteSeparateFiles(CodeNamespace cn) + { + var validName = ValidateName(cn.Name); + var ccu = new CodeCompileUnit(); + var cns = new CodeNamespace(validName); + + cns.Imports.AddRange(cn.Imports.Cast().ToArray()); + cns.Comments.AddRange(cn.Comments); + ccu.Namespaces.Add(cns); + + foreach (CodeTypeDeclaration ctd in cn.Types) { - Write(writer, cu); - Content = writer.ToString(); + var contentName = ctd.Name; + cns.Types.Clear(); + cns.Types.Add(ctd); + using (var writer = new StringWriter()) + { + Write(writer, ccu); + Contents.Add((contentName, writer.ToString())); + } } } + + static readonly Regex InvalidCharacters = new Regex($"[{string.Join("", Path.GetInvalidFileNameChars())}]", RegexOptions.Compiled); + + private string ValidateName(string name) => InvalidCharacters.Replace(name, "_"); } public void Execute(GeneratorExecutionContext context) @@ -35,10 +78,14 @@ public void Execute(GeneratorExecutionContext context) #if DEBUG if (!Debugger.IsAttached) { - //Debugger.Launch(); + // Debugger.Launch(); } #endif var configurations = GetConfigurations(context); + bool generateSeparateFiles = + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_separatefiles", out var generateSeparateFilesStr) && + bool.TryParse(generateSeparateFilesStr, out var parsedGenerateSeparateFiles) && + parsedGenerateSeparateFiles; foreach (var (schemaFile, @namespace) in configurations) { @@ -50,10 +97,15 @@ public void Execute(GeneratorExecutionContext context) var generator = new Generator(); generator.NamespaceProvider.Add(new NamespaceKey(), @namespace); - MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter(); + generator.SeparateClasses = generateSeparateFiles; + MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter(generateSeparateFiles); generator.OutputWriter = memoryOutputWriter; generator.Generate(schemaSet); - context.AddSource("Pocos", memoryOutputWriter.Content); + + foreach (var (name, content) in memoryOutputWriter.Contents) + { + context.AddSource(name, content); + } } } @@ -64,7 +116,7 @@ public void Initialize(GeneratorInitializationContext context) static IEnumerable<(AdditionalText SchemaFile, string Namespace)> GetConfigurations(GeneratorExecutionContext context) { - if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_Namespace", out var @namespace)) + if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_namespace", out var @namespace)) { @namespace = "Generated"; } From 577a76f97b754cdfd3f37472ee88c89e36a6aa0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Sun, 10 Apr 2022 21:08:23 +0200 Subject: [PATCH 3/9] scope namespace and separate file generation to the xsd use ItemMetadata instead of global configuration --- ...mlSchemaClassGenerator.SourceGenerator.Tests.csproj | 9 +++------ .../XmlSchemaClassGenerator.SourceGenerator.props | 4 ++-- .../XsdSourceGenerator.cs | 10 +++++----- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj b/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj index 9e241475..c2dd5eba 100644 --- a/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj +++ b/XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj @@ -26,13 +26,10 @@ - + - - - Sample.Generated - true - diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props index 51ba6ba2..a2b65278 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props @@ -1,6 +1,6 @@  - - + + diff --git a/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs index d8558a5d..db7c4af6 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs +++ b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs @@ -116,13 +116,13 @@ public void Initialize(GeneratorInitializationContext context) static IEnumerable<(AdditionalText SchemaFile, string Namespace)> GetConfigurations(GeneratorExecutionContext context) { - if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_namespace", out var @namespace)) - { - @namespace = "Generated"; - } - foreach (AdditionalText file in context.AdditionalFiles) { + if (!context.AnalyzerConfigOptions.GetOptions(file).TryGetValue("build_metadata.AdditionalFiles.xscgen_Namespace", out var @namespace)) + { + @namespace = "Generated"; + } + if (Path.GetExtension(file.Path).Equals(".xsd", StringComparison.OrdinalIgnoreCase)) { yield return (file, @namespace); From 85f11dc1385bf51cbea51a6492a27ef87729574b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Fri, 15 Apr 2022 20:53:16 +0200 Subject: [PATCH 4/9] change generated file names also add option for prefix --- ...SchemaClassGenerator.SourceGenerator.props | 1 + .../XsdSourceGenerator.cs | 74 ++++++++++++++----- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props index a2b65278..08b674a0 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.props @@ -2,5 +2,6 @@ + diff --git a/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs index db7c4af6..97db1721 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs +++ b/XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs @@ -18,12 +18,16 @@ public class XsdSourceGenerator : ISourceGenerator internal class MemoryOutputWriter : OutputWriter { private readonly bool separateFiles; + private readonly string schemaFileName; + private readonly string prefix; public ICollection<(string Name, string Content)> Contents { get; private set; } = new List<(string, string)>(); - public MemoryOutputWriter(bool separateFiles) + public MemoryOutputWriter(bool separateFiles, string schemaFileName, string prefix) { this.separateFiles = separateFiles; + this.schemaFileName = schemaFileName; + this.prefix = prefix; } public override void Write(CodeNamespace cn) @@ -40,14 +44,14 @@ public override void Write(CodeNamespace cn) using (var writer = new StringWriter()) { Write(writer, cu); - Contents.Add(("Pocos", writer.ToString())); + Contents.Add(($"{this.prefix ?? string.Empty}{this.schemaFileName}.g.cs", writer.ToString())); } } } private void WriteSeparateFiles(CodeNamespace cn) { - var validName = ValidateName(cn.Name); + var validName = GetSanitizedName(cn.Name); var ccu = new CodeCompileUnit(); var cns = new CodeNamespace(validName); @@ -63,14 +67,14 @@ private void WriteSeparateFiles(CodeNamespace cn) using (var writer = new StringWriter()) { Write(writer, ccu); - Contents.Add((contentName, writer.ToString())); + Contents.Add(($"{this.prefix ?? string.Empty}{contentName}.g.cs", writer.ToString())); } } } static readonly Regex InvalidCharacters = new Regex($"[{string.Join("", Path.GetInvalidFileNameChars())}]", RegexOptions.Compiled); - private string ValidateName(string name) => InvalidCharacters.Replace(name, "_"); + private string GetSanitizedName(string name) => InvalidCharacters.Replace(name, "_"); } public void Execute(GeneratorExecutionContext context) @@ -81,24 +85,23 @@ public void Execute(GeneratorExecutionContext context) // Debugger.Launch(); } #endif - var configurations = GetConfigurations(context); - bool generateSeparateFiles = - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_separatefiles", out var generateSeparateFilesStr) && - bool.TryParse(generateSeparateFilesStr, out var parsedGenerateSeparateFiles) && - parsedGenerateSeparateFiles; + var sources = GetConfigurations(context); - foreach (var (schemaFile, @namespace) in configurations) + foreach (var source in sources) { - var schemaStr = schemaFile.GetText().ToString(); + var schemaStr = source.AdditionalText.GetText().ToString(); var stringReader = new StringReader(schemaStr); var schemaSet = new XmlSchemaSet(); schemaSet.Add(null, XmlReader.Create(stringReader)); var generator = new Generator(); - generator.NamespaceProvider.Add(new NamespaceKey(), @namespace); - generator.SeparateClasses = generateSeparateFiles; - MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter(generateSeparateFiles); + generator.NamespaceProvider.Add(new NamespaceKey(), source.Namespace); + generator.SeparateClasses = source.GenerateSeparateFiles; + MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter( + source.GenerateSeparateFiles, + Path.GetFileNameWithoutExtension(source.AdditionalText.Path), + source.Prefix); generator.OutputWriter = memoryOutputWriter; generator.Generate(schemaSet); @@ -114,20 +117,55 @@ public void Initialize(GeneratorInitializationContext context) // do nothing } - static IEnumerable<(AdditionalText SchemaFile, string Namespace)> GetConfigurations(GeneratorExecutionContext context) + static IEnumerable GetConfigurations(GeneratorExecutionContext context) { foreach (AdditionalText file in context.AdditionalFiles) { - if (!context.AnalyzerConfigOptions.GetOptions(file).TryGetValue("build_metadata.AdditionalFiles.xscgen_Namespace", out var @namespace)) + AnalyzerConfigOptions fileOptions = context.AnalyzerConfigOptions.GetOptions(file); + if (!fileOptions.TryGetValue("build_metadata.AdditionalFiles.xscgen_namespace", out var @namespace)) { @namespace = "Generated"; } + if (!fileOptions.TryGetValue("build_metadata.AdditionalFiles.xscgen_prefix", out var prefix)) + { + prefix = null; + } + + bool generateSeparateFiles = + fileOptions.TryGetValue("build_metadata.AdditionalFiles.xscgen_separatefiles", out var generateSeparateFilesStr) && + bool.TryParse(generateSeparateFilesStr, out var parsedGenerateSeparateFiles) && + parsedGenerateSeparateFiles; + if (Path.GetExtension(file.Path).Equals(".xsd", StringComparison.OrdinalIgnoreCase)) { - yield return (file, @namespace); + yield return new GenerationSource( + file, + @namespace, + generateSeparateFiles, + prefix); } } } + + sealed class GenerationSource + { + public GenerationSource( + AdditionalText additionalText, + string @namespace, + bool generateSeparateFiles, + string prefix) + { + AdditionalText = additionalText; + Namespace = @namespace; + GenerateSeparateFiles = generateSeparateFiles; + Prefix = prefix; + } + + public AdditionalText AdditionalText { get; } + public string Namespace { get; } + public bool GenerateSeparateFiles { get; } + public string Prefix { get; } + } } } From 5b1dd3b7f13f2bc7fc494e90c03fc1e61f37851f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Fri, 15 Apr 2022 21:05:06 +0200 Subject: [PATCH 5/9] upgrade to System.CodeDom 6.0.0 --- .../XmlSchemaClassGenerator.SourceGenerator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj index 8b409108..65ea8ec2 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj @@ -34,7 +34,7 @@ - + From 8e96b4e153475599f8384184d92017149a578efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Fri, 15 Apr 2022 21:06:37 +0200 Subject: [PATCH 6/9] upgrade other packages 5.0.0 -> 6.0.0 --- .../XmlSchemaClassGenerator.SourceGenerator.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj index 65ea8ec2..70396f8f 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj @@ -35,8 +35,8 @@ - - + + From 485b198bcf455bda131246b475f894b7138152f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Fri, 15 Apr 2022 21:23:07 +0200 Subject: [PATCH 7/9] add System.Collections.Immutable dependency --- .../XmlSchemaClassGenerator.SourceGenerator.csproj | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj index 70396f8f..52f65cca 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj @@ -38,7 +38,8 @@ - + + @@ -51,8 +52,9 @@ - + + @@ -62,8 +64,9 @@ - + + From b029226f6ab7fe79a52f0be6d5f2e3d5a2b2f950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Tue, 3 May 2022 13:08:50 +0200 Subject: [PATCH 8/9] use System.Collections.Immutable 5.0.0 work-around for assembly mismatch and missing method exception when building in environments that have System.Collections.Immutable 5.0.0 loaded at source generator runtime --- .../XmlSchemaClassGenerator.SourceGenerator.csproj | 2 +- XmlSchemaClassGenerator/XmlSchemaClassGenerator.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj index 52f65cca..4a73e0e4 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj @@ -38,7 +38,7 @@ - + diff --git a/XmlSchemaClassGenerator/XmlSchemaClassGenerator.csproj b/XmlSchemaClassGenerator/XmlSchemaClassGenerator.csproj index 233ee716..834ee80b 100644 --- a/XmlSchemaClassGenerator/XmlSchemaClassGenerator.csproj +++ b/XmlSchemaClassGenerator/XmlSchemaClassGenerator.csproj @@ -48,7 +48,7 @@ - + From c4f8e4dd16a756e5fa934d1c7707e11ed56d9439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20H=C3=BCbner?= Date: Tue, 3 May 2022 13:43:53 +0200 Subject: [PATCH 9/9] update to latest roslyn packages --- ...mlSchemaClassGenerator.SourceGenerator.csproj | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj index 4a73e0e4..5963eb31 100644 --- a/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj +++ b/XmlSchemaClassGenerator.SourceGenerator/XmlSchemaClassGenerator.SourceGenerator.csproj @@ -29,8 +29,8 @@ - - + + @@ -61,12 +61,12 @@ - - - - - - + + + + + +