Skip to content

Commit 7f31bed

Browse files
committed
Improve code quality
1 parent aaf5331 commit 7f31bed

File tree

1 file changed

+119
-84
lines changed

1 file changed

+119
-84
lines changed

Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs

Lines changed: 119 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,37 @@
1313

1414
namespace 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

Comments
 (0)