Skip to content

Commit b9c8975

Browse files
authored
Merge pull request github#14493 from tamasvajk/fix/params-attribute-argument
C#: Fix params attribute argument extraction
2 parents 342b3d7 + 791a642 commit b9c8975

File tree

5 files changed

+140
-0
lines changed

5 files changed

+140
-0
lines changed

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,16 @@ private void ExtractArguments(TextWriter trapFile)
8282
var paramName = Symbol.AttributeConstructor?.Parameters[i].Name;
8383
var argSyntax = ctorArguments?.SingleOrDefault(a => a.NameColon is not null && a.NameColon.Name.Identifier.Text == paramName);
8484

85+
var isParamsParameter = false;
86+
8587
if (argSyntax is null && // couldn't find named argument
8688
ctorArguments?.Count > childIndex && // there're more arguments
8789
ctorArguments[childIndex].NameColon is null) // the argument is positional
8890
{
91+
// The current argument is not named
92+
// so the previous ones were also not named
93+
// so the child index matches the parameter index.
94+
isParamsParameter = Symbol?.AttributeConstructor?.Parameters[childIndex].IsParams == true;
8995
argSyntax = ctorArguments[childIndex];
9096
}
9197

@@ -94,6 +100,28 @@ private void ExtractArguments(TextWriter trapFile)
94100
argSyntax?.Expression,
95101
this,
96102
childIndex++);
103+
104+
if (isParamsParameter &&
105+
ctorArguments is not null)
106+
{
107+
// The current argument is a params argument, so we're processing all the remaining arguments:
108+
while (childIndex < ctorArguments.Count)
109+
{
110+
if (ctorArguments[childIndex].Expression is null)
111+
{
112+
// This shouldn't happen
113+
continue;
114+
}
115+
116+
CreateExpressionFromArgument(
117+
constructorArgument,
118+
ctorArguments[childIndex].Expression,
119+
this,
120+
childIndex);
121+
122+
childIndex++;
123+
}
124+
}
97125
}
98126

