diff --git a/Flow.Launcher.Localization.Analyzers/Flow.Launcher.Localization.Analyzers.csproj b/Flow.Launcher.Localization.Analyzers/Flow.Launcher.Localization.Analyzers.csproj
index ce219d0..523f664 100644
--- a/Flow.Launcher.Localization.Analyzers/Flow.Launcher.Localization.Analyzers.csproj
+++ b/Flow.Launcher.Localization.Analyzers/Flow.Launcher.Localization.Analyzers.csproj
@@ -16,4 +16,8 @@
+
+
+
+
diff --git a/Flow.Launcher.Localization.Analyzers/Localize/ContextAvailabilityAnalyzer.cs b/Flow.Launcher.Localization.Analyzers/Localize/ContextAvailabilityAnalyzer.cs
index 8123d25..72a2775 100644
--- a/Flow.Launcher.Localization.Analyzers/Localize/ContextAvailabilityAnalyzer.cs
+++ b/Flow.Launcher.Localization.Analyzers/Localize/ContextAvailabilityAnalyzer.cs
@@ -1,5 +1,6 @@
using System.Collections.Immutable;
using System.Linq;
+using Flow.Launcher.Localization.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -17,10 +18,6 @@ public class ContextAvailabilityAnalyzer : DiagnosticAnalyzer
AnalyzerDiagnostics.ContextIsNotDeclared
);
- private const string PluginContextTypeName = "PluginInitContext";
-
- private const string PluginInterfaceName = "IPluginI18n";
-
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
@@ -30,6 +27,12 @@ public override void Initialize(AnalysisContext context)
private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
+ var configOptions = context.Options.AnalyzerConfigOptionsProvider;
+ var useDI = configOptions.GetFLLUseDependencyInjection();
+
+ // If we use dependency injection, we don't need to check for this context property
+ if (useDI) return;
+
var classDeclaration = (ClassDeclarationSyntax)context.Node;
var semanticModel = context.SemanticModel;
var classSymbol = semanticModel.GetDeclaredSymbol(classDeclaration);
@@ -38,7 +41,7 @@ private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
var contextProperty = classDeclaration.Members.OfType()
.Select(p => semanticModel.GetDeclaredSymbol(p))
- .FirstOrDefault(p => p?.Type.Name is PluginContextTypeName);
+ .FirstOrDefault(p => p?.Type.Name is Constants.PluginContextTypeName);
if (contextProperty != null)
{
@@ -67,7 +70,7 @@ private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
.OfType()
.SelectMany(f => f.Declaration.Variables)
.Select(f => semanticModel.GetDeclaredSymbol(f))
- .FirstOrDefault(f => f is IFieldSymbol fs && fs.Type.Name is PluginContextTypeName);
+ .FirstOrDefault(f => f is IFieldSymbol fs && fs.Type.Name is Constants.PluginContextTypeName);
var parentSyntax = fieldDeclaration
?.DeclaringSyntaxReferences[0]
.GetSyntax()
@@ -89,6 +92,6 @@ private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
}
private static bool IsPluginEntryClass(INamedTypeSymbol namedTypeSymbol) =>
- namedTypeSymbol?.Interfaces.Any(i => i.Name == PluginInterfaceName) ?? false;
+ namedTypeSymbol?.Interfaces.Any(i => i.Name == Constants.PluginInterfaceName) ?? false;
}
}
diff --git a/Flow.Launcher.Localization.Analyzers/Localize/OldGetTranslateAnalyzerCodeFixProvider.cs b/Flow.Launcher.Localization.Analyzers/Localize/OldGetTranslateAnalyzerCodeFixProvider.cs
index 37552ce..1040270 100644
--- a/Flow.Launcher.Localization.Analyzers/Localize/OldGetTranslateAnalyzerCodeFixProvider.cs
+++ b/Flow.Launcher.Localization.Analyzers/Localize/OldGetTranslateAnalyzerCodeFixProvider.cs
@@ -109,6 +109,5 @@ InvocationExpressionSyntax invocationExpr
var newRoot = root.ReplaceNode(invocationExpr, newInnerInvocationExpr);
return context.Document.WithSyntaxRoot(newRoot);
}
-
}
}
diff --git a/Flow.Launcher.Localization.Shared/Constants.cs b/Flow.Launcher.Localization.Shared/Constants.cs
new file mode 100644
index 0000000..beac8aa
--- /dev/null
+++ b/Flow.Launcher.Localization.Shared/Constants.cs
@@ -0,0 +1,18 @@
+using System.Text.RegularExpressions;
+
+namespace Flow.Launcher.Localization.Shared
+{
+ public static class Constants
+ {
+ public const string DefaultNamespace = "Flow.Launcher";
+ public const string ClassName = "Localize";
+ public const string PluginInterfaceName = "IPluginI18n";
+ public const string PluginContextTypeName = "PluginInitContext";
+ public const string SystemPrefixUri = "clr-namespace:System;assembly=mscorlib";
+ public const string XamlPrefixUri = "http://schemas.microsoft.com/winfx/2006/xaml";
+ public const string XamlTag = "String";
+ public const string KeyAttribute = "Key";
+
+ public static readonly Regex LanguagesXamlRegex = new Regex(@"\\Languages\\[^\\]+\.xaml$", RegexOptions.IgnoreCase);
+ }
+}
diff --git a/Flow.Launcher.Localization.Shared/Flow.Launcher.Localization.Shared.csproj b/Flow.Launcher.Localization.Shared/Flow.Launcher.Localization.Shared.csproj
new file mode 100644
index 0000000..ae15976
--- /dev/null
+++ b/Flow.Launcher.Localization.Shared/Flow.Launcher.Localization.Shared.csproj
@@ -0,0 +1,14 @@
+
+
+
+ 0.0.1
+ netstandard2.0
+ true
+ Flow.Launcher.Localization.Shared
+
+
+
+
+
+
+
diff --git a/Flow.Launcher.Localization.Shared/Helper.cs b/Flow.Launcher.Localization.Shared/Helper.cs
new file mode 100644
index 0000000..94b186c
--- /dev/null
+++ b/Flow.Launcher.Localization.Shared/Helper.cs
@@ -0,0 +1,17 @@
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace Flow.Launcher.Localization.Shared
+{
+ public static class Helper
+ {
+ public static bool GetFLLUseDependencyInjection(this AnalyzerConfigOptionsProvider configOptions)
+ {
+ if (!configOptions.GlobalOptions.TryGetValue("build_property.FLLUseDependencyInjection", out var result) ||
+ !bool.TryParse(result, out var useDI))
+ {
+ return false; // Default to false
+ }
+ return useDI;
+ }
+ }
+}
diff --git a/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj b/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
index 40d585d..db8fa41 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
+++ b/Flow.Launcher.Localization.SourceGenerators/Flow.Launcher.Localization.SourceGenerators.csproj
@@ -14,5 +14,9 @@
+
+
+
+
diff --git a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
index 9a52e3e..583ea8d 100644
--- a/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
+++ b/Flow.Launcher.Localization.SourceGenerators/Localize/LocalizeSourceGenerator.cs
@@ -3,12 +3,13 @@
using System.Collections.Immutable;
using System.Linq;
using System.Text;
-using System.Text.RegularExpressions;
using System.Threading;
using System.Xml.Linq;
+using Flow.Launcher.Localization.Shared;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;
namespace Flow.Launcher.Localization.SourceGenerators.Localize
@@ -21,19 +22,6 @@ public partial class LocalizeSourceGenerator : IIncrementalGenerator
{
#region Fields
- private const string CoreNamespace1 = "Flow.Launcher";
- private const string CoreNamespace2 = "Flow.Launcher.Core";
- private const string DefaultNamespace = "Flow.Launcher";
- private const string ClassName = "Localize";
- private const string PluginInterfaceName = "IPluginI18n";
- private const string PluginContextTypeName = "PluginInitContext";
- private const string systemPrefixUri = "clr-namespace:System;assembly=mscorlib";
- private const string xamlPrefixUri = "http://schemas.microsoft.com/winfx/2006/xaml";
- private const string XamlTag = "String";
- private const string KeyTag = "Key";
-
- private static readonly Regex _languagesXamlRegex = new Regex(@"\\Languages\\[^\\]+\.xaml$", RegexOptions.IgnoreCase);
-
private static readonly Version PackageVersion = typeof(LocalizeSourceGenerator).Assembly.GetName().Version;
private static readonly ImmutableArray _emptyLocalizableStrings = ImmutableArray.Empty;
@@ -50,7 +38,7 @@ public partial class LocalizeSourceGenerator : IIncrementalGenerator
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var xamlFiles = context.AdditionalTextsProvider
- .Where(file => _languagesXamlRegex.IsMatch(file.Path));
+ .Where(file => Constants.LanguagesXamlRegex.IsMatch(file.Path));
var localizedStrings = xamlFiles
.Select((file, ct) => ParseXamlFile(file, ct))
@@ -75,7 +63,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
var compilation = context.CompilationProvider;
- var combined = localizedStrings.Combine(invocationKeys).Combine(pluginClasses).Combine(compilation).Combine(xamlFiles.Collect());
+ var configOptions = context.AnalyzerConfigOptionsProvider;
+
+ var combined = localizedStrings.Combine(invocationKeys).Combine(pluginClasses).Combine(configOptions).Combine(compilation).Combine(xamlFiles.Collect());
context.RegisterSourceOutput(combined, Execute);
}
@@ -86,10 +76,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
/// The source production context.
/// The provided data.
private void Execute(SourceProductionContext spc,
- ((((ImmutableArray LocalizableStrings,
- ImmutableHashSet InvocationKeys),
- ImmutableArray PluginClassInfos),
- Compilation Compilation),
+ (((((ImmutableArray LocalizableStrings,
+ ImmutableHashSet InvocationKeys),
+ ImmutableArray PluginClassInfos),
+ AnalyzerConfigOptionsProvider ConfigOptionsProvider),
+ Compilation Compilation),
ImmutableArray AdditionalTexts) data)
{
var xamlFiles = data.AdditionalTexts;
@@ -103,23 +94,28 @@ private void Execute(SourceProductionContext spc,
}
var compilation = data.Item1.Compilation;
- var pluginClasses = data.Item1.Item1.PluginClassInfos;
- var usedKeys = data.Item1.Item1.Item1.InvocationKeys;
- var localizedStrings = data.Item1.Item1.Item1.LocalizableStrings;
+ var configOptions = data.Item1.Item1.ConfigOptionsProvider;
+ var pluginClasses = data.Item1.Item1.Item1.PluginClassInfos;
+ var usedKeys = data.Item1.Item1.Item1.Item1.InvocationKeys;
+ var localizedStrings = data.Item1.Item1.Item1.Item1.LocalizableStrings;
- var assemblyName = compilation.AssemblyName ?? DefaultNamespace;
+ var assemblyName = compilation.AssemblyName ?? Constants.DefaultNamespace;
var optimizationLevel = compilation.Options.OptimizationLevel;
+ var useDI = configOptions.GetFLLUseDependencyInjection();
- var pluginInfo = GetValidPluginInfo(pluginClasses, spc);
- var isCoreAssembly = assemblyName == CoreNamespace1 || assemblyName == CoreNamespace2;
-
+ PluginClassInfo pluginInfo = null;
+ if (!useDI)
+ {
+ pluginInfo = GetValidPluginInfo(pluginClasses, spc);
+ }
+
GenerateSource(
spc,
xamlFiles[0],
localizedStrings,
optimizationLevel,
assemblyName,
- isCoreAssembly,
+ useDI,
pluginInfo,
usedKeys);
}
@@ -155,11 +151,11 @@ private static ImmutableArray ParseXamlFile(AdditionalText fi
string uri = attr.Value;
string prefix = attr.Name.LocalName;
- if (uri == systemPrefixUri)
+ if (uri == Constants.SystemPrefixUri)
{
systemPrefix = prefix;
}
- else if (uri == xamlPrefixUri)
+ else if (uri == Constants.XamlPrefixUri)
{
xamlPrefix = prefix;
}
@@ -179,14 +175,14 @@ private static ImmutableArray ParseXamlFile(AdditionalText fi
}
var localizableStrings = new List();
- foreach (var element in doc.Descendants(systemNs + XamlTag)) // "String" elements in system namespace
+ foreach (var element in doc.Descendants(systemNs + Constants.XamlTag)) // "String" elements in system namespace
{
if (ct.IsCancellationRequested)
{
return _emptyLocalizableStrings;
}
- var key = element.Attribute(xNs + KeyTag)?.Value; // "Key" attribute in xaml namespace
+ var key = element.Attribute(xNs + Constants.KeyAttribute)?.Value; // "Key" attribute in xaml namespace
var value = element.Value;
var comment = element.PreviousNode as XComment;
@@ -424,7 +420,7 @@ private static string GetLocalizationKeyFromInvocation(GeneratorSyntaxContext co
parts.Reverse();
// Check if the first part is ClassName and there's at least one more part
- if (parts.Count < 2 || parts[0] != ClassName)
+ if (parts.Count < 2 || parts[0] != Constants.ClassName)
{
return null;
}
@@ -440,7 +436,7 @@ private static PluginClassInfo GetPluginClassInfo(GeneratorSyntaxContext context
{
var classDecl = (ClassDeclarationSyntax)context.Node;
var location = GetLocation(context.SemanticModel.SyntaxTree, classDecl);
- if (!classDecl.BaseList?.Types.Any(t => t.Type.ToString() == PluginInterfaceName) ?? true)
+ if (!classDecl.BaseList?.Types.Any(t => t.Type.ToString() == Constants.PluginInterfaceName) ?? true)
{
// Cannot find class that implements IPluginI18n
return null;
@@ -448,7 +444,7 @@ private static PluginClassInfo GetPluginClassInfo(GeneratorSyntaxContext context
var property = classDecl.Members
.OfType()
- .FirstOrDefault(p => p.Type.ToString() == PluginContextTypeName);
+ .FirstOrDefault(p => p.Type.ToString() == Constants.PluginContextTypeName);
if (property is null)
{
// Cannot find context
@@ -532,7 +528,7 @@ private static void GenerateSource(
ImmutableArray localizedStrings,
OptimizationLevel optimizationLevel,
string assemblyName,
- bool isCoreAssembly,
+ bool useDI,
PluginClassInfo pluginInfo,
IEnumerable usedKeys)
{
@@ -560,13 +556,6 @@ private static void GenerateSource(
GeneratedHeaderFromPath(sourceBuilder, xamlFile.Path);
sourceBuilder.AppendLine();
- // Generate usings
- if (isCoreAssembly)
- {
- sourceBuilder.AppendLine("using Flow.Launcher.Core.Resource;");
- sourceBuilder.AppendLine();
- }
-
// Generate nullable enable
sourceBuilder.AppendLine("#nullable enable");
sourceBuilder.AppendLine();
@@ -603,11 +592,26 @@ private static void GenerateSource(
// Generate class
sourceBuilder.AppendLine($"[System.CodeDom.Compiler.GeneratedCode(\"{nameof(LocalizeSourceGenerator)}\", \"{PackageVersion}\")]");
- sourceBuilder.AppendLine($"public static class {ClassName}");
+ sourceBuilder.AppendLine($"public static class {Constants.ClassName}");
sourceBuilder.AppendLine("{");
- // Generate localization methods
var tabString = Spacing(1);
+
+ // 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 localization methods
foreach (var ls in localizedStrings)
{
// TODO: Add support for usedKeys
@@ -617,13 +621,13 @@ private static void GenerateSource(
}*/
GenerateDocComments(sourceBuilder, ls, tabString);
- GenerateLocalizationMethod(sourceBuilder, ls, isCoreAssembly, pluginInfo, tabString);
+ GenerateLocalizationMethod(sourceBuilder, ls, getTranslation, tabString);
}
sourceBuilder.AppendLine("}");
// Add source to context
- spc.AddSource($"{ClassName}.{assemblyName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
+ spc.AddSource($"{Constants.ClassName}.{assemblyName}.g.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
private static void GeneratedHeaderFromPath(StringBuilder sb, string xamlFilePath)
@@ -673,8 +677,7 @@ private static void GenerateDocComments(StringBuilder sb, LocalizableString ls,
private static void GenerateLocalizationMethod(
StringBuilder sb,
LocalizableString ls,
- bool isCoreAssembly,
- PluginClassInfo pluginInfo,
+ string getTranslation,
string tabString)
{
sb.Append($"{tabString}public static string {ls.Key}(");
@@ -687,18 +690,8 @@ private static void GenerateLocalizationMethod(
? $", {string.Join(", ", parameters.Select(p => p.Name))}"
: string.Empty;
- if (isCoreAssembly)
- {
- var getTranslation = "InternationalizationManager.Instance.GetTranslation";
- sb.AppendLine(parameters.Count > 0
- ? !ls.Format ?
- $"string.Format({getTranslation}(\"{ls.Key}\"){formatArgs});"
- : $"string.Format(System.Globalization.CultureInfo.CurrentCulture, {getTranslation}(\"{ls.Key}\"){formatArgs});"
- : $"{getTranslation}(\"{ls.Key}\");");
- }
- else if (pluginInfo?.IsValid == true)
+ if (!(string.IsNullOrEmpty(getTranslation)))
{
- var getTranslation = $"{pluginInfo.ContextAccessor}.API.GetTranslation";
sb.AppendLine(parameters.Count > 0
? !ls.Format ?
$"string.Format({getTranslation}(\"{ls.Key}\"){formatArgs});"
diff --git a/Flow.Launcher.Localization.slnx b/Flow.Launcher.Localization.slnx
index dc9bd15..27c8f44 100644
--- a/Flow.Launcher.Localization.slnx
+++ b/Flow.Launcher.Localization.slnx
@@ -1,5 +1,6 @@
+
diff --git a/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj b/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj
index e2f86be..03db6d9 100644
--- a/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj
+++ b/Flow.Launcher.Localization/Flow.Launcher.Localization.csproj
@@ -1,41 +1,46 @@
-
- 0.0.1
- netstandard2.0
- true
- Flow.Launcher.Localization
+
+ 0.0.1
+ netstandard2.0
+ true
+ Flow.Launcher.Localization
- false
- true
- true
- true
-
+ false
+ true
+ true
+ true
+
-
-
-
-
+
+
+ All
+
+
+ All
+
+
+ All
+
+
-
-
-
-
+
+
+ true
+ analyzers/dotnet/cs
+ false
+
+
+ true
+ analyzers/dotnet/cs
+ false
+
+
+ true
+ analyzers/dotnet/cs
+ false
+
+
+
diff --git a/Flow.Launcher.Localization/build/Flow.Launcher.Localization.props b/Flow.Launcher.Localization/build/Flow.Launcher.Localization.props
new file mode 100644
index 0000000..80b3641
--- /dev/null
+++ b/Flow.Launcher.Localization/build/Flow.Launcher.Localization.props
@@ -0,0 +1,6 @@
+
+
+
+
+
+