1313
1414namespace Flow . Launcher . Localization . SourceGenerators . Localize
1515{
16+ /// <summary>
17+ /// Generates properties for strings based on resource files.
18+ /// </summary>
1619 [ Generator ]
1720 public partial class LocalizeSourceGenerator : IIncrementalGenerator
1821 {
22+ #region Fields
23+
1924 private const string CoreNamespace1 = "Flow.Launcher" ;
2025 private const string CoreNamespace2 = "Flow.Launcher.Core" ;
2126 private const string DefaultNamespace = "Flow.Launcher" ;
2227 private const string ClassName = "Localize" ;
2328 private const string PluginInterfaceName = "IPluginI18n" ;
2429 private const string PluginContextTypeName = "PluginInitContext" ;
25- private const string XamlTag = "String" ;
2630 private const string XamlPrefix = "system" ;
27- private const string DefaultLanguageFilePathEndsWith = @"\Languages\en.xaml" ;
28- private static readonly Regex s_languagesXamlRegex = new Regex ( @"\\Languages\\[^\\]+\.xaml$" , RegexOptions . IgnoreCase ) ;
31+ private const string XamlTag = "String" ;
32+
33+ private readonly Regex _languagesXamlRegex = new Regex ( @"\\Languages\\[^\\]+\.xaml$" , RegexOptions . IgnoreCase ) ;
34+
35+ #endregion
36+
37+ #region Incremental Generator
2938
39+ /// <summary>
40+ /// Initializes the generator and registers source output based on resource files.
41+ /// </summary>
42+ /// <param name="context">The initialization context.</param>
3043 public void Initialize ( IncrementalGeneratorInitializationContext context )
3144 {
3245 var xamlFiles = context . AdditionalTextsProvider
33- . Where ( file => s_languagesXamlRegex . IsMatch ( file . Path ) ) ;
46+ . Where ( file => _languagesXamlRegex . IsMatch ( file . Path ) ) ;
3447
3548 var localizedStrings = xamlFiles
3649 . Select ( ( file , ct ) => ParseXamlFile ( file , ct ) )
@@ -94,78 +107,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
94107 } ) ;
95108 }
96109
97- private static void GenerateSource (
98- SourceProductionContext context ,
99- ImmutableArray < LocalizableString > localizedStrings ,
100- IEnumerable < string > unusedKeys ,
101- OptimizationLevel optimizationLevel ,
102- string assemblyName ,
103- bool isCoreAssembly ,
104- PluginClassInfo pluginInfo )
105- {
106- var sourceBuilder = new StringBuilder ( ) ;
107- sourceBuilder . AppendLine ( "// <auto-generated />" ) ;
108- sourceBuilder . AppendLine ( "#nullable enable" ) ;
109-
110- if ( isCoreAssembly )
111- {
112- sourceBuilder . AppendLine ( "using Flow.Launcher.Core.Resource;" ) ;
113- }
114-
115- sourceBuilder . AppendLine ( $ "namespace { assemblyName } ;") ;
116- sourceBuilder . AppendLine ( ) ;
117- sourceBuilder . AppendLine ( $ "[System.CodeDom.Compiler.GeneratedCode(\" { nameof ( LocalizeSourceGenerator ) } \" , \" 1.0.0\" )]") ;
118- sourceBuilder . AppendLine ( $ "public static class { ClassName } ") ;
119- sourceBuilder . AppendLine ( "{" ) ;
120-
121- foreach ( var ls in localizedStrings )
122- {
123- if ( optimizationLevel == OptimizationLevel . Release && unusedKeys . Contains ( ls . Key ) )
124- continue ;
125-
126- GenerateDocComments ( sourceBuilder , ls ) ;
127- GenerateLocalizationMethod ( sourceBuilder , ls , isCoreAssembly , pluginInfo ) ;
128- }
129-
130- sourceBuilder . AppendLine ( "}" ) ;
131-
132- context . AddSource ( $ "{ ClassName } .g.cs", SourceText . From ( sourceBuilder . ToString ( ) , Encoding . UTF8 ) ) ;
133- }
134-
135- private static void GenerateLocalizationMethod (
136- StringBuilder sb ,
137- LocalizableString ls ,
138- bool isCoreAssembly ,
139- PluginClassInfo pluginInfo )
140- {
141- sb . Append ( $ "public static string { ls . Key } (") ;
142- var parameters = BuildParameters ( ls ) ;
143- sb . Append ( string . Join ( ", " , parameters . Select ( p => $ "{ p . Type } { p . Name } ") ) ) ;
144- sb . Append ( ") => " ) ;
145-
146- var formatArgs = parameters . Count > 0
147- ? $ ", { string . Join ( ", " , parameters . Select ( p => p . Name ) ) } "
148- : string . Empty ;
149-
150- if ( isCoreAssembly )
151- {
152- sb . AppendLine ( parameters . Count > 0
153- ? $ "string.Format(InternationalizationManager.Instance.GetTranslation(\" { ls . Key } \" ){ formatArgs } );"
154- : $ "InternationalizationManager.Instance.GetTranslation(\" { ls . Key } \" );") ;
155- }
156- else if ( pluginInfo ? . IsValid == true )
157- {
158- sb . AppendLine ( parameters . Count > 0
159- ? $ "string.Format({ pluginInfo . ContextAccessor } .API.GetTranslation(\" { ls . Key } \" ){ formatArgs } );"
160- : $ "{ pluginInfo . ContextAccessor } .API.GetTranslation(\" { ls . Key } \" );") ;
161- }
162- else
163- {
164- sb . AppendLine ( "\" LOCALIZATION_ERROR\" ;" ) ;
165- }
110+ #endregion
166111
167- sb . AppendLine ( ) ;
168- }
112+ #region Parse Xaml File
169113
170114 private static ImmutableArray < LocalizableString > ParseXamlFile ( AdditionalText file , CancellationToken ct )
171115 {
@@ -219,6 +163,10 @@ private static (string Summary, ImmutableArray<LocalizableStringParam> Parameter
219163 }
220164 }
221165
166+ #endregion
167+
168+ #region Get Localization Keys
169+
222170 private static string GetLocalizationKeyFromInvocation ( GeneratorSyntaxContext context , CancellationToken ct )
223171 {
224172 var invocation = ( InvocationExpressionSyntax ) context . Node ;
@@ -232,6 +180,10 @@ private static string GetLocalizationKeyFromInvocation(GeneratorSyntaxContext co
232180 return null ;
233181 }
234182
183+ #endregion
184+
185+ #region Get Plugin Class Info
186+
235187 private static PluginClassInfo GetPluginClassInfo ( GeneratorSyntaxContext context , CancellationToken ct )
236188 {
237189 var classDecl = ( ClassDeclarationSyntax ) context . Node ;
@@ -276,19 +228,46 @@ private static PluginClassInfo GetValidPluginInfo(
276228 return null ;
277229 }
278230
279- private static List < MethodParameter > BuildParameters ( LocalizableString ls )
231+ #endregion
232+
233+ #region Generate Source
234+
235+ private static void GenerateSource (
236+ SourceProductionContext context ,
237+ ImmutableArray < LocalizableString > localizedStrings ,
238+ IEnumerable < string > unusedKeys ,
239+ OptimizationLevel optimizationLevel ,
240+ string assemblyName ,
241+ bool isCoreAssembly ,
242+ PluginClassInfo pluginInfo )
280243 {
281- var parameters = new List < MethodParameter > ( ) ;
282- for ( var i = 0 ; i < 10 ; i ++ )
244+ var sourceBuilder = new StringBuilder ( ) ;
245+ sourceBuilder . AppendLine ( "// <auto-generated />" ) ;
246+ sourceBuilder . AppendLine ( "#nullable enable" ) ;
247+
248+ if ( isCoreAssembly )
283249 {
284- if ( ! ls . Value . Contains ( $ "{{{i}}}") ) continue ;
250+ sourceBuilder . AppendLine ( "using Flow.Launcher.Core.Resource;" ) ;
251+ }
285252
286- var param = ls . Params . FirstOrDefault ( p => p . Index == i ) ;
287- parameters . Add ( param is null
288- ? new MethodParameter ( $ "arg{ i } ", "object?" )
289- : new MethodParameter ( param . Name , param . Type ) ) ;
253+ sourceBuilder . AppendLine ( $ "namespace { assemblyName } ;") ;
254+ sourceBuilder . AppendLine ( ) ;
255+ sourceBuilder . AppendLine ( $ "[System.CodeDom.Compiler.GeneratedCode(\" { nameof ( LocalizeSourceGenerator ) } \" , \" 1.0.0\" )]") ;
256+ sourceBuilder . AppendLine ( $ "public static class { ClassName } ") ;
257+ sourceBuilder . AppendLine ( "{" ) ;
258+
259+ foreach ( var ls in localizedStrings )
260+ {
261+ if ( optimizationLevel == OptimizationLevel . Release && unusedKeys . Contains ( ls . Key ) )
262+ continue ;
263+
264+ GenerateDocComments ( sourceBuilder , ls ) ;
265+ GenerateLocalizationMethod ( sourceBuilder , ls , isCoreAssembly , pluginInfo ) ;
290266 }
291- return parameters ;
267+
268+ sourceBuilder . AppendLine ( "}" ) ;
269+
270+ context . AddSource ( $ "{ ClassName } .g.cs", SourceText . From ( sourceBuilder . ToString ( ) , Encoding . UTF8 ) ) ;
292271 }
293272
294273 private static void GenerateDocComments ( StringBuilder sb , LocalizableString ls )
@@ -307,6 +286,60 @@ private static void GenerateDocComments(StringBuilder sb, LocalizableString ls)
307286 sb . AppendLine ( "/// </code>" ) ;
308287 }
309288
289+ private static void GenerateLocalizationMethod (
290+ StringBuilder sb ,
291+ LocalizableString ls ,
292+ bool isCoreAssembly ,
293+ PluginClassInfo pluginInfo )
294+ {
295+ sb . Append ( $ "public static string { ls . Key } (") ;
296+ var parameters = BuildParameters ( ls ) ;
297+ sb . Append ( string . Join ( ", " , parameters . Select ( p => $ "{ p . Type } { p . Name } ") ) ) ;
298+ sb . Append ( ") => " ) ;
299+
300+ var formatArgs = parameters . Count > 0
301+ ? $ ", { string . Join ( ", " , parameters . Select ( p => p . Name ) ) } "
302+ : string . Empty ;
303+
304+ if ( isCoreAssembly )
305+ {
306+ sb . AppendLine ( parameters . Count > 0
307+ ? $ "string.Format(InternationalizationManager.Instance.GetTranslation(\" { ls . Key } \" ){ formatArgs } );"
308+ : $ "InternationalizationManager.Instance.GetTranslation(\" { ls . Key } \" );") ;
309+ }
310+ else if ( pluginInfo ? . IsValid == true )
311+ {
312+ sb . AppendLine ( parameters . Count > 0
313+ ? $ "string.Format({ pluginInfo . ContextAccessor } .API.GetTranslation(\" { ls . Key } \" ){ formatArgs } );"
314+ : $ "{ pluginInfo . ContextAccessor } .API.GetTranslation(\" { ls . Key } \" );") ;
315+ }
316+ else
317+ {
318+ sb . AppendLine ( "\" LOCALIZATION_ERROR\" ;" ) ;
319+ }
320+
321+ sb . AppendLine ( ) ;
322+ }
323+
324+ private static List < MethodParameter > BuildParameters ( LocalizableString ls )
325+ {
326+ var parameters = new List < MethodParameter > ( ) ;
327+ for ( var i = 0 ; i < 10 ; i ++ )
328+ {
329+ if ( ! ls . Value . Contains ( $ "{{{i}}}") ) continue ;
330+
331+ var param = ls . Params . FirstOrDefault ( p => p . Index == i ) ;
332+ parameters . Add ( param is null
333+ ? new MethodParameter ( $ "arg{ i } ", "object?" )
334+ : new MethodParameter ( param . Name , param . Type ) ) ;
335+ }
336+ return parameters ;
337+ }
338+
339+ #endregion
340+
341+ #region Classes
342+
310343 public class MethodParameter
311344 {
312345 public string Name { get ; }
@@ -364,5 +397,7 @@ public PluginClassInfo(string className, string propertyName, bool isValid)
364397 IsValid = isValid ;
365398 }
366399 }
400+
401+ #endregion
367402 }
368403}
0 commit comments