99127
foreach (var namedArgument in Symbol.NamedArguments)

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,22 @@ arguments
9090
| attributes.cs:125:18:125:29 | [return: My3(...)] | 0 | attributes.cs:125:31:125:32 | 12 |
9191
| attributes.cs:128:10:128:21 | [My3(...)] | 0 | attributes.cs:128:23:128:24 | 13 |
9292
| attributes.cs:129:17:129:28 | [My3(...)] | 0 | attributes.cs:129:30:129:31 | 14 |
93+
| attributes.cs:141:6:141:11 | [Params(...)] | 0 | attributes.cs:141:13:141:15 | "a" |
94+
| attributes.cs:141:6:141:11 | [Params(...)] | 1 | attributes.cs:141:18:141:20 | "b" |
95+
| attributes.cs:141:6:141:11 | [Params(...)] | 2 | attributes.cs:141:23:141:23 | 1 |
96+
| attributes.cs:141:6:141:11 | [Params(...)] | 3 | attributes.cs:141:26:141:26 | 2 |
97+
| attributes.cs:141:6:141:11 | [Params(...)] | 4 | attributes.cs:141:29:141:29 | 3 |
98+
| attributes.cs:144:6:144:11 | [Params(...)] | 0 | attributes.cs:144:17:144:19 | "a" |
99+
| attributes.cs:144:6:144:11 | [Params(...)] | 1 | attributes.cs:144:26:144:28 | "b" |
100+
| attributes.cs:144:6:144:11 | [Params(...)] | 2 | attributes.cs:144:31:144:31 | 1 |
101+
| attributes.cs:144:6:144:11 | [Params(...)] | 3 | attributes.cs:144:34:144:34 | 2 |
102+
| attributes.cs:144:6:144:11 | [Params(...)] | 4 | attributes.cs:144:37:144:37 | 3 |
103+
| attributes.cs:147:6:147:11 | [Params(...)] | 0 | attributes.cs:147:35:147:37 | "a" |
104+
| attributes.cs:147:6:147:11 | [Params(...)] | 1 | attributes.cs:147:26:147:28 | "b" |
105+
| attributes.cs:147:6:147:11 | [Params(...)] | 2 | attributes.cs:147:19:147:19 | 1 |
106+
| attributes.cs:150:6:150:11 | [Params(...)] | 0 | attributes.cs:150:45:150:47 | "a" |
107+
| attributes.cs:150:6:150:11 | [Params(...)] | 1 | attributes.cs:150:36:150:38 | "b" |
108+
| attributes.cs:150:6:150:11 | [Params(...)] | 2 | attributes.cs:150:19:150:29 | array creation of type Int32[] |
93109
constructorArguments
94110
| Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 1 |
95111
| Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 3 |
@@ -170,6 +186,22 @@ constructorArguments
170186
| attributes.cs:125:18:125:29 | [return: My3(...)] | 0 | attributes.cs:125:31:125:32 | 12 |
171187
| attributes.cs:128:10:128:21 | [My3(...)] | 0 | attributes.cs:128:23:128:24 | 13 |
172188
| attributes.cs:129:17:129:28 | [My3(...)] | 0 | attributes.cs:129:30:129:31 | 14 |
189+
| attributes.cs:141:6:141:11 | [Params(...)] | 0 | attributes.cs:141:13:141:15 | "a" |
190+
| attributes.cs:141:6:141:11 | [Params(...)] | 1 | attributes.cs:141:18:141:20 | "b" |
191+
| attributes.cs:141:6:141:11 | [Params(...)] | 2 | attributes.cs:141:23:141:23 | 1 |
192+
| attributes.cs:141:6:141:11 | [Params(...)] | 3 | attributes.cs:141:26:141:26 | 2 |
193+
| attributes.cs:141:6:141:11 | [Params(...)] | 4 | attributes.cs:141:29:141:29 | 3 |
194+
| attributes.cs:144:6:144:11 | [Params(...)] | 0 | attributes.cs:144:17:144:19 | "a" |
195+
| attributes.cs:144:6:144:11 | [Params(...)] | 1 | attributes.cs:144:26:144:28 | "b" |
196+
| attributes.cs:144:6:144:11 | [Params(...)] | 2 | attributes.cs:144:31:144:31 | 1 |
197+
| attributes.cs:144:6:144:11 | [Params(...)] | 3 | attributes.cs:144:34:144:34 | 2 |
198+
| attributes.cs:144:6:144:11 | [Params(...)] | 4 | attributes.cs:144:37:144:37 | 3 |
199+
| attributes.cs:147:6:147:11 | [Params(...)] | 0 | attributes.cs:147:35:147:37 | "a" |
200+
| attributes.cs:147:6:147:11 | [Params(...)] | 1 | attributes.cs:147:26:147:28 | "b" |
201+
| attributes.cs:147:6:147:11 | [Params(...)] | 2 | attributes.cs:147:19:147:19 | 1 |
202+
| attributes.cs:150:6:150:11 | [Params(...)] | 0 | attributes.cs:150:45:150:47 | "a" |
203+
| attributes.cs:150:6:150:11 | [Params(...)] | 1 | attributes.cs:150:36:150:38 | "b" |
204+
| attributes.cs:150:6:150:11 | [Params(...)] | 2 | attributes.cs:150:19:150:29 | array creation of type Int32[] |
173205
namedArguments
174206
| Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] |
175207
| Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] |

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
| attributes.cs:126:9:126:11 | get_Prop1 | attributes.cs:125:18:125:29 | [return: My3(...)] | My3Attribute |
3333
| attributes.cs:130:9:130:11 | set_Prop1 | attributes.cs:128:10:128:21 | [My3(...)] | My3Attribute |
3434
| attributes.cs:130:9:130:11 | value | attributes.cs:129:17:129:28 | [My3(...)] | My3Attribute |
35+
| attributes.cs:142:17:142:18 | M1 | attributes.cs:141:6:141:11 | [Params(...)] | Class1+ParamsAttribute |
36+
| attributes.cs:145:17:145:18 | M2 | attributes.cs:144:6:144:11 | [Params(...)] | Class1+ParamsAttribute |
37+
| attributes.cs:148:17:148:18 | M3 | attributes.cs:147:6:147:11 | [Params(...)] | Class1+ParamsAttribute |
38+
| attributes.cs:151:17:151:18 | M4 | attributes.cs:150:6:150:11 | [Params(...)] | Class1+ParamsAttribute |
3539
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:10:12:10:24 | [assembly: AssemblyTitle(...)] | System.Reflection.AssemblyTitleAttribute |
3640
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:11:12:11:30 | [assembly: AssemblyDescription(...)] | System.Reflection.AssemblyDescriptionAttribute |
3741
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:12:12:12:32 | [assembly: AssemblyConfiguration(...)] | System.Reflection.AssemblyConfigurationAttribute |

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,3 +405,59 @@ attributes.cs:
405405
# 130| 0: [AssignExpr] ... = ...
406406
# 130| 0: [FieldAccess] access to field p
407407
# 130| 1: [ParameterAccess] access to parameter value
408+
# 134| [Class] Class1
409+
# 136| 5: [Class] ParamsAttribute
410+
#-----| 3: (Base types)
411+
# 136| 0: [TypeMention] Attribute
412+
# 138| 4: [InstanceConstructor] ParamsAttribute
413+
#-----| 2: (Parameters)
414+
# 138| 0: [Parameter] s1
415+
# 138| -1: [TypeMention] string
416+
# 138| 1: [Parameter] s2
417+
# 138| -1: [TypeMention] string
418+
# 138| 2: [Parameter] args
419+
# 138| -1: [TypeMention] Int32[]
420+
# 138| 1: [TypeMention] int
421+
# 138| 4: [BlockStmt] {...}
422+
# 142| 6: [Method] M1
423+
# 142| -1: [TypeMention] Void
424+
#-----| 0: (Attributes)
425+
# 141| 1: [DefaultAttribute] [Params(...)]
426+
# 141| -1: [TypeMention] ParamsAttribute
427+
# 141| 0: [StringLiteralUtf16] "a"
428+
# 141| 1: [StringLiteralUtf16] "b"
429+
# 141| 2: [IntLiteral] 1
430+
# 141| 3: [IntLiteral] 2
431+
# 141| 4: [IntLiteral] 3
432+
# 142| 4: [BlockStmt] {...}
433+
# 145| 7: [Method] M2
434+
# 145| -1: [TypeMention] Void
435+
#-----| 0: (Attributes)
436+
# 144| 1: [DefaultAttribute] [Params(...)]
437+
# 144| -1: [TypeMention] ParamsAttribute
438+
# 144| 0: [StringLiteralUtf16] "a"
439+
# 144| 1: [StringLiteralUtf16] "b"
440+
# 144| 2: [IntLiteral] 1
441+
# 144| 3: [IntLiteral] 2
442+
# 144| 4: [IntLiteral] 3
443+
# 145| 4: [BlockStmt] {...}
444+
# 148| 8: [Method] M3
445+
# 148| -1: [TypeMention] Void
446+
#-----| 0: (Attributes)
447+
# 147| 1: [DefaultAttribute] [Params(...)]
448+
# 147| -1: [TypeMention] ParamsAttribute
449+
# 147| 0: [StringLiteralUtf16] "a"
450+
# 147| 1: [StringLiteralUtf16] "b"
451+
# 147| 2: [IntLiteral] 1
452+
# 148| 4: [BlockStmt] {...}
453+
# 151| 9: [Method] M4
454+
# 151| -1: [TypeMention] Void
455+
#-----| 0: (Attributes)
456+
# 150| 1: [DefaultAttribute] [Params(...)]
457+
# 150| -1: [TypeMention] ParamsAttribute
458+
# 150| 0: [StringLiteralUtf16] "a"
459+
# 150| 1: [StringLiteralUtf16] "b"
460+
# 150| 2: [ArrayCreation] array creation of type Int32[]
461+
# 150| -1: [ArrayInitializer] { ..., ... }
462+
# 150| 0: [IntLiteral] 1
463+
# 151| 4: [BlockStmt] {...}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,24 @@ public int Prop1
129129
[param: My3Attribute(14)]
130130
set { p = value; }
131131
}
132+
}
133+
134+
class Class1
135+
{
136+
public class ParamsAttribute : Attribute
137+
{
138+
public ParamsAttribute(string s1, string s2, params int[] args) { }
139+
}
140+
141+
[Params("a", "b", 1, 2, 3)]
142+
public void M1() { }
143+
144+
[Params(s1: "a", s2: "b", 1, 2, 3)]
145+
public void M2() { }
146+
147+
[Params(args: 1, s2: "b", s1: "a")]
148+
public void M3() { }
149+
150+
[Params(args: new[] { 1 }, s2: "b", s1: "a")]
151+
public void M4() { }
132152
}

0 commit comments

Comments
 (0)