@@ -268,18 +268,12 @@ private void ExtractAttributes(SyntaxList<AttributeListSyntax> attributes, List<
268
268
{
269
269
foreach ( var attribute in attributes . SelectMany ( a => a . Attributes ) )
270
270
{
271
- var attributeDescription = new AttributeDescription ( semanticModel . GetTypeDisplayString ( attribute ) , attribute . Name . ToString ( ) ) ;
271
+ var attributeDescription = this . CreateAttributeDescription ( attribute ) ;
272
272
attributeDescriptions . Add ( attributeDescription ) ;
273
273
274
274
if ( attribute . ArgumentList != null )
275
275
{
276
- foreach ( var argument in attribute . ArgumentList . Arguments )
277
- {
278
- var value = argument . Expression ! . ResolveValue ( semanticModel ) ;
279
-
280
- var argumentDescription = new AttributeArgumentDescription ( argument . NameEquals ? . Name . ToString ( ) ?? argument . Expression . ResolveValue ( semanticModel ) , semanticModel . GetTypeDisplayString ( argument . Expression ! ) , value ) ;
281
- attributeDescription . Arguments . Add ( argumentDescription ) ;
282
- }
276
+ this . AddAttributeArguments ( attribute , attributeDescription ) ;
283
277
}
284
278
}
285
279
}
@@ -314,4 +308,43 @@ private static Modifier ParseModifiers(SyntaxTokenList modifiers)
314
308
{
315
309
return ( Modifier ) modifiers . Select ( m => Enum . TryParse ( typeof ( Modifier ) , m . ValueText , true , out var value ) ? ( int ) value : 0 ) . Sum ( ) ;
316
310
}
311
+
312
+ private AttributeDescription CreateAttributeDescription ( AttributeSyntax attribute )
313
+ {
314
+ var typeDisplayString = semanticModel . GetTypeDisplayString ( attribute ) ;
315
+ var attributeName = attribute . Name . ToString ( ) ;
316
+
317
+ return new AttributeDescription ( typeDisplayString , attributeName ) ;
318
+ }
319
+
320
+ private void AddAttributeArguments ( AttributeSyntax attribute , AttributeDescription attributeDescription )
321
+ {
322
+ var argumentType = semanticModel . GetTypeInfo ( attribute ) . Type ;
323
+ var ctor = FindMatchingArgumentConstructor ( argumentType , attribute . ArgumentList ! . Arguments . Count ) ;
324
+
325
+ for ( int i = 0 ; i < attribute . ArgumentList . Arguments . Count ; i ++ )
326
+ {
327
+ var argument = attribute . ArgumentList . Arguments [ i ] ;
328
+ var argumentDescription = this . CreateArgumentDescription ( argument , ctor , i ) ;
329
+
330
+ attributeDescription . Arguments . Add ( argumentDescription ) ;
331
+ }
332
+ }
333
+
334
+ private static IMethodSymbol ? FindMatchingArgumentConstructor ( ITypeSymbol ? argumentType , int argumentCount )
335
+ {
336
+ return argumentType ?
337
+ . GetMembers ( ".ctor" )
338
+ . OfType < IMethodSymbol > ( )
339
+ . FirstOrDefault ( c => c . Parameters . Length == argumentCount ) ;
340
+ }
341
+
342
+ private AttributeArgumentDescription CreateArgumentDescription ( AttributeArgumentSyntax argument , IMethodSymbol ? ctor , int index )
343
+ {
344
+ var name = argument . NameEquals ? . Name . ToString ( ) ?? ctor ? . Parameters [ index ] . Name ?? argument . Expression . ResolveValue ( semanticModel ) ;
345
+ var typeDisplayString = semanticModel . GetTypeDisplayString ( argument . Expression ! ) ;
346
+ var value = argument . Expression ! . ResolveValue ( semanticModel ) ;
347
+
348
+ return new AttributeArgumentDescription ( name , typeDisplayString , value ) ;
349
+ }
317
350
}
0 commit comments