Make JVM backend work with Collection.size as val

0. Such properties are called special because their accessor JVM name differs from usual one
1. When making call to such property, always choose special name
2. When generating Kotlin class inheriting such property generate `final bridge int size() { return this.getSize(); }`
3. If there is no `size` declaration in current class generate `bridge int getSize() { // super-call }`
This commit is contained in:
Denis Zharkov
2015-10-06 14:10:20 +03:00
parent 252c82abe3
commit 6a1566a6dc
18 changed files with 638 additions and 26 deletions
@@ -0,0 +1,101 @@
import java.util.*;
interface A0 {
val size: Int get() = 56
}
class B0 : Collection<String>, A0 {
override fun isEmpty() = throw UnsupportedOperationException()
override fun contains(o: Any?) = throw UnsupportedOperationException()
override fun iterator() = throw UnsupportedOperationException()
override fun containsAll(c: Collection<Any?>) = throw UnsupportedOperationException()
}
open class A1 {
val size: Int = 56
}
class B1 : Collection<String>, A1() {
override fun isEmpty() = throw UnsupportedOperationException()
override fun contains(o: Any?) = throw UnsupportedOperationException()
override fun iterator() = throw UnsupportedOperationException()
override fun containsAll(c: Collection<Any?>) = throw UnsupportedOperationException()
}
interface I2 {
val size: Int
}
val list = ArrayList<String>()
class B2 : ArrayList<String>(list), I2
interface I3<T> {
val size: T
}
class B3 : ArrayList<String>(list), I3<Int>
interface I4<T> {
val size: T get() = 56 as T
}
class B4 : Collection<String>, I4<Int> {
override fun isEmpty() = throw UnsupportedOperationException()
override fun contains(o: Any?) = throw UnsupportedOperationException()
override fun iterator() = throw UnsupportedOperationException()
override fun containsAll(c: Collection<Any?>) = throw UnsupportedOperationException()
}
interface I5 : Collection<String> {
override val size: Int get() = 56
}
class B5 : I5 {
override fun isEmpty() = throw UnsupportedOperationException()
override fun contains(o: Any?) = throw UnsupportedOperationException()
override fun iterator() = throw UnsupportedOperationException()
override fun containsAll(c: Collection<Any?>) = throw UnsupportedOperationException()
}
fun box(): String {
list.add("1")
val b0 = B0()
if (b0.size != 56) return "fail 0: ${b0.size}"
var x: Collection<String> = B0()
if (x.size != 56) return "fail 00: ${x.size}"
val a0: A0 = b0
if (a0.size != 56) return "fail 000: ${a0.size}"
val b1 = B1()
if (b1.size != 56) return "fail 1: ${b1.size}"
x = B1()
if (x.size != 56) return "fail 2: ${x.size}"
val b2 = B2()
if (b2.size != 1) return "fail 3: ${b2.size}"
x = B2()
if (x.size != 1) return "fail 4: ${x.size}"
val i2: I2 = b2
if (i2.size != 1) return "fail 5: ${i2.size}"
val b3 = B3()
if (b3.size != 1) return "fail 6: ${b3.size}"
x = B3()
if (x.size != 1) return "fail 7: ${x.size}"
val i3: I3<Int> = b3
if (i3.size != 1) return "fail 8: ${i3.size}"
val b4 = B4()
if (b4.size != 56) return "fail 9: ${b4.size}"
x = B4()
if (x.size != 56) return "fail 10: ${x.size}"
val b5 = B5()
if (b5.size != 56) return "fail 11: ${b5.size}"
x = B5()
if (x.size != 56) return "fail 12: ${x.size}"
return "OK"
}
@@ -0,0 +1,94 @@
class A1 : MutableCollection<String> {
override val size: Int
get() = 56
override fun isEmpty(): Boolean {
throw UnsupportedOperationException()
}
override fun contains(o: Any?): Boolean {
throw UnsupportedOperationException()
}
override fun iterator(): MutableIterator<String> {
throw UnsupportedOperationException()
}
override fun containsAll(c: Collection<Any?>): Boolean {
throw UnsupportedOperationException()
}
override fun add(e: String): Boolean {
throw UnsupportedOperationException()
}
override fun remove(o: Any?): Boolean {
throw UnsupportedOperationException()
}
override fun addAll(c: Collection<String>): Boolean {
throw UnsupportedOperationException()
}
override fun removeAll(c: Collection<Any?>): Boolean {
throw UnsupportedOperationException()
}
override fun retainAll(c: Collection<Any?>): Boolean {
throw UnsupportedOperationException()
}
override fun clear() {
throw UnsupportedOperationException()
}
}
class A2 : java.util.AbstractCollection<String>() {
override val size: Int
get() = 56
override fun iterator(): MutableIterator<String> {
throw UnsupportedOperationException()
}
}
class A3 : java.util.ArrayList<String>() {
override val size: Int
get() = 56
}
interface Sized {
val size: Int
}
class A4 : java.util.ArrayList<String>(), Sized {
override val size: Int
get() = 56
}
fun check56(x: Collection<String>) {
if (x.size != 56) throw java.lang.RuntimeException("fail ${x.size}")
}
fun box(): String {
val a1 = A1()
if (a1.size != 56) return "fail 1: ${a1.size}"
check56(a1)
val a2 = A2()
if (a2.size != 56) return "fail 2: ${a2.size}"
check56(a2)
val a3 = A3()
if (a3.size != 56) return "fail 3: ${a3.size}"
check56(a3)
val a4 = A4()
if (a4.size != 56) return "fail 4: ${a4.size}"
check56(a4)
val sized: Sized = a4
if (sized.size != 56) return "fail 5: ${a4.size}"
return "OK"
}
@@ -0,0 +1,10 @@
class A : java.util.ArrayList<String>() {
override val size: Int get() = super.size + 56
}
fun box(): String {
val a = A()
if (a.size != 56) return "fail: ${a.size}"
return "OK"
}
@@ -0,0 +1,41 @@
class A : Map<String, String> {
override val size: Int get() = 56
override fun isEmpty(): Boolean {
throw UnsupportedOperationException()
}
override fun containsKey(key: Any?): Boolean {
throw UnsupportedOperationException()
}
override fun containsValue(value: Any?): Boolean {
throw UnsupportedOperationException()
}
override fun get(key: Any?): String? {
throw UnsupportedOperationException()
}
override fun keySet(): Set<String> {
throw UnsupportedOperationException()
}
override fun values(): Collection<String> {
throw UnsupportedOperationException()
}
override fun entrySet(): Set<Map.Entry<String, String>> {
throw UnsupportedOperationException()
}
}
fun box(): String {
val a = A()
if (a.size != 56) return "fail 1: ${a.size}"
val x: Map<String, String> = a
if (x.size != 56) return "fail 2: ${x.size}"
return "OK"
}
@@ -0,0 +1,5 @@
public class Test extends java.util.ArrayList<String> {
public final int size() {
return 56;
}
}
@@ -0,0 +1,12 @@
class OurTest : Test()
fun box(): String {
val t = OurTest()
val x: MutableCollection<String> = t
if (t.size != 56) return "fail 1: ${t.size}"
if (x.size != 56) return "fail 1: ${x.size}"
return "OK"
}
@@ -0,0 +1,65 @@
abstract class A1 : Collection<String> {
override val size: Int get() = 1
}
abstract class A2 : Collection<String> {
abstract override val size: Int
}
abstract class A3 : java.util.AbstractCollection<String>() {
override val size: Int get() = 1
}
abstract class A4 : java.util.AbstractCollection<String>() {
abstract override val size: Int
}
abstract class A5 : java.util.ArrayList<String>() {
override val size: Int get() = 1
}
abstract class A6 : java.util.ArrayList<String>() {
abstract override val size: Int
}
abstract class A7 : MutableList<String>
abstract class A8 : java.util.ArrayList<String>()
interface A9 : List<String> {}
fun box(
a1: A1,
a2: A2,
a3: A3,
a4: A4,
a5: A5,
a6: A6,
a7: A7,
a8: A8,
a9: A9,
c1: Collection<String>,
c2: MutableCollection<String>
) {
a1.size
a2.size
a3.size
a4.size
a5.size
a6.size
a7.size
a8.size
a9.size
c1.size
c2.size
}
/*
*/
// 8 public final bridge size\(\)I
// 8 INVOKEVIRTUAL A[0-9]+\.size \(\)I
// 1 INVOKEINTERFACE A9+\.size \(\)I
// 8 INVOKEVIRTUAL A[0-9]+\.getSize() \(\)I
// 2 INVOKEINTERFACE java\/util\/Collection.size \(\)I
// 4 public abstract getSize\(\)I