Support secondary constructors in JVM backend

There is a lot of changes about closures calculating and generating.

1. As classes can have more than one constructor each of them should
have closure arguments.

2. Captured variables set is the same for all of them.

3. Within constructors bodies/delegating calls closure parameters
should be accessed through method arguments because fields may be
not initialized yet.
This commit is contained in:
Denis Zharkov
2015-02-24 19:47:16 +03:00
parent 6779e95767
commit e65382e6ec
35 changed files with 1290 additions and 39 deletions

View File

@@ -0,0 +1,11 @@
class WithGenerics {
public static String foo1() {
A<Double> x = new A<Double>("OK");
return x.toString();
}
public static String foo2() {
A<Integer> x = new A<Integer>(123);
return x.toString();
}
}

View File

@@ -0,0 +1,20 @@
open class A<T> {
val prop: String
constructor(x: String) {
prop = x
}
constructor(x: T) {
prop = x.toString()
}
override fun toString() = prop
}
fun box(): String {
val a1 = WithGenerics.foo1()
if (a1 != "OK") return "fail1: $a1"
val a2 = WithGenerics.foo2()
if (a2 != "123") return "fail2: $a2"
return "OK"
}

View File

@@ -0,0 +1,14 @@
class WithPrimary {
public static A test1() {
return new A("123", "abc");
}
public static A test2() {
return new A();
}
public static A test3() {
return new A("123", 456);
}
public static A test4() {
return new A(1.0);
}
}

View File

@@ -0,0 +1,21 @@
class A(val x: String = "def_x", val y: String = "1") {
constructor(x: String, y: Int): this(x, y.toString()) {}
constructor(x: Double): this(x.toString(), "def_y") {}
override fun toString() = "$x#$y"
}
fun box(): String {
val test1 = WithPrimary.test1().toString()
if (test1 != "123#abc") return "fail1: $test1"
val test2 = WithPrimary.test2().toString()
if (test2 != "def_x#1") return "fail2: $test2"
val test3 = WithPrimary.test3().toString()
if (test3 != "123#456") return "fail3: $test3"
val test4 = WithPrimary.test4().toString()
if (test4 != "1.0#def_y") return "fail4: $test4"
return "OK"
}

View File

@@ -0,0 +1,5 @@
public class WithVarargs {
public static String foo() {
return new A("1", "2", "3").getProp();
}
}

View File

@@ -0,0 +1,23 @@
fun join(x: Array<out String>): String {
var result = ""
for (i in x) {
result += i
result += "#"
}
return result
}
class A {
val prop: String
constructor(vararg x: String) {
prop = join(x)
}
}
fun box(): String {
val a1 = WithVarargs.foo()
if (a1 != "1#2#3#") return "fail1: ${a1}"
return "OK"
}

View File

@@ -0,0 +1,14 @@
class WithoutPrimary {
public static A test1() {
return new A("123", "abc");
}
public static A test2() {
return new A(null, 1, 3, null);
}
public static A test3() {
return new A("123", 456);
}
public static A test4() {
return new A(1.0);
}
}

View File

@@ -0,0 +1,27 @@
class A {
val x: String
val y: String
constructor(x: String, y: String) {
this.x = x
this.y = y
}
constructor(x: String = "def_x", y: Int = 1): this(x, y.toString()) {}
constructor(x: Double): this(x.toString(), "def_y") {}
override fun toString() = "$x#$y"
}
fun box(): String {
val test1 = WithoutPrimary.test1().toString()
if (test1 != "123#abc") return "fail1: $test1"
val test2 = WithoutPrimary.test2().toString()
if (test2 != "def_x#1") return "fail2: $test2"
val test3 = WithoutPrimary.test3().toString()
if (test3 != "123#456") return "fail3: $test3"
val test4 = WithoutPrimary.test4().toString()
if (test4 != "1.0#def_y") return "fail4: $test4"
return "OK"
}