Rewrite mutable collection stub method generation
The main problem of the previous approach was that we were only generating erased method signatures, which was incorrect in case a class also had a member from another supertype with the same signature as the substituted one from the collection. Javac issues compilation errors when compiling Java code against such classes. Also all the needed method stub signatures were hardcoded in generateBuiltInMethodStubs() and the case of MutableListIterator was missing
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
class MyListIterator<T> : ListIterator<T> {
|
||||
override fun next(): T = null!!
|
||||
override fun hasNext(): Boolean = null!!
|
||||
override fun hasPrevious(): Boolean = null!!
|
||||
override fun previous(): T = null!!
|
||||
override fun nextIndex(): Int = null!!
|
||||
override fun previousIndex(): Int = null!!
|
||||
}
|
||||
|
||||
fun expectUoe(block: () -> Any) {
|
||||
try {
|
||||
block()
|
||||
throw AssertionError()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val list = MyListIterator<String>() as MutableListIterator<String>
|
||||
|
||||
expectUoe { list.set("") }
|
||||
expectUoe { list.add("") }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
abstract class A : Iterator<String> {
|
||||
abstract fun remove(): Unit
|
||||
}
|
||||
|
||||
class B(var result: String) : A() {
|
||||
override fun next() = ""
|
||||
override fun hasNext() = false
|
||||
override fun remove() {
|
||||
result = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = B("Fail") as MutableIterator<String>
|
||||
a.next()
|
||||
a.hasNext()
|
||||
a.remove()
|
||||
|
||||
return (a as B).result
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import java.util.ArrayList
|
||||
|
||||
class A<E> : List<E> by ArrayList<E>()
|
||||
|
||||
class B : List<String> by A<String>()
|
||||
|
||||
fun expectUoe(block: () -> Any) {
|
||||
try {
|
||||
block()
|
||||
throw AssertionError()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A<String>() as MutableList<String>
|
||||
expectUoe { a.add("") }
|
||||
expectUoe { a.remove("") }
|
||||
expectUoe { a.addAll(a) }
|
||||
expectUoe { a.addAll(0, a) }
|
||||
expectUoe { a.removeAll(a) }
|
||||
expectUoe { a.retainAll(a) }
|
||||
expectUoe { a.clear() }
|
||||
expectUoe { a.add(0, "") }
|
||||
expectUoe { a.set(0, "") }
|
||||
expectUoe { a.remove(0) }
|
||||
a.listIterator()
|
||||
a.listIterator(0)
|
||||
a.subList(0, 0)
|
||||
|
||||
val b = B() as MutableList<String>
|
||||
expectUoe { b.add("") }
|
||||
expectUoe { b.remove("") }
|
||||
expectUoe { b.addAll(b) }
|
||||
expectUoe { b.addAll(0, b) }
|
||||
expectUoe { b.removeAll(b) }
|
||||
expectUoe { b.retainAll(b) }
|
||||
expectUoe { b.clear() }
|
||||
expectUoe { b.add(0, "") }
|
||||
expectUoe { b.set(0, "") }
|
||||
expectUoe { b.remove(0) }
|
||||
b.listIterator()
|
||||
b.listIterator(0)
|
||||
b.subList(0, 0)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import java.util.AbstractList
|
||||
|
||||
class A : AbstractList<String>() {
|
||||
override fun get(index: Int): String = ""
|
||||
override fun size(): Int = 0
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val b = A()
|
||||
|
||||
a.addAll(b)
|
||||
a.addAll(0, b)
|
||||
a.removeAll(b)
|
||||
a.retainAll(b)
|
||||
a.clear()
|
||||
a.remove("")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import java.util.AbstractMap
|
||||
import java.util.Collections
|
||||
|
||||
class A : AbstractMap<Int, String>() {
|
||||
override fun entrySet(): Set<Map.Entry<Int, String>> = Collections.emptySet()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val b = A()
|
||||
|
||||
a.remove(0)
|
||||
|
||||
a.putAll(b)
|
||||
a.clear()
|
||||
|
||||
a.keySet()
|
||||
a.values()
|
||||
a.entrySet()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.util.HashSet
|
||||
|
||||
class A : HashSet<Long>()
|
||||
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val b = A()
|
||||
|
||||
a.iterator()
|
||||
|
||||
a.add(0L)
|
||||
a.remove(0L)
|
||||
|
||||
a.addAll(b)
|
||||
a.removeAll(b)
|
||||
a.retainAll(b)
|
||||
a.clear()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.util.HashMap
|
||||
|
||||
class A : HashMap<String, Double>()
|
||||
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val b = A()
|
||||
|
||||
a.put("", 0.0)
|
||||
a.remove("")
|
||||
|
||||
a.putAll(b)
|
||||
a.clear()
|
||||
|
||||
a.keySet()
|
||||
a.values()
|
||||
a.entrySet()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.util.HashSet
|
||||
|
||||
class A : HashSet<Long>()
|
||||
|
||||
fun box(): String {
|
||||
val a = A()
|
||||
val b = A()
|
||||
|
||||
a.iterator()
|
||||
|
||||
a.add(0L)
|
||||
a.remove(0L)
|
||||
|
||||
a.addAll(b)
|
||||
a.removeAll(b)
|
||||
a.retainAll(b)
|
||||
a.clear()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
trait Addable {
|
||||
fun add(s: String): Boolean = true
|
||||
}
|
||||
|
||||
class C : Addable, List<String> {
|
||||
override fun size(): Int = null!!
|
||||
override fun isEmpty(): Boolean = null!!
|
||||
override fun contains(o: Any?): Boolean = null!!
|
||||
override fun iterator(): Iterator<String> = null!!
|
||||
override fun containsAll(c: Collection<Any?>): Boolean = null!!
|
||||
override fun get(index: Int): String = null!!
|
||||
override fun indexOf(o: Any?): Int = null!!
|
||||
override fun lastIndexOf(o: Any?): Int = null!!
|
||||
override fun listIterator(): ListIterator<String> = null!!
|
||||
override fun listIterator(index: Int): ListIterator<String> = null!!
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<String> = null!!
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
val a = C()
|
||||
if (!a.add("")) return "Fail 1"
|
||||
if (!(a as Addable).add("")) return "Fail 2"
|
||||
if (!(a as MutableList<String>).add("")) return "Fail 3"
|
||||
return "OK"
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "Fail: no stub method should be generated"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
open class SetStringImpl {
|
||||
fun add(s: String): Boolean = false
|
||||
fun remove(o: Any?): Boolean = false
|
||||
fun clear(): Unit {}
|
||||
}
|
||||
|
||||
class S : Set<String>, SetStringImpl() {
|
||||
override fun size(): Int = 0
|
||||
override fun isEmpty(): Boolean = true
|
||||
override fun contains(o: Any?): Boolean = false
|
||||
override fun iterator(): Iterator<String> = null!!
|
||||
override fun containsAll(c: Collection<Any?>) = false
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val s = S() as MutableSet<String>
|
||||
s.add("")
|
||||
s.remove("")
|
||||
s.clear()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import java.util.Collections
|
||||
|
||||
class A<U : Number, V : U, W : V> : Set<W> {
|
||||
override fun size(): Int = 0
|
||||
override fun isEmpty(): Boolean = true
|
||||
override fun contains(o: Any?): Boolean = false
|
||||
override fun iterator(): Iterator<W> = Collections.emptySet<W>().iterator()
|
||||
override fun containsAll(c: Collection<Any?>): Boolean = c.isEmpty()
|
||||
}
|
||||
|
||||
fun expectUoe(block: () -> Any) {
|
||||
try {
|
||||
block()
|
||||
throw AssertionError()
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A<Int, Int, Int>() as MutableSet<Int>
|
||||
|
||||
a.iterator()
|
||||
|
||||
expectUoe { a.add(42) }
|
||||
expectUoe { a.remove(42) }
|
||||
expectUoe { a.addAll(a) }
|
||||
expectUoe { a.removeAll(a) }
|
||||
expectUoe { a.retainAll(a) }
|
||||
expectUoe { a.clear() }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import java.util.ArrayList
|
||||
|
||||
class MyCollection<T> : Collection<List<Iterator<T>>> {
|
||||
override fun iterator() = null!!
|
||||
override fun size(): Int = null!!
|
||||
override fun isEmpty(): Boolean = null!!
|
||||
override fun contains(o: Any?): Boolean = null!!
|
||||
override fun containsAll(c: Collection<Any?>): Boolean = null!!
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val c = MyCollection<String>() as MutableCollection<List<Iterator<String>>>
|
||||
try {
|
||||
c.add(ArrayList())
|
||||
return "Fail"
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class MyIterator<E : Number> : Iterator<E> {
|
||||
override fun next() = null!!
|
||||
override fun hasNext() = null!!
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
(MyIterator<Int>() as MutableIterator<Number>).remove()
|
||||
return "Fail"
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
trait ListAny : List<Any>
|
||||
trait ListString : List<String>
|
||||
|
||||
trait AddStringImpl {
|
||||
fun add(s: String) {}
|
||||
}
|
||||
|
||||
class A : ListAny, ListString, AddStringImpl {
|
||||
override fun size(): Int = 0
|
||||
override fun isEmpty(): Boolean = true
|
||||
override fun contains(o: Any?): Boolean = false
|
||||
override fun iterator(): Iterator<String> = null!!
|
||||
override fun containsAll(c: Collection<Any?>): Boolean = false
|
||||
override fun get(index: Int): String = null!!
|
||||
override fun indexOf(o: Any?): Int = -1
|
||||
override fun lastIndexOf(o: Any?): Int = -1
|
||||
override fun listIterator(): ListIterator<String> = null!!
|
||||
override fun listIterator(index: Int): ListIterator<String> = null!!
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<String> = null!!
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A() as MutableList<String>
|
||||
a.add("Fail")
|
||||
return "OK"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import java.lang.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Test {
|
||||
public static class IterableImpl implements Iterable<String> {
|
||||
public Iterator<String> iterator() { return new IteratorImpl(); }
|
||||
}
|
||||
|
||||
public static class IteratorImpl implements Iterator<String> {
|
||||
public boolean hasNext() { return false; }
|
||||
public String next() { return null; }
|
||||
public void remove() { }
|
||||
}
|
||||
|
||||
public static class MapEntryImpl implements Map.Entry<String, String> {
|
||||
public String getKey() { return null; }
|
||||
public String getValue() { return null; }
|
||||
public String setValue(String s) { return null; }
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
class MyIterable : Test.IterableImpl()
|
||||
class MyIterator : Test.IteratorImpl()
|
||||
class MyMapEntry : Test.MapEntryImpl()
|
||||
|
||||
fun box(): String {
|
||||
MyIterable().iterator()
|
||||
|
||||
val a = MyIterator()
|
||||
a.hasNext()
|
||||
a.next()
|
||||
a.remove()
|
||||
|
||||
val b = MyMapEntry()
|
||||
b.getKey()
|
||||
b.getValue()
|
||||
b.setValue(null)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class Test {
|
||||
interface A {
|
||||
boolean add(String s);
|
||||
}
|
||||
|
||||
static class D extends C {}
|
||||
|
||||
void test() {
|
||||
A a = new D();
|
||||
a.add("lol");
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
abstract class C : Test.A, List<String> {
|
||||
override fun size(): Int = null!!
|
||||
override fun isEmpty(): Boolean = null!!
|
||||
override fun contains(o: Any?): Boolean = null!!
|
||||
override fun iterator(): Iterator<String> = null!!
|
||||
override fun containsAll(c: Collection<Any?>): Boolean = null!!
|
||||
override fun get(index: Int): String = null!!
|
||||
override fun indexOf(o: Any?): Int = null!!
|
||||
override fun lastIndexOf(o: Any?): Int = null!!
|
||||
override fun listIterator(): ListIterator<String> = null!!
|
||||
override fun listIterator(index: Int): ListIterator<String> = null!!
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<String> = null!!
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
Test().test()
|
||||
return "Fail"
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user