55using System . Collections . Generic ;
66using System . Diagnostics ;
77using System . IO ;
8+ using System . Linq ;
9+ using System . Text . RegularExpressions ;
810using System . Xml ;
911using 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