@@ -111,7 +111,9 @@ public void Execute(GeneratorExecutionContext context)
111111 SemanticModel ? model = null ;
112112 SyntaxTree ? modelSyntaxTree = null ;
113113
114- var docoptTypes = new List < ( string ? Namespace , string Name , DocoptArgumentsAttribute ? ArgumentsAttribute ,
114+ var docoptTypes = new List < ( string ? Namespace , string Name ,
115+ IEnumerable < TypeDeclarationSyntax > Parents ,
116+ DocoptArgumentsAttribute ? ArgumentsAttribute ,
115117 SourceText Help , GenerationOptions Options ) > ( ) ;
116118
117119 foreach ( var ( cds , attributeData ) in syntaxReceiver . ClassAttributes )
@@ -137,7 +139,7 @@ public void Execute(GeneratorExecutionContext context)
137139 && name == attribute . HelpConstName ? Some ( help ) : default )
138140 . FirstOrDefault ( ) ;
139141 if ( help is { } someHelp )
140- docoptTypes . Add ( ( namespaceName , className , attribute , SourceText . From ( someHelp ) , GenerationOptions . SkipHelpConst ) ) ;
142+ docoptTypes . Add ( ( namespaceName , className , cds . GetParents ( ) . Where ( tds => tds is ClassDeclarationSyntax ) . Reverse ( ) , attribute , SourceText . From ( someHelp ) , GenerationOptions . SkipHelpConst ) ) ;
141143 else
142144 context . ReportDiagnostic ( Diagnostic . Create ( MissingHelpConstError , symbol . Locations . First ( ) , symbol , attribute . HelpConstName ) ) ;
143145 }
@@ -156,18 +158,38 @@ public void Execute(GeneratorExecutionContext context)
156158 && ! string . IsNullOrWhiteSpace ( name )
157159 ? name
158160 : Path . GetFileName ( at . Path ) . Partition ( "." ) . Item1 + "Arguments" ,
161+ Enumerable . Empty < TypeDeclarationSyntax > ( ) ,
159162 ( DocoptArgumentsAttribute ? ) null ,
160163 text ,
161164 GenerationOptions . None ) )
162165 : default )
163166 . ToImmutableArray ( ) ;
164167
165- foreach ( var ( ns , name , attribute , help , options ) in docoptSources . Concat ( docoptTypes ) )
168+ var hintNameBuilder = new StringBuilder ( ) ;
169+
170+ foreach ( var ( ns , name , parents , attribute , help , options ) in docoptSources . Concat ( docoptTypes ) )
166171 {
167172 try
168173 {
169- if ( Generate ( ns , name , attribute ? . HelpConstName , help , options ) is { Length : > 0 } source )
170- context . AddSource ( ( ns is { } someNamespace ? someNamespace + "." + name : name ) + ".cs" , source ) ;
174+ var parentNames = parents . Select ( p => p . Identifier . ToString ( ) ) . ToArray ( ) ;
175+ if ( Generate ( ns , name , parentNames , attribute ? . HelpConstName , help , options ) is { Length : > 0 } source )
176+ {
177+ hintNameBuilder . Clear ( ) ;
178+ if ( ns is { } someNamespace )
179+ hintNameBuilder . Append ( someNamespace ) . Append ( '.' ) ;
180+ if ( parentNames . Length > 0 )
181+ {
182+ foreach ( var pn in parentNames )
183+ {
184+ // NOTE! Microsoft.CodeAnalysis.CSharp 3.10 does not allow use of "+"
185+ // as is conventional for nested types. It is allowed later versions;
186+ // see: https://github.com/dotnet/roslyn/issues/58476
187+ hintNameBuilder . Append ( pn ) . Append ( '-' ) ;
188+ }
189+ }
190+ hintNameBuilder . Append ( name ) ;
191+ context . AddSource ( hintNameBuilder . Append ( ".cs" ) . ToString ( ) , source ) ;
192+ }
171193 }
172194 catch ( DocoptLanguageErrorException e )
173195 {
@@ -208,17 +230,17 @@ enum GenerationOptions
208230 }
209231
210232 public static SourceText Generate ( string ? ns , string name , SourceText text ) =>
211- Generate ( ns , name , null , text , GenerationOptions . None ) ;
233+ Generate ( ns , name , Enumerable . Empty < string > ( ) , null , text , GenerationOptions . None ) ;
212234
213- static SourceText Generate ( string ? ns , string name , string ? helpConstName ,
235+ static SourceText Generate ( string ? ns , string name , IEnumerable < string > parents , string ? helpConstName ,
214236 SourceText text , GenerationOptions generationOptions ) =>
215- Generate ( ns , name , helpConstName , text , null , generationOptions ) ;
237+ Generate ( ns , name , parents , helpConstName , text , null , generationOptions ) ;
216238
217239 public static SourceText Generate ( string ? ns , string name ,
218240 SourceText text , Encoding ? outputEncoding ) =>
219- Generate ( ns , name , null , text , outputEncoding , GenerationOptions . None ) ;
241+ Generate ( ns , name , Enumerable . Empty < string > ( ) , null , text , outputEncoding , GenerationOptions . None ) ;
220242
221- static SourceText Generate ( string ? ns , string name , string ? helpConstName ,
243+ static SourceText Generate ( string ? ns , string name , IEnumerable < string > parents , string ? helpConstName ,
222244 SourceText text , Encoding ? outputEncoding , GenerationOptions options )
223245 {
224246 if ( text . Length == 0 )
@@ -229,7 +251,7 @@ static SourceText Generate(string? ns, string name, string? helpConstName,
229251
230252 Generate ( code ,
231253 ns is { Length : 0 } ? null : ns ,
232- name , helpConstName ?? DefaultHelpConstName , helpText ,
254+ name , parents , helpConstName ?? DefaultHelpConstName , helpText ,
233255 options ) ;
234256
235257 return new StringBuilderSourceText ( code . StringBuilder , outputEncoding ?? text . Encoding ?? Utf8BomlessEncoding ) ;
@@ -238,6 +260,7 @@ static SourceText Generate(string? ns, string name, string? helpConstName,
238260 static void Generate ( CSharpSourceBuilder code ,
239261 string ? ns ,
240262 string name ,
263+ IEnumerable < string > parents ,
241264 string helpConstName ,
242265 string helpText ,
243266 GenerationOptions generationOptions )
@@ -267,6 +290,7 @@ static void Generate(CSharpSourceBuilder code,
267290
268291 . NewLine
269292 [ ns is not null ? code . Namespace ( ns ) : code . Blank ( ) ]
293+ [ from p in parents select code . Partial . Class [ p ] . NewLine . BlockStart ]
270294
271295 . Partial . Class [ name ] [ " : IEnumerable<KeyValuePair<string, object?>>" ] . NewLine . SkipNextNewLine . Block [ code
272296 [ ( generationOptions & GenerationOptions . SkipHelpConst ) == GenerationOptions . SkipHelpConst
@@ -353,6 +377,7 @@ static void Generate(CSharpSourceBuilder code,
353377 } ]
354378 . NewLine )
355379 ] // class
380+ [ from p in parents select code . BlockEnd ]
356381 [ ns is not null ? code . BlockEnd : code . Blank ( ) ]
357382 . Blank ( ) ;
358383
0 commit comments