3
3
using System . Collections . Immutable ;
4
4
using System . Linq ;
5
5
using System . Text ;
6
- using System . Text . RegularExpressions ;
7
6
using System . Threading ;
8
7
using System . Xml . Linq ;
8
+ using Flow . Launcher . Localization . Shared ;
9
9
using Microsoft . CodeAnalysis ;
10
10
using Microsoft . CodeAnalysis . CSharp ;
11
11
using Microsoft . CodeAnalysis . CSharp . Syntax ;
12
+ using Microsoft . CodeAnalysis . Diagnostics ;
12
13
using Microsoft . CodeAnalysis . Text ;
13
14
14
15
namespace Flow . Launcher . Localization . SourceGenerators . Localize
@@ -21,19 +22,6 @@ public partial class LocalizeSourceGenerator : IIncrementalGenerator
21
22
{
22
23
#region Fields
23
24
24
- private const string CoreNamespace1 = "Flow.Launcher" ;
25
- private const string CoreNamespace2 = "Flow.Launcher.Core" ;
26
- private const string DefaultNamespace = "Flow.Launcher" ;
27
- private const string ClassName = "Localize" ;
28
- private const string PluginInterfaceName = "IPluginI18n" ;
29
- private const string PluginContextTypeName = "PluginInitContext" ;
30
- private const string systemPrefixUri = "clr-namespace:System;assembly=mscorlib" ;
31
- private const string xamlPrefixUri = "http://schemas.microsoft.com/winfx/2006/xaml" ;
32
- private const string XamlTag = "String" ;
33
- private const string KeyTag = "Key" ;
34
-
35
- private static readonly Regex _languagesXamlRegex = new Regex ( @"\\Languages\\[^\\]+\.xaml$" , RegexOptions . IgnoreCase ) ;
36
-
37
25
private static readonly Version PackageVersion = typeof ( LocalizeSourceGenerator ) . Assembly . GetName ( ) . Version ;
38
26
39
27
private static readonly ImmutableArray < LocalizableString > _emptyLocalizableStrings = ImmutableArray < LocalizableString > . Empty ;
@@ -50,7 +38,7 @@ public partial class LocalizeSourceGenerator : IIncrementalGenerator
50
38
public void Initialize ( IncrementalGeneratorInitializationContext context )
51
39
{
52
40
var xamlFiles = context . AdditionalTextsProvider
53
- . Where ( file => _languagesXamlRegex . IsMatch ( file . Path ) ) ;
41
+ . Where ( file => Constants . LanguagesXamlRegex . IsMatch ( file . Path ) ) ;
54
42
55
43
var localizedStrings = xamlFiles
56
44
. Select ( ( file , ct ) => ParseXamlFile ( file , ct ) )
@@ -75,7 +63,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
75
63
76
64
var compilation = context . CompilationProvider ;
77
65
78
- var combined = localizedStrings . Combine ( invocationKeys ) . Combine ( pluginClasses ) . Combine ( compilation ) . Combine ( xamlFiles . Collect ( ) ) ;
66
+ var configOptions = context . AnalyzerConfigOptionsProvider ;
67
+
68
+ var combined = localizedStrings . Combine ( invocationKeys ) . Combine ( pluginClasses ) . Combine ( configOptions ) . Combine ( compilation ) . Combine ( xamlFiles . Collect ( ) ) ;
79
69
80
70
context . RegisterSourceOutput ( combined , Execute ) ;
81
71
}
@@ -86,10 +76,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
86
76
/// <param name="spc">The source production context.</param>
87
77
/// <param name="data">The provided data.</param>
88
78
private void Execute ( SourceProductionContext spc ,
89
- ( ( ( ( ImmutableArray < LocalizableString > LocalizableStrings ,
90
- ImmutableHashSet < string > InvocationKeys ) ,
91
- ImmutableArray < PluginClassInfo > PluginClassInfos ) ,
92
- Compilation Compilation ) ,
79
+ ( ( ( ( ( ImmutableArray < LocalizableString > LocalizableStrings ,
80
+ ImmutableHashSet < string > InvocationKeys ) ,
81
+ ImmutableArray < PluginClassInfo > PluginClassInfos ) ,
82
+ AnalyzerConfigOptionsProvider ConfigOptionsProvider ) ,
83
+ Compilation Compilation ) ,
93
84
ImmutableArray < AdditionalText > AdditionalTexts ) data )
94
85
{
95
86
var xamlFiles = data . AdditionalTexts ;
@@ -103,23 +94,28 @@ private void Execute(SourceProductionContext spc,
103
94
}
104
95
105
96
var compilation = data . Item1 . Compilation ;
106
- var pluginClasses = data . Item1 . Item1 . PluginClassInfos ;
107
- var usedKeys = data . Item1 . Item1 . Item1 . InvocationKeys ;
108
- var localizedStrings = data . Item1 . Item1 . Item1 . LocalizableStrings ;
97
+ var configOptions = data . Item1 . Item1 . ConfigOptionsProvider ;
98
+ var pluginClasses = data . Item1 . Item1 . Item1 . PluginClassInfos ;
99
+ var usedKeys = data . Item1 . Item1 . Item1 . Item1 . InvocationKeys ;
100
+ var localizedStrings = data . Item1 . Item1 . Item1 . Item1 . LocalizableStrings ;
109
101
110
- var assemblyName = compilation . AssemblyName ?? DefaultNamespace ;
102
+ var assemblyName = compilation . AssemblyName ?? Constants . DefaultNamespace ;
111
103
var optimizationLevel = compilation . Options . OptimizationLevel ;
104
+ var useDI = configOptions . GetFLLUseDependencyInjection ( ) ;
112
105
113
- var pluginInfo = GetValidPluginInfo ( pluginClasses , spc ) ;
114
- var isCoreAssembly = assemblyName == CoreNamespace1 || assemblyName == CoreNamespace2 ;
115
-
106
+ PluginClassInfo pluginInfo = null ;
107
+ if ( ! useDI )
108
+ {
109
+ pluginInfo = GetValidPluginInfo ( pluginClasses , spc ) ;
110
+ }
111
+
116
112
GenerateSource (
117
113
spc ,
118
114
xamlFiles [ 0 ] ,
119
115
localizedStrings ,
120
116
optimizationLevel ,
121
117
assemblyName ,
122
- isCoreAssembly ,
118
+ useDI ,
123
119
pluginInfo ,
124
120
usedKeys ) ;
125
121
}
@@ -155,11 +151,11 @@ private static ImmutableArray<LocalizableString> ParseXamlFile(AdditionalText fi
155
151
string uri = attr . Value ;
156
152
string prefix = attr . Name . LocalName ;
157
153
158
- if ( uri == systemPrefixUri )
154
+ if ( uri == Constants . SystemPrefixUri )
159
155
{
160
156
systemPrefix = prefix ;
161
157
}
162
- else if ( uri == xamlPrefixUri )
158
+ else if ( uri == Constants . XamlPrefixUri )
163
159
{
164
160
xamlPrefix = prefix ;
165
161
}
@@ -179,14 +175,14 @@ private static ImmutableArray<LocalizableString> ParseXamlFile(AdditionalText fi
179
175
}
180
176
181
177
var localizableStrings = new List < LocalizableString > ( ) ;
182
- foreach ( var element in doc . Descendants ( systemNs + XamlTag ) ) // "String" elements in system namespace
178
+ foreach ( var element in doc . Descendants ( systemNs + Constants . XamlTag ) ) // "String" elements in system namespace
183
179
{
184
180
if ( ct . IsCancellationRequested )
185
181
{
186
182
return _emptyLocalizableStrings ;
187
183
}
188
184
189
- var key = element . Attribute ( xNs + KeyTag ) ? . Value ; // "Key" attribute in xaml namespace
185
+ var key = element . Attribute ( xNs + Constants . KeyAttribute ) ? . Value ; // "Key" attribute in xaml namespace
190
186
var value = element . Value ;
191
187
var comment = element . PreviousNode as XComment ;
192
188
@@ -424,7 +420,7 @@ private static string GetLocalizationKeyFromInvocation(GeneratorSyntaxContext co
424
420
parts . Reverse ( ) ;
425
421
426
422
// Check if the first part is ClassName and there's at least one more part
427
- if ( parts . Count < 2 || parts [ 0 ] != ClassName )
423
+ if ( parts . Count < 2 || parts [ 0 ] != Constants . ClassName )
428
424
{
429
425
return null ;
430
426
}
@@ -440,15 +436,15 @@ private static PluginClassInfo GetPluginClassInfo(GeneratorSyntaxContext context
440
436
{
441
437
var classDecl = ( ClassDeclarationSyntax ) context . Node ;
442
438
var location = GetLocation ( context . SemanticModel . SyntaxTree , classDecl ) ;
443
- if ( ! classDecl . BaseList ? . Types . Any ( t => t . Type . ToString ( ) == PluginInterfaceName ) ?? true )
439
+ if ( ! classDecl . BaseList ? . Types . Any ( t => t . Type . ToString ( ) == Constants . PluginInterfaceName ) ?? true )
444
440
{
445
441
// Cannot find class that implements IPluginI18n
446
442
return null ;
447
443
}
448
444
449
445
var property = classDecl . Members
450
446
. OfType < PropertyDeclarationSyntax > ( )
451
- . FirstOrDefault ( p => p . Type . ToString ( ) == PluginContextTypeName ) ;
447
+ . FirstOrDefault ( p => p . Type . ToString ( ) == Constants . PluginContextTypeName ) ;
452
448
if ( property is null )
453
449
{
454
450
// Cannot find context
@@ -532,7 +528,7 @@ private static void GenerateSource(
532
528
ImmutableArray < LocalizableString > localizedStrings ,
533
529
OptimizationLevel optimizationLevel ,
534
530
string assemblyName ,
535
- bool isCoreAssembly ,
531
+ bool useDI ,
536
532
PluginClassInfo pluginInfo ,
537
533
IEnumerable < string > usedKeys )
538
534
{
@@ -560,13 +556,6 @@ private static void GenerateSource(
560
556
GeneratedHeaderFromPath ( sourceBuilder , xamlFile . Path ) ;
561
557
sourceBuilder . AppendLine ( ) ;
562
558
563
- // Generate usings
564
- if ( isCoreAssembly )
565
- {
566
- sourceBuilder . AppendLine ( "using Flow.Launcher.Core.Resource;" ) ;
567
- sourceBuilder . AppendLine ( ) ;
568
- }
569
-
570
559
// Generate nullable enable
571
560
sourceBuilder . AppendLine ( "#nullable enable" ) ;
572
561
sourceBuilder . AppendLine ( ) ;
@@ -603,11 +592,26 @@ private static void GenerateSource(
603
592
604
593
// Generate class
605
594
sourceBuilder . AppendLine ( $ "[System.CodeDom.Compiler.GeneratedCode(\" { nameof ( LocalizeSourceGenerator ) } \" , \" { PackageVersion } \" )]") ;
606
- sourceBuilder . AppendLine ( $ "public static class { ClassName } ") ;
595
+ sourceBuilder . AppendLine ( $ "public static class { Constants . ClassName } ") ;
607
596
sourceBuilder . AppendLine ( "{" ) ;
608
597
609
- // Generate localization methods
610
598
var tabString = Spacing ( 1 ) ;
599
+
600
+ // Generate API instance
601
+ string getTranslation = null ;
602
+ if ( useDI )
603
+ {
604
+ sourceBuilder . AppendLine ( $ "{ tabString } private static Flow.Launcher.Plugin.IPublicAPI? api = null;") ;
605
+ sourceBuilder . AppendLine ( $ "{ tabString } private static Flow.Launcher.Plugin.IPublicAPI Api => api ??= CommunityToolkit.Mvvm.DependencyInjection.Ioc.Default.GetRequiredService<Flow.Launcher.Plugin.IPublicAPI>();") ;
606
+ sourceBuilder . AppendLine ( ) ;
607
+ getTranslation = "Api.GetTranslation" ;
608
+ }
609
+ else if ( pluginInfo ? . IsValid == true )
610
+ {
611
+ getTranslation = $ "{ pluginInfo . ContextAccessor } .API.GetTranslation";
612
+ }
613
+
614
+ // Generate localization methods
611
615
foreach ( var ls in localizedStrings )
612
616
{
613
617
// TODO: Add support for usedKeys
@@ -617,13 +621,13 @@ private static void GenerateSource(
617
621
}*/
618
622
619
623
GenerateDocComments ( sourceBuilder , ls , tabString ) ;
620
- GenerateLocalizationMethod ( sourceBuilder , ls , isCoreAssembly , pluginInfo , tabString ) ;
624
+ GenerateLocalizationMethod ( sourceBuilder , ls , getTranslation , tabString ) ;
621
625
}
622
626
623
627
sourceBuilder . AppendLine ( "}" ) ;
624
628
625
629
// Add source to context
626
- spc . AddSource ( $ "{ ClassName } .{ assemblyName } .g.cs", SourceText . From ( sourceBuilder . ToString ( ) , Encoding . UTF8 ) ) ;
630
+ spc . AddSource ( $ "{ Constants . ClassName } .{ assemblyName } .g.cs", SourceText . From ( sourceBuilder . ToString ( ) , Encoding . UTF8 ) ) ;
627
631
}
628
632
629
633
private static void GeneratedHeaderFromPath ( StringBuilder sb , string xamlFilePath )
@@ -673,8 +677,7 @@ private static void GenerateDocComments(StringBuilder sb, LocalizableString ls,
673
677
private static void GenerateLocalizationMethod (
674
678
StringBuilder sb ,
675
679
LocalizableString ls ,
676
- bool isCoreAssembly ,
677
- PluginClassInfo pluginInfo ,
680
+ string getTranslation ,
678
681
string tabString )
679
682
{
680
683
sb . Append ( $ "{ tabString } public static string { ls . Key } (") ;
@@ -687,18 +690,8 @@ private static void GenerateLocalizationMethod(
687
690
? $ ", { string . Join ( ", " , parameters . Select ( p => p . Name ) ) } "
688
691
: string . Empty ;
689
692
690
- if ( isCoreAssembly )
691
- {
692
- var getTranslation = "InternationalizationManager.Instance.GetTranslation" ;
693
- sb . AppendLine ( parameters . Count > 0
694
- ? ! ls . Format ?
695
- $ "string.Format({ getTranslation } (\" { ls . Key } \" ){ formatArgs } );"
696
- : $ "string.Format(System.Globalization.CultureInfo.CurrentCulture, { getTranslation } (\" { ls . Key } \" ){ formatArgs } );"
697
- : $ "{ getTranslation } (\" { ls . Key } \" );") ;
698
- }
699
- else if ( pluginInfo ? . IsValid == true )
693
+ if ( ! ( string . IsNullOrEmpty ( getTranslation ) ) )
700
694
{
701
- var getTranslation = $ "{ pluginInfo . ContextAccessor } .API.GetTranslation";
702
695
sb . AppendLine ( parameters . Count > 0
703
696
? ! ls . Format ?
704
697
$ "string.Format({ getTranslation } (\" { ls . Key } \" ){ formatArgs } );"
0 commit comments