@@ -87,6 +87,17 @@ public class InspectionXmlDocAnalyzer : DiagnosticAnalyzer
87
87
new LocalizableResourceString ( nameof ( Resources . MissingNameAttributeDescription ) , Resources . ResourceManager , typeof ( Resources ) )
88
88
) ;
89
89
90
+ public const string DuplicateNameAttribute = "DuplicateNameAttribute" ;
91
+ private static readonly DiagnosticDescriptor DuplicateNameAttributeRule = new DiagnosticDescriptor (
92
+ DuplicateNameAttribute ,
93
+ new LocalizableResourceString ( nameof ( Resources . DuplicateNameAttribute ) , Resources . ResourceManager , typeof ( Resources ) ) ,
94
+ new LocalizableResourceString ( nameof ( Resources . DuplicateNameAttributeMessageFormat ) , Resources . ResourceManager , typeof ( Resources ) ) ,
95
+ new LocalizableResourceString ( nameof ( Resources . XmlDocAnalyzerCategory ) , Resources . ResourceManager , typeof ( Resources ) ) . ToString ( ) ,
96
+ DiagnosticSeverity . Error ,
97
+ true ,
98
+ new LocalizableResourceString ( nameof ( Resources . DuplicateNameAttributeDescription ) , Resources . ResourceManager , typeof ( Resources ) )
99
+ ) ;
100
+
90
101
public const string MissingTypeAttribute = "MissingTypeAttribute" ;
91
102
private static readonly DiagnosticDescriptor MissingTypeAttributeRule = new DiagnosticDescriptor (
92
103
MissingTypeAttribute ,
@@ -130,7 +141,8 @@ public class InspectionXmlDocAnalyzer : DiagnosticAnalyzer
130
141
MissingModuleElementRule ,
131
142
MissingExampleElementRule ,
132
143
MissingTypeAttributeRule ,
133
- InvalidTypeAttributeRule
144
+ InvalidTypeAttributeRule ,
145
+ DuplicateNameAttributeRule
134
146
) ;
135
147
136
148
public override void Initialize ( AnalysisContext context )
@@ -182,13 +194,16 @@ private static void CheckWhyElement(SymbolAnalysisContext context, INamedTypeSym
182
194
}
183
195
}
184
196
185
- private static void CheckNameAttribute ( SymbolAnalysisContext context , XElement element , Location location )
197
+ private static string CheckNameAttributeAndReturnValue ( SymbolAnalysisContext context , XElement element , Location location )
186
198
{
187
- if ( ! element . Attributes ( ) . Any ( a => a . Name . LocalName . Equals ( "name" ) ) )
199
+ var nameAttribute = element . Attributes ( ) . FirstOrDefault ( a => a . Name . LocalName . Equals ( "name" ) ) ;
200
+ if ( nameAttribute == null )
188
201
{
189
202
var diagnostic = Diagnostic . Create ( MissingNameAttributeRule , location , element . Name . LocalName ) ;
190
203
context . ReportDiagnostic ( diagnostic ) ;
191
204
}
205
+
206
+ return nameAttribute ? . Value ;
192
207
}
193
208
194
209
private static void CheckReferenceElement ( SymbolAnalysisContext context , INamedTypeSymbol symbol , XElement xml , ICollection < AttributeData > requiredLibAttributes )
@@ -199,12 +214,25 @@ private static void CheckReferenceElement(SymbolAnalysisContext context, INamedT
199
214
context . ReportDiagnostic ( diagnostic ) ;
200
215
}
201
216
217
+ var xmlRefLibs = new List < string > ( ) ;
202
218
foreach ( var element in xml . Elements ( "reference" ) )
203
219
{
204
- CheckNameAttribute ( context , element , symbol . Locations [ 0 ] ) ;
220
+ var name = CheckNameAttributeAndReturnValue ( context , element , symbol . Locations [ 0 ] ) ;
221
+ if ( name != null )
222
+ {
223
+ xmlRefLibs . Add ( name ) ;
224
+ }
225
+ }
226
+
227
+ var duplicateNames = xmlRefLibs
228
+ . GroupBy ( name => name )
229
+ . Where ( group => group . Count ( ) > 1 ) ;
230
+ foreach ( var name in duplicateNames )
231
+ {
232
+ var diagnostic = Diagnostic . Create ( DuplicateNameAttributeRule , symbol . Locations [ 0 ] , name , "reference" ) ;
233
+ context . ReportDiagnostic ( diagnostic ) ;
205
234
}
206
235
207
- var xmlRefLibs = xml . Elements ( "reference" ) . Select ( e => e . Attribute ( "name" ) ? . Value ) . ToList ( ) ;
208
236
foreach ( var attribute in requiredLibAttributes )
209
237
{
210
238
var requiredLib = attribute . ConstructorArguments [ 0 ] . Value . ToString ( ) ;
@@ -255,11 +283,26 @@ private static void CheckModuleElements(SymbolAnalysisContext context, INamedTyp
255
283
context . ReportDiagnostic ( diagnostic ) ;
256
284
}
257
285
286
+ var moduleNames = new List < string > ( ) ;
258
287
foreach ( var module in example . Elements ( "module" ) )
259
288
{
260
- CheckNameAttribute ( context , module , symbol . Locations [ 0 ] ) ;
289
+ var moduleName = CheckNameAttributeAndReturnValue ( context , module , symbol . Locations [ 0 ] ) ;
290
+ if ( moduleName != null )
291
+ {
292
+ moduleNames . Add ( moduleName ) ;
293
+ }
294
+
261
295
CheckTypeAttribute ( context , module , symbol . Locations [ 0 ] ) ;
262
296
}
297
+
298
+ var duplicateNames = moduleNames
299
+ . GroupBy ( name => name )
300
+ . Where ( group => group . Count ( ) > 1 ) ;
301
+ foreach ( var name in duplicateNames )
302
+ {
303
+ var diagnostic = Diagnostic . Create ( DuplicateNameAttributeRule , symbol . Locations [ 0 ] , name , "module" ) ;
304
+ context . ReportDiagnostic ( diagnostic ) ;
305
+ }
263
306
}
264
307
265
308
private static void CheckHasResultAttribute ( SymbolAnalysisContext context , XElement element , Location location )
0 commit comments