@@ -54,6 +54,28 @@ public class InspectionXmlDocAnalyzer : DiagnosticAnalyzer
54
54
new LocalizableResourceString ( nameof ( Resources . MissingRequiredLibAttributeDescription ) , Resources . ResourceManager , typeof ( Resources ) )
55
55
) ;
56
56
57
+ public const string MissingHostAppElement = "MissingHostAppElement" ;
58
+ private static readonly DiagnosticDescriptor MissingHostAppElementRule = new DiagnosticDescriptor (
59
+ MissingHostAppElement ,
60
+ new LocalizableResourceString ( nameof ( Resources . MissingInspectionHostAppElement ) , Resources . ResourceManager , typeof ( Resources ) ) ,
61
+ new LocalizableResourceString ( nameof ( Resources . MissingInspectionHostAppElementMessageFormat ) , Resources . ResourceManager , typeof ( Resources ) ) ,
62
+ new LocalizableResourceString ( nameof ( Resources . XmlDocAnalyzerCategory ) , Resources . ResourceManager , typeof ( Resources ) ) . ToString ( ) ,
63
+ DiagnosticSeverity . Error ,
64
+ true ,
65
+ new LocalizableResourceString ( nameof ( Resources . MissingInspectionHostAppElementDescription ) , Resources . ResourceManager , typeof ( Resources ) )
66
+ ) ;
67
+
68
+ public const string MissingRequiredHostAttribute = "MissingRequiredHostAttribute" ;
69
+ private static readonly DiagnosticDescriptor MissingRequiredHostAttributeRule = new DiagnosticDescriptor (
70
+ MissingRequiredHostAttribute ,
71
+ new LocalizableResourceString ( nameof ( Resources . MissingRequiredHostAttribute ) , Resources . ResourceManager , typeof ( Resources ) ) ,
72
+ new LocalizableResourceString ( nameof ( Resources . MissingRequiredHostAttributeMessageFormat ) , Resources . ResourceManager , typeof ( Resources ) ) ,
73
+ new LocalizableResourceString ( nameof ( Resources . XmlDocAnalyzerCategory ) , Resources . ResourceManager , typeof ( Resources ) ) . ToString ( ) ,
74
+ DiagnosticSeverity . Error ,
75
+ true ,
76
+ new LocalizableResourceString ( nameof ( Resources . MissingRequiredHostAttributeDescription ) , Resources . ResourceManager , typeof ( Resources ) )
77
+ ) ;
78
+
57
79
public const string MissingExampleElement = "MissingExampleElement" ;
58
80
private static readonly DiagnosticDescriptor MissingExampleElementRule = new DiagnosticDescriptor (
59
81
MissingExampleElement ,
@@ -142,7 +164,9 @@ public class InspectionXmlDocAnalyzer : DiagnosticAnalyzer
142
164
MissingExampleElementRule ,
143
165
MissingTypeAttributeRule ,
144
166
InvalidTypeAttributeRule ,
145
- DuplicateNameAttributeRule
167
+ DuplicateNameAttributeRule ,
168
+ MissingHostAppElementRule ,
169
+ MissingRequiredHostAttributeRule
146
170
) ;
147
171
148
172
public override void Initialize ( AnalysisContext context )
@@ -164,9 +188,19 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context)
164
188
CheckWhyElement ( context , namedTypeSymbol , xml ) ;
165
189
CheckExampleElement ( context , namedTypeSymbol , xml ) ;
166
190
167
- var requiredLibraryAttributes = namedTypeSymbol . GetAttributes ( ) . Where ( a => a . AttributeClass . Name == "RequiredLibraryAttribute" ) . ToList ( ) ;
168
- CheckReferenceElement ( context , namedTypeSymbol , xml , requiredLibraryAttributes ) ;
169
- CheckRequiredLibAttribute ( context , namedTypeSymbol , xml , requiredLibraryAttributes ) ;
191
+ var attributes = namedTypeSymbol . GetAttributes ( ) ;
192
+ var requiredLibraryAttributes = attributes
193
+ . Where ( a => a . AttributeClass . Name == "RequiredLibraryAttribute" )
194
+ . ToList ( ) ;
195
+ var requiredHostAttributes = attributes
196
+ . Where ( a => a . AttributeClass . Name == "RequiredHostAttribute" )
197
+ . ToList ( ) ;
198
+
199
+ CheckAttributeRelatedElementElements ( context , namedTypeSymbol , xml , requiredLibraryAttributes , "reference" , MissingReferenceElementRule ) ;
200
+ CheckAttributeRelatedElementElements ( context , namedTypeSymbol , xml , requiredHostAttributes , "hostApp" , MissingHostAppElementRule ) ;
201
+
202
+ CheckXmlRelatedAttribute ( context , namedTypeSymbol , xml , requiredLibraryAttributes , "reference" , MissingRequiredLibAttributeRule ) ;
203
+ CheckXmlRelatedAttribute ( context , namedTypeSymbol , xml , requiredHostAttributes , "hostApp" , MissingRequiredHostAttributeRule ) ;
170
204
}
171
205
172
206
private static bool IsInspectionClass ( INamedTypeSymbol namedTypeSymbol )
@@ -206,54 +240,66 @@ private static string CheckNameAttributeAndReturnValue(SymbolAnalysisContext con
206
240
return nameAttribute ? . Value ;
207
241
}
208
242
209
- private static void CheckReferenceElement ( SymbolAnalysisContext context , INamedTypeSymbol symbol , XElement xml , ICollection < AttributeData > requiredLibAttributes )
243
+ private static void CheckAttributeRelatedElementElements ( SymbolAnalysisContext context , INamedTypeSymbol symbol , XElement xml , ICollection < AttributeData > requiredAttributes , string xmlElementName , DiagnosticDescriptor requiredElementDescriptor )
210
244
{
211
- if ( requiredLibAttributes . Any ( ) && ! xml . Elements ( "reference" ) . Any ( ) )
245
+ if ( requiredAttributes . Any ( ) && ! xml . Elements ( xmlElementName ) . Any ( ) )
212
246
{
213
- var diagnostic = Diagnostic . Create ( MissingReferenceElementRule , symbol . Locations [ 0 ] , symbol . Name ) ;
247
+ var diagnostic = Diagnostic . Create ( requiredElementDescriptor , symbol . Locations [ 0 ] , symbol . Name ) ;
214
248
context . ReportDiagnostic ( diagnostic ) ;
215
249
}
216
250
217
- var xmlRefLibs = new List < string > ( ) ;
218
- foreach ( var element in xml . Elements ( "reference" ) )
251
+ var xmlElementNames = new List < string > ( ) ;
252
+ foreach ( var element in xml . Elements ( xmlElementName ) )
219
253
{
220
254
var name = CheckNameAttributeAndReturnValue ( context , element , symbol . Locations [ 0 ] ) ;
221
255
if ( name != null )
222
256
{
223
- xmlRefLibs . Add ( name ) ;
257
+ xmlElementNames . Add ( name ) ;
224
258
}
225
259
}
226
260
227
- var duplicateNames = xmlRefLibs
228
- . GroupBy ( name => name )
229
- . Where ( group => group . Count ( ) > 1 )
230
- . Select ( group => group . Key ) ;
231
- foreach ( var name in duplicateNames )
232
- {
233
- var diagnostic = Diagnostic . Create ( DuplicateNameAttributeRule , symbol . Locations [ 0 ] , name , "reference" ) ;
234
- context . ReportDiagnostic ( diagnostic ) ;
235
- }
236
-
237
- foreach ( var attribute in requiredLibAttributes )
261
+ CheckForDuplicateNames ( context , symbol , xmlElementName , xmlElementNames ) ;
262
+
263
+ var requiredNames = requiredAttributes
264
+ . Where ( a => a . ConstructorArguments . Length > 0 )
265
+ . Select ( a => a . ConstructorArguments [ 0 ] . Value . ToString ( ) )
266
+ . ToList ( ) ;
267
+ foreach ( var requiredName in requiredNames )
238
268
{
239
- var requiredLib = attribute . ConstructorArguments [ 0 ] . Value . ToString ( ) ;
240
- if ( xmlRefLibs . All ( lib => lib != requiredLib ) )
269
+ if ( requiredNames . All ( lib => lib != requiredName ) )
241
270
{
242
- var diagnostic = Diagnostic . Create ( MissingReferenceElementRule , symbol . Locations [ 0 ] , symbol . Name ) ;
271
+ var diagnostic = Diagnostic . Create ( requiredElementDescriptor , symbol . Locations [ 0 ] , symbol . Name ) ;
243
272
context . ReportDiagnostic ( diagnostic ) ;
244
273
}
245
274
}
246
275
}
247
276
248
- private static void CheckRequiredLibAttribute ( SymbolAnalysisContext context , INamedTypeSymbol symbol , XElement xml , IEnumerable < AttributeData > requiredLibAttributes )
277
+ private static void CheckForDuplicateNames ( SymbolAnalysisContext context , INamedTypeSymbol symbol , string xmlElementName , List < string > names )
278
+ {
279
+ var duplicateNames = names
280
+ . GroupBy ( name => name )
281
+ . Where ( group => @group . Count ( ) > 1 )
282
+ . Select ( group => @group . Key ) ;
283
+ foreach ( var name in duplicateNames )
284
+ {
285
+ var diagnostic = Diagnostic . Create ( DuplicateNameAttributeRule , symbol . Locations [ 0 ] , name , xmlElementName ) ;
286
+ context . ReportDiagnostic ( diagnostic ) ;
287
+ }
288
+ }
289
+
290
+ private static void CheckXmlRelatedAttribute ( SymbolAnalysisContext context , INamedTypeSymbol symbol , XElement xml , IEnumerable < AttributeData > requiredAttributes , string xmlElementName , DiagnosticDescriptor requiredAttributeDescriptor )
249
291
{
250
- var requiredLibs = requiredLibAttributes . Select ( a => a . ConstructorArguments [ 0 ] . Value . ToString ( ) ) . ToList ( ) ;
251
- foreach ( var element in xml . Elements ( "reference" ) )
292
+ var requiredNames = requiredAttributes
293
+ . Where ( a => a . ConstructorArguments . Length > 0 )
294
+ . Select ( a => a . ConstructorArguments [ 0 ] . Value . ToString ( ) )
295
+ . ToList ( ) ;
296
+
297
+ foreach ( var element in xml . Elements ( xmlElementName ) )
252
298
{
253
- var xmlRefLib = element . Attribute ( "name" ) ? . Value ;
254
- if ( xmlRefLib == null || requiredLibs . All ( lib => lib != xmlRefLib ) )
299
+ var name = element . Attribute ( "name" ) ? . Value ;
300
+ if ( name == null || requiredNames . All ( lib => lib != name ) )
255
301
{
256
- var diagnostic = Diagnostic . Create ( MissingRequiredLibAttributeRule , symbol . Locations [ 0 ] , symbol . Name , xmlRefLib ) ;
302
+ var diagnostic = Diagnostic . Create ( requiredAttributeDescriptor , symbol . Locations [ 0 ] , symbol . Name , name ) ;
257
303
context . ReportDiagnostic ( diagnostic ) ;
258
304
}
259
305
}
@@ -296,15 +342,7 @@ private static void CheckModuleElements(SymbolAnalysisContext context, INamedTyp
296
342
CheckTypeAttribute ( context , module , symbol . Locations [ 0 ] ) ;
297
343
}
298
344
299
- var duplicateNames = moduleNames
300
- . GroupBy ( name => name )
301
- . Where ( group => group . Count ( ) > 1 )
302
- . Select ( group => group . Key ) ;
303
- foreach ( var name in duplicateNames )
304
- {
305
- var diagnostic = Diagnostic . Create ( DuplicateNameAttributeRule , symbol . Locations [ 0 ] , name , "module" ) ;
306
- context . ReportDiagnostic ( diagnostic ) ;
307
- }
345
+ CheckForDuplicateNames ( context , symbol , "module" , moduleNames ) ;
308
346
}
309
347
310
348
private static void CheckHasResultAttribute ( SymbolAnalysisContext context , XElement element , Location location )
0 commit comments