C#: Fix attribute argument extraction when default argument value is present

This commit is contained in:
Tamas Vajk
2021-01-04 14:14:57 +01:00
parent 6d95ad3282
commit 44372f4db7
5 changed files with 175 additions and 129 deletions

View File

@@ -66,12 +66,18 @@ namespace Semmle.Extraction.CSharp.Entities
private void ExtractArguments(TextWriter trapFile)
{
var ctorArguments = attributeSyntax?.ArgumentList?.Arguments.Where(a => a.NameEquals == null).ToList();
var childIndex = 0;
foreach (var constructorArgument in symbol.ConstructorArguments)
{
var argSyntax = ctorArguments?.Count > childIndex
? ctorArguments[childIndex]
: null;
CreateExpressionFromArgument(
constructorArgument,
attributeSyntax?.ArgumentList.Arguments[childIndex].Expression,
argSyntax?.Expression,
this,
childIndex++);
}

View File

@@ -47,18 +47,22 @@ arguments
| attributes.cs:57:6:57:16 | [My(...)] | 0 | attributes.cs:57:18:57:21 | true |
| attributes.cs:57:6:57:16 | [My(...)] | 1 | attributes.cs:57:28:57:29 | "" |
| attributes.cs:57:6:57:16 | [My(...)] | 2 | attributes.cs:57:36:57:36 | 0 |
| attributes.cs:76:2:76:5 | [Args(...)] | 0 | attributes.cs:76:7:76:8 | 42 |
| attributes.cs:76:2:76:5 | [Args(...)] | 1 | attributes.cs:76:11:76:14 | null |
| attributes.cs:76:2:76:5 | [Args(...)] | 2 | attributes.cs:76:17:76:25 | typeof(...) |
| attributes.cs:76:2:76:5 | [Args(...)] | 3 | attributes.cs:76:28:76:30 | access to constant A |
| attributes.cs:76:2:76:5 | [Args(...)] | 4 | attributes.cs:76:33:76:53 | array creation of type Int32[] |
| attributes.cs:76:2:76:5 | [Args(...)] | 5 | attributes.cs:76:63:76:93 | array creation of type Object[] |
| attributes.cs:79:6:79:9 | [Args(...)] | 0 | attributes.cs:79:11:79:16 | ... + ... |
| attributes.cs:79:6:79:9 | [Args(...)] | 1 | attributes.cs:79:19:79:39 | array creation of type Int32[] |
| attributes.cs:79:6:79:9 | [Args(...)] | 2 | attributes.cs:79:42:79:45 | null |
| attributes.cs:79:6:79:9 | [Args(...)] | 3 | attributes.cs:79:48:79:52 | (...) ... |
| attributes.cs:79:6:79:9 | [Args(...)] | 4 | attributes.cs:79:55:79:58 | null |
| attributes.cs:79:6:79:9 | [Args(...)] | 5 | attributes.cs:79:68:79:98 | array creation of type Object[] |
| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:10:58:13 | true |
| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:16:58:20 | false |
| attributes.cs:58:6:58:8 | [My2(...)] | 2 | attributes.cs:58:6:58:8 | 12 |
| attributes.cs:58:6:58:8 | [My2(...)] | 3 | attributes.cs:58:27:58:28 | 42 |
| attributes.cs:77:2:77:5 | [Args(...)] | 0 | attributes.cs:77:7:77:8 | 42 |
| attributes.cs:77:2:77:5 | [Args(...)] | 1 | attributes.cs:77:11:77:14 | null |
| attributes.cs:77:2:77:5 | [Args(...)] | 2 | attributes.cs:77:17:77:25 | typeof(...) |
| attributes.cs:77:2:77:5 | [Args(...)] | 3 | attributes.cs:77:28:77:30 | access to constant A |
| attributes.cs:77:2:77:5 | [Args(...)] | 4 | attributes.cs:77:33:77:53 | array creation of type Int32[] |
| attributes.cs:77:2:77:5 | [Args(...)] | 5 | attributes.cs:77:63:77:93 | array creation of type Object[] |
| attributes.cs:80:6:80:9 | [Args(...)] | 0 | attributes.cs:80:11:80:16 | ... + ... |
| attributes.cs:80:6:80:9 | [Args(...)] | 1 | attributes.cs:80:19:80:39 | array creation of type Int32[] |
| attributes.cs:80:6:80:9 | [Args(...)] | 2 | attributes.cs:80:42:80:45 | null |
| attributes.cs:80:6:80:9 | [Args(...)] | 3 | attributes.cs:80:48:80:52 | (...) ... |
| attributes.cs:80:6:80:9 | [Args(...)] | 4 | attributes.cs:80:55:80:58 | null |
| attributes.cs:80:6:80:9 | [Args(...)] | 5 | attributes.cs:80:68:80:98 | array creation of type Object[] |
constructorArguments
| Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 1 |
| Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 3 |
@@ -101,16 +105,19 @@ constructorArguments
| attributes.cs:46:6:46:16 | [Conditional(...)] | 0 | attributes.cs:46:18:46:25 | "DEBUG2" |
| attributes.cs:54:6:54:16 | [My(...)] | 0 | attributes.cs:54:18:54:22 | false |
| attributes.cs:57:6:57:16 | [My(...)] | 0 | attributes.cs:57:18:57:21 | true |
| attributes.cs:76:2:76:5 | [Args(...)] | 0 | attributes.cs:76:7:76:8 | 42 |
| attributes.cs:76:2:76:5 | [Args(...)] | 1 | attributes.cs:76:11:76:14 | null |
| attributes.cs:76:2:76:5 | [Args(...)] | 2 | attributes.cs:76:17:76:25 | typeof(...) |
| attributes.cs:76:2:76:5 | [Args(...)] | 3 | attributes.cs:76:28:76:30 | access to constant A |
| attributes.cs:76:2:76:5 | [Args(...)] | 4 | attributes.cs:76:33:76:53 | array creation of type Int32[] |
| attributes.cs:79:6:79:9 | [Args(...)] | 0 | attributes.cs:79:11:79:16 | ... + ... |
| attributes.cs:79:6:79:9 | [Args(...)] | 1 | attributes.cs:79:19:79:39 | array creation of type Int32[] |
| attributes.cs:79:6:79:9 | [Args(...)] | 2 | attributes.cs:79:42:79:45 | null |
| attributes.cs:79:6:79:9 | [Args(...)] | 3 | attributes.cs:79:48:79:52 | (...) ... |
| attributes.cs:79:6:79:9 | [Args(...)] | 4 | attributes.cs:79:55:79:58 | null |
| attributes.cs:58:6:58:8 | [My2(...)] | 0 | attributes.cs:58:10:58:13 | true |
| attributes.cs:58:6:58:8 | [My2(...)] | 1 | attributes.cs:58:16:58:20 | false |
| attributes.cs:58:6:58:8 | [My2(...)] | 2 | attributes.cs:58:6:58:8 | 12 |
| attributes.cs:77:2:77:5 | [Args(...)] | 0 | attributes.cs:77:7:77:8 | 42 |
| attributes.cs:77:2:77:5 | [Args(...)] | 1 | attributes.cs:77:11:77:14 | null |
| attributes.cs:77:2:77:5 | [Args(...)] | 2 | attributes.cs:77:17:77:25 | typeof(...) |
| attributes.cs:77:2:77:5 | [Args(...)] | 3 | attributes.cs:77:28:77:30 | access to constant A |
| attributes.cs:77:2:77:5 | [Args(...)] | 4 | attributes.cs:77:33:77:53 | array creation of type Int32[] |
| attributes.cs:80:6:80:9 | [Args(...)] | 0 | attributes.cs:80:11:80:16 | ... + ... |
| attributes.cs:80:6:80:9 | [Args(...)] | 1 | attributes.cs:80:19:80:39 | array creation of type Int32[] |
| attributes.cs:80:6:80:9 | [Args(...)] | 2 | attributes.cs:80:42:80:45 | null |
| attributes.cs:80:6:80:9 | [Args(...)] | 3 | attributes.cs:80:48:80:52 | (...) ... |
| attributes.cs:80:6:80:9 | [Args(...)] | 4 | attributes.cs:80:55:80:58 | null |
namedArguments
| Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] |
| Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] |
@@ -119,5 +126,6 @@ namedArguments
| attributes.cs:41:10:41:13 | [Args(...)] | Prop | attributes.cs:41:90:41:120 | array creation of type Object[] |
| attributes.cs:57:6:57:16 | [My(...)] | x | attributes.cs:57:36:57:36 | 0 |
| attributes.cs:57:6:57:16 | [My(...)] | y | attributes.cs:57:28:57:29 | "" |
| attributes.cs:76:2:76:5 | [Args(...)] | Prop | attributes.cs:76:63:76:93 | array creation of type Object[] |
| attributes.cs:79:6:79:9 | [Args(...)] | Prop | attributes.cs:79:68:79:98 | array creation of type Object[] |
| attributes.cs:58:6:58:8 | [My2(...)] | X | attributes.cs:58:27:58:28 | 42 |
| attributes.cs:77:2:77:5 | [Args(...)] | Prop | attributes.cs:77:63:77:93 | array creation of type Object[] |
| attributes.cs:80:6:80:9 | [Args(...)] | Prop | attributes.cs:80:68:80:98 | array creation of type Object[] |

