JS backend: support for explicit delegation
#KT-4479 Fixed
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// This test was adapted from compiler/testData/codegen/box/classes
|
||||
package foo
|
||||
|
||||
trait Trait1 {
|
||||
fun foo(): String
|
||||
}
|
||||
|
||||
trait Trait2 {
|
||||
fun bar(): String
|
||||
}
|
||||
|
||||
class T1 : Trait1 {
|
||||
override fun foo() = "aaa"
|
||||
}
|
||||
|
||||
class T2 : Trait2 {
|
||||
override fun bar() = "bbb"
|
||||
}
|
||||
|
||||
class C(a: Trait1, b: Trait2) : Trait1 by a, Trait2 by b
|
||||
|
||||
fun box(): String {
|
||||
val c = C(T1(), T2())
|
||||
if (c.foo() != "aaa") return "fail"
|
||||
if (c.bar() != "bbb") return "fail"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// This test was adapted from compiler/testData/codegen/box/classes
|
||||
package foo
|
||||
|
||||
trait One {
|
||||
public open fun foo(): Int
|
||||
public open fun faz(): Int = 10
|
||||
}
|
||||
trait Two {
|
||||
public open fun foo(): Int
|
||||
public open fun quux(): Int = 100
|
||||
}
|
||||
|
||||
class OneImpl : One {
|
||||
public override fun foo() = 1
|
||||
}
|
||||
class TwoImpl : Two {
|
||||
public override fun foo() = 2
|
||||
}
|
||||
|
||||
class Test2(a: One, b: Two) : Two by b, One by a {
|
||||
public override fun foo() = 0
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var t2 = Test2(OneImpl(), TwoImpl())
|
||||
if (t2.foo() != 0)
|
||||
return "Fail #1"
|
||||
if (t2.faz() != 10)
|
||||
return "Fail #2"
|
||||
if (t2.quux() != 100)
|
||||
return "Fail #3"
|
||||
if (t2 !is One)
|
||||
return "Fail #4"
|
||||
if (t2 !is Two)
|
||||
return "Fail #5"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// This test was adapted from compiler/testData/codegen/box/classes
|
||||
package foo
|
||||
|
||||
open trait First {
|
||||
public open fun foo(): Int
|
||||
}
|
||||
|
||||
open trait Second : First {
|
||||
public open fun bar(): Int
|
||||
}
|
||||
|
||||
class Impl : Second {
|
||||
public override fun foo() = 1
|
||||
public override fun bar() = 2
|
||||
}
|
||||
|
||||
class Test(s: Second) : Second by s {}
|
||||
|
||||
fun box(): String {
|
||||
var t = Test(Impl())
|
||||
if (t.foo() != 1)
|
||||
return "Fail #1"
|
||||
if (t.bar() != 2)
|
||||
return "Fail #2"
|
||||
if (t !is First)
|
||||
return "Fail #3"
|
||||
if (t !is Second)
|
||||
return "Fail #4"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(x: String): String
|
||||
var prop: String
|
||||
}
|
||||
|
||||
class BaseImpl(val s: String) : Base {
|
||||
override fun foo(x: String): String = "Base: ${s}:${x}"
|
||||
override var prop: String = "prop"
|
||||
}
|
||||
|
||||
class Derived(b: Base) : Base by b
|
||||
|
||||
|
||||
fun box(): String {
|
||||
var d = Derived(BaseImpl("test"))
|
||||
assertEquals("Base: test:!!", d.foo("!!"), "delegation by argument, function member")
|
||||
assertEquals("prop", d.prop, "delegation by argument, get property")
|
||||
|
||||
d.prop = "new value"
|
||||
assertEquals("new value", d.prop, "delegation by argument, set property")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(arg: String): String
|
||||
}
|
||||
|
||||
class BaseImpl(val s1: String, val s2: String) : Base {
|
||||
override fun foo(arg: String): String = "BaseImpl:foo ${s1}:${s2}:${arg}"
|
||||
}
|
||||
|
||||
class Derived(s1: String, s2: String) : Base by BaseImpl(s1, s2)
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("BaseImpl:foo arg1:arg2:!!", Derived("arg1", "arg2").foo("!!"), "delegation with two arguments")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(x: String): String
|
||||
}
|
||||
|
||||
class BaseImpl(val s: String) : Base {
|
||||
override fun foo(x: String): String = "Base: ${s}:${x}"
|
||||
}
|
||||
|
||||
fun newBase(s: String): Base = BaseImpl(s)
|
||||
|
||||
class Derived() : Base by newBase("test")
|
||||
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("Base: test:!!", Derived().foo("!!"), "delegation by function expression")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(x: String): String
|
||||
}
|
||||
|
||||
class BaseImpl(val s: String) : Base {
|
||||
override fun foo(x: String): String = "Base: ${s}:${x}"
|
||||
}
|
||||
|
||||
var global = true
|
||||
|
||||
class Derived() : Base by if (global) BaseImpl("then") else BaseImpl("else")
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("Base: then:!!", Derived().foo("!!"), "delegation by if expression")
|
||||
global = false
|
||||
assertEquals("Base: else:!!", Derived().foo("!!"), "delegation by if expression")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(s: String): String
|
||||
var prop: String
|
||||
}
|
||||
|
||||
trait Base1 : Base {
|
||||
}
|
||||
|
||||
trait Base2 : Base1 {
|
||||
override fun foo(s: String): String = "Base2:foo ${s}"
|
||||
}
|
||||
|
||||
class Base2Impl() : Base2 {
|
||||
override var prop: String = ""
|
||||
set(value) {
|
||||
$prop = "prop:${value}"
|
||||
}
|
||||
}
|
||||
|
||||
class Derived() : Base by Base2Impl()
|
||||
|
||||
class Derived1() : Base1 by Base2Impl()
|
||||
|
||||
class Derived2() : Base2 by Base2Impl()
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("Base2:foo !!", Derived().foo("!!"), "delegation (Base)")
|
||||
assertEquals("Base2:foo !!", Derived1().foo("!!"), "delegation (Base1)")
|
||||
assertEquals("Base2:foo !!", Derived2().foo("!!"), "delegation (Base2)")
|
||||
|
||||
var d = Derived()
|
||||
d.prop = "A"
|
||||
assertEquals("prop:A", d.prop, "delegation (Base) set property")
|
||||
|
||||
var d1 = Derived1()
|
||||
d1.prop = "B"
|
||||
assertEquals("prop:B", d1.prop, "delegation (Base1) set property")
|
||||
|
||||
var d2 = Derived1()
|
||||
d2.prop = "C"
|
||||
assertEquals("prop:C", d2.prop, "delegation (Base2) set property")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(x: String): String
|
||||
}
|
||||
|
||||
class BaseImpl(val s: String) : Base {
|
||||
override fun foo(x: String): String = "Base: ${s}:${x}"
|
||||
}
|
||||
|
||||
class Derived() : Base by BaseImpl("test")
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("Base: test:!!", Derived().foo("!!"), "delegation by new instance")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(x: String): String
|
||||
var prop: String
|
||||
}
|
||||
|
||||
class BaseImpl(val s: String) : Base {
|
||||
override fun foo(x: String) = "BaseImpl.foo: ${s}:${x}"
|
||||
override var prop: String = "init"
|
||||
set(value) {
|
||||
$prop = "prop:${value}"
|
||||
}
|
||||
}
|
||||
|
||||
class Base2Impl(val s: String) : Base by BaseImpl("${s} by BaseImpl")
|
||||
|
||||
class Derived(val s: String) : Base by Base2Impl("${s} by Base2Impl")
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("BaseImpl.foo: Derived by Base2Impl by BaseImpl:!!", Derived("Derived").foo("!!"))
|
||||
|
||||
var d = Derived("Derived")
|
||||
assertEquals("init", d.prop)
|
||||
|
||||
d.prop = "A"
|
||||
assertEquals("prop:A", d.prop)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(x: String): String
|
||||
}
|
||||
|
||||
class BaseImpl(val s: String) : Base {
|
||||
override fun foo(x: String): String = "Base: ${s}:${x}"
|
||||
}
|
||||
|
||||
var global = ""
|
||||
|
||||
open class DerivedBase() {
|
||||
{
|
||||
global += ":DerivedBase"
|
||||
}
|
||||
}
|
||||
|
||||
fun newBase(): Base {
|
||||
global += ":newBase"
|
||||
return BaseImpl("test")
|
||||
}
|
||||
|
||||
class Derived() : DerivedBase(), Base by newBase() {
|
||||
{
|
||||
global += ":Derived"
|
||||
}
|
||||
}
|
||||
|
||||
class Derived1() : Base by newBase(), DerivedBase() {
|
||||
{
|
||||
global += ":Derived"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var d = Derived()
|
||||
assertEquals(":DerivedBase:newBase:Derived", global, "evaluation order")
|
||||
|
||||
global = ""
|
||||
var d1 = Derived1()
|
||||
assertEquals(":DerivedBase:newBase:Derived", global, "evaluation order")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun foo(x: String): String
|
||||
}
|
||||
|
||||
class BaseImpl(val s: String) : Base {
|
||||
override fun foo(x: String): String = "Base: ${s}:${x}"
|
||||
}
|
||||
|
||||
trait Base2 {
|
||||
abstract fun bar(x: String): String
|
||||
}
|
||||
|
||||
class Base2Impl(val s: String) : Base2 {
|
||||
override fun bar(x: String): String = "Base2: ${s}:${x}"
|
||||
}
|
||||
|
||||
var global = ""
|
||||
|
||||
open class DerivedBase() {
|
||||
{
|
||||
global += ":DerivedBase"
|
||||
}
|
||||
}
|
||||
|
||||
fun newBase(): Base {
|
||||
global += ":newBase"
|
||||
return BaseImpl("test")
|
||||
}
|
||||
|
||||
fun newBase2(): Base2 {
|
||||
global += ":newBase2"
|
||||
return Base2Impl("test")
|
||||
}
|
||||
|
||||
class Derived() : DerivedBase(), Base by newBase(), Base2 by newBase2() {
|
||||
{
|
||||
global += ":Derived"
|
||||
}
|
||||
}
|
||||
|
||||
class Derived1() : Base by newBase(), DerivedBase(), Base2 by newBase2() {
|
||||
{
|
||||
global += ":Derived"
|
||||
}
|
||||
}
|
||||
|
||||
class Derived2() : Base by newBase(), Base2 by newBase2(), DerivedBase() {
|
||||
{
|
||||
global += ":Derived"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var d = Derived()
|
||||
assertEquals(":DerivedBase:newBase:newBase2:Derived", global, "evaluation order 1")
|
||||
|
||||
global = ""
|
||||
var d1 = Derived1()
|
||||
assertEquals(":DerivedBase:newBase:newBase2:Derived", global, "evaluation order 2")
|
||||
|
||||
global = ""
|
||||
var d2 = Derived2()
|
||||
assertEquals(":DerivedBase:newBase:newBase2:Derived", global, "evaluation order 3")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun Int.foo(): String
|
||||
}
|
||||
|
||||
open class BaseImpl(val s: String) : Base {
|
||||
override fun Int.foo(): String = "Int.foo ${s}:${this}"
|
||||
}
|
||||
|
||||
class Derived() : Base by BaseImpl("test") {
|
||||
fun bar(x: Int): String = x.foo()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("Int.foo test:5", Derived().bar(5))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
abstract fun String.foo(arg: String): String
|
||||
}
|
||||
|
||||
open class BaseImpl(val s: String) : Base {
|
||||
override fun String.foo(arg: String): String = "Int.foo ${s}:${this}:${arg}"
|
||||
}
|
||||
|
||||
class Derived() : Base by BaseImpl("test") {
|
||||
fun bar(x: String, arg: String): String = x.foo(arg)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("Int.foo test:A:B", Derived().bar("A", "B"))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package foo
|
||||
|
||||
trait Base {
|
||||
var prop: String
|
||||
var Int.foo: String
|
||||
}
|
||||
|
||||
open class BaseImpl(val s: String) : Base {
|
||||
override var prop: String = "init"
|
||||
override var Int.foo: String
|
||||
get() = "get Int.foo:${s}:${this}"
|
||||
set(value) {
|
||||
prop = "set Int.foo:${s}:${this}:${value}"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Derived() : Base by BaseImpl("test") {
|
||||
fun getFooValue(x: Int): String = x.foo
|
||||
fun setFooValue(x: Int, value: String) {
|
||||
x.foo = value
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var d = Derived()
|
||||
assertEquals("get Int.foo:test:5", d.getFooValue(5))
|
||||
|
||||
d.setFooValue(10, "A")
|
||||
assertEquals("set Int.foo:test:10:A", d.prop)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// This test was adapted from compiler/testData/codegen/box/classes
|
||||
package foo
|
||||
|
||||
trait A<T> {
|
||||
fun foo(t: T): String
|
||||
}
|
||||
|
||||
class Derived(a: A<Int>) : A<Int> by a
|
||||
|
||||
fun box(): String {
|
||||
val o = object : A<Int> {
|
||||
override fun foo(t: Int) = if (t == 42) "OK" else "Fail $t"
|
||||
}
|
||||
return Derived(o).foo(42)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// This test was adapted from compiler/testData/codegen/box/classes
|
||||
package foo
|
||||
|
||||
trait TextField {
|
||||
fun getText(): String
|
||||
}
|
||||
|
||||
trait InputTextField : TextField {
|
||||
fun setText(text: String)
|
||||
}
|
||||
|
||||
trait MooableTextField : InputTextField {
|
||||
fun moo(a: Int, b: Int, c: Int): Int
|
||||
}
|
||||
|
||||
class SimpleTextField : MooableTextField {
|
||||
private var text2 = ""
|
||||
override fun getText() = text2
|
||||
override fun setText(text: String) {
|
||||
this.text2 = text
|
||||
}
|
||||
override fun moo(a: Int, b: Int, c: Int) = a + b + c
|
||||
}
|
||||
|
||||
class TextFieldWrapper(textField: MooableTextField) : MooableTextField by textField
|
||||
|
||||
fun box(): String {
|
||||
val textField = TextFieldWrapper(SimpleTextField())
|
||||
textField.setText("hello world!")
|
||||
|
||||
if (!textField.getText().equals("hello world!")) return "FAIL #!1"
|
||||
if (textField.moo(1, 2, 3) != 6) return "FAIL #2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user