Skip to content

Commit 04074c4

Browse files
committed
C#: Fix named attribute argument extraction
1 parent 44372f4 commit 04074c4

File tree

4 files changed

+28
-15
lines changed

4 files changed

+28
-15
lines changed

csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,18 @@ private void ExtractArguments(TextWriter trapFile)
6969
var ctorArguments = attributeSyntax?.ArgumentList?.Arguments.Where(a => a.NameEquals == null).ToList();
7070

7171
var childIndex = 0;
72-
foreach (var constructorArgument in symbol.ConstructorArguments)
72+
for (var i = 0; i < symbol.ConstructorArguments.Length; i++)
7373
{
74-
var argSyntax = ctorArguments?.Count > childIndex
75-
? ctorArguments[childIndex]
76-
: null;
74+
var constructorArgument = symbol.ConstructorArguments[i];
75+
var paramName = symbol.AttributeConstructor?.Parameters[i].Name;
76+
var argSyntax = ctorArguments?.SingleOrDefault(a => a.NameColon != null && a.NameColon.Name.Identifier.Text == paramName);
77+
78+
if (argSyntax == null && // couldn't find named argument
79+
ctorArguments?.Count > childIndex && // there're more arguments
80+
ctorArguments[childIndex].NameColon == null) // the argument is positional
81+
{
82+
argSyntax = ctorArguments[childIndex];
83+
}
7784

7885
CreateExpressionFromArgument(
7986
constructorArgument,

csharp/ql/test/library-tests/attributes/AttributeArguments.expected

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ arguments
4747
| attributes.cs:57:6:57:16 | [My(...)] | 0 | attributes.cs:57:18:57:21 | true |
4848
| attributes.cs:57:6:57:16 | [My(...)] | 1 | attributes.cs:57:28:57:29 | "" |
4949
| attributes.cs:57:6:57:16 | [My(...)] | 2 | attributes.cs:57:36:57:36 | 0 |
50-
| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:10:58:13 | true |
51-
| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:16:58:20 | false |
50+
| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:28:58:32 | false |
51+
| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:13:58:16 | true |
5252
| attributes.cs:58:6:58:8 | [My2(...)] | 2 | attributes.cs:58:6:58:8 | 12 |
53-
| attributes.cs:58:6:58:8 | [My2(...)] | 3 | attributes.cs:58:27:58:28 | 42 |
53+
| attributes.cs:58:6:58:8 | [My2(...)] | 3 | attributes.cs:58:22:58:22 | 1 |
54+
| attributes.cs:58:6:58:8 | [My2(...)] | 4 | attributes.cs:58:39:58:40 | 42 |
5455
| attributes.cs:77:2:77:5 | [Args(...)] | 0 | attributes.cs:77:7:77:8 | 42 |
5556
| attributes.cs:77:2:77:5 | [Args(...)] | 1 | attributes.cs:77:11:77:14 | null |
5657
| attributes.cs:77:2:77:5 | [Args(...)] | 2 | attributes.cs:77:17:77:25 | typeof(...) |
@@ -105,9 +106,10 @@ constructorArguments
105106
| attributes.cs:46:6:46:16 | [Conditional(...)] | 0 | attributes.cs:46:18:46:25 | "DEBUG2" |
106107
| attributes.cs:54:6:54:16 | [My(...)] | 0 | attributes.cs:54:18:54:22 | false |
107108
| attributes.cs:57:6:57:16 | [My(...)] | 0 | attributes.cs:57:18:57:21 | true |
108-
| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:10:58:13 | true |
109-
| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:16:58:20 | false |
109+
| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:28:58:32 | false |
110+
| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:13:58:16 | true |
110111
| attributes.cs:58:6:58:8 | [My2(...)] | 2 | attributes.cs:58:6:58:8 | 12 |
112+
| attributes.cs:58:6:58:8 | [My2(...)] | 3 | attributes.cs:58:22:58:22 | 1 |
111113
| attributes.cs:77:2:77:5 | [Args(...)] | 0 | attributes.cs:77:7:77:8 | 42 |
112114
| attributes.cs:77:2:77:5 | [Args(...)] | 1 | attributes.cs:77:11:77:14 | null |
113115
| attributes.cs:77:2:77:5 | [Args(...)] | 2 | attributes.cs:77:17:77:25 | typeof(...) |
@@ -126,6 +128,6 @@ namedArguments
126128
| attributes.cs:41:10:41:13 | [Args(...)] | Prop | attributes.cs:41:90:41:120 | array creation of type Object[] |
127129
| attributes.cs:57:6:57:16 | [My(...)] | x | attributes.cs:57:36:57:36 | 0 |
128130
| attributes.cs:57:6:57:16 | [My(...)] | y | attributes.cs:57:28:57:29 | "" |
129-
| attributes.cs:58:6:58:8 | [My2(...)] | X | attributes.cs:58:27:58:28 | 42 |
131+
| attributes.cs:58:6:58:8 | [My2(...)] | X | attributes.cs:58:39:58:40 | 42 |
130132
| attributes.cs:77:2:77:5 | [Args(...)] | Prop | attributes.cs:77:63:77:93 | array creation of type Object[] |
131133
| attributes.cs:80:6:80:9 | [Args(...)] | Prop | attributes.cs:80:68:80:98 | array creation of type Object[] |

csharp/ql/test/library-tests/attributes/PrintAst.expected

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,10 @@ attributes.cs:
140140
# 57| 2: [IntLiteral] 0
141141
# 58| 2: [Attribute] [My2(...)]
142142
# 58| -1: [TypeMention] My2Attribute
143-
# 58| 0: [BoolLiteral] true
144-
# 58| 1: [BoolLiteral] false
145-
# 58| 3: [IntLiteral] 42
143+
# 58| 0: [BoolLiteral] false
144+
# 58| 1: [BoolLiteral] true
145+
# 58| 3: [IntLiteral] 1
146+
# 58| 4: [IntLiteral] 42
146147
# 59| 4: [BlockStmt] {...}
147148
# 62| [Class] MyAttribute
148149
#-----| 3: (Base types)
@@ -268,4 +269,7 @@ attributes.cs:
268269
# 88| 2: [Parameter] i
269270
# 88| -1: [TypeMention] int
270271
# 88| 1: [IntLiteral] 12
272+
# 88| 3: [Parameter] j
273+
# 88| -1: [TypeMention] int
274+
# 88| 1: [IntLiteral] 13
271275
# 88| 4: [BlockStmt] {...}

csharp/ql/test/library-tests/attributes/attributes.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class Bar
5555
void M1() { }
5656

5757
[MyAttribute(true, y = "", x = 0)]
58-
[My2(true, false, X = 42)]
58+
[My2(b: true, j: 1, a: false, X = 42)]
5959
void M2() { }
6060
}
6161

@@ -85,5 +85,5 @@ public class X
8585
class My2Attribute : Attribute
8686
{
8787
public int X { get; set; }
88-
public My2Attribute(bool a, bool b, int i = 12) { }
88+
public My2Attribute(bool a, bool b, int i = 12, int j = 13) { }
8989
}

0 commit comments

Comments
 (0)