Intentions: Convert function type parameter to receiver

#KT-14246 In Progress
This commit is contained in:
Alexey Sedunov
2016-11-29 17:37:39 +03:00
parent 9cadfd01ae
commit d4ed2d2022
43 changed files with 1066 additions and 16 deletions
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.intentions.ConvertFunctionTypeParameterToReceiverIntention
@@ -0,0 +1,4 @@
// IS_APPLICABLE: false
fun foo(f: Int.(<caret>Boolean) -> String) {
}
@@ -0,0 +1,10 @@
// SHOULD_FAIL_WITH: Following expression won't be processed since refactoring can't preserve its semantics: this
val o = object {
fun bar() {
foo { i, b -> "$this: $i $b" }
}
}
fun foo(f: (<caret>Int, Boolean) -> String) {
}
@@ -0,0 +1,22 @@
fun foo(f: (<caret>Int, Boolean) -> String) {
f(1, false)
bar(f)
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun baz(f: (Int, Boolean) -> String) {
fun g(i: Int, b: Boolean) = ""
foo(f)
foo(::g)
foo(lambda())
foo { i, b -> "${i + 1} $b" }
}
@@ -0,0 +1,22 @@
fun foo(f: Int.(<caret>Boolean) -> String) {
1.f(false)
bar(f)
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun baz(f: (Int, Boolean) -> String) {
fun g(i: Int, b: Boolean) = ""
foo(f)
foo(::g)
foo(lambda())
foo { b -> "${this + 1} $b" }
}
@@ -0,0 +1,41 @@
open class Foo(f: (<caret>Int, Boolean) -> String) {
constructor(a: Int, f: (Int, Boolean) -> String) : this(f)
constructor(a: Int) : this(::g)
constructor(a: Int, b: Int) : this(lambda())
constructor(a: Int, b: Int, c: Int) : this({ i, b -> "${i + 1} $b" })
init {
f(1, false)
bar(f)
}
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo(f)
Foo(::g)
Foo(lambda())
Foo { i, b -> "${i + 1} $b" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo(f)
class Baz2 : Foo(::g)
class Baz3 : Foo(lambda())
class Baz4 : Foo({ i, b -> "${i + 1} $b" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super(f)
constructor(a: Int) : super(::g)
constructor(a: Int, b: Int) : super(lambda())
constructor(a: Int, b: Int, c: Int) : super({ i, b -> "${i + 1} $b" })
}
@@ -0,0 +1,41 @@
open class Foo(f: Int.(<caret>Boolean) -> String) {
constructor(a: Int, f: (Int, Boolean) -> String) : this(f)
constructor(a: Int) : this(::g)
constructor(a: Int, b: Int) : this(lambda())
constructor(a: Int, b: Int, c: Int) : this({ b -> "${this + 1} $b" })
init {
1.f(false)
bar(f)
}
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo(f)
Foo(::g)
Foo(lambda())
Foo { b -> "${this + 1} $b" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo(f)
class Baz2 : Foo(::g)
class Baz3 : Foo(lambda())
class Baz4 : Foo({ b -> "${this + 1} $b" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super(f)
constructor(a: Int) : super(::g)
constructor(a: Int, b: Int) : super(lambda())
constructor(a: Int, b: Int, c: Int) : super({ b -> "${this + 1} $b" })
}
@@ -0,0 +1,41 @@
open class Foo {
constructor(f: (<caret>Int, Boolean) -> String) {
f(1, false)
bar(f)
}
constructor(a: Int, f: (Int, Boolean) -> String) : this(f)
constructor(a: Int) : this(::g)
constructor(a: Int, b: Int) : this(lambda())
constructor(a: Int, b: Int, c: Int) : this({ i, b -> "${i + 1} $b" })
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo(f)
Foo(::g)
Foo(lambda())
Foo { i, b -> "${i + 1} $b" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo(f)
class Baz2 : Foo(::g)
class Baz3 : Foo(lambda())
class Baz4 : Foo({ i, b -> "${i + 1} $b" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super(f)
constructor(a: Int) : super(::g)
constructor(a: Int, b: Int) : super(lambda())
constructor(a: Int, b: Int, c: Int) : super({ i, b -> "${i + 1} $b" })
}
@@ -0,0 +1,41 @@
open class Foo {
constructor(f: Int.(<caret>Boolean) -> String) {
1.f(false)
bar(f)
}
constructor(a: Int, f: (Int, Boolean) -> String) : this(f)
constructor(a: Int) : this(::g)
constructor(a: Int, b: Int) : this(lambda())
constructor(a: Int, b: Int, c: Int) : this({ b -> "${this + 1} $b" })
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo(f)
Foo(::g)
Foo(lambda())
Foo { b -> "${this + 1} $b" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo(f)
class Baz2 : Foo(::g)
class Baz3 : Foo(lambda())
class Baz4 : Foo({ b -> "${this + 1} $b" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super(f)
constructor(a: Int) : super(::g)
constructor(a: Int, b: Int) : super(lambda())
constructor(a: Int, b: Int, c: Int) : super({ b -> "${this + 1} $b" })
}
@@ -0,0 +1,6 @@
class J extends K {
@Override
public void foo(@NotNull Function2<? super Integer, ? super Boolean, String> f) {
super.foo(f);
}
}
@@ -0,0 +1,6 @@
class J extends K {
@Override
public void foo(@NotNull Function2<? super Integer, ? super Boolean, String> f) {
super.foo(f);
}
}
@@ -0,0 +1,5 @@
open class K {
open fun foo(f: (<caret>Int, Boolean) -> String) {
}
}
@@ -0,0 +1,5 @@
open class K {
open fun foo(f: Int.(<caret>Boolean) -> String) {
}
}
@@ -0,0 +1,22 @@
fun foo(f: (Int, <caret>Boolean) -> String) {
f(1, false)
bar(f)
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun baz(f: (Int, Boolean) -> String) {
fun g(i: Int, b: Boolean) = ""
foo(f)
foo(::g)
foo(lambda())
foo { i, b -> "${i + 1} $b" }
}
@@ -0,0 +1,23 @@
fun foo(f: Boolean.(Int<caret>) -> String) {
false.f(1)
bar { i, b -> b.f(i) }
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun baz(f: (Int, Boolean) -> String) {
fun g(i: Int, b: Boolean) = ""
foo { i -> f(i, this) }
foo { i -> (::g)(i, this) }
val f1 = lambda()
foo { i -> f1(i, this) }
foo { i -> "${i + 1} ${this}" }
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: Callable reference transformation is not supported: ::foo
fun foo(f: (Int, <caret>Boolean) -> String) {
}
fun baz(f: (Int, Boolean) -> String) {
val x = ::foo
}
@@ -0,0 +1,39 @@
open class Foo(f: (Int, <caret>Boolean) -> String) {
constructor(a: Int, f: (Int, Boolean) -> String) : this(f)
constructor(a: Int) : this(::g)
constructor(a: Int, b: Int, c: Int) : this({ i, b -> "${i + 1} $b" })
init {
f(1, false)
bar(f)
}
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo(f)
Foo(::g)
Foo(lambda())
Foo { i, b -> "${i + 1} $b" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo(f)
class Baz2 : Foo(::g)
class Baz3 : Foo(lambda())
class Baz4 : Foo({ i, b -> "${i + 1} $b" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super(f)
constructor(a: Int) : super(::g)
constructor(a: Int, b: Int, c: Int) : super({ i, b -> "${i + 1} $b" })
}
@@ -0,0 +1,43 @@
open class Foo(f: Boolean.(Int<caret>) -> String) {
constructor(a: Int, f: (Int, Boolean) -> String) : this({ i -> f(i, this) })
constructor(a: Int) : this({ i -> (::g)(i, this) })
constructor(a: Int, b: Int, c: Int) : this({ i -> "${i + 1} ${this}" })
init {
false.f(1)
bar { i, b -> b.f(i) }
}
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo { i -> f(i, this) }
Foo { i -> (::g)(i, this) }
val f1 = lambda()
Foo { i -> f1(i, this) }
Foo { i -> "${i + 1} ${this}" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo({ i -> f(i, this) })
class Baz2 : Foo({ i -> (::g)(i, this) })
val f = lambda()
class Baz3 : Foo({ i -> f(i, this) })
class Baz4 : Foo({ i -> "${i + 1} ${this}" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super({ i -> f(i, this) })
constructor(a: Int) : super({ i -> (::g)(i, this) })
constructor(a: Int, b: Int, c: Int) : super({ i -> "${i + 1} ${this}" })
}
@@ -0,0 +1,39 @@
open class Foo {
constructor(f: (Int, <caret>Boolean) -> String){
f(1, false)
bar(f)
}
constructor(a: Int, f: (Int, Boolean) -> String) : this(f)
constructor(a: Int) : this(::g)
constructor(a: Int, b: Int, c: Int) : this({ i, b -> "${i + 1} $b" })
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo(f)
Foo(::g)
Foo(lambda())
Foo { i, b -> "${i + 1} $b" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo(f)
class Baz2 : Foo(::g)
class Baz3 : Foo(lambda())
class Baz4 : Foo({ i, b -> "${i + 1} $b" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super(f)
constructor(a: Int) : super(::g)
constructor(a: Int, b: Int, c: Int) : super({ i, b -> "${i + 1} $b" })
}
@@ -0,0 +1,43 @@
open class Foo {
constructor(f: Boolean.(Int<caret>) -> String){
false.f(1)
bar { i, b -> b.f(i) }
}
constructor(a: Int, f: (Int, Boolean) -> String) : this({ i -> f(i, this) })
constructor(a: Int) : this({ i -> (::g)(i, this) })
constructor(a: Int, b: Int, c: Int) : this({ i -> "${i + 1} ${this}" })
}
fun bar(f: (Int, Boolean) -> String) {
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
fun g(i: Int, b: Boolean) = ""
fun baz(f: (Int, Boolean) -> String) {
Foo { i -> f(i, this) }
Foo { i -> (::g)(i, this) }
val f1 = lambda()
Foo { i -> f1(i, this) }
Foo { i -> "${i + 1} ${this}" }
}
class Baz1(f: (Int, Boolean) -> String) : Foo({ i -> f(i, this) })
class Baz2 : Foo({ i -> (::g)(i, this) })
val f = lambda()
class Baz3 : Foo({ i -> f(i, this) })
class Baz4 : Foo({ i -> "${i + 1} ${this}" })
class Baz5 : Foo {
constructor(f: (Int, Boolean) -> String) : super({ i -> f(i, this) })
constructor(a: Int) : super({ i -> (::g)(i, this) })
constructor(a: Int, b: Int, c: Int) : super({ i -> "${i + 1} ${this}" })
}
@@ -0,0 +1,8 @@
// SHOULD_FAIL_WITH: Following expression won't be processed since refactoring can't preserve its semantics: lambda()
open class Foo(f: (Int, <caret>Boolean) -> String)
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
class Baz5 : Foo {
constructor() : super(lambda())
}
@@ -0,0 +1,6 @@
// SHOULD_FAIL_WITH: Following expression won't be processed since refactoring can't preserve its semantics: lambda()
open class Foo(f: (Int, <caret>Boolean) -> String) {
constructor() : this(lambda())
}
fun lambda(): (Int, Boolean) -> String = { i, b -> "$i $b"}
@@ -0,0 +1,6 @@
class J extends K {
@Override
public void foo(@NotNull Function2<? super Integer, ? super Boolean, String> f) {
super.foo(f);
}
}
@@ -0,0 +1,6 @@
// SHOULD_FAIL_WITH: Can't replace non-Kotlin reference with call expression: super.foo
open class K {
open fun foo(f: (Int, <caret>Boolean) -> String) {
}
}
@@ -0,0 +1,2 @@
// IS_APPLICABLE: false
fun foo(f: (Int, Boolean) -> String): (<caret>Int, Boolean) -> String = f
@@ -0,0 +1,4 @@
// IS_APPLICABLE: false
fun foo(f: (Int, Boolean) -> <caret>String) {
}
@@ -0,0 +1,11 @@
open class A {
open fun foo(f: (Int, <caret>Boolean) -> String) {
}
}
class B : A() {
override fun foo(f: (Int, Boolean) -> String) {
}
}
@@ -0,0 +1,11 @@
open class A {
open fun foo(f: Boolean.(Int<caret>) -> String) {
}
}
class B : A() {
override fun foo(f: Boolean.(Int) -> String) {
}
}