Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e0afaa4

Browse files
tamasvajkigfoo
authored andcommitted
Fix Parameter.getACallArgument for parameters of extension methods
1 parent 1e8d077 commit e0afaa4

5 files changed

Lines changed: 81 additions & 5 deletions

File tree

java/ql/lib/semmle/code/java/ControlFlowGraph.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,13 +558,13 @@ private module ControlFlowGraphImpl {
558558
or
559559
exists(ExtensionMethodAccess e | e = this |
560560
// the actual qualifier of the expression method access
561-
index = -1 and result.(Expr).isNthChildOf(this, index)
561+
index = -1 and result.(Expr).isNthChildOf(this, index) and not result instanceof TypeAccess
562562
or
563563
// the extension receiver
564564
index = 0 and result = e.getQualifier()
565565
or
566566
// the arguments
567-
result = e.getArgument(index)
567+
result = e.getArgument(index - 1)
568568
)
569569
or
570570
exists(StringTemplateExpr e | e = this | result = e.getComponent(index))

java/ql/lib/semmle/code/java/Expr.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,9 +1994,9 @@ class ExtensionMethodAccess extends MethodAccess {
19941994
// whereas the actual arguments begin at index 1.
19951995
override Expr getQualifier() { result.isNthChildOf(this, 0) }
19961996

1997-
override Expr getAnArgument() { result.getIndex() >= 1 and result.getParent() = this }
1997+
override Expr getAnArgument() { result = getArgument(_) }
19981998

1999-
override Expr getArgument(int index) { result = super.getArgument(index + 1) }
1999+
override Expr getArgument(int index) { result = super.getArgument(index + 1) and index >= 0 }
20002000
}
20012001

20022002
/** A type access is a (possibly qualified) reference to a type. */

java/ql/lib/semmle/code/java/Variable.qll

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ class Parameter extends Element, @param, LocalScopeVariable {
8989
/** Holds if this formal parameter is a variable arity parameter. */
9090
predicate isVarargs() { isVarargsParam(this) }
9191

92+
/** Holds if this formal parameter is a parameter representing the dispatch receiver in an extension method. */
93+
predicate isExtensionParameter() {
94+
getPosition() = 0 and this.getCallable() instanceof ExtensionMethod
95+
}
96+
9297
/**
9398
* Gets an argument for this parameter in any call to the callable that declares this formal
9499
* parameter.
@@ -103,7 +108,20 @@ class Parameter extends Element, @param, LocalScopeVariable {
103108
pragma[noinline]
104109
private Expr getACallArgument(int i) {
105110
exists(Call call |
106-
result = call.getArgument(i) and
111+
(
112+
exists(int idx |
113+
(
114+
idx = i and not call instanceof ExtensionMethodAccess
115+
or
116+
idx = i - 1 and call instanceof ExtensionMethodAccess
117+
) and
118+
result = call.getArgument(idx)
119+
)
120+
or
121+
i = 0 and
122+
call instanceof ExtensionMethodAccess and
123+
result = call.getQualifier()
124+
) and
107125
call.getCallee().getSourceDeclaration().getAParameter() = this
108126
)
109127
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
parametersWithArgs
2+
| extensions.kt:3:25:3:34 | p1 | 0 | extensions.kt:21:34:21:36 | foo |
3+
| extensions.kt:6:28:6:37 | p1 | 0 | extensions.kt:25:40:25:42 | foo |
4+
| extensions.kt:9:5:9:13 | <this> | 0 | extensions.kt:22:5:22:15 | new SomeClass(...) |
5+
| extensions.kt:9:23:9:32 | p1 | 1 | extensions.kt:22:26:22:28 | foo |
6+
| extensions.kt:10:5:10:16 | <this> | 0 | extensions.kt:26:5:26:18 | new AnotherClass(...) |
7+
| extensions.kt:10:29:10:38 | p1 | 1 | extensions.kt:26:32:26:34 | foo |
8+
| extensions.kt:12:5:12:13 | <this> | 0 | extensions.kt:23:5:23:15 | new SomeClass(...) |
9+
| extensions.kt:12:23:12:32 | p1 | 1 | extensions.kt:23:26:23:28 | foo |
10+
| extensions.kt:13:5:13:16 | <this> | 0 | extensions.kt:27:5:27:18 | new AnotherClass(...) |
11+
| extensions.kt:13:26:13:35 | p1 | 1 | extensions.kt:27:29:27:31 | foo |
12+
| extensions.kt:15:5:15:13 | <this> | 0 | extensions.kt:24:5:24:15 | new SomeClass(...) |
13+
| extensions.kt:15:32:15:38 | p1 | 1 | extensions.kt:24:34:24:34 | 1 |
14+
| extensions.kt:16:5:16:16 | <this> | 0 | extensions.kt:28:5:28:18 | new AnotherClass(...) |
15+
| extensions.kt:16:35:16:44 | p1 | 1 | extensions.kt:28:38:28:40 | foo |
16+
| extensions.kt:18:5:18:10 | <this> | 0 | extensions.kt:29:6:29:15 | someString |
17+
| extensions.kt:18:16:18:25 | p1 | 1 | extensions.kt:29:23:29:25 | foo |
18+
| extensions.kt:30:9:30:14 | <this> | 0 | extensions.kt:31:6:31:15 | someString |
19+
| extensions.kt:30:20:30:29 | p1 | 1 | extensions.kt:31:23:31:30 | bazParam |
20+
extensionParameter
21+
| extensions.kt:9:5:9:13 | <this> |
22+
| extensions.kt:10:5:10:16 | <this> |
23+
| extensions.kt:12:5:12:13 | <this> |
24+
| extensions.kt:13:5:13:16 | <this> |
25+
| extensions.kt:15:5:15:13 | <this> |
26+
| extensions.kt:16:5:16:16 | <this> |
27+
| extensions.kt:18:5:18:10 | <this> |
28+
| extensions.kt:30:9:30:14 | <this> |
29+
#select
30+
| extensions.kt:3:5:3:38 | someClassMethod | extensions.kt:3:25:3:34 | p1 | 0 |
31+
| extensions.kt:6:5:6:41 | anotherClassMethod | extensions.kt:6:28:6:37 | p1 | 0 |
32+
| extensions.kt:9:1:9:36 | someFun | extensions.kt:9:5:9:13 | <this> | 0 |
33+
| extensions.kt:9:1:9:36 | someFun | extensions.kt:9:23:9:32 | p1 | 1 |
34+
| extensions.kt:10:1:10:42 | anotherFun | extensions.kt:10:5:10:16 | <this> | 0 |
35+
| extensions.kt:10:1:10:42 | anotherFun | extensions.kt:10:29:10:38 | p1 | 1 |
36+
| extensions.kt:12:1:12:36 | bothFun | extensions.kt:12:5:12:13 | <this> | 0 |
37+
| extensions.kt:12:1:12:36 | bothFun | extensions.kt:12:23:12:32 | p1 | 1 |
38+
| extensions.kt:13:1:13:39 | bothFun | extensions.kt:13:5:13:16 | <this> | 0 |
39+
| extensions.kt:13:1:13:39 | bothFun | extensions.kt:13:26:13:35 | p1 | 1 |
40+
| extensions.kt:15:1:15:57 | bothFunDiffTypes | extensions.kt:15:5:15:13 | <this> | 0 |
41+
| extensions.kt:15:1:15:57 | bothFunDiffTypes | extensions.kt:15:32:15:38 | p1 | 1 |
42+
| extensions.kt:16:1:16:70 | bothFunDiffTypes | extensions.kt:16:5:16:16 | <this> | 0 |
43+
| extensions.kt:16:1:16:70 | bothFunDiffTypes | extensions.kt:16:35:16:44 | p1 | 1 |
44+
| extensions.kt:18:1:18:51 | bar | extensions.kt:18:5:18:10 | <this> | 0 |
45+
| extensions.kt:18:1:18:51 | bar | extensions.kt:18:16:18:25 | p1 | 1 |
46+
| extensions.kt:30:5:30:55 | baz | extensions.kt:30:9:30:14 | <this> | 0 |
47+
| extensions.kt:30:5:30:55 | baz | extensions.kt:30:20:30:29 | p1 | 1 |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import java
2+
3+
from Method m, int n
4+
where m.fromSource()
5+
select m, m.getParameter(n), n
6+
7+
query predicate parametersWithArgs(Parameter p, int idx, Expr arg) {
8+
p.fromSource() and p.getPosition() = idx and p.getAnArgument() = arg
9+
}
10+
11+
query predicate extensionParameter(Parameter p) { p.isExtensionParameter() }

0 commit comments

Comments
 (0)