66using System . Collections . Generic ;
77using System . IO ;
88using System . Linq ;
9+ using System . Text . RegularExpressions ;
910using JetBrains . Annotations ;
1011using Microsoft . CodeAnalysis ;
1112using Microsoft . CodeAnalysis . CSharp ;
@@ -69,7 +70,7 @@ public void Execute(GeneratorExecutionContext context)
6970 continue ;
7071
7172 [ CanBeNull ]
72- string GetDeclaration ( IProjectContainer container )
73+ string GetDeclaration ( IProjectContainer container , string folderName = null )
7374 {
7475 var prefix = new string ( '_' , container . Descendants ( x => x . Parent ) . Count ( ) + 1 ) ;
7576 var model = new
@@ -79,21 +80,24 @@ string GetDeclaration(IProjectContainer container)
7980 Name = GetEscapedName ( container switch
8081 {
8182 Solution => member . Name ,
82- SolutionFolder folder => prefix . Substring ( 1 ) + folder . Name ,
83+ SolutionFolder folder => folderName ?? folder . Name ,
8384 _ => throw new ArgumentOutOfRangeException ( nameof ( container ) , container , null )
8485 } ) ,
8586 Projects = container . Projects . OrderBy ( x => x . Name ) . Select ( x => new
8687 {
8788 x . Name ,
88- EscapedName = GetEscapedName ( x . Name ) ,
89+ EscapedName = GetEscapedName ( x . Name )
8990 } ) ,
9091 Folders = container . SolutionFolders . OrderBy ( x => x . Name ) . Select ( x => new
9192 {
9293 x . Name ,
93- TypeName = prefix + GetEscapedName ( x . Name ) ,
94- EscapedName = GetEscapedName ( x . Name ) ,
94+ TypeName = folderName ?? $ " { prefix } { GetEscapedName ( x . Name ) } " ,
95+ EscapedName = GetEscapedName ( x . Name )
9596 } ) ,
96- Declarations = container . SolutionFolders . OrderBy ( x => x . Name ) . Select ( GetDeclaration ) . ToArray ( ) ,
97+ Declarations = container . SolutionFolders
98+ . OrderBy ( x => x . Name )
99+ . Select ( x => GetDeclaration ( x , $ "{ prefix } { GetEscapedName ( x . Name ) } ") )
100+ . ToArray ( )
97101 } ;
98102
99103 // lang=csharp
@@ -119,10 +123,20 @@ internal class {{ name }}(SolutionFolderModel model, Nuke.Common.ProjectModel.So
119123 """ ) ;
120124 return template . Render ( model ) ;
121125
122- string GetEscapedName ( string name ) => name
123- // .Replace(".", fancyNaming ? "丨" : "_")
124- . Replace ( "." , fancyNaming ? "٠" : "_" )
125- . ReplaceRegex ( @"(^[\W^\d]|[\W])" , _ => "_" ) ;
126+
127+ string GetEscapedName ( string name )
128+ {
129+ name = s_nonAlphanumericPattern
130+ . Replace (
131+ name . Replace ( "." , fancyNaming ? "٠" : "_" ) ,
132+ _ => "_"
133+ ) ;
134+
135+ if ( s_startsWithNumberPattern . IsMatch ( name ) )
136+ return "_" + name ;
137+
138+ return name ;
139+ }
126140 }
127141 }
128142 }
@@ -160,4 +174,7 @@ static AbsolutePath GetRootDirectoryFrom(Compilation compilation)
160174 return Constants . TryGetRootDirectoryFrom ( startDirectory ) . NotNull ( ) ;
161175 }
162176 }
177+
178+ private static readonly Regex s_nonAlphanumericPattern = new ( "[^A-Za-z0-9_]" , RegexOptions . Compiled ) ;
179+ private static readonly Regex s_startsWithNumberPattern = new ( "^[0-9]" , RegexOptions . Compiled ) ;
163180}
0 commit comments