FIR: Rework loading overrides of special built-in methods from Java

Some of the changed data is correct, but some diagnostics are incorrect
Corner cases like having both contains(Object) and contains(String)
within implementation of Collection<String> is not supported
This commit is contained in:
Denis.Zharkov
2021-02-17 18:31:57 +03:00
parent 4b0aeb7105
commit 45018ea468
25 changed files with 725 additions and 372 deletions
@@ -0,0 +1,85 @@
// FILE: CollectionStringImpl.java
import java.util.Collection;
import java.util.Iterator;
public class CollectionStringImpl implements Collection<String> {
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(Object o) {
return false;
}
@Override
public Iterator<String> iterator() {
return null;
}
@Override
public Object[] toArray() {
return new Object[0];
}
@Override
public <T> T[] toArray(T[] a) {
return null;
}
@Override
public boolean add(String s) {
return false;
}
@Override
public boolean remove(Object o) {
return false;
}
@Override
public boolean containsAll(Collection<?> c) {
return false;
}
@Override
public boolean addAll(Collection<? extends String> c) {
return false;
}
@Override
public boolean removeAll(Collection<?> c) {
return false;
}
@Override
public boolean retainAll(Collection<?> c) {
return false;
}
@Override
public void clear() {
}
public boolean contains(String o) {
return true;
}
}
// FILE: main.kt
fun test(x: CollectionStringImpl) {
x.<!AMBIGUITY!>contains<!>("")
(x as Collection<String>).contains("")
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// FILE: CollectionStringImpl.java
import java.util.Collection;
@@ -40,14 +40,14 @@ fun foo(
1 <!INAPPLICABLE_CANDIDATE!>in<!> a
b.contains("")
b.contains(1)
b.<!INAPPLICABLE_CANDIDATE!>contains<!>(1)
"" in b
1 in b
1 <!INAPPLICABLE_CANDIDATE!>in<!> b
ic.contains("")
ic.contains(1)
ic.<!INAPPLICABLE_CANDIDATE!>contains<!>(1)
"" in ic
1 in ic
1 <!INAPPLICABLE_CANDIDATE!>in<!> ic
ka.contains("")
ka.<!INAPPLICABLE_CANDIDATE!>contains<!>(1)
@@ -55,9 +55,9 @@ fun foo(
1 <!INAPPLICABLE_CANDIDATE!>in<!> ka
kb.contains("")
kb.contains(1)
kb.<!INAPPLICABLE_CANDIDATE!>contains<!>(1)
"" in kb
1 in kb
1 <!INAPPLICABLE_CANDIDATE!>in<!> kb
al.contains("")
al.<!INAPPLICABLE_CANDIDATE!>contains<!>(1)
@@ -40,16 +40,16 @@ fun foo(
a.<!INAPPLICABLE_CANDIDATE!>containsAll<!>(ca)
b.containsAll(cs)
b.containsAll(ca)
b.<!INAPPLICABLE_CANDIDATE!>containsAll<!>(ca)
ic.containsAll(cs)
ic.containsAll(ca)
ic.<!INAPPLICABLE_CANDIDATE!>containsAll<!>(ca)
ka.containsAll(cs)
ka.<!INAPPLICABLE_CANDIDATE!>containsAll<!>(ca)
kb.containsAll(cs)
kb.containsAll(ca)
kb.<!INAPPLICABLE_CANDIDATE!>containsAll<!>(ca)
al.containsAll(cs)
al.<!INAPPLICABLE_CANDIDATE!>containsAll<!>(ca)
@@ -12,13 +12,13 @@ abstract class KA : A() {
}
fun foo(a: A, ka: KA) {
a.contains("")
a.contains(1)
"" in a
1 in a
a.<!AMBIGUITY!>contains<!>("")
a.<!NONE_APPLICABLE!>contains<!>(1)
"" <!AMBIGUITY!>in<!> a
1 <!NONE_APPLICABLE!>in<!> a
ka.contains("")
ka.contains(1)
ka.<!INAPPLICABLE_CANDIDATE!>contains<!>(1)
"" in ka
1 in ka
1 <!INAPPLICABLE_CANDIDATE!>in<!> ka
}
@@ -0,0 +1,19 @@
// FILE: Dict.java
public abstract class Dict<K, V> {
abstract public V get(Object key);
}
// FILE: MHashtable.java
abstract public class MHashtable<X, Y> extends Dict<X, Y> implements java.util.Map<X, Y> {
public V get(Object key) { return null; }
}
// FILE: main.kt
abstract class C1 : MHashtable<String, Int>()
abstract class C2 : MHashtable<String, Int>() {
override fun <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>get<!>(key: String) = 1
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// FILE: Dict.java
public abstract class Dict<K, V> {
@@ -1,32 +0,0 @@
// JAVAC_EXPECTED_FILE
// FILE: A.java
abstract public class A extends B {
public Integer removeAt(int x) { }
public boolean remove(Integer x) { }
}
// FILE: main.kt
import java.util.*;
abstract class B : MutableList<Int>, AbstractList<Int>() {
override fun removeAt(index: Int): Int = null!!
override fun remove(element: Int): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Boolean<!> = null!!
}
abstract class D : AbstractList<Int>() {
// removeAt() doesn't exist in java/util/AbstractList, it's a
// fake override of the method from kotlin/collections/MutableList
override fun removeAt(index: Int): Int = null!!
// AbstractList::remove() should return Int here. No fake overrides created.
// This may be a bug because the old compiler doesn't report a diagnostic here.
override fun remove(element: Int): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Boolean<!> = null!!
}
fun main(a: A, b: B, c: ArrayList<Int>) {
a.remove(1)
a.removeAt(0)
b.remove(1)
b.removeAt(0)
c.remove(1)
c.removeAt(0)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JAVAC_EXPECTED_FILE
// FILE: A.java
abstract public class A extends B {
@@ -1,12 +0,0 @@
// JAVAC_EXPECTED_FILE
// FILE: A.java
abstract public class A extends java.util.ArrayList<String> {
public final int size() { return 0; }
}
// FILE: main.kt
class B : A() {
override val size: Int = 1
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JAVAC_EXPECTED_FILE
// FILE: A.java
@@ -0,0 +1,113 @@
// FILE: AbstractSpecializedMap.java
public abstract class AbstractSpecializedMap implements java.util.Map<Integer, Double> {
public abstract double put(int x, double y);
public abstract double remove(int k);
public abstract double get(int k);
public abstract boolean containsKey(int k);
public boolean containsKey(Object x) {
return false;
}
public abstract boolean containsValue(double v);
public boolean containsValue(Object x) {
return false;
}
}
// FILE: SpecializedMap.java
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class SpecializedMap extends AbstractSpecializedMap {
public double put(int x, double y) {
return 123.0;
}
@Override
public Double get(Object key) {
return null;
}
@Override
public Double put(Integer key, Double value) {
return null;
}
public double remove(int k) {
return 456.0;
}
public Double remove(Object ok) {
return null;
}
public double get(int k) {
return 789.0;
}
public boolean containsKey(int k) {
return true;
}
public boolean containsValue(double v) {
return true;
}
@Override
public void putAll(Map<? extends Integer, ? extends Double> m) {
}
@Override
public void clear() {
}
@NotNull
@Override
public Set<Integer> keySet() {
return null;
}
@NotNull
@Override
public Collection<Double> values() {
return null;
}
@NotNull
@Override
public Set<Entry<Integer, Double>> entrySet() {
return null;
}
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return false;
}
}
// FILE: main.kt
fun foo(x: SpecializedMap) {
x.containsKey(1)
x.<!INAPPLICABLE_CANDIDATE!>containsKey<!>(null)
x.<!AMBIGUITY!>get<!>(2)
x.<!NONE_APPLICABLE!>get<!>(null)
x.<!AMBIGUITY!>remove<!>(3)
x.<!NONE_APPLICABLE!>remove<!>(null)
x.put(4, 5.0)
x.put(4, null)
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// FILE: AbstractSpecializedMap.java
public abstract class AbstractSpecializedMap implements java.util.Map<Integer, Double> {
public abstract double put(int x, double y);