Skip to content

Commit 9938956

Browse files
committed
add option to generate separate files
1 parent ea60b2c commit 9938956

5 files changed

Lines changed: 74 additions & 10 deletions

File tree

XmlSchemaClassGenerator.SourceGenerator.Tests/Samples/simple_schema.xsd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
<xs:restriction base="xs:string"/>
2020
</xs:simpleType>
2121
</xs:element>
22+
<xs:element name="ComplexChild1">
23+
<xs:complexType id="SomeComplexType">
24+
<xs:all>
25+
<xs:element name="Child11"></xs:element>
26+
</xs:all>
27+
</xs:complexType>
28+
</xs:element>
2229
</xs:all>
2330
</xs:complexType>
2431
</xs:element>

XmlSchemaClassGenerator.SourceGenerator.Tests/SimpleSchemaTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System;
21
using Xunit;
32

43
namespace XmlSchemaClassGenerator.SourceGenerator.Tests
@@ -11,7 +10,11 @@ public void Compiles()
1110
new Sample.Generated.MyRootElement
1211
{
1312
Child1 = true,
14-
Child2 = "foo"
13+
Child2 = "foo",
14+
ComplexChild1 = new Sample.Generated.MyRootElementComplexChild1
15+
{
16+
Child11 = null
17+
}
1518
};
1619
}
1720
}

XmlSchemaClassGenerator.SourceGenerator.Tests/XmlSchemaClassGenerator.SourceGenerator.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
<PropertyGroup>
3333
<xscgen_Namespace>Sample.Generated</xscgen_Namespace>
34+
<xscgen_SeparateFiles>true</xscgen_SeparateFiles>
3435
</PropertyGroup>
3536

3637
<ItemGroup>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<Project>
22
<ItemGroup>
33
<CompilerVisibleProperty Include="xscgen_Namespace" />
4+
<CompilerVisibleProperty Include="xscgen_SeparateFiles" />
45
</ItemGroup>
56
</Project>

XmlSchemaClassGenerator.SourceGenerator/XsdSourceGenerator.cs

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Collections.Generic;
66
using System.Diagnostics;
77
using System.IO;
8+
using System.Linq;
9+
using System.Text.RegularExpressions;
810
using System.Xml;
911
using System.Xml.Schema;
1012

@@ -15,30 +17,75 @@ public class XsdSourceGenerator : ISourceGenerator
1517
{
1618
internal class MemoryOutputWriter : OutputWriter
1719
{
18-
public string Content { get; set; }
20+
private readonly bool separateFiles;
21+
22+
public ICollection<(string Name, string Content)> Contents { get; private set; } = new List<(string, string)>();
23+
24+
public MemoryOutputWriter(bool separateFiles)
25+
{
26+
this.separateFiles = separateFiles;
27+
}
1928

2029
public override void Write(CodeNamespace cn)
2130
{
2231
var cu = new CodeCompileUnit();
2332
cu.Namespaces.Add(cn);
2433

25-
using (var writer = new StringWriter())
34+
if (separateFiles)
35+
{
36+
WriteSeparateFiles(cn);
37+
}
38+
else
39+
{
40+
using (var writer = new StringWriter())
41+
{
42+
Write(writer, cu);
43+
Contents.Add(("Pocos", writer.ToString()));
44+
}
45+
}
46+
}
47+
48+
private void WriteSeparateFiles(CodeNamespace cn)
49+
{
50+
var validName = ValidateName(cn.Name);
51+
var ccu = new CodeCompileUnit();
52+
var cns = new CodeNamespace(validName);
53+
54+
cns.Imports.AddRange(cn.Imports.Cast<CodeNamespaceImport>().ToArray());
55+
cns.Comments.AddRange(cn.Comments);
56+
ccu.Namespaces.Add(cns);
57+
58+
foreach (CodeTypeDeclaration ctd in cn.Types)
2659
{
27-
Write(writer, cu);
28-
Content = writer.ToString();
60+
var contentName = ctd.Name;
61+
cns.Types.Clear();
62+
cns.Types.Add(ctd);
63+
using (var writer = new StringWriter())
64+
{
65+
Write(writer, ccu);
66+
Contents.Add((contentName, writer.ToString()));
67+
}
2968
}
3069
}
70+
71+
static readonly Regex InvalidCharacters = new Regex($"[{string.Join("", Path.GetInvalidFileNameChars())}]", RegexOptions.Compiled);
72+
73+
private string ValidateName(string name) => InvalidCharacters.Replace(name, "_");
3174
}
3275

3376
public void Execute(GeneratorExecutionContext context)
3477
{
3578
#if DEBUG
3679
if (!Debugger.IsAttached)
3780
{
38-
//Debugger.Launch();
81+
// Debugger.Launch();
3982
}
4083
#endif
4184
var configurations = GetConfigurations(context);
85+
bool generateSeparateFiles =
86+
context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_separatefiles", out var generateSeparateFilesStr) &&
87+
bool.TryParse(generateSeparateFilesStr, out var parsedGenerateSeparateFiles) &&
88+
parsedGenerateSeparateFiles;
4289

4390
foreach (var (schemaFile, @namespace) in configurations)
4491
{
@@ -50,10 +97,15 @@ public void Execute(GeneratorExecutionContext context)
5097

5198
var generator = new Generator();
5299
generator.NamespaceProvider.Add(new NamespaceKey(), @namespace);
53-
MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter();
100+
generator.SeparateClasses = generateSeparateFiles;
101+
MemoryOutputWriter memoryOutputWriter = new MemoryOutputWriter(generateSeparateFiles);
54102
generator.OutputWriter = memoryOutputWriter;
55103
generator.Generate(schemaSet);
56-
context.AddSource("Pocos", memoryOutputWriter.Content);
104+
105+
foreach (var (name, content) in memoryOutputWriter.Contents)
106+
{
107+
context.AddSource(name, content);
108+
}
57109
}
58110
}
59111

@@ -64,7 +116,7 @@ public void Initialize(GeneratorInitializationContext context)
64116

65117
static IEnumerable<(AdditionalText SchemaFile, string Namespace)> GetConfigurations(GeneratorExecutionContext context)
66118
{
67-
if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_Namespace", out var @namespace))
119+
if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.xscgen_namespace", out var @namespace))
68120
{
69121
@namespace = "Generated";
70122
}

0 commit comments

Comments
 (0)