@@ -57,60 +57,29 @@ class Call extends DotNet::Call, Expr, @call {
5757 *
5858 * This takes into account both positional and named arguments, but does not
5959 * consider default arguments.
60- *
61- * An argument must always have a type that is convertible to the relevant
62- * parameter type. Therefore, `params` arguments are only taken into account
63- * when they are passed as explicit arrays. For example, in the call to `M1`
64- * on line 5, `o` is not an argument for `M1`'s `args` parameter, while
65- * `new object[] { o }` on line 6 is, in
66- *
67- * ```csharp
68- * class C {
69- * void M1(params object[] args) { }
70- *
71- * void M2(object o) {
72- * M1(o);
73- * M1(new object[] { o });
74- * }
75- * }
76- * ```
7760 */
7861 cached
7962 override Expr getArgumentForParameter ( DotNet:: Parameter p ) {
8063 this .getTarget ( ) .getAParameter ( ) = p and
8164 (
8265 // Appears in the positional part of the call
83- result = this .getImplicitArgument ( p .getPosition ( ) ) and
84- (
85- p .( Parameter ) .isParams ( )
86- implies
87- (
88- isValidExplicitParamsType ( p , result .getType ( ) ) and
89- not this .hasMultipleParamsArguments ( )
90- )
91- )
66+ result = this .getImplicitArgument ( p )
9267 or
9368 // Appears in the named part of the call
94- result = this .getExplicitArgument ( p .getName ( ) ) and
95- ( p .( Parameter ) .isParams ( ) implies isValidExplicitParamsType ( p , result .getType ( ) ) )
96- )
97- }
98-
99- /**
100- * Holds if this call has multiple arguments for a `params` parameter
101- * of the targeted callable.
102- */
103- private predicate hasMultipleParamsArguments ( ) {
104- exists ( Parameter p | p = this .getTarget ( ) .getAParameter ( ) |
105- p .isParams ( ) and
106- exists ( this .getArgument ( any ( int i | i > p .getPosition ( ) ) ) )
69+ result = this .getExplicitArgument ( p .getName ( ) )
10770 )
10871 }
10972
11073 pragma [ noinline]
111- private Expr getImplicitArgument ( int pos ) {
112- result = this .getArgument ( pos ) and
113- not exists ( result .getExplicitArgumentName ( ) )
74+ private Expr getImplicitArgument ( DotNet:: Parameter p ) {
75+ not exists ( result .getExplicitArgumentName ( ) ) and
76+ (
77+ p .( Parameter ) .isParams ( ) and
78+ result = this .getArgument ( any ( int i | i >= p .getPosition ( ) ) )
79+ or
80+ not p .( Parameter ) .isParams ( ) and
81+ result = this .getArgument ( p .getPosition ( ) )
82+ )
11483 }
11584
11685 pragma [ nomagic]
@@ -254,28 +223,6 @@ class Call extends DotNet::Call, Expr, @call {
254223 override string toString ( ) { result = "call" }
255224}
256225
257- /**
258- * Holds if the type `t` is a valid argument type for passing an explicit array
259- * to the `params` parameter `p`. For example, the types `object[]` and `string[]`
260- * of the arguments on lines 4 and 5, respectively, are valid for the parameter
261- * `args` on line 1 in
262- *
263- * ```csharp
264- * void M(params object[] args) { ... }
265- *
266- * void CallM(object[] os, string[] ss, string s) {
267- * M(os);
268- * M(ss);
269- * M(s);
270- * }
271- * ```
272- */
273- pragma [ nomagic]
274- private predicate isValidExplicitParamsType ( Parameter p , Type t ) {
275- p .isParams ( ) and
276- t .isImplicitlyConvertibleTo ( p .getType ( ) )
277- }
278-
279226/**
280227 * A method call, for example `a.M()` on line 5 in
281228 *
0 commit comments