View File

@@ -13,9 +13,10 @@
| attributes.cs:47:17:47:19 | foo | attributes.cs:46:6:46:16 | [Conditional(...)] | System.Diagnostics.ConditionalAttribute |
| attributes.cs:52:23:52:23 | x | attributes.cs:52:14:52:16 | [Foo(...)] | Foo |
| attributes.cs:55:10:55:11 | M1 | attributes.cs:54:6:54:16 | [My(...)] | MyAttribute |
| attributes.cs:58:10:58:11 | M2 | attributes.cs:57:6:57:16 | [My(...)] | MyAttribute |
| attributes.cs:77:14:77:14 | X | attributes.cs:76:2:76:5 | [Args(...)] | ArgsAttribute |
| attributes.cs:81:9:81:18 | SomeMethod | attributes.cs:79:6:79:9 | [Args(...)] | ArgsAttribute |
| attributes.cs:59:10:59:11 | M2 | attributes.cs:57:6:57:16 | [My(...)] | MyAttribute |
| attributes.cs:59:10:59:11 | M2 | attributes.cs:58:6:58:8 | [My2(...)] | My2Attribute |
| attributes.cs:78:14:78:14 | X | attributes.cs:77:2:77:5 | [Args(...)] | ArgsAttribute |
| attributes.cs:82:9:82:18 | SomeMethod | attributes.cs:80:6:80:9 | [Args(...)] | ArgsAttribute |
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:10:12:10:24 | [AssemblyTitle(...)] | System.Reflection.AssemblyTitleAttribute |
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:11:12:11:30 | [AssemblyDescription(...)] | System.Reflection.AssemblyDescriptionAttribute |
| attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:12:12:12:32 | [AssemblyConfiguration(...)] | System.Reflection.AssemblyConfigurationAttribute |

View File

@@ -130,118 +130,142 @@ attributes.cs:
# 54| -1: [TypeMention] MyAttribute
# 54| 0: [BoolLiteral] false
# 55| 4: [BlockStmt] {...}
# 58| 7: [Method] M2
# 58| -1: [TypeMention] Void
# 59| 7: [Method] M2
# 59| -1: [TypeMention] Void
#-----| 0: (Attributes)
# 57| 1: [Attribute] [My(...)]
# 57| -1: [TypeMention] MyAttribute
# 57| 0: [BoolLiteral] true
# 57| 1: [StringLiteral] ""
# 57| 2: [IntLiteral] 0
# 58| 4: [BlockStmt] {...}
# 61| [Class] MyAttribute
# 58| 2: [Attribute] [My2(...)]
# 58| -1: [TypeMention] My2Attribute
# 58| 0: [BoolLiteral] true
# 58| 1: [BoolLiteral] false
# 58| 3: [IntLiteral] 42
# 59| 4: [BlockStmt] {...}
# 62| [Class] MyAttribute
#-----| 3: (Base types)
# 61| 0: [TypeMention] Attribute
# 63| 4: [Field] x
# 63| -1: [TypeMention] int
# 64| 5: [IndexerProperty] y
# 64| -1: [TypeMention] string
# 64| 3: [Getter] get_y
# 64| 4: [Setter] set_y
# 62| 0: [TypeMention] Attribute
# 64| 4: [Field] x
# 64| -1: [TypeMention] int
# 65| 5: [IndexerProperty] y
# 65| -1: [TypeMention] string
# 65| 3: [Getter] get_y
# 65| 4: [Setter] set_y
#-----| 2: (Parameters)
# 64| 0: [Parameter] value
# 65| 6: [InstanceConstructor] MyAttribute
# 65| 0: [Parameter] value
# 66| 6: [InstanceConstructor] MyAttribute
#-----| 2: (Parameters)
# 65| 0: [Parameter] b
# 65| -1: [TypeMention] bool
# 65| 4: [BlockStmt] {...}
# 68| [Enum] E
# 68| 5: [Field] A
# 68| 1: [AssignExpr] ... = ...
# 68| 0: [MemberConstantAccess] access to constant A
# 68| 1: [IntLiteral] 42
# 70| [Class] ArgsAttribute
# 66| 0: [Parameter] b
# 66| -1: [TypeMention] bool
# 66| 4: [BlockStmt] {...}
# 69| [Enum] E
# 69| 5: [Field] A
# 69| 1: [AssignExpr] ... = ...
# 69| 0: [MemberConstantAccess] access to constant A
# 69| 1: [IntLiteral] 42
# 71| [Class] ArgsAttribute
#-----| 3: (Base types)
# 70| 0: [TypeMention] Attribute
# 72| 4: [Property] Prop
# 72| -1: [TypeMention] Object[]
# 72| 1: [TypeMention] object
# 72| 3: [Getter] get_Prop
# 72| 4: [Setter] set_Prop
# 71| 0: [TypeMention] Attribute
# 73| 4: [Property] Prop
# 73| -1: [TypeMention] Object[]
# 73| 1: [TypeMention] object
# 73| 3: [Getter] get_Prop
# 73| 4: [Setter] set_Prop
#-----| 2: (Parameters)
# 72| 0: [Parameter] value
# 73| 5: [InstanceConstructor] ArgsAttribute
# 73| 0: [Parameter] value
# 74| 5: [InstanceConstructor] ArgsAttribute
#-----| 2: (Parameters)
# 73| 0: [Parameter] i
# 73| -1: [TypeMention] int
# 73| 1: [Parameter] o
# 73| -1: [TypeMention] object
# 73| 2: [Parameter] t
# 73| -1: [TypeMention] Type
# 73| 3: [Parameter] e
# 73| -1: [TypeMention] E
# 73| 4: [Parameter] arr
# 73| -1: [TypeMention] Int32[]
# 73| 1: [TypeMention] int
# 73| 4: [BlockStmt] {...}
# 77| [Class] X
# 74| 0: [Parameter] i
# 74| -1: [TypeMention] int
# 74| 1: [Parameter] o
# 74| -1: [TypeMention] object
# 74| 2: [Parameter] t
# 74| -1: [TypeMention] Type
# 74| 3: [Parameter] e
# 74| -1: [TypeMention] E
# 74| 4: [Parameter] arr
# 74| -1: [TypeMention] Int32[]
# 74| 1: [TypeMention] int
# 74| 4: [BlockStmt] {...}
# 78| [Class] X
#-----| 0: (Attributes)
# 76| 1: [Attribute] [Args(...)]
# 76| -1: [TypeMention] ArgsAttribute
# 76| 0: [IntLiteral] 42
# 76| 1: [NullLiteral] null
# 76| 2: [TypeofExpr] typeof(...)
# 76| 0: [TypeAccess] access to type X
# 76| 0: [TypeMention] X
# 76| 3: [MemberConstantAccess] access to constant A
# 76| -1: [TypeAccess] access to type E
# 76| 0: [TypeMention] E
# 76| 4: [ArrayCreation] array creation of type Int32[]
# 76| -2: [TypeMention] Int32[]
# 76| 1: [TypeMention] int
# 76| -1: [ArrayInitializer] { ..., ... }
# 76| 0: [IntLiteral] 1
# 76| 1: [IntLiteral] 2
# 76| 2: [IntLiteral] 3
# 76| 5: [ArrayCreation] array creation of type Object[]
# 76| -2: [TypeMention] Object[]
# 76| 1: [TypeMention] object
# 76| -1: [ArrayInitializer] { ..., ... }
# 76| 0: [CastExpr] (...) ...
# 76| 1: [IntLiteral] 1
# 76| 1: [TypeofExpr] typeof(...)
# 76| 0: [TypeAccess] access to type Int32
# 76| 0: [TypeMention] int
# 81| 5: [Method] SomeMethod
# 81| -1: [TypeMention] int
# 77| 1: [Attribute] [Args(...)]
# 77| -1: [TypeMention] ArgsAttribute
# 77| 0: [IntLiteral] 42
# 77| 1: [NullLiteral] null
# 77| 2: [TypeofExpr] typeof(...)
# 77| 0: [TypeAccess] access to type X
# 77| 0: [TypeMention] X
# 77| 3: [MemberConstantAccess] access to constant A
# 77| -1: [TypeAccess] access to type E
# 77| 0: [TypeMention] E
# 77| 4: [ArrayCreation] array creation of type Int32[]
# 77| -2: [TypeMention] Int32[]
# 77| 1: [TypeMention] int
# 77| -1: [ArrayInitializer] { ..., ... }
# 77| 0: [IntLiteral] 1
# 77| 1: [IntLiteral] 2
# 77| 2: [IntLiteral] 3
# 77| 5: [ArrayCreation] array creation of type Object[]
# 77| -2: [TypeMention] Object[]
# 77| 1: [TypeMention] object
# 77| -1: [ArrayInitializer] { ..., ... }
# 77| 0: [CastExpr] (...) ...
# 77| 1: [IntLiteral] 1
# 77| 1: [TypeofExpr] typeof(...)
# 77| 0: [TypeAccess] access to type Int32
# 77| 0: [TypeMention] int
# 82| 5: [Method] SomeMethod
# 82| -1: [TypeMention] int
#-----| 0: (Attributes)
# 79| 1: [Attribute] [Args(...)]
# 79| -1: [TypeMention] ArgsAttribute
# 79| 0: [AddExpr] ... + ...
# 79| 0: [IntLiteral] 42
# 79| 1: [IntLiteral] 0
# 79| 1: [ArrayCreation] array creation of type Int32[]
# 79| -2: [TypeMention] Int32[]
# 79| 1: [TypeMention] int
# 79| -1: [ArrayInitializer] { ..., ... }
# 79| 0: [IntLiteral] 1
# 79| 1: [IntLiteral] 2
# 79| 2: [IntLiteral] 3
# 79| 2: [NullLiteral] null
# 79| 3: [CastExpr] (...) ...
# 79| 0: [TypeAccess] access to type E
# 79| 0: [TypeMention] E
# 79| 1: [IntLiteral] 12
# 79| 4: [NullLiteral] null
# 79| 5: [ArrayCreation] array creation of type Object[]
# 79| -2: [TypeMention] Object[]
# 79| 1: [TypeMention] object
# 79| -1: [ArrayInitializer] { ..., ... }
# 79| 0: [CastExpr] (...) ...
# 79| 1: [IntLiteral] 1
# 79| 1: [TypeofExpr] typeof(...)
# 79| 0: [TypeAccess] access to type Int32
# 79| 0: [TypeMention] int
# 81| 4: [BlockStmt] {...}
# 81| 0: [ReturnStmt] return ...;
# 81| 0: [IntLiteral] 1
# 80| 1: [Attribute] [Args(...)]
# 80| -1: [TypeMention] ArgsAttribute
# 80| 0: [AddExpr] ... + ...
# 80| 0: [IntLiteral] 42
# 80| 1: [IntLiteral] 0
# 80| 1: [ArrayCreation] array creation of type Int32[]
# 80| -2: [TypeMention] Int32[]
# 80| 1: [TypeMention] int
# 80| -1: [ArrayInitializer] { ..., ... }
# 80| 0: [IntLiteral] 1
# 80| 1: [IntLiteral] 2
# 80| 2: [IntLiteral] 3
# 80| 2: [NullLiteral] null
# 80| 3: [CastExpr] (...) ...
# 80| 0: [TypeAccess] access to type E
# 80| 0: [TypeMention] E
# 80| 1: [IntLiteral] 12
# 80| 4: [NullLiteral] null
# 80| 5: [ArrayCreation] array creation of type Object[]
# 80| -2: [TypeMention] Object[]
# 80| 1: [TypeMention] object
# 80| -1: [ArrayInitializer] { ..., ... }
# 80| 0: [CastExpr] (...) ...
# 80| 1: [IntLiteral] 1
# 80| 1: [TypeofExpr] typeof(...)
# 80| 0: [TypeAccess] access to type Int32
# 80| 0: [TypeMention] int
# 82| 4: [BlockStmt] {...}
# 82| 0: [ReturnStmt] return ...;
# 82| 0: [IntLiteral] 1
# 85| [Class] My2Attribute
#-----| 3: (Base types)
# 85| 0: [TypeMention] Attribute
# 87| 4: [Property] X
# 87| -1: [TypeMention] int
# 87| 3: [Getter] get_X
# 87| 4: [Setter] set_X
#-----| 2: (Parameters)
# 87| 0: [Parameter] value
# 88| 5: [InstanceConstructor] My2Attribute
#-----| 2: (Parameters)
# 88| 0: [Parameter] a
# 88| -1: [TypeMention] bool
# 88| 1: [Parameter] b
# 88| -1: [TypeMention] bool
# 88| 2: [Parameter] i
# 88| -1: [TypeMention] int
# 88| 1: [IntLiteral] 12
# 88| 4: [BlockStmt] {...}

View File

@@ -55,6 +55,7 @@ class Bar
void M1() { }
[MyAttribute(true, y = "", x = 0)]
[My2(true, false, X = 42)]
void M2() { }
}
@@ -80,3 +81,9 @@ public class X
[return: Args(42 + 0, new int[] { 1, 2, 3 }, null, (E)12, null, Prop = new object[] { 1, typeof(int) })]
int SomeMethod() { return 1; }
}
class My2Attribute : Attribute
{
public int X { get; set; }
public My2Attribute(bool a, bool b, int i = 12) { }
}