Track lambda parameters in inbound data flow analysis

This commit is contained in:
Valentin Kipyatkov
2020-04-10 16:18:07 +03:00
parent 799b2d7291
commit c19a16f1e0
33 changed files with 404 additions and 35 deletions
@@ -1,4 +1,4 @@
8 val x = foo(1, 2) { { <bold>it</bold> } }
8 val x = foo(1, <bold>2</bold>) { { it } }
8 val <bold>x = foo(1, 2) { { it } }</bold>
8 val x = <bold>foo(1, 2) { { it } }</bold>
3 fun <bold>foo(a: Int, b: Int, f: (Int) -> (Int) -> Int): Int {</bold>
@@ -11,4 +11,13 @@
8 [LAMBDA] val x = foo(1, 2) { <bold>{ it }</bold> }
8 val x = foo(1, 2) { <bold>{ it }</bold> }
8 val x = foo(1, 2) { { <bold>it</bold> } }
8 [LAMBDA CALLS] val x = foo(1, 2) { <bold>{ it }</bold> }
8 [LAMBDA CALLS] val x = foo(1, 2) <bold>{ { it } }</bold>
8 [LAMBDA] [LAMBDA CALLS] val x = foo(1, 2) <bold>{ { it } }</bold>
3 [LAMBDA] [LAMBDA CALLS] fun foo(a: Int, b: Int, <bold>f: (Int) -> (Int) -> Int</bold>): Int {
4 [LAMBDA] [LAMBDA CALLS] return <bold>f</bold>(a)(b)
4 [LAMBDA CALLS] return <bold>f(a)</bold>(b)
4 return f(a)(<bold>b</bold>)
3 fun foo(a: Int, <bold>b: Int</bold>, f: (Int) -> (Int) -> Int): Int {
8 val x = foo(1, <bold>2</bold>) { { it } }
@@ -10,3 +10,12 @@
8 [LAMBDA] val x = foo(1, 2) { <bold>{ it }</bold> }
8 val x = foo(1, 2) { <bold>{ it }</bold> }
8 val x = foo(1, 2) { { <bold>it</bold> } }
8 [LAMBDA CALLS] val x = foo(1, 2) { <bold>{ it }</bold> }
8 [LAMBDA CALLS] val x = foo(1, 2) <bold>{ { it } }</bold>
8 [LAMBDA] [LAMBDA CALLS] val x = foo(1, 2) <bold>{ { it } }</bold>
3 [LAMBDA] [LAMBDA CALLS] fun foo(a: Int, b: Int, <bold>f: (Int) -> (Int) -> Int</bold>): Int {
4 [LAMBDA] [LAMBDA CALLS] return <bold>f</bold>(a)(b)
4 [LAMBDA CALLS] return <bold>f(a)</bold>(b)
4 return f(a)(<bold>b</bold>)
3 fun foo(a: Int, <bold>b: Int</bold>, f: (Int) -> (Int) -> Int): Int {
8 val x = foo(1, <bold>2</bold>) { { it } }
@@ -0,0 +1,21 @@
// FLOW: IN
fun foo(f: String.(Int) -> Unit) {
f("", 1)
"".f(2)
with("") {
f(3)
}
}
fun test() {
foo {
println(<caret>it)
}
}
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
@@ -0,0 +1,18 @@
4 f("", <bold>1</bold>)
15 println(<bold>it</bold>)
14 [LAMBDA CALLS] foo <bold>{</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
4 f("", <bold>1</bold>)
6 "".f(<bold>2</bold>)
15 println(<bold>it</bold>)
14 [LAMBDA CALLS] foo <bold>{</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
6 "".f(<bold>2</bold>)
9 f(<bold>3</bold>)
15 println(<bold>it</bold>)
14 [LAMBDA CALLS] foo <bold>{</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
9 f(<bold>3</bold>)
@@ -0,0 +1,4 @@
[NotNull Values]
15 println(<bold>it</bold>)
15 println(<bold>it</bold>)
@@ -0,0 +1,6 @@
15 println(<bold>it</bold>)
14 [LAMBDA CALLS] foo <bold>{</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
4 f("", <bold>1</bold>)
6 "".f(<bold>2</bold>)
9 f(<bold>3</bold>)
+21
View File
@@ -0,0 +1,21 @@
// FLOW: IN
fun foo(f: String.(Int) -> Unit) {
f("", 1)
"".f(2)
with("") {
f(3)
}
}
fun test() {
foo { i ->
println(<caret>i)
}
}
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
@@ -0,0 +1,21 @@
4 f("", <bold>1</bold>)
15 println(<bold>i</bold>)
14 foo { <bold>i</bold> ->
14 [LAMBDA CALLS] foo <bold>{ i -></bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
4 f("", <bold>1</bold>)
6 "".f(<bold>2</bold>)
15 println(<bold>i</bold>)
14 foo { <bold>i</bold> ->
14 [LAMBDA CALLS] foo <bold>{ i -></bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
6 "".f(<bold>2</bold>)
9 f(<bold>3</bold>)
15 println(<bold>i</bold>)
14 foo { <bold>i</bold> ->
14 [LAMBDA CALLS] foo <bold>{ i -></bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
9 f(<bold>3</bold>)
@@ -0,0 +1,4 @@
[NotNull Values]
15 println(<bold>i</bold>)
15 println(<bold>i</bold>)
@@ -0,0 +1,7 @@
15 println(<bold>i</bold>)
14 foo { <bold>i</bold> ->
14 [LAMBDA CALLS] foo <bold>{ i -></bold>
3 [LAMBDA CALLS] fun foo(<bold>f: String.(Int) -> Unit</bold>) {
4 f("", <bold>1</bold>)
6 "".f(<bold>2</bold>)
9 f(<bold>3</bold>)
+11
View File
@@ -0,0 +1,11 @@
// FLOW: IN
fun foo(f: (Int) -> Unit): Int {
return f(1)
}
fun test() {
foo {
println(<caret>it)
}
}
@@ -0,0 +1,6 @@
4 return f(<bold>1</bold>)
9 println(<bold>it</bold>)
8 [LAMBDA CALLS] foo <bold>{</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Unit</bold>): Int {
4 return f(<bold>1</bold>)
@@ -0,0 +1,3 @@
[NotNull Values]
9 println(<bold>it</bold>)
9 println(<bold>it</bold>)
@@ -0,0 +1,4 @@
9 println(<bold>it</bold>)
8 [LAMBDA CALLS] foo <bold>{</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Unit</bold>): Int {
4 return f(<bold>1</bold>)
+11
View File
@@ -0,0 +1,11 @@
// FLOW: IN
fun foo(f: (Int) -> Unit): Int {
return f(1)
}
fun test() {
foo { value ->
println(<caret>value)
}
}
@@ -0,0 +1,7 @@
4 return f(<bold>1</bold>)
9 println(<bold>value</bold>)
8 foo { <bold>value</bold> ->
8 [LAMBDA CALLS] foo <bold>{ value -></bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Unit</bold>): Int {
4 return f(<bold>1</bold>)
@@ -0,0 +1,3 @@
[NotNull Values]
9 println(<bold>value</bold>)
9 println(<bold>value</bold>)
@@ -0,0 +1,5 @@
9 println(<bold>value</bold>)
8 foo { <bold>value</bold> ->
8 [LAMBDA CALLS] foo <bold>{ value -></bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Unit</bold>): Int {
4 return f(<bold>1</bold>)
+4 -1
View File
@@ -1,4 +1,4 @@
8 val x = foo { <bold>it</bold> }
4 return f(<bold>1</bold>)
8 val <bold>x = foo { it }</bold>
8 val x = <bold>foo { it }</bold>
3 fun <bold>foo(f: (Int) -> Int): Int {</bold>
@@ -8,4 +8,7 @@
8 [LAMBDA] val x = foo <bold>{ it }</bold>
8 val x = foo <bold>{ it }</bold>
8 val x = foo { <bold>it</bold> }
8 [LAMBDA CALLS] val x = foo <bold>{ it }</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
4 return f(<bold>1</bold>)
+3
View File
@@ -7,3 +7,6 @@
8 [LAMBDA] val x = foo <bold>{ it }</bold>
8 val x = foo <bold>{ it }</bold>
8 val x = foo { <bold>it</bold> }
8 [LAMBDA CALLS] val x = foo <bold>{ it }</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
4 return f(<bold>1</bold>)
@@ -1,4 +1,4 @@
9 val y = foo { <bold>it</bold> }
5 return x(<bold>1</bold>)
9 val <bold>y = foo { it }</bold>
9 val y = <bold>foo { it }</bold>
3 fun <bold>foo(f: (Int) -> Int): Int {</bold>
@@ -10,4 +10,9 @@
9 [LAMBDA] val y = foo <bold>{ it }</bold>
9 val y = foo <bold>{ it }</bold>
9 val y = foo { <bold>it</bold> }
9 [LAMBDA CALLS] val y = foo <bold>{ it }</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
4 [LAMBDA CALLS] val x = <bold>f</bold>
4 [LAMBDA CALLS] val <bold>x = f</bold>
5 return x(<bold>1</bold>)
@@ -9,3 +9,8 @@
9 [LAMBDA] val y = foo <bold>{ it }</bold>
9 val y = foo <bold>{ it }</bold>
9 val y = foo { <bold>it</bold> }
9 [LAMBDA CALLS] val y = foo <bold>{ it }</bold>
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
4 [LAMBDA CALLS] val x = <bold>f</bold>
4 [LAMBDA CALLS] val <bold>x = f</bold>
5 return x(<bold>1</bold>)
+7 -1
View File
@@ -1,4 +1,4 @@
5 fun bar(a: Int): Int = foo(a) { if (it > 0) <bold>it</bold> else return 0 }
5 fun bar(<bold>a: Int</bold>): Int = foo(a) { if (it > 0) it else return 0 }
5 fun <bold>bar(a: Int): Int = foo(a) { if (it > 0) it else return 0 }</bold>
5 fun bar(a: Int): Int = <bold>foo(a) { if (it > 0) it else return 0 }</bold>
3 inline fun <bold>foo(a: Int, f: (Int) -> Int) = f(a)</bold>
@@ -9,6 +9,12 @@
5 fun bar(a: Int): Int = foo(a) <bold>{ if (it > 0) it else return 0 }</bold>
5 fun bar(a: Int): Int = foo(a) { <bold>if (it > 0) it else return 0</bold> }
5 fun bar(a: Int): Int = foo(a) { if (it > 0) <bold>it</bold> else return 0 }
5 [LAMBDA CALLS] fun bar(a: Int): Int = foo(a) <bold>{ if (it > 0) it else return 0 }</bold>
3 [LAMBDA CALLS] inline fun foo(a: Int, <bold>f: (Int) -> Int</bold>) = f(a)
3 inline fun foo(a: Int, f: (Int) -> Int) = f(<bold>a</bold>)
3 inline fun foo(<bold>a: Int</bold>, f: (Int) -> Int) = f(a)
5 fun bar(a: Int): Int = foo(<bold>a</bold>) { if (it > 0) it else return 0 }
5 fun bar(<bold>a: Int</bold>): Int = foo(a) { if (it > 0) it else return 0 }
5 fun bar(a: Int): Int = foo(a) { if (it > 0) it else return <bold>0</bold> }
5 fun <bold>bar(a: Int): Int = foo(a) { if (it > 0) it else return 0 }</bold>
@@ -8,4 +8,10 @@
5 fun bar(a: Int): Int = foo(a) <bold>{ if (it > 0) it else return 0 }</bold>
5 fun bar(a: Int): Int = foo(a) { <bold>if (it > 0) it else return 0</bold> }
5 fun bar(a: Int): Int = foo(a) { if (it > 0) <bold>it</bold> else return 0 }
5 [LAMBDA CALLS] fun bar(a: Int): Int = foo(a) <bold>{ if (it > 0) it else return 0 }</bold>
3 [LAMBDA CALLS] inline fun foo(a: Int, <bold>f: (Int) -> Int</bold>) = f(a)
3 inline fun foo(a: Int, f: (Int) -> Int) = f(<bold>a</bold>)
3 inline fun foo(<bold>a: Int</bold>, f: (Int) -> Int) = f(a)
5 fun bar(a: Int): Int = foo(<bold>a</bold>) { if (it > 0) it else return 0 }
5 fun bar(<bold>a: Int</bold>): Int = foo(a) { if (it > 0) it else return 0 }
5 fun bar(a: Int): Int = foo(a) { if (it > 0) it else return <bold>0</bold> }