@@ -67,44 +67,65 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
6767
6868 var compilation = context . CompilationProvider ;
6969
70- var combined = localizedStrings . Combine ( invocationKeys ) . Combine ( pluginClasses ) . Combine ( compilation ) ;
70+ var combined = localizedStrings . Combine ( invocationKeys ) . Combine ( pluginClasses ) . Combine ( compilation ) . Combine ( xamlFiles . Collect ( ) ) ;
7171
72- context . RegisterSourceOutput ( combined , ( spc , data ) =>
72+ context . RegisterSourceOutput ( combined , Execute ) ;
73+ }
74+
75+ /// <summary>
76+ /// Executes the generation of string properties based on the provided data.
77+ /// </summary>
78+ /// <param name="spc">The source production context.</param>
79+ /// <param name="data">The provided data.</param>
80+ private void Execute ( SourceProductionContext spc ,
81+ ( ( ( ( ImmutableArray < LocalizableString > LocalizableStrings ,
82+ ImmutableHashSet < string > Strings ) ,
83+ ImmutableArray < PluginClassInfo > PluginClassInfos ) ,
84+ Compilation Compilation ) ,
85+ ImmutableArray < AdditionalText > AdditionalTexts ) data )
86+ {
87+ var xamlFiles = data . AdditionalTexts ;
88+ if ( xamlFiles . Length == 0 )
7389 {
74- var ( Left , Right ) = data ;
75- var localizedStringsList = Left . Left . Left ;
76- var usedKeys = Left . Left . Right ;
77- var pluginClassesList = Left . Right ;
78- var compilationData = Right ;
90+ spc . ReportDiagnostic ( Diagnostic . Create (
91+ SourceGeneratorDiagnostics . CouldNotFindResourceDictionaries ,
92+ Location . None
93+ ) ) ;
94+ return ;
95+ }
7996
80- var assemblyName = compilationData . AssemblyName ?? DefaultNamespace ;
81- var optimizationLevel = compilationData . Options . OptimizationLevel ;
97+ var compilationData = data . Item1 . Compilation ;
98+ var pluginClassesList = data . Item1 . Item1 . PluginClassInfos ;
99+ var usedKeys = data . Item1 . Item1 . Item1 . Strings ;
100+ var localizedStringsList = data . Item1 . Item1 . Item1 . LocalizableStrings ;
82101
83- var unusedKeys = localizedStringsList
84- . Select ( ls => ls . Key )
85- . ToImmutableHashSet ( )
86- . Except ( usedKeys ) ;
102+ var assemblyName = compilationData . AssemblyName ?? DefaultNamespace ;
103+ var optimizationLevel = compilationData . Options . OptimizationLevel ;
87104
88- foreach ( var key in unusedKeys )
89- {
90- spc . ReportDiagnostic ( Diagnostic . Create (
91- SourceGeneratorDiagnostics . LocalizationKeyUnused ,
92- Location . None ,
93- key ) ) ;
94- }
105+ var unusedKeys = localizedStringsList
106+ . Select ( ls => ls . Key )
107+ . ToImmutableHashSet ( )
108+ . Except ( usedKeys ) ;
95109
96- var pluginInfo = GetValidPluginInfo ( pluginClassesList , spc ) ;
97- var isCoreAssembly = assemblyName == CoreNamespace1 || assemblyName == CoreNamespace2 ;
98-
99- GenerateSource (
100- spc ,
101- localizedStringsList ,
102- unusedKeys ,
103- optimizationLevel ,
104- assemblyName ,
105- isCoreAssembly ,
106- pluginInfo ) ;
107- } ) ;
110+ foreach ( var key in unusedKeys )
111+ {
112+ spc . ReportDiagnostic ( Diagnostic . Create (
113+ SourceGeneratorDiagnostics . LocalizationKeyUnused ,
114+ Location . None ,
115+ key ) ) ;
116+ }
117+
118+ var pluginInfo = GetValidPluginInfo ( pluginClassesList , spc ) ;
119+ var isCoreAssembly = assemblyName == CoreNamespace1 || assemblyName == CoreNamespace2 ;
120+
121+ GenerateSource (
122+ spc ,
123+ localizedStringsList ,
124+ unusedKeys ,
125+ optimizationLevel ,
126+ assemblyName ,
127+ isCoreAssembly ,
128+ pluginInfo ) ;
108129 }
109130
110131 #endregion
@@ -187,47 +208,93 @@ private static string GetLocalizationKeyFromInvocation(GeneratorSyntaxContext co
187208 private static PluginClassInfo GetPluginClassInfo ( GeneratorSyntaxContext context , CancellationToken ct )
188209 {
189210 var classDecl = ( ClassDeclarationSyntax ) context . Node ;
211+ var location = GetLocation ( context . SemanticModel . SyntaxTree , classDecl ) ;
190212 if ( ! classDecl . BaseList ? . Types . Any ( t => t . Type . ToString ( ) == PluginInterfaceName ) ?? true )
213+ {
214+ // Cannot find class that implements IPluginI18n
191215 return null ;
216+ }
192217
193218 var property = classDecl . Members
194219 . OfType < PropertyDeclarationSyntax > ( )
195220 . FirstOrDefault ( p => p . Type . ToString ( ) == PluginContextTypeName ) ;
196-
197221 if ( property is null )
198- return new PluginClassInfo ( classDecl . Identifier . Text , null , false ) ;
222+ {
223+ // Cannot find context
224+ return new PluginClassInfo ( location , classDecl . Identifier . Text , null , false , false , false ) ;
225+ }
199226
200227 var modifiers = property . Modifiers ;
201- var isValid = modifiers . Any ( SyntaxKind . StaticKeyword ) &&
202- ! modifiers . Any ( SyntaxKind . PrivateKeyword ) &&
203- ! modifiers . Any ( SyntaxKind . ProtectedKeyword ) ;
204-
205228 return new PluginClassInfo (
229+ location ,
206230 classDecl . Identifier . Text ,
207231 property . Identifier . Text ,
208- isValid ) ;
232+ modifiers . Any ( SyntaxKind . StaticKeyword ) ,
233+ modifiers . Any ( SyntaxKind . PrivateKeyword ) ,
234+ modifiers . Any ( SyntaxKind . ProtectedKeyword ) ) ;
209235 }
210236
211237 private static PluginClassInfo GetValidPluginInfo (
212238 ImmutableArray < PluginClassInfo > pluginClasses ,
213239 SourceProductionContext context )
214240 {
241+ if ( pluginClasses . All ( p => p is null || p . PropertyName == null ) )
242+ {
243+ context . ReportDiagnostic ( Diagnostic . Create (
244+ SourceGeneratorDiagnostics . CouldNotFindPluginEntryClass ,
245+ Location . None
246+ ) ) ;
247+ return null ;
248+ }
249+
215250 foreach ( var pluginClass in pluginClasses )
216251 {
217- if ( pluginClass ? . IsValid == true )
252+ if ( pluginClass == null || pluginClass . PropertyName is null )
253+ {
254+ continue ;
255+ }
256+
257+ if ( pluginClass . IsValid == true )
258+ {
218259 return pluginClass ;
260+ }
261+
262+ if ( ! pluginClass . IsStatic )
263+ {
264+ context . ReportDiagnostic ( Diagnostic . Create (
265+ SourceGeneratorDiagnostics . ContextPropertyNotStatic ,
266+ pluginClass . Location ,
267+ pluginClass . PropertyName
268+ ) ) ;
269+ }
270+
271+ if ( pluginClass . IsPrivate )
272+ {
273+ context . ReportDiagnostic ( Diagnostic . Create (
274+ SourceGeneratorDiagnostics . ContextPropertyIsPrivate ,
275+ pluginClass . Location ,
276+ pluginClass . PropertyName
277+ ) ) ;
278+ }
219279
220- if ( pluginClass . IsValid == false )
280+ if ( pluginClass . IsProtected )
221281 {
222- // TODO
223- //context.ReportDiagnostic(Diagnostic.Create(
224- // SourceGeneratorDiagnostics.InvalidPluginConfiguration,
225- // Location.None));
282+ context . ReportDiagnostic ( Diagnostic . Create (
283+ SourceGeneratorDiagnostics . ContextPropertyIsProtected ,
284+ pluginClass . Location ,
285+ pluginClass . PropertyName
286+ ) ) ;
226287 }
227288 }
289+
228290 return null ;
229291 }
230292
293+ private static Location GetLocation ( SyntaxTree syntaxTree , CSharpSyntaxNode classDeclaration )
294+ {
295+ return Location . Create ( syntaxTree , classDeclaration . GetLocation ( ) . SourceSpan ) ;
296+ }
297+
231298 #endregion
232299
233300 #region Generate Source
@@ -384,17 +451,24 @@ public LocalizableString(string key, string value, string summary, IEnumerable<L
384451
385452 public class PluginClassInfo
386453 {
454+ public Location Location { get ; }
387455 public string ClassName { get ; }
388456 public string PropertyName { get ; }
389- public bool IsValid { get ; }
457+ public bool IsStatic { get ; }
458+ public bool IsPrivate { get ; }
459+ public bool IsProtected { get ; }
390460
391461 public string ContextAccessor => $ "{ ClassName } .{ PropertyName } ";
462+ public bool IsValid => PropertyName != null && IsStatic && ( ! IsPrivate ) && ( ! IsProtected ) ;
392463
393- public PluginClassInfo ( string className , string propertyName , bool isValid )
464+ public PluginClassInfo ( Location location , string className , string propertyName , bool isStatic , bool isPrivate , bool isProtected )
394465 {
466+ Location = location ;
395467 ClassName = className ;
396468 PropertyName = propertyName ;
397- IsValid = isValid ;
469+ IsStatic = isStatic ;
470+ IsPrivate = isPrivate ;
471+ IsProtected = isProtected ;
398472 }
399473 }
400474
0 commit comments