JS: more default arguments fixes (KT-24413, KT-21968 fixed)

MPP-related:
* inherited from interfaces
* inherited body from interface
* default arguments in an interface, implemented by a class delegate
* super call of a method with default argument

Also:
* inheritance from an interface and another interface descendant (KT-21968)
* inheritance through an intermediate interface
This commit is contained in:
Anton Bannykh
2018-05-15 14:55:59 +03:00
parent da7b59984f
commit 03e46ce0ca
21 changed files with 357 additions and 55 deletions
@@ -1,6 +1,4 @@
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// TARGET_BACKEND: JVM
// WITH_RUNTIME
class A(value: Int = 1)
@@ -1,6 +1,4 @@
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// TARGET_BACKEND: JVM
// WITH_RUNTIME
class A(val a: Int = 1,
@@ -0,0 +1,15 @@
// See KT-21968
interface A {
fun f(cause: Int? = null): Boolean
}
open class B : A {
override fun f(cause: Int?): Boolean = true
}
class D : B(), A
fun box(): String {
return if (D().f()) "OK" else "fail"
}
@@ -0,0 +1,20 @@
// IGNORE_BACKEND: JVM
// See KT-15971
interface Foo {
fun foo(a: Double = 1.0): Double
}
interface FooChain: Foo
open class Impl {
fun foo(a: Double) = a
}
class FooImpl : FooChain, Impl()
fun box(): String {
if (FooImpl().foo() != 1.0) return "fail"
if (FooImpl().foo(2.0) != 2.0) return "fail"
return "OK"
}
@@ -1,4 +1,4 @@
// IGNORE_BACKEND: JVM, JS
// IGNORE_BACKEND: JVM
interface I<T> {
val prop: T
@@ -1,4 +1,4 @@
// IGNORE_BACKEND: JVM, JS
// IGNORE_BACKEND: JVM
interface I<T> {
val prop: T
@@ -1,6 +1,4 @@
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// TARGET_BACKEND: JVM
// WITH_RUNTIME
open class MyClass {
@@ -0,0 +1,69 @@
// !LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND: JVM
// FILE: lib.kt
expect interface I {
fun foo(x: Int = 1): Unit
}
// FILE: main.kt
var log = ""
fun log(a: String) {
log += a + ";"
}
interface C {
fun foo(x: Int): Unit {
log("C.foo($x)")
}
}
actual interface I {
actual fun foo(x: Int): Unit
}
class G(c: C) : C by c, I
class H(c: C) : I, C by c
fun test1() {
log = ""
val g1 = G(object: C {})
g1.foo(2)
g1.foo()
val g2 = G(object: C {
override fun foo(x: Int) {
log("[2] object:C.foo($x)")
}
})
g2.foo(2)
g2.foo()
}
fun test2() {
log = ""
val h1 = H(object: C {})
h1.foo(2)
h1.foo()
val h2 = H(object: C {
override fun foo(x: Int) {
log("[2] object:C.foo($x)")
}
})
h2.foo(2)
h2.foo()
}
fun box(): String {
test1()
if (log != "C.foo(2);C.foo(1);[2] object:C.foo(2);[2] object:C.foo(1);") return "fail1: $log"
test2()
if (log != "C.foo(2);C.foo(1);[2] object:C.foo(2);[2] object:C.foo(1);") return "fail2: $log"
return "OK"
}
@@ -0,0 +1,17 @@
// !LANGUAGE: +MultiPlatformProjects
// FILE: lib.kt
expect interface I {
fun f(p: String = "OK"): String
}
// FILE: main.kt
actual interface I {
actual fun f(p: String): String
}
class Impl : I {
override fun f(p: String) = p
}
fun box() = Impl().f()
@@ -0,0 +1,48 @@
// !LANGUAGE: +MultiPlatformProjects
// FILE: lib.kt
package foo
expect interface H {
fun foo(x: String = "default"): String
}
// FILE: main.kt
package foo
actual interface H {
actual fun foo(x: String): String
}
interface I: H {
override fun foo(x: String): String = "I.foo($x)"
}
interface J : I {
override fun foo(x: String): String
}
interface K : J {
override fun foo(x: String): String = "K.foo($x)"
}
class A : I
class B : K
fun box(): String {
val a = A()
var r = a.foo()
if (r != "I.foo(default)") return "fail: A.foo()"
r = a.foo("Q")
if (r != "I.foo(Q)") return "fail A.foo(Q): $r"
val b = B()
r = b.foo()
if (r != "K.foo(default)") return "fail B.foo(): $r"
r = b.foo("W")
if (r != "K.foo(W)") return "fail B.foo(W): $r"
return "OK"
}
@@ -0,0 +1,40 @@
// !LANGUAGE: +MultiPlatformProjects
// IGNORE_BACKEND: JVM
// FILE: lib.kt
package foo
expect open class A {
open fun foo(x: Int = 20, y: Int = 3): Int
}
// FILE: main.kt
package foo
actual open class A {
actual open fun foo(x: Int, y: Int) = x + y
}
open class B : A() {
override fun foo(x: Int, y: Int) = 0
fun bar1() = super.foo()
fun bar2() = super.foo(30)
fun bar3() = super.foo(y = 4)
}
fun box(): String {
val v1 = B().bar1()
if (v1 != 23) return "fail1: $v1"
val v2 = B().bar2()
if (v2 != 33) return "fail2: $v2"
val v3 = B().bar3()
if (v3 != 24) return "fail3: $v3"
return "OK"
}