From b777fd3123dc0eb04b5002985198abdaf17d5dd0 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 15:15:12 +0800
Subject: [PATCH 01/23] Support enum localization
---
.../Attributes/EnumLocalizeAttribute.cs | 12 +
.../Attributes/EnumLocalizeKeyAttribute.cs | 33 +++
.../Attributes/EnumLocalizeValueAttribute.cs | 33 +++
.../Constants.cs | 7 +-
Flow.Launcher.Localization.Shared/Helper.cs | 26 +-
.../AnalyzerReleases.Unshipped.md | 1 +
.../Localize/EnumSourceGenerator.cs | 269 ++++++++++++++++++
.../Localize/LocalizeSourceGenerator.cs | 16 +-
.../SourceGeneratorDiagnostics.cs | 9 +
9 files changed, 387 insertions(+), 19 deletions(-)
create mode 100644 Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
create mode 100644 Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
create mode 100644 Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
create mode 100644 Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
new file mode 100644
index 0000000..8c98b89
--- /dev/null
+++ b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Flow.Launcher.Localization.SourceGenerators.Shared.Attributes
+{
+ ///
+ /// Attribute to mark an enum for localization.
+ ///
+ [AttributeUsage(AttributeTargets.Enum)]
+ public class EnumLocalizeAttribute : Attribute
+ {
+ }
+}
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
new file mode 100644
index 0000000..de4a08f
--- /dev/null
+++ b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Flow.Launcher.Localization.SourceGenerators.Shared.Attributes
+{
+ ///
+ /// Attribute to mark a localization key for an enum field.
+ ///
+ [AttributeUsage(AttributeTargets.Field)]
+ public class EnumLocalizeKeyAttribute : Attribute
+ {
+ public static readonly EnumLocalizeKeyAttribute Default = new EnumLocalizeKeyAttribute();
+
+ public EnumLocalizeKeyAttribute() : this(string.Empty)
+ {
+ }
+
+ public EnumLocalizeKeyAttribute(string enumLocalizeKey)
+ {
+ EnumLocalizeKey = enumLocalizeKey;
+ }
+
+ public virtual string LocalizeKey => EnumLocalizeKey;
+
+ protected string EnumLocalizeKey { get; set; }
+
+ public override bool Equals(object obj) =>
+ obj is EnumLocalizeKeyAttribute other && other.LocalizeKey == LocalizeKey;
+
+ public override int GetHashCode() => LocalizeKey?.GetHashCode() ?? 0;
+
+ public override bool IsDefaultAttribute() => Equals(Default);
+ }
+}
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
new file mode 100644
index 0000000..5af0499
--- /dev/null
+++ b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Flow.Launcher.Localization.SourceGenerators.Shared.Attributes
+{
+ ///
+ /// Attribute to mark a localization value for an enum field.
+ ///
+ [AttributeUsage(AttributeTargets.Field)]
+ public class EnumLocalizeValueAttribute : Attribute
+ {
+ public static readonly EnumLocalizeValueAttribute Default = new EnumLocalizeValueAttribute();
+
+ public EnumLocalizeValueAttribute() : this(string.Empty)
+ {
+ }
+
+ public EnumLocalizeValueAttribute(string enumLocalizeValue)
+ {
+ EnumLocalizeValue = enumLocalizeValue;
+ }
+
+ public virtual string LocalizeValue => EnumLocalizeValue;
+
+ protected string EnumLocalizeValue { get; set; }
+
+ public override bool Equals(object obj) =>
+ obj is EnumLocalizeValueAttribute other && other.LocalizeValue == LocalizeValue;
+
+ public override int GetHashCode() => LocalizeValue?.GetHashCode() ?? 0;
+
+ public override bool IsDefaultAttribute() => Equals(Default);
+ }
+}
diff --git a/Flow.Launcher.Localization.Shared/Constants.cs b/Flow.Launcher.Localization.Shared/Constants.cs
index 568da5d..f5c9279 100644
--- a/Flow.Launcher.Localization.Shared/Constants.cs
+++ b/Flow.Launcher.Localization.Shared/Constants.cs
@@ -1,4 +1,5 @@
-using System.Text.RegularExpressions;
+using Flow.Launcher.Localization.SourceGenerators.Shared.Attributes;
+using System.Text.RegularExpressions;
namespace Flow.Launcher.Localization.Shared
{
@@ -20,6 +21,10 @@ public static class Constants
public const string OldLocalizationMethodName = "GetTranslation";
public const string StringFormatMethodName = "Format";
public const string StringFormatTypeName = "string";
+ public const string EnumLocalizeClassSuffix = "Data";
+ public const string EnumLocalizeAttributeName = nameof(EnumLocalizeAttribute);
+ public const string EnumLocalizeKeyAttributeName = nameof(EnumLocalizeKeyAttribute);
+ public const string EnumLocalizeValueAttributeName = nameof(EnumLocalizeValueAttribute);
public static readonly Regex LanguagesXamlRegex = new Regex(@"\\Languages\\[^\\]+\.xaml$", RegexOptions.IgnoreCase);
public static readonly string[] OldLocalizationClasses = { "IPublicAPI", "Internationalization" };
diff --git a/Flow.Launcher.Localization.Shared/Helper.cs b/Flow.Launcher.Localization.Shared/Helper.cs
index d9502ac..044fa45 100644
--- a/Flow.Launcher.Localization.Shared/Helper.cs
+++ b/Flow.Launcher.Localization.Shared/Helper.cs
@@ -1,9 +1,11 @@
-using Microsoft.CodeAnalysis;
+using System;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
-using System.Linq;
-using System.Threading;
namespace Flow.Launcher.Localization.Shared
{
@@ -81,5 +83,23 @@ private static Location GetCodeFixLocation(PropertyDeclarationSyntax property, S
}
#endregion
+
+ #region Tab String
+
+ public static string Spacing(int n)
+ {
+ Span spaces = stackalloc char[n * 4];
+ spaces.Fill(' ');
+
+ var sb = new StringBuilder(n * 4);
+ foreach (var c in spaces)
+ {
+ _ = sb.Append(c);
+ }
+
+ return sb.ToString();
+ }
+
+ #endregion
}
}
diff --git a/Flow.Launcher.Localization.SourceGenerators/AnalyzerReleases.Unshipped.md b/Flow.Launcher.Localization.SourceGenerators/AnalyzerReleases.Unshipped.md
index f60d258..c1ad7a3 100644
--- a/Flow.Launcher.Localization.SourceGenerators/AnalyzerReleases.Unshipped.md
+++ b/Flow.Launcher.Localization.SourceGenerators/AnalyzerReleases.Unshipped.md
@@ -11,3 +11,4 @@ FLSG0004 | Localization | Warning | FLSG0004_ContextPropertyNotStatic
FLSG0005 | Localization | Warning | FLSG0005_ContextPropertyIsPrivate
FLSG0006 | Localization | Warning | FLSG0006_ContextPropertyIsProtected
FLSG0007 | Localization | Warning | FLSG0007_LocalizationKeyUnused
+FLSG0008 | Localization | Warning | FLSG0008_EnumFieldLocalizationKeyValueInvalid
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
new file mode 100644
index 0000000..88a73cc
--- /dev/null
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -0,0 +1,269 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Text;
+using Flow.Launcher.Localization.Shared;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Text;
+
+namespace Flow.Launcher.Localization.SourceGenerators.Localize
+{
+ [Generator]
+ public partial class EnumSourceGenerator : IIncrementalGenerator
+ {
+ #region Fields
+
+ private static readonly Version PackageVersion = typeof(EnumSourceGenerator).Assembly.GetName().Version;
+
+ private static readonly ImmutableArray _emptyEnumFields = ImmutableArray.Empty;
+
+ #endregion
+
+ #region Incremental Generator
+
+ ///
+ /// Initializes the generator and registers source output based on resource files.
+ ///
+ /// The initialization context.
+ public void Initialize(IncrementalGeneratorInitializationContext context)
+ {
+ var enumDeclarations = context.SyntaxProvider
+ .CreateSyntaxProvider(
+ predicate: (s, _) => s is EnumDeclarationSyntax,
+ transform: (ctx, _) => (EnumDeclarationSyntax)ctx.Node)
+ .Where(ed => ed.AttributeLists.Count > 0)
+ .Collect();
+
+ var compilation = context.CompilationProvider;
+
+ var compilationEnums = enumDeclarations.Combine(compilation);
+
+ context.RegisterSourceOutput(compilationEnums, Execute);
+ }
+
+ ///
+ /// Executes the generation of string properties based on the provided data.
+ ///
+ /// The source production context.
+ /// The provided data.
+ private void Execute(SourceProductionContext spc,
+ (ImmutableArray Enums, Compilation Compilation) data)
+ {
+ var enums = data.Enums;
+ var compilation = data.Compilation;
+
+ var assemblyName = compilation.AssemblyName ?? Constants.DefaultNamespace;
+
+ foreach (var enumDeclaration in enums.Distinct())
+ {
+ var semanticModel = compilation.GetSemanticModel(enumDeclaration.SyntaxTree);
+ var enumSymbol = semanticModel.GetDeclaredSymbol(enumDeclaration) as INamedTypeSymbol;
+
+ // Check if the enum has the EnumLocalize attribute
+ if (enumSymbol?.GetAttributes().Any(ad =>
+ ad.AttributeClass?.Name == Constants.EnumLocalizeAttributeName) ?? false)
+ {
+ GenerateSource(spc, enumSymbol, assemblyName);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Generate Source
+
+ private void GenerateSource(SourceProductionContext spc, INamedTypeSymbol enumSymbol, string assemblyName)
+ {
+ var enumFullName = enumSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ var enumDataClassName = $"{enumSymbol.Name}{Constants.EnumLocalizeClassSuffix}";
+ var enumName = enumSymbol.Name;
+ var enumNamespace = enumSymbol.ContainingNamespace.ToDisplayString();
+ var tabString = Helper.Spacing(1);
+
+ var sourceBuilder = new StringBuilder();
+
+ // Generate header
+ GeneratedHeaderFromPath(sourceBuilder, enumFullName);
+ sourceBuilder.AppendLine();
+
+ // Generate using directives
+ sourceBuilder.AppendLine("using System.Collections.Generic;");
+ sourceBuilder.AppendLine("using Flow.Launcher.Plugin;");
+ sourceBuilder.AppendLine();
+
+ // Generate namespace
+ sourceBuilder.AppendLine($"namespace {enumNamespace};");
+ sourceBuilder.AppendLine();
+
+ // Generate class
+ sourceBuilder.AppendLine($"[System.CodeDom.Compiler.GeneratedCode(\"{nameof(EnumSourceGenerator)}\", \"{PackageVersion}\")]");
+ sourceBuilder.AppendLine($"public class {enumDataClassName}");
+ sourceBuilder.AppendLine("{");
+
+ // Generate properties
+ sourceBuilder.AppendLine($"{tabString}public {enumName} Value {{ get; private init; }}");
+ sourceBuilder.AppendLine($"{tabString}public string Display {{ get; set; }}");
+ sourceBuilder.AppendLine($"{tabString}public string LocalizationKey {{ get; set; }}");
+ sourceBuilder.AppendLine($"{tabString}public string LocalizationValue {{ get; set; }}");
+ sourceBuilder.AppendLine();
+
+ // Generate GetValues method
+ sourceBuilder.AppendLine($"{tabString}public static List<{enumDataClassName}> GetValues()");
+ sourceBuilder.AppendLine($"{tabString}{{");
+ sourceBuilder.AppendLine($"{tabString}{tabString}return new List<{enumDataClassName}>");
+ sourceBuilder.AppendLine($"{tabString}{tabString}{{");
+ var enumFields = GetEnumFields(spc, enumSymbol, enumFullName);
+ if (enumFields.Length == 0) return;
+ foreach (var enumField in enumFields)
+ {
+ GenerateEnumField(sourceBuilder, enumField, enumName, tabString);
+ }
+ sourceBuilder.AppendLine($"{tabString}{tabString}}};");
+ sourceBuilder.AppendLine($"{tabString}}}");
+ sourceBuilder.AppendLine();
+
+ // Generate UpdateLabels method
+ GenerateUpdateLabelsMethod(sourceBuilder, enumDataClassName, tabString);
+
+ sourceBuilder.AppendLine($"}}");
+
+ // Add source to context
+ spc.AddSource($"{Constants.ClassName}.{enumNamespace}.{enumDataClassName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ }
+
+ private static void GeneratedHeaderFromPath(StringBuilder sb, string enumFullName)
+ {
+ if (string.IsNullOrEmpty(enumFullName))
+ {
+ sb.AppendLine("/// ");
+ }
+ else
+ {
+ sb.AppendLine("/// ")
+ .AppendLine($"/// From: {enumFullName}")
+ .AppendLine("/// ");
+ }
+ }
+
+ private static void GenerateEnumField(StringBuilder sb, EnumField enumField, string enumName, string tabString)
+ {
+ sb.AppendLine($"{tabString}{tabString}{tabString}new()");
+ sb.AppendLine($"{tabString}{tabString}{tabString}{{");
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}Value = {enumName}.{enumField.EnumFieldName},");
+ if (enumField.UseLocalizationKey)
+ {
+ // TODO
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}Display = Main.Context.API.GetTranslation(\"{enumField.LocalizationKey}\"),");
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}LocalizationKey = \"{enumField.LocalizationKey}\",");
+ }
+ else
+ {
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}Display = \"{enumField.LocalizationValue}\",");
+ }
+ if (enumField.LocalizationValue != null)
+ {
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}LocalizationValue = \"{enumField.LocalizationValue}\",");
+ }
+ sb.AppendLine($"{tabString}{tabString}{tabString}}},");
+ }
+
+ private static void GenerateUpdateLabelsMethod(StringBuilder sb, string enumDataClassName, string tabString)
+ {
+ sb.AppendLine($"{tabString}public static void UpdateLabels(List<{enumDataClassName}> options)");
+ sb.AppendLine($"{tabString}{{");
+ sb.AppendLine($"{tabString}{tabString}foreach (var item in options)");
+ sb.AppendLine($"{tabString}{tabString}{{");
+ sb.AppendLine($"{tabString}{tabString}{tabString}if (!string.IsNullOrEmpty(item.LocalizationKey))");
+ sb.AppendLine($"{tabString}{tabString}{tabString}{{");
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}item.Display = Main.Context.API.GetTranslation(item.LocalizationKey);");
+ sb.AppendLine($"{tabString}{tabString}{tabString}}}");
+ sb.AppendLine($"{tabString}{tabString}}}");
+ sb.AppendLine($"{tabString}}}");
+ }
+
+ #endregion
+
+ #region Get Enum Fields
+
+ private static ImmutableArray GetEnumFields(SourceProductionContext spc, INamedTypeSymbol enumSymbol, string enumFullName)
+ {
+ // Iterate through enum members and get enum fields
+ var enumFields = new List();
+ var enumError = false;
+ foreach (var member in enumSymbol.GetMembers().Where(m => m.Kind == SymbolKind.Field))
+ {
+ if (member is IFieldSymbol fieldSymbol)
+ {
+ var enumFieldName = fieldSymbol.Name;
+
+ // Check if the field has the EnumLocalizeKey attribute
+ var keyAttr = fieldSymbol.GetAttributes()
+ .FirstOrDefault(a => a.AttributeClass?.Name == Constants.EnumLocalizeKeyAttributeName);
+ var keyAttrExist = keyAttr != null;
+
+ // Check if the field has the EnumLocalizeValue attribute
+ var valueAttr = fieldSymbol.GetAttributes()
+ .FirstOrDefault(a => a.AttributeClass?.Name == Constants.EnumLocalizeValueAttributeName);
+ var valueAttrExist = valueAttr != null;
+
+ // Get the key and value from the attributes
+ var key = keyAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
+ var value = valueAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
+
+ if (keyAttrExist && !string.IsNullOrEmpty(key))
+ {
+ // If localization key exists and is valid, use it
+ enumFields.Add(new EnumField(enumFieldName, key, valueAttrExist ? value : null));
+ }
+ else if (valueAttrExist)
+ {
+ // If localization value exists, use it
+ enumFields.Add(new EnumField(enumFieldName, value));
+ }
+ else
+ {
+ // If localization key and value are not provided, do not generate the field and report a diagnostic
+ spc.ReportDiagnostic(Diagnostic.Create(
+ SourceGeneratorDiagnostics.EnumFieldLocalizationKeyValueInvalid,
+ Location.None,
+ $"{enumFullName}.{enumFieldName}"));
+ enumError = true;
+ }
+ }
+ }
+
+ // If there was an error, do not generate the class
+ if (enumError) return _emptyEnumFields;
+
+ return enumFields.ToImmutableArray();
+ }
+
+ #endregion
+
+ #region Classes
+
+ public class EnumField
+ {
+ public string EnumFieldName { get; set; }
+ public string LocalizationKey { get; set; }
+ public string LocalizationValue { get; set; }
+
+ public bool UseLocalizationKey => LocalizationKey != null;
+
+ public EnumField(string enumFieldName, string localizationValue) : this(enumFieldName, null, localizationValue)
+ {
+ }
+
+ public EnumField(string enumFieldName, string localizationKey, string localizationValue)
+ {
+ EnumFieldName = enumFieldName;
+ LocalizationKey = localizationKey;
+ LocalizationValue = localizationValue;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index 9b2e0ca..931426d 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -572,7 +572,7 @@ private static void GenerateSource(
sourceBuilder.AppendLine($"public static class {Constants.ClassName}");
sourceBuilder.AppendLine("{");
- var tabString = Spacing(1);
+ var tabString = Helper.Spacing(1);
// Generate API instance
string getTranslation = null;
@@ -677,20 +677,6 @@ private static void GenerateLocalizationMethod(
sb.AppendLine();
}
- private static string Spacing(int n)
- {
- Span spaces = stackalloc char[n * 4];
- spaces.Fill(' ');
-
- var sb = new StringBuilder(n * 4);
- foreach (var c in spaces)
- {
- _ = sb.Append(c);
- }
-
- return sb.ToString();
- }
-
#endregion
#region Classes
diff --git a/Flow.Launcher.Localization.SourceGenerators/SourceGeneratorDiagnostics.cs b/Flow.Launcher.Localization.SourceGenerators/SourceGeneratorDiagnostics.cs
index d162cdb..f8cde85 100644
--- a/Flow.Launcher.Localization.SourceGenerators/SourceGeneratorDiagnostics.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/SourceGeneratorDiagnostics.cs
@@ -67,5 +67,14 @@ public static class SourceGeneratorDiagnostics
DiagnosticSeverity.Warning,
isEnabledByDefault: true
);
+
+ public static readonly DiagnosticDescriptor EnumFieldLocalizationKeyValueInvalid = new DiagnosticDescriptor(
+ "FLSG0008",
+ "Enum field localization key and value invalid",
+ $"Enum field `{{0}}` does not have a valid localization key or value",
+ "Localization",
+ DiagnosticSeverity.Warning,
+ isEnabledByDefault: true
+ );
}
}
From e65572e2ccf55573b75ab879d2ab565e930c8f88 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 15:16:11 +0800
Subject: [PATCH 02/23] Fix namespaces
---
.../Attributes/EnumLocalizeAttribute.cs | 2 +-
.../Attributes/EnumLocalizeKeyAttribute.cs | 2 +-
.../Attributes/EnumLocalizeValueAttribute.cs | 2 +-
Flow.Launcher.Localization.Shared/Constants.cs | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
index 8c98b89..5053ed1 100644
--- a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
+++ b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
@@ -1,6 +1,6 @@
using System;
-namespace Flow.Launcher.Localization.SourceGenerators.Shared.Attributes
+namespace Flow.Launcher.Localization.Shared.Attributes
{
///
/// Attribute to mark an enum for localization.
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
index de4a08f..df00e77 100644
--- a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
+++ b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
@@ -1,6 +1,6 @@
using System;
-namespace Flow.Launcher.Localization.SourceGenerators.Shared.Attributes
+namespace Flow.Launcher.Localization.Shared.Attributes
{
///
/// Attribute to mark a localization key for an enum field.
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
index 5af0499..74cf62b 100644
--- a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
+++ b/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
@@ -1,6 +1,6 @@
using System;
-namespace Flow.Launcher.Localization.SourceGenerators.Shared.Attributes
+namespace Flow.Launcher.Localization.Shared.Attributes
{
///
/// Attribute to mark a localization value for an enum field.
diff --git a/Flow.Launcher.Localization.Shared/Constants.cs b/Flow.Launcher.Localization.Shared/Constants.cs
index f5c9279..eddbdf5 100644
--- a/Flow.Launcher.Localization.Shared/Constants.cs
+++ b/Flow.Launcher.Localization.Shared/Constants.cs
@@ -1,4 +1,4 @@
-using Flow.Launcher.Localization.SourceGenerators.Shared.Attributes;
+using Flow.Launcher.Localization.Shared.Attributes;
using System.Text.RegularExpressions;
namespace Flow.Launcher.Localization.Shared
From fdbf20d73849c6c63389a7d81400dd9ab0ff05d1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 16:34:53 +0800
Subject: [PATCH 03/23] Add new attribution project
---
.../EnumLocalizeAttribute.cs | 2 +-
.../EnumLocalizeKeyAttribute.cs | 2 +-
.../EnumLocalizeValueAttribute.cs | 2 +-
.../Flow.Launcher.Localization.Attributes.csproj | 8 ++++++++
Flow.Launcher.Localization.Shared/Constants.cs | 9 ++++-----
Flow.Launcher.Localization.slnx | 1 +
6 files changed, 16 insertions(+), 8 deletions(-)
rename {Flow.Launcher.Localization.Shared/Attributes => Flow.Launcher.Localization.Attributes}/EnumLocalizeAttribute.cs (79%)
rename {Flow.Launcher.Localization.Shared/Attributes => Flow.Launcher.Localization.Attributes}/EnumLocalizeKeyAttribute.cs (94%)
rename {Flow.Launcher.Localization.Shared/Attributes => Flow.Launcher.Localization.Attributes}/EnumLocalizeValueAttribute.cs (94%)
create mode 100644 Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs b/Flow.Launcher.Localization.Attributes/EnumLocalizeAttribute.cs
similarity index 79%
rename from Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
rename to Flow.Launcher.Localization.Attributes/EnumLocalizeAttribute.cs
index 5053ed1..21f2a06 100644
--- a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeAttribute.cs
+++ b/Flow.Launcher.Localization.Attributes/EnumLocalizeAttribute.cs
@@ -1,6 +1,6 @@
using System;
-namespace Flow.Launcher.Localization.Shared.Attributes
+namespace Flow.Launcher.Localization.Attributes
{
///
/// Attribute to mark an enum for localization.
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs b/Flow.Launcher.Localization.Attributes/EnumLocalizeKeyAttribute.cs
similarity index 94%
rename from Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
rename to Flow.Launcher.Localization.Attributes/EnumLocalizeKeyAttribute.cs
index df00e77..39d75eb 100644
--- a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeKeyAttribute.cs
+++ b/Flow.Launcher.Localization.Attributes/EnumLocalizeKeyAttribute.cs
@@ -1,6 +1,6 @@
using System;
-namespace Flow.Launcher.Localization.Shared.Attributes
+namespace Flow.Launcher.Localization.Attributes
{
///
/// Attribute to mark a localization key for an enum field.
diff --git a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs b/Flow.Launcher.Localization.Attributes/EnumLocalizeValueAttribute.cs
similarity index 94%
rename from Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
rename to Flow.Launcher.Localization.Attributes/EnumLocalizeValueAttribute.cs
index 74cf62b..75c3859 100644
--- a/Flow.Launcher.Localization.Shared/Attributes/EnumLocalizeValueAttribute.cs
+++ b/Flow.Launcher.Localization.Attributes/EnumLocalizeValueAttribute.cs
@@ -1,6 +1,6 @@
using System;
-namespace Flow.Launcher.Localization.Shared.Attributes
+namespace Flow.Launcher.Localization.Attributes
{
///
/// Attribute to mark a localization value for an enum field.
diff --git a/Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj b/Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj
new file mode 100644
index 0000000..8cae302
--- /dev/null
+++ b/Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj
@@ -0,0 +1,8 @@
+
+
+
+ netstandard2.0
+ Flow.Launcher.Localization.Attribute
+
+
+
diff --git a/Flow.Launcher.Localization.Shared/Constants.cs b/Flow.Launcher.Localization.Shared/Constants.cs
index eddbdf5..a4610ec 100644
--- a/Flow.Launcher.Localization.Shared/Constants.cs
+++ b/Flow.Launcher.Localization.Shared/Constants.cs
@@ -1,5 +1,4 @@
-using Flow.Launcher.Localization.Shared.Attributes;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
namespace Flow.Launcher.Localization.Shared
{
@@ -22,9 +21,9 @@ public static class Constants
public const string StringFormatMethodName = "Format";
public const string StringFormatTypeName = "string";
public const string EnumLocalizeClassSuffix = "Data";
- public const string EnumLocalizeAttributeName = nameof(EnumLocalizeAttribute);
- public const string EnumLocalizeKeyAttributeName = nameof(EnumLocalizeKeyAttribute);
- public const string EnumLocalizeValueAttributeName = nameof(EnumLocalizeValueAttribute);
+ public const string EnumLocalizeAttributeName = "EnumLocalizeAttribute";
+ public const string EnumLocalizeKeyAttributeName = "EnumLocalizeKeyAttribute";
+ public const string EnumLocalizeValueAttributeName = "EnumLocalizeValueAttribute";
public static readonly Regex LanguagesXamlRegex = new Regex(@"\\Languages\\[^\\]+\.xaml$", RegexOptions.IgnoreCase);
public static readonly string[] OldLocalizationClasses = { "IPublicAPI", "Internationalization" };
diff --git a/Flow.Launcher.Localization.slnx b/Flow.Launcher.Localization.slnx
index 27c8f44..779a1ca 100644
--- a/Flow.Launcher.Localization.slnx
+++ b/Flow.Launcher.Localization.slnx
@@ -1,5 +1,6 @@
+
From 4e993c37776d4a63d835cf3451d4e6cd84caa7b3 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 16:58:50 +0800
Subject: [PATCH 04/23] Include Flow.Launcher.Localization.Attributes project
---
.../Flow.Launcher.Localization.csproj | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj b/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj
index b9ee6bc..5cf25ff 100644
--- a/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj
+++ b/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj
@@ -6,7 +6,7 @@
Flow.Launcher.Localization
Flow.Launcher.Localization
false
- true
+ false
true
true
@@ -33,6 +33,9 @@
All
+
+ runtime
+
All
@@ -47,6 +50,11 @@
analyzers/dotnet/cs
false
+
+ true
+ lib/$(TargetFramework)
+ true
+
true
analyzers/dotnet/cs
From f2bc91d642fc57034d28b2be587f3965b95ced98 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 17:36:51 +0800
Subject: [PATCH 05/23] Add summary for classes, properties and methods
---
.../Localize/EnumSourceGenerator.cs | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 88a73cc..8d263c2 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -98,18 +98,42 @@ private void GenerateSource(SourceProductionContext spc, INamedTypeSymbol enumSy
sourceBuilder.AppendLine();
// Generate class
+ sourceBuilder.AppendLine($"/// ");
+ sourceBuilder.AppendLine($"/// Data class for ");
+ sourceBuilder.AppendLine($"/// ");
sourceBuilder.AppendLine($"[System.CodeDom.Compiler.GeneratedCode(\"{nameof(EnumSourceGenerator)}\", \"{PackageVersion}\")]");
sourceBuilder.AppendLine($"public class {enumDataClassName}");
sourceBuilder.AppendLine("{");
// Generate properties
+ sourceBuilder.AppendLine($"{tabString}/// ");
+ sourceBuilder.AppendLine($"{tabString}/// The value of the enum");
+ sourceBuilder.AppendLine($"{tabString}/// ");
sourceBuilder.AppendLine($"{tabString}public {enumName} Value {{ get; private init; }}");
+ sourceBuilder.AppendLine();
+
+ sourceBuilder.AppendLine($"{tabString}/// ");
+ sourceBuilder.AppendLine($"{tabString}/// The display text of the enum value");
+ sourceBuilder.AppendLine($"{tabString}/// ");
sourceBuilder.AppendLine($"{tabString}public string Display {{ get; set; }}");
+ sourceBuilder.AppendLine();
+
+ sourceBuilder.AppendLine($"{tabString}/// ");
+ sourceBuilder.AppendLine($"{tabString}/// The localization key of the enum value");
+ sourceBuilder.AppendLine($"{tabString}/// ");
sourceBuilder.AppendLine($"{tabString}public string LocalizationKey {{ get; set; }}");
+ sourceBuilder.AppendLine();
+
+ sourceBuilder.AppendLine($"{tabString}/// ");
+ sourceBuilder.AppendLine($"{tabString}/// The localization value of the enum value");
+ sourceBuilder.AppendLine($"{tabString}/// ");
sourceBuilder.AppendLine($"{tabString}public string LocalizationValue {{ get; set; }}");
sourceBuilder.AppendLine();
// Generate GetValues method
+ sourceBuilder.AppendLine($"{tabString}/// ");
+ sourceBuilder.AppendLine($"{tabString}/// Get all values of ");
+ sourceBuilder.AppendLine($"{tabString}/// ");
sourceBuilder.AppendLine($"{tabString}public static List<{enumDataClassName}> GetValues()");
sourceBuilder.AppendLine($"{tabString}{{");
sourceBuilder.AppendLine($"{tabString}{tabString}return new List<{enumDataClassName}>");
@@ -171,6 +195,10 @@ private static void GenerateEnumField(StringBuilder sb, EnumField enumField, str
private static void GenerateUpdateLabelsMethod(StringBuilder sb, string enumDataClassName, string tabString)
{
+ sb.AppendLine($"{tabString}/// ");
+ sb.AppendLine($"{tabString}/// Update the labels of the enum values when culture info changes.");
+ sb.AppendLine($"{tabString}/// See for more details");
+ sb.AppendLine($"{tabString}/// ");
sb.AppendLine($"{tabString}public static void UpdateLabels(List<{enumDataClassName}> options)");
sb.AppendLine($"{tabString}{{");
sb.AppendLine($"{tabString}{tabString}foreach (var item in options)");
From a47ce440a219fdbf1c7007067236ab4a204671b1 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 17:51:32 +0800
Subject: [PATCH 06/23] Fix root namespace
---
.../Flow.Launcher.Localization.Attributes.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj b/Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj
index 8cae302..dd973d9 100644
--- a/Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj
+++ b/Flow.Launcher.Localization.Attributes/Flow.Launcher.Localization.Attributes.csproj
@@ -2,7 +2,7 @@
netstandard2.0
- Flow.Launcher.Localization.Attribute
+ Flow.Launcher.Localization.Attributes
From 5a92b4b68b3c01c3455cf97f28fef104411a0f31 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 17:52:24 +0800
Subject: [PATCH 07/23] Use global namespace
---
.../Localize/EnumSourceGenerator.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 8d263c2..75650e3 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -90,7 +90,6 @@ private void GenerateSource(SourceProductionContext spc, INamedTypeSymbol enumSy
// Generate using directives
sourceBuilder.AppendLine("using System.Collections.Generic;");
- sourceBuilder.AppendLine("using Flow.Launcher.Plugin;");
sourceBuilder.AppendLine();
// Generate namespace
@@ -197,7 +196,7 @@ private static void GenerateUpdateLabelsMethod(StringBuilder sb, string enumData
{
sb.AppendLine($"{tabString}/// ");
sb.AppendLine($"{tabString}/// Update the labels of the enum values when culture info changes.");
- sb.AppendLine($"{tabString}/// See for more details");
+ sb.AppendLine($"{tabString}/// See for more details");
sb.AppendLine($"{tabString}/// ");
sb.AppendLine($"{tabString}public static void UpdateLabels(List<{enumDataClassName}> options)");
sb.AppendLine($"{tabString}{{");
From 2baa32f820957c90f1ae40fdb59a765c6e9995e2 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 18:05:57 +0800
Subject: [PATCH 08/23] Move get valid plugin info to shared space
---
.../Localize/LocalizeSourceGenerator.cs | 86 +-----------------
.../PluginInfoHelper.cs | 88 +++++++++++++++++++
2 files changed, 91 insertions(+), 83 deletions(-)
create mode 100644 Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index 931426d..a4af84b 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -100,7 +100,9 @@ private void Execute(SourceProductionContext spc,
var assemblyName = compilation.AssemblyName ?? Constants.DefaultNamespace;
var useDI = configOptions.GetFLLUseDependencyInjection();
- var pluginInfo = GetValidPluginInfo(pluginClasses, spc, useDI);
+ var pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc, useDI);
+
+ if (pluginInfo == null) return;
GenerateSource(
spc,
@@ -421,88 +423,6 @@ private static string GetLocalizationKeyFromInvocation(GeneratorSyntaxContext co
#endregion
- #region Get Plugin Class Info
-
- private static PluginClassInfo GetValidPluginInfo(
- ImmutableArray pluginClasses,
- SourceProductionContext context,
- bool useDI)
- {
- // If p is null, this class does not implement IPluginI18n
- var iPluginI18nClasses = pluginClasses.Where(p => p != null).ToArray();
- if (iPluginI18nClasses.Length == 0)
- {
- context.ReportDiagnostic(Diagnostic.Create(
- SourceGeneratorDiagnostics.CouldNotFindPluginEntryClass,
- Location.None
- ));
- return null;
- }
-
- // If we use dependency injection, we do not need to check if there is a valid plugin context
- // Also we do not need to return the plugin info
- if (useDI)
- {
- return null;
- }
-
- // If p.PropertyName is null, this class does not have PluginInitContext property
- var iPluginI18nClassesWithContext = iPluginI18nClasses.Where(p => p.PropertyName != null).ToArray();
- if (iPluginI18nClassesWithContext.Length == 0)
- {
- foreach (var pluginClass in iPluginI18nClasses)
- {
- context.ReportDiagnostic(Diagnostic.Create(
- SourceGeneratorDiagnostics.CouldNotFindContextProperty,
- pluginClass.Location,
- pluginClass.ClassName
- ));
- }
- return null;
- }
-
- // Rest classes have implemented IPluginI18n and have PluginInitContext property
- // Check if the property is valid
- foreach (var pluginClass in iPluginI18nClassesWithContext)
- {
- if (pluginClass.IsValid == true)
- {
- return pluginClass;
- }
-
- if (!pluginClass.IsStatic)
- {
- context.ReportDiagnostic(Diagnostic.Create(
- SourceGeneratorDiagnostics.ContextPropertyNotStatic,
- pluginClass.Location,
- pluginClass.PropertyName
- ));
- }
-
- if (pluginClass.IsPrivate)
- {
- context.ReportDiagnostic(Diagnostic.Create(
- SourceGeneratorDiagnostics.ContextPropertyIsPrivate,
- pluginClass.Location,
- pluginClass.PropertyName
- ));
- }
-
- if (pluginClass.IsProtected)
- {
- context.ReportDiagnostic(Diagnostic.Create(
- SourceGeneratorDiagnostics.ContextPropertyIsProtected,
- pluginClass.Location,
- pluginClass.PropertyName
- ));
- }
- }
-
- return null;
- }
-
- #endregion
-
#region Generate Source
private static void GenerateSource(
diff --git a/Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs b/Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs
new file mode 100644
index 0000000..7a77103
--- /dev/null
+++ b/Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs
@@ -0,0 +1,88 @@
+using System.Collections.Immutable;
+using System.Linq;
+using Flow.Launcher.Localization.Shared;
+using Microsoft.CodeAnalysis;
+
+namespace Flow.Launcher.Localization.SourceGenerators
+{
+ internal class PluginInfoHelper
+ {
+ public static PluginClassInfo GetValidPluginInfoAndReportDiagnostic(
+ ImmutableArray pluginClasses,
+ SourceProductionContext context,
+ bool useDI)
+ {
+ // If p is null, this class does not implement IPluginI18n
+ var iPluginI18nClasses = pluginClasses.Where(p => p != null).ToArray();
+ if (iPluginI18nClasses.Length == 0)
+ {
+ context.ReportDiagnostic(Diagnostic.Create(
+ SourceGeneratorDiagnostics.CouldNotFindPluginEntryClass,
+ Location.None
+ ));
+ return null;
+ }
+
+ // If we use dependency injection, we do not need to check if there is a valid plugin context
+ // Also we do not need to return the plugin info
+ if (useDI)
+ {
+ return null;
+ }
+
+ // If p.PropertyName is null, this class does not have PluginInitContext property
+ var iPluginI18nClassesWithContext = iPluginI18nClasses.Where(p => p.PropertyName != null).ToArray();
+ if (iPluginI18nClassesWithContext.Length == 0)
+ {
+ foreach (var pluginClass in iPluginI18nClasses)
+ {
+ context.ReportDiagnostic(Diagnostic.Create(
+ SourceGeneratorDiagnostics.CouldNotFindContextProperty,
+ pluginClass.Location,
+ pluginClass.ClassName
+ ));
+ }
+ return null;
+ }
+
+ // Rest classes have implemented IPluginI18n and have PluginInitContext property
+ // Check if the property is valid
+ foreach (var pluginClass in iPluginI18nClassesWithContext)
+ {
+ if (pluginClass.IsValid == true)
+ {
+ return pluginClass;
+ }
+
+ if (!pluginClass.IsStatic)
+ {
+ context.ReportDiagnostic(Diagnostic.Create(
+ SourceGeneratorDiagnostics.ContextPropertyNotStatic,
+ pluginClass.Location,
+ pluginClass.PropertyName
+ ));
+ }
+
+ if (pluginClass.IsPrivate)
+ {
+ context.ReportDiagnostic(Diagnostic.Create(
+ SourceGeneratorDiagnostics.ContextPropertyIsPrivate,
+ pluginClass.Location,
+ pluginClass.PropertyName
+ ));
+ }
+
+ if (pluginClass.IsProtected)
+ {
+ context.ReportDiagnostic(Diagnostic.Create(
+ SourceGeneratorDiagnostics.ContextPropertyIsProtected,
+ pluginClass.Location,
+ pluginClass.PropertyName
+ ));
+ }
+ }
+
+ return null;
+ }
+ }
+}
From 49c12b554f1fc5a56864b0651edd582eec7160bd Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 18:08:37 +0800
Subject: [PATCH 09/23] Support useDI & Fix api translation issue
---
.../Localize/EnumSourceGenerator.cs | 75 +++++++++++++++----
1 file changed, 61 insertions(+), 14 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 75650e3..48f94a8 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -6,6 +6,7 @@
using Flow.Launcher.Localization.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;
namespace Flow.Launcher.Localization.SourceGenerators.Localize
@@ -36,9 +37,18 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
.Where(ed => ed.AttributeLists.Count > 0)
.Collect();
+ var pluginClasses = context.SyntaxProvider
+ .CreateSyntaxProvider(
+ predicate: (n, _) => n is ClassDeclarationSyntax,
+ transform: (c, t) => Helper.GetPluginClassInfo((ClassDeclarationSyntax)c.Node, c.SemanticModel, t))
+ .Where(info => info != null)
+ .Collect();
+
var compilation = context.CompilationProvider;
- var compilationEnums = enumDeclarations.Combine(compilation);
+ var configOptions = context.AnalyzerConfigOptionsProvider;
+
+ var compilationEnums = enumDeclarations.Combine(pluginClasses).Combine(configOptions).Combine(compilation);
context.RegisterSourceOutput(compilationEnums, Execute);
}
@@ -49,14 +59,24 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
/// The source production context.
/// The provided data.
private void Execute(SourceProductionContext spc,
- (ImmutableArray Enums, Compilation Compilation) data)
+ (((ImmutableArray EnumsDeclarations,
+ ImmutableArray PluginClassInfos),
+ AnalyzerConfigOptionsProvider ConfigOptionsProvider),
+ Compilation Compilation) data)
{
- var enums = data.Enums;
var compilation = data.Compilation;
+ var configOptions = data.Item1.ConfigOptionsProvider;
+ var pluginClasses = data.Item1.Item1.PluginClassInfos;
+ var enumsDeclarations = data.Item1.Item1.EnumsDeclarations;
var assemblyName = compilation.AssemblyName ?? Constants.DefaultNamespace;
+ var useDI = configOptions.GetFLLUseDependencyInjection();
+
+ var pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc, useDI);
+
+ if (pluginInfo == null) return;
- foreach (var enumDeclaration in enums.Distinct())
+ foreach (var enumDeclaration in enumsDeclarations.Distinct())
{
var semanticModel = compilation.GetSemanticModel(enumDeclaration.SyntaxTree);
var enumSymbol = semanticModel.GetDeclaredSymbol(enumDeclaration) as INamedTypeSymbol;
@@ -65,7 +85,7 @@ private void Execute(SourceProductionContext spc,
if (enumSymbol?.GetAttributes().Any(ad =>
ad.AttributeClass?.Name == Constants.EnumLocalizeAttributeName) ?? false)
{
- GenerateSource(spc, enumSymbol, assemblyName);
+ GenerateSource(spc, enumSymbol, useDI, pluginInfo, assemblyName);
}
}
}
@@ -74,7 +94,12 @@ private void Execute(SourceProductionContext spc,
#region Generate Source
- private void GenerateSource(SourceProductionContext spc, INamedTypeSymbol enumSymbol, string assemblyName)
+ private void GenerateSource(
+ SourceProductionContext spc,
+ INamedTypeSymbol enumSymbol,
+ bool useDI,
+ PluginClassInfo pluginInfo,
+ string assemblyName)
{
var enumFullName = enumSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
var enumDataClassName = $"{enumSymbol.Name}{Constants.EnumLocalizeClassSuffix}";
@@ -129,6 +154,20 @@ private void GenerateSource(SourceProductionContext spc, INamedTypeSymbol enumSy
sourceBuilder.AppendLine($"{tabString}public string LocalizationValue {{ get; set; }}");
sourceBuilder.AppendLine();
+ // Generate API instance
+ string getTranslation = null;
+ if (useDI)
+ {
+ sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI? api = null;");
+ sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI Api => api ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
+ sourceBuilder.AppendLine();
+ getTranslation = "Api.GetTranslation";
+ }
+ else if (pluginInfo?.IsValid == true)
+ {
+ getTranslation = $"{pluginInfo.ContextAccessor}.API.GetTranslation";
+ }
+
// Generate GetValues method
sourceBuilder.AppendLine($"{tabString}/// ");
sourceBuilder.AppendLine($"{tabString}/// Get all values of ");
@@ -141,19 +180,19 @@ private void GenerateSource(SourceProductionContext spc, INamedTypeSymbol enumSy
if (enumFields.Length == 0) return;
foreach (var enumField in enumFields)
{
- GenerateEnumField(sourceBuilder, enumField, enumName, tabString);
+ GenerateEnumField(sourceBuilder, getTranslation, enumField, enumName, tabString);
}
sourceBuilder.AppendLine($"{tabString}{tabString}}};");
sourceBuilder.AppendLine($"{tabString}}}");
sourceBuilder.AppendLine();
// Generate UpdateLabels method
- GenerateUpdateLabelsMethod(sourceBuilder, enumDataClassName, tabString);
+ GenerateUpdateLabelsMethod(sourceBuilder, getTranslation, enumDataClassName, tabString);
sourceBuilder.AppendLine($"}}");
// Add source to context
- spc.AddSource($"{Constants.ClassName}.{enumNamespace}.{enumDataClassName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ spc.AddSource($"{Constants.ClassName}.{assemblyName}.{enumNamespace}.{enumDataClassName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
private static void GeneratedHeaderFromPath(StringBuilder sb, string enumFullName)
@@ -170,15 +209,19 @@ private static void GeneratedHeaderFromPath(StringBuilder sb, string enumFullNam
}
}
- private static void GenerateEnumField(StringBuilder sb, EnumField enumField, string enumName, string tabString)
+ private static void GenerateEnumField(
+ StringBuilder sb,
+ string getTranslation,
+ EnumField enumField,
+ string enumName,
+ string tabString)
{
sb.AppendLine($"{tabString}{tabString}{tabString}new()");
sb.AppendLine($"{tabString}{tabString}{tabString}{{");
sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}Value = {enumName}.{enumField.EnumFieldName},");
if (enumField.UseLocalizationKey)
{
- // TODO
- sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}Display = Main.Context.API.GetTranslation(\"{enumField.LocalizationKey}\"),");
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}Display = {getTranslation}(\"{enumField.LocalizationKey}\"),");
sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}LocalizationKey = \"{enumField.LocalizationKey}\",");
}
else
@@ -192,7 +235,11 @@ private static void GenerateEnumField(StringBuilder sb, EnumField enumField, str
sb.AppendLine($"{tabString}{tabString}{tabString}}},");
}
- private static void GenerateUpdateLabelsMethod(StringBuilder sb, string enumDataClassName, string tabString)
+ private static void GenerateUpdateLabelsMethod(
+ StringBuilder sb,
+ string getTranslation,
+ string enumDataClassName,
+ string tabString)
{
sb.AppendLine($"{tabString}/// ");
sb.AppendLine($"{tabString}/// Update the labels of the enum values when culture info changes.");
@@ -204,7 +251,7 @@ private static void GenerateUpdateLabelsMethod(StringBuilder sb, string enumData
sb.AppendLine($"{tabString}{tabString}{{");
sb.AppendLine($"{tabString}{tabString}{tabString}if (!string.IsNullOrEmpty(item.LocalizationKey))");
sb.AppendLine($"{tabString}{tabString}{tabString}{{");
- sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}item.Display = Main.Context.API.GetTranslation(item.LocalizationKey);");
+ sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}item.Display = {getTranslation}(item.LocalizationKey);");
sb.AppendLine($"{tabString}{tabString}{tabString}}}");
sb.AppendLine($"{tabString}{tabString}}}");
sb.AppendLine($"{tabString}}}");
From b6d291a57d4180554029b52678502aa364c463de Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 18:08:54 +0800
Subject: [PATCH 10/23] Code quality
---
.../Localize/EnumSourceGenerator.cs | 114 +++++++++---------
1 file changed, 57 insertions(+), 57 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 48f94a8..6c9d168 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -92,6 +92,63 @@ private void Execute(SourceProductionContext spc,
#endregion
+ #region Get Enum Fields
+
+ private static ImmutableArray GetEnumFields(SourceProductionContext spc, INamedTypeSymbol enumSymbol, string enumFullName)
+ {
+ // Iterate through enum members and get enum fields
+ var enumFields = new List();
+ var enumError = false;
+ foreach (var member in enumSymbol.GetMembers().Where(m => m.Kind == SymbolKind.Field))
+ {
+ if (member is IFieldSymbol fieldSymbol)
+ {
+ var enumFieldName = fieldSymbol.Name;
+
+ // Check if the field has the EnumLocalizeKey attribute
+ var keyAttr = fieldSymbol.GetAttributes()
+ .FirstOrDefault(a => a.AttributeClass?.Name == Constants.EnumLocalizeKeyAttributeName);
+ var keyAttrExist = keyAttr != null;
+
+ // Check if the field has the EnumLocalizeValue attribute
+ var valueAttr = fieldSymbol.GetAttributes()
+ .FirstOrDefault(a => a.AttributeClass?.Name == Constants.EnumLocalizeValueAttributeName);
+ var valueAttrExist = valueAttr != null;
+
+ // Get the key and value from the attributes
+ var key = keyAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
+ var value = valueAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
+
+ if (keyAttrExist && !string.IsNullOrEmpty(key))
+ {
+ // If localization key exists and is valid, use it
+ enumFields.Add(new EnumField(enumFieldName, key, valueAttrExist ? value : null));
+ }
+ else if (valueAttrExist)
+ {
+ // If localization value exists, use it
+ enumFields.Add(new EnumField(enumFieldName, value));
+ }
+ else
+ {
+ // If localization key and value are not provided, do not generate the field and report a diagnostic
+ spc.ReportDiagnostic(Diagnostic.Create(
+ SourceGeneratorDiagnostics.EnumFieldLocalizationKeyValueInvalid,
+ Location.None,
+ $"{enumFullName}.{enumFieldName}"));
+ enumError = true;
+ }
+ }
+ }
+
+ // If there was an error, do not generate the class
+ if (enumError) return _emptyEnumFields;
+
+ return enumFields.ToImmutableArray();
+ }
+
+ #endregion
+
#region Generate Source
private void GenerateSource(
@@ -259,63 +316,6 @@ private static void GenerateUpdateLabelsMethod(
#endregion
- #region Get Enum Fields
-
- private static ImmutableArray GetEnumFields(SourceProductionContext spc, INamedTypeSymbol enumSymbol, string enumFullName)
- {
- // Iterate through enum members and get enum fields
- var enumFields = new List();
- var enumError = false;
- foreach (var member in enumSymbol.GetMembers().Where(m => m.Kind == SymbolKind.Field))
- {
- if (member is IFieldSymbol fieldSymbol)
- {
- var enumFieldName = fieldSymbol.Name;
-
- // Check if the field has the EnumLocalizeKey attribute
- var keyAttr = fieldSymbol.GetAttributes()
- .FirstOrDefault(a => a.AttributeClass?.Name == Constants.EnumLocalizeKeyAttributeName);
- var keyAttrExist = keyAttr != null;
-
- // Check if the field has the EnumLocalizeValue attribute
- var valueAttr = fieldSymbol.GetAttributes()
- .FirstOrDefault(a => a.AttributeClass?.Name == Constants.EnumLocalizeValueAttributeName);
- var valueAttrExist = valueAttr != null;
-
- // Get the key and value from the attributes
- var key = keyAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
- var value = valueAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
-
- if (keyAttrExist && !string.IsNullOrEmpty(key))
- {
- // If localization key exists and is valid, use it
- enumFields.Add(new EnumField(enumFieldName, key, valueAttrExist ? value : null));
- }
- else if (valueAttrExist)
- {
- // If localization value exists, use it
- enumFields.Add(new EnumField(enumFieldName, value));
- }
- else
- {
- // If localization key and value are not provided, do not generate the field and report a diagnostic
- spc.ReportDiagnostic(Diagnostic.Create(
- SourceGeneratorDiagnostics.EnumFieldLocalizationKeyValueInvalid,
- Location.None,
- $"{enumFullName}.{enumFieldName}"));
- enumError = true;
- }
- }
- }
-
- // If there was an error, do not generate the class
- if (enumError) return _emptyEnumFields;
-
- return enumFields.ToImmutableArray();
- }
-
- #endregion
-
#region Classes
public class EnumField
From 9836cff2e036f7ce4262e60c60cd8e6db606db1d Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 18:17:56 +0800
Subject: [PATCH 11/23] Add assembly version for source generator project
---
.../Flow.Launcher.Localization.SourceGenerators.csproj | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj b/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
index 1a95f4d..90bd0d3 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
+++ b/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
@@ -4,6 +4,8 @@
netstandard2.0
true
Flow.Launcher.Localization.SourceGenerators
+
+ 0.2.15
From 13dfbb294766e59ab20f6b087a85ca753b71e1db Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 19:03:44 +0800
Subject: [PATCH 12/23] Change local variable name
---
.../Localize/EnumSourceGenerator.cs | 10 +++++-----
.../Localize/LocalizeSourceGenerator.cs | 10 +++++-----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 6c9d168..ff33b00 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -69,7 +69,7 @@ private void Execute(SourceProductionContext spc,
var pluginClasses = data.Item1.Item1.PluginClassInfos;
var enumsDeclarations = data.Item1.Item1.EnumsDeclarations;
- var assemblyName = compilation.AssemblyName ?? Constants.DefaultNamespace;
+ var assemblyNamespace = compilation.AssemblyName ?? Constants.DefaultNamespace;
var useDI = configOptions.GetFLLUseDependencyInjection();
var pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc, useDI);
@@ -85,7 +85,7 @@ private void Execute(SourceProductionContext spc,
if (enumSymbol?.GetAttributes().Any(ad =>
ad.AttributeClass?.Name == Constants.EnumLocalizeAttributeName) ?? false)
{
- GenerateSource(spc, enumSymbol, useDI, pluginInfo, assemblyName);
+ GenerateSource(spc, enumSymbol, useDI, pluginInfo, assemblyNamespace);
}
}
}
@@ -156,7 +156,7 @@ private void GenerateSource(
INamedTypeSymbol enumSymbol,
bool useDI,
PluginClassInfo pluginInfo,
- string assemblyName)
+ string assemblyNamespace)
{
var enumFullName = enumSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
var enumDataClassName = $"{enumSymbol.Name}{Constants.EnumLocalizeClassSuffix}";
@@ -222,7 +222,7 @@ private void GenerateSource(
}
else if (pluginInfo?.IsValid == true)
{
- getTranslation = $"{pluginInfo.ContextAccessor}.API.GetTranslation";
+ getTranslation = $"{assemblyNamespace}.{pluginInfo.ContextAccessor}.API.GetTranslation";
}
// Generate GetValues method
@@ -249,7 +249,7 @@ private void GenerateSource(
sourceBuilder.AppendLine($"}}");
// Add source to context
- spc.AddSource($"{Constants.ClassName}.{assemblyName}.{enumNamespace}.{enumDataClassName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ spc.AddSource($"{Constants.ClassName}.{assemblyNamespace}.{enumNamespace}.{enumDataClassName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
private static void GeneratedHeaderFromPath(StringBuilder sb, string enumFullName)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index a4af84b..5fd06ac 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -97,7 +97,7 @@ private void Execute(SourceProductionContext spc,
var usedKeys = data.Item1.Item1.Item1.Item1.InvocationKeys;
var localizedStrings = data.Item1.Item1.Item1.Item1.LocalizableStrings;
- var assemblyName = compilation.AssemblyName ?? Constants.DefaultNamespace;
+ var assemblyNamespace = compilation.AssemblyName ?? Constants.DefaultNamespace;
var useDI = configOptions.GetFLLUseDependencyInjection();
var pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc, useDI);
@@ -108,7 +108,7 @@ private void Execute(SourceProductionContext spc,
spc,
xamlFiles[0],
localizedStrings,
- assemblyName,
+ assemblyNamespace,
useDI,
pluginInfo,
usedKeys);
@@ -429,7 +429,7 @@ private static void GenerateSource(
SourceProductionContext spc,
AdditionalText xamlFile,
ImmutableArray localizedStrings,
- string assemblyName,
+ string assemblyNamespace,
bool useDI,
PluginClassInfo pluginInfo,
IEnumerable usedKeys)
@@ -458,7 +458,7 @@ private static void GenerateSource(
sourceBuilder.AppendLine();
// Generate namespace
- sourceBuilder.AppendLine($"namespace {assemblyName};");
+ sourceBuilder.AppendLine($"namespace {assemblyNamespace};");
sourceBuilder.AppendLine();
// Uncomment them for debugging
@@ -518,7 +518,7 @@ private static void GenerateSource(
sourceBuilder.AppendLine("}");
// Add source to context
- spc.AddSource($"{Constants.ClassName}.{assemblyName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ spc.AddSource($"{Constants.ClassName}.{assemblyNamespace}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
private static void GeneratedHeaderFromPath(StringBuilder sb, string xamlFilePath)
From 81f4889a97e5e20777ca21e761974ed91b714e61 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 19:04:21 +0800
Subject: [PATCH 13/23] Use one Api
---
.../Localize/EnumSourceGenerator.cs | 6 ++----
.../Localize/LocalizeSourceGenerator.cs | 3 ++-
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index ff33b00..5163e48 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -215,10 +215,8 @@ private void GenerateSource(
string getTranslation = null;
if (useDI)
{
- sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI? api = null;");
- sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI Api => api ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
- sourceBuilder.AppendLine();
- getTranslation = "Api.GetTranslation";
+ // Use Api from LocalizeSourceGenerator
+ getTranslation = $"{assemblyNamespace}.{Constants.ClassName}.Api.GetTranslation";
}
else if (pluginInfo?.IsValid == true)
{
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index 5fd06ac..9e6b3d0 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -499,7 +499,8 @@ private static void GenerateSource(
if (useDI)
{
sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI? api = null;");
- sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI Api => api ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
+ // Internal for EnumSourceGenerator to use
+ sourceBuilder.AppendLine($"{tabString}internal static Flow.Launcher.Plugin.IPublicAPI Api => api ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
sourceBuilder.AppendLine();
getTranslation = "Api.GetTranslation";
}
From f79cbb98ab77045ab09ba93f3593f30635402669 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 19:33:18 +0800
Subject: [PATCH 14/23] Fix useDI issue
---
.../Localize/EnumSourceGenerator.cs | 19 ++++++++++++++++---
.../Localize/LocalizeSourceGenerator.cs | 19 ++++++++++++++++---
.../PluginInfoHelper.cs | 10 +---------
3 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 5163e48..84cf171 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -72,9 +72,22 @@ private void Execute(SourceProductionContext spc,
var assemblyNamespace = compilation.AssemblyName ?? Constants.DefaultNamespace;
var useDI = configOptions.GetFLLUseDependencyInjection();
- var pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc, useDI);
-
- if (pluginInfo == null) return;
+ PluginClassInfo pluginInfo;
+ if (useDI)
+ {
+ // If we use dependency injection, we do not need to check if there is a valid plugin context
+ // Also we do not need to return the plugin info
+ pluginInfo = null;
+ }
+ else
+ {
+ pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc);
+ if (pluginInfo == null)
+ {
+ // If we cannot find a valid plugin info, we do not need to generate the source
+ return;
+ }
+ }
foreach (var enumDeclaration in enumsDeclarations.Distinct())
{
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index 9e6b3d0..3c9a387 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -100,9 +100,22 @@ private void Execute(SourceProductionContext spc,
var assemblyNamespace = compilation.AssemblyName ?? Constants.DefaultNamespace;
var useDI = configOptions.GetFLLUseDependencyInjection();
- var pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc, useDI);
-
- if (pluginInfo == null) return;
+ PluginClassInfo pluginInfo;
+ if (useDI)
+ {
+ // If we use dependency injection, we do not need to check if there is a valid plugin context
+ // Also we do not need to return the plugin info
+ pluginInfo = null;
+ }
+ else
+ {
+ pluginInfo = PluginInfoHelper.GetValidPluginInfoAndReportDiagnostic(pluginClasses, spc);
+ if (pluginInfo == null)
+ {
+ // If we cannot find a valid plugin info, we do not need to generate the source
+ return;
+ }
+ }
GenerateSource(
spc,
diff --git a/Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs b/Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs
index 7a77103..a26ee57 100644
--- a/Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/PluginInfoHelper.cs
@@ -9,8 +9,7 @@ internal class PluginInfoHelper
{
public static PluginClassInfo GetValidPluginInfoAndReportDiagnostic(
ImmutableArray pluginClasses,
- SourceProductionContext context,
- bool useDI)
+ SourceProductionContext context)
{
// If p is null, this class does not implement IPluginI18n
var iPluginI18nClasses = pluginClasses.Where(p => p != null).ToArray();
@@ -23,13 +22,6 @@ public static PluginClassInfo GetValidPluginInfoAndReportDiagnostic(
return null;
}
- // If we use dependency injection, we do not need to check if there is a valid plugin context
- // Also we do not need to return the plugin info
- if (useDI)
- {
- return null;
- }
-
// If p.PropertyName is null, this class does not have PluginInitContext property
var iPluginI18nClassesWithContext = iPluginI18nClasses.Where(p => p.PropertyName != null).ToArray();
if (iPluginI18nClassesWithContext.Length == 0)
From 107e4eebfdcecb4f11cd54b86d0c847e9789442f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 19:44:43 +0800
Subject: [PATCH 15/23] Fix code comments
---
.../Localize/EnumSourceGenerator.cs | 5 ++---
.../Localize/LocalizeSourceGenerator.cs | 1 -
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 84cf171..2b031ca 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -25,7 +25,7 @@ public partial class EnumSourceGenerator : IIncrementalGenerator
#region Incremental Generator
///
- /// Initializes the generator and registers source output based on resource files.
+ /// Initializes the generator and registers source output based on enum declarations.
///
/// The initialization context.
public void Initialize(IncrementalGeneratorInitializationContext context)
@@ -54,7 +54,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
}
///
- /// Executes the generation of string properties based on the provided data.
+ /// Executes the generation of enum data classes based on the provided data.
///
/// The source production context.
/// The provided data.
@@ -76,7 +76,6 @@ private void Execute(SourceProductionContext spc,
if (useDI)
{
// If we use dependency injection, we do not need to check if there is a valid plugin context
- // Also we do not need to return the plugin info
pluginInfo = null;
}
else
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index 3c9a387..be8d07d 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -104,7 +104,6 @@ private void Execute(SourceProductionContext spc,
if (useDI)
{
// If we use dependency injection, we do not need to check if there is a valid plugin context
- // Also we do not need to return the plugin info
pluginInfo = null;
}
else
From 1673504f58a04dcf6ea7adaf3867eb1df69eb090 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 20:05:48 +0800
Subject: [PATCH 16/23] Use one internal static api instance
---
.../Constants.cs | 4 +
.../Localize/EnumSourceGenerator.cs | 4 +-
.../Localize/LocalizeSourceGenerator.cs | 7 +-
.../Localize/PublicApiSourceGenerator.cs | 107 ++++++++++++++++++
4 files changed, 115 insertions(+), 7 deletions(-)
create mode 100644 Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs
diff --git a/Flow.Launcher.Localization.Shared/Constants.cs b/Flow.Launcher.Localization.Shared/Constants.cs
index a4610ec..dee43d0 100644
--- a/Flow.Launcher.Localization.Shared/Constants.cs
+++ b/Flow.Launcher.Localization.Shared/Constants.cs
@@ -24,6 +24,10 @@ public static class Constants
public const string EnumLocalizeAttributeName = "EnumLocalizeAttribute";
public const string EnumLocalizeKeyAttributeName = "EnumLocalizeKeyAttribute";
public const string EnumLocalizeValueAttributeName = "EnumLocalizeValueAttribute";
+ // Use PublicApi instead of PublicAPI for possible combiguity with Flow.Launcher.Plugin.IPublicAPI
+ public const string PublicApiClassName = "PublicApi";
+ public const string PublicApiPrivatePropertyName = "instance";
+ public const string PublicApiInternalPropertyName = "Instance";
public static readonly Regex LanguagesXamlRegex = new Regex(@"\\Languages\\[^\\]+\.xaml$", RegexOptions.IgnoreCase);
public static readonly string[] OldLocalizationClasses = { "IPublicAPI", "Internationalization" };
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 2b031ca..a26b688 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -227,8 +227,8 @@ private void GenerateSource(
string getTranslation = null;
if (useDI)
{
- // Use Api from LocalizeSourceGenerator
- getTranslation = $"{assemblyNamespace}.{Constants.ClassName}.Api.GetTranslation";
+ // Use instance from PublicApiSourceGenerator
+ getTranslation = $"{assemblyNamespace}.{Constants.PublicApiClassName}.{Constants.PublicApiInternalPropertyName}.GetTranslation";
}
else if (pluginInfo?.IsValid == true)
{
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index be8d07d..43e6ee1 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -510,11 +510,8 @@ private static void GenerateSource(
string getTranslation = null;
if (useDI)
{
- sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI? api = null;");
- // Internal for EnumSourceGenerator to use
- sourceBuilder.AppendLine($"{tabString}internal static Flow.Launcher.Plugin.IPublicAPI Api => api ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
- sourceBuilder.AppendLine();
- getTranslation = "Api.GetTranslation";
+ // Use instance from PublicApiSourceGenerator
+ getTranslation = $"{assemblyNamespace}.{Constants.PublicApiClassName}.{Constants.PublicApiInternalPropertyName}.GetTranslation";
}
else if (pluginInfo?.IsValid == true)
{
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs
new file mode 100644
index 0000000..2c3d1a1
--- /dev/null
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs
@@ -0,0 +1,107 @@
+using System;
+using System.Text;
+using Flow.Launcher.Localization.Shared;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Text;
+
+namespace Flow.Launcher.Localization.SourceGenerators.Localize
+{
+ [Generator]
+ public partial class PublicApiSourceGenerator : IIncrementalGenerator
+ {
+ #region Fields
+
+ private static readonly Version PackageVersion = typeof(PublicApiSourceGenerator).Assembly.GetName().Version;
+
+ #endregion
+
+ #region Incremental Generator
+
+ ///
+ /// Initializes the generator and registers source output based on build property FLLUseDependencyInjection.
+ ///
+ /// The initialization context.
+ public void Initialize(IncrementalGeneratorInitializationContext context)
+ {
+ var compilation = context.CompilationProvider;
+
+ var configOptions = context.AnalyzerConfigOptionsProvider;
+
+ var compilationEnums = configOptions.Combine(compilation);
+
+ context.RegisterSourceOutput(compilationEnums, Execute);
+ }
+
+ ///
+ /// Executes the generation of public api property based on the provided data.
+ ///
+ /// The source production context.
+ /// The provided data.
+ private void Execute(SourceProductionContext spc,
+ (AnalyzerConfigOptionsProvider ConfigOptionsProvider, Compilation Compilation) data)
+ {
+ var compilation = data.Compilation;
+ var configOptions = data.ConfigOptionsProvider;
+
+ var assemblyNamespace = compilation.AssemblyName ?? Constants.DefaultNamespace;
+ var useDI = configOptions.GetFLLUseDependencyInjection();
+
+ // If we do not use dependency injection, we do not need to generate the public api property
+ if (!useDI) return;
+
+ GenerateSource(spc, assemblyNamespace);
+ }
+
+ #endregion
+
+ #region Generate Source
+
+ private void GenerateSource(
+ SourceProductionContext spc,
+ string assemblyNamespace)
+ {
+ var tabString = Helper.Spacing(1);
+
+ var sourceBuilder = new StringBuilder();
+
+ // Generate header
+ GeneratedHeaderFromPath(sourceBuilder);
+ sourceBuilder.AppendLine();
+
+ // Generate nullable enable
+ sourceBuilder.AppendLine("#nullable enable");
+ sourceBuilder.AppendLine();
+
+ // Generate namespace
+ sourceBuilder.AppendLine($"namespace {assemblyNamespace};");
+ sourceBuilder.AppendLine();
+
+ // Generate class
+ sourceBuilder.AppendLine($"[System.CodeDom.Compiler.GeneratedCode(\"{nameof(PublicApiSourceGenerator)}\", \"{PackageVersion}\")]");
+ sourceBuilder.AppendLine($"internal static class {Constants.PublicApiClassName}");
+ sourceBuilder.AppendLine("{");
+
+ // Generate properties
+ sourceBuilder.AppendLine($"{tabString}private static Flow.Launcher.Plugin.IPublicAPI? {Constants.PublicApiPrivatePropertyName} = null;");
+ sourceBuilder.AppendLine();
+ sourceBuilder.AppendLine($"{tabString}/// ");
+ sourceBuilder.AppendLine($"{tabString}/// Get instance");
+ sourceBuilder.AppendLine($"{tabString}/// ");
+ sourceBuilder.AppendLine($"{tabString}internal static Flow.Launcher.Plugin.IPublicAPI {Constants.PublicApiInternalPropertyName} => {Constants.PublicApiPrivatePropertyName} ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
+ sourceBuilder.AppendLine();
+
+ sourceBuilder.AppendLine($"}}");
+
+ // Add source to context
+ spc.AddSource($"{Constants.PublicApiClassName}.{assemblyNamespace}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ }
+
+ private static void GeneratedHeaderFromPath(StringBuilder sb)
+ {
+ sb.AppendLine("/// ");
+ }
+
+ #endregion
+ }
+}
From 965ede1f474580517370580f3ed68b7640e8c867 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 20:09:29 +0800
Subject: [PATCH 17/23] Slight adjust
---
.../Localize/PublicApiSourceGenerator.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs
index 2c3d1a1..92593b7 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/PublicApiSourceGenerator.cs
@@ -88,9 +88,8 @@ private void GenerateSource(
sourceBuilder.AppendLine($"{tabString}/// ");
sourceBuilder.AppendLine($"{tabString}/// Get instance");
sourceBuilder.AppendLine($"{tabString}/// ");
- sourceBuilder.AppendLine($"{tabString}internal static Flow.Launcher.Plugin.IPublicAPI {Constants.PublicApiInternalPropertyName} => {Constants.PublicApiPrivatePropertyName} ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
- sourceBuilder.AppendLine();
-
+ sourceBuilder.AppendLine($"{tabString}internal static Flow.Launcher.Plugin.IPublicAPI {Constants.PublicApiInternalPropertyName} =>" +
+ $"{Constants.PublicApiPrivatePropertyName} ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService();");
sourceBuilder.AppendLine($"}}");
// Add source to context
From 6ecdbb82866a454c5b88e703176dadac9e9e4400 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 20:18:29 +0800
Subject: [PATCH 18/23] Restore assembly version
---
.../Flow.Launcher.Localization.SourceGenerators.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj b/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
index 90bd0d3..be6dda3 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
+++ b/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
@@ -5,7 +5,7 @@
true
Flow.Launcher.Localization.SourceGenerators
- 0.2.15
+ 0.0.2
From c55d88d1da50845e47a2c8260120bd2f27f4b335 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Thu, 3 Apr 2025 20:26:29 +0800
Subject: [PATCH 19/23] Use string.IsNullOrWhiteSpace instead of null check or
IsNullOrEmpty
---
.../Localize/EnumSourceGenerator.cs | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index a26b688..3f3410a 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -131,7 +131,8 @@ private static ImmutableArray GetEnumFields(SourceProductionContext s
var key = keyAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
var value = valueAttr?.ConstructorArguments.FirstOrDefault().Value?.ToString() ?? string.Empty;
- if (keyAttrExist && !string.IsNullOrEmpty(key))
+ // Users may use " " as a key, so we need to check if the key is not empty and not whitespace
+ if (keyAttrExist && !string.IsNullOrWhiteSpace(key))
{
// If localization key exists and is valid, use it
enumFields.Add(new EnumField(enumFieldName, key, valueAttrExist ? value : null));
@@ -316,7 +317,8 @@ private static void GenerateUpdateLabelsMethod(
sb.AppendLine($"{tabString}{{");
sb.AppendLine($"{tabString}{tabString}foreach (var item in options)");
sb.AppendLine($"{tabString}{tabString}{{");
- sb.AppendLine($"{tabString}{tabString}{tabString}if (!string.IsNullOrEmpty(item.LocalizationKey))");
+ // Users may use " " as a key, so we need to check if the key is not empty and not whitespace
+ sb.AppendLine($"{tabString}{tabString}{tabString}if (!string.IsNullOrWhiteSpace(item.LocalizationKey))");
sb.AppendLine($"{tabString}{tabString}{tabString}{{");
sb.AppendLine($"{tabString}{tabString}{tabString}{tabString}item.Display = {getTranslation}(item.LocalizationKey);");
sb.AppendLine($"{tabString}{tabString}{tabString}}}");
@@ -334,7 +336,8 @@ public class EnumField
public string LocalizationKey { get; set; }
public string LocalizationValue { get; set; }
- public bool UseLocalizationKey => LocalizationKey != null;
+ // Users may use " " as a key, so we need to check if the key is not empty and not whitespace
+ public bool UseLocalizationKey => !string.IsNullOrWhiteSpace(LocalizationKey);
public EnumField(string enumFieldName, string localizationValue) : this(enumFieldName, null, localizationValue)
{
From 23cf8f11901ab41c8bb365980b8a50db30ac9056 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 09:32:28 +0800
Subject: [PATCH 20/23] Improve tab string performance
---
Flow.Launcher.Localization.Shared/Helper.cs | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/Flow.Launcher.Localization.Shared/Helper.cs b/Flow.Launcher.Localization.Shared/Helper.cs
index 044fa45..0807cef 100644
--- a/Flow.Launcher.Localization.Shared/Helper.cs
+++ b/Flow.Launcher.Localization.Shared/Helper.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Linq;
-using System.Text;
+using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
@@ -88,16 +86,7 @@ private static Location GetCodeFixLocation(PropertyDeclarationSyntax property, S
public static string Spacing(int n)
{
- Span spaces = stackalloc char[n * 4];
- spaces.Fill(' ');
-
- var sb = new StringBuilder(n * 4);
- foreach (var c in spaces)
- {
- _ = sb.Append(c);
- }
-
- return sb.ToString();
+ return new string(' ', n * 4);
}
#endregion
From 903f22ec9836929eda44e61dad7d2267a49c172b Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 09:36:03 +0800
Subject: [PATCH 21/23] Remove \n for last string
---
.../Localize/LocalizeSourceGenerator.cs | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index 43e6ee1..43589ce 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -521,8 +521,9 @@ private static void GenerateSource(
// Generate localization methods
foreach (var ls in localizedStrings)
{
+ var isLast = ls.Equals(localizedStrings.Last());
GenerateDocComments(sourceBuilder, ls, tabString);
- GenerateLocalizationMethod(sourceBuilder, ls, getTranslation, tabString);
+ GenerateLocalizationMethod(sourceBuilder, ls, getTranslation, tabString, isLast);
}
sourceBuilder.AppendLine("}");
@@ -579,7 +580,8 @@ private static void GenerateLocalizationMethod(
StringBuilder sb,
LocalizableString ls,
string getTranslation,
- string tabString)
+ string tabString,
+ bool last)
{
sb.Append($"{tabString}public static string {ls.Key}(");
@@ -604,7 +606,10 @@ private static void GenerateLocalizationMethod(
sb.AppendLine("\"LOCALIZATION_ERROR\";");
}
- sb.AppendLine();
+ if (!last)
+ {
+ sb.AppendLine();
+ }
}
#endregion
From d7a8a2bfc986f7498bb4ee79b13a0a5fe5f4c767 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Fri, 4 Apr 2025 09:39:39 +0800
Subject: [PATCH 22/23] Adjust enum full name style
---
.../Localize/EnumSourceGenerator.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
index 3f3410a..76a218f 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/EnumSourceGenerator.cs
@@ -171,7 +171,9 @@ private void GenerateSource(
PluginClassInfo pluginInfo,
string assemblyNamespace)
{
- var enumFullName = enumSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
+ var enumFullName = enumSymbol.ToDisplayString(new SymbolDisplayFormat(
+ globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted, // Remove global:: symbol
+ typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces));
var enumDataClassName = $"{enumSymbol.Name}{Constants.EnumLocalizeClassSuffix}";
var enumName = enumSymbol.Name;
var enumNamespace = enumSymbol.ContainingNamespace.ToDisplayString();
From 169a4b5b1a6830759e7682cfd3c88de3dfe50a7c Mon Sep 17 00:00:00 2001
From: Jack Ye <1160210343@qq.com>
Date: Fri, 4 Apr 2025 09:48:36 +0800
Subject: [PATCH 23/23] Fix typos
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Flow.Launcher.Localization.Shared/Constants.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Flow.Launcher.Localization.Shared/Constants.cs b/Flow.Launcher.Localization.Shared/Constants.cs
index dee43d0..8932aa9 100644
--- a/Flow.Launcher.Localization.Shared/Constants.cs
+++ b/Flow.Launcher.Localization.Shared/Constants.cs
@@ -24,7 +24,7 @@ public static class Constants
public const string EnumLocalizeAttributeName = "EnumLocalizeAttribute";
public const string EnumLocalizeKeyAttributeName = "EnumLocalizeKeyAttribute";
public const string EnumLocalizeValueAttributeName = "EnumLocalizeValueAttribute";
- // Use PublicApi instead of PublicAPI for possible combiguity with Flow.Launcher.Plugin.IPublicAPI
+ // Use PublicApi instead of PublicAPI for possible ambiguity with Flow.Launcher.Plugin.IPublicAPI
public const string PublicApiClassName = "PublicApi";
public const string PublicApiPrivatePropertyName = "instance";
public const string PublicApiInternalPropertyName = "Instance";