Introduce additional overridability rule
It works only for Java methods and it's purpose is Java overridability rules emulation, namely distinction of primitive types and their wrappers. For example `void foo(Integer x)` should not be an override for `void foo(int x)` #KT-11440 Fixed #KT-11389 Fixed
This commit is contained in:
@@ -969,8 +969,12 @@ public class KotlinTypeMapper {
|
||||
}
|
||||
|
||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||
if (writeCustomParameter(f, parameter, sw)) continue;
|
||||
writeParameter(sw, parameter.getType(), f);
|
||||
boolean forceBoxing = MethodSignatureMappingKt.forceSingleValueParameterBoxing(f);
|
||||
writeParameter(
|
||||
sw,
|
||||
forceBoxing ? TypeUtils.makeNullable(parameter.getType()) : parameter.getType(),
|
||||
f
|
||||
);
|
||||
}
|
||||
|
||||
sw.writeReturnType();
|
||||
@@ -1020,24 +1024,6 @@ public class KotlinTypeMapper {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean writeCustomParameter(
|
||||
@NotNull FunctionDescriptor f,
|
||||
@NotNull ValueParameterDescriptor parameter,
|
||||
@NotNull JvmSignatureWriter sw
|
||||
) {
|
||||
FunctionDescriptor overridden =
|
||||
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(f);
|
||||
if (overridden == null) return false;
|
||||
if (SpecialBuiltinMembers.isFromJavaOrBuiltins(f)) return false;
|
||||
|
||||
if (overridden.getName().asString().equals("remove") && mapType(parameter.getType()).getSort() == Type.INT) {
|
||||
writeParameter(sw, TypeUtils.makeNullable(parameter.getType()), f);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getDefaultDescriptor(@NotNull Method method, @Nullable String dispatchReceiverDescriptor, boolean isExtension) {
|
||||
String descriptor = method.getDescriptor();
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
// 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 box(): String {
|
||||
val x = SpecializedMap()
|
||||
if (!x.containsKey(1)) return "fail 1"
|
||||
if (x.containsKey(null)) return "fail 2"
|
||||
|
||||
if (!x.containsValue(2.0)) return "fail 3"
|
||||
if (x.containsValue(null)) return "fail 4"
|
||||
|
||||
if (x.put(1, 5.0) != 123.0) return "fail 5"
|
||||
if (x.put(1, null) != null) return "fail 6"
|
||||
|
||||
if (x.remove(1) != 456.0) return "fail 7"
|
||||
if (x.remove(null) != null) return "fail 8"
|
||||
|
||||
if (x.get(1) != 789.0) return "fail 9"
|
||||
if (x.get(null) != null) return "fail 10"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// FILE: A.java
|
||||
import java.util.HashMap;
|
||||
|
||||
public class A extends HashMap<Integer, Double> {
|
||||
public double put(int x, double y) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double put(Integer key, Double value) {
|
||||
return super.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun box(): String {
|
||||
val o = A()
|
||||
o.put(1, 2.0)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// FILE: B.java
|
||||
public interface B<T1, T2> {
|
||||
double put(int x, double y);
|
||||
T2 put(T1 x, T2 y);
|
||||
}
|
||||
// FILE: A.java
|
||||
import java.util.HashMap;
|
||||
|
||||
public class A extends HashMap<Integer, Double> implements B<Integer, Double> {
|
||||
public double put(int x, double y) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double put(Integer key, Double value) {
|
||||
return super.put(key, value);
|
||||
}
|
||||
}
|
||||
// FILE: main.kt
|
||||
fun test(){
|
||||
val o = A()
|
||||
o.put(1, 2.0)
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package
|
||||
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public open class A : java.util.HashMap<kotlin.Int!, kotlin.Double!>, B<kotlin.Int!, kotlin.Double!> {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ val entries: kotlin.collections.MutableSet<kotlin.collections.MutableMap.MutableEntry<kotlin.Int!, kotlin.Double!>>
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var entrySet: kotlin.collections.(Mutable)Set<kotlin.collections.(Mutable)Map.(Mutable)Entry<kotlin.Int!, kotlin.Double!>!>!
|
||||
invisible_fake final override /*1*/ /*fake_override*/ val hashSeed: kotlin.Int
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var keySet: kotlin.collections.(Mutable)Set<kotlin.Int!>!
|
||||
public open override /*1*/ /*fake_override*/ val keys: kotlin.collections.MutableSet<kotlin.Int!>
|
||||
invisible_fake final override /*1*/ /*fake_override*/ val loadFactor: kotlin.Float
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var modCount: kotlin.Int
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var size: kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ val size: kotlin.Int
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var table: kotlin.Array<(out) java.util.HashMap.Entry<kotlin.Int!, kotlin.Double!>!>!
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var threshold: kotlin.Int
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var useAltHashing: kotlin.Boolean
|
||||
invisible_fake final override /*1*/ /*fake_override*/ var values: kotlin.collections.(Mutable)Collection<kotlin.Double!>!
|
||||
public open override /*1*/ /*fake_override*/ val values: kotlin.collections.MutableCollection<kotlin.Double!>
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun addEntry(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int!, /*2*/ p2: kotlin.Double!, /*3*/ p3: kotlin.Int): kotlin.Unit
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun capacity(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public open override /*1*/ /*fake_override*/ fun containsKey(/*0*/ key: kotlin.Int!): kotlin.Boolean
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun containsNullValue(): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun containsValue(/*0*/ value: kotlin.Double!): kotlin.Boolean
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun createEntry(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int!, /*2*/ p2: kotlin.Double!, /*3*/ p3: kotlin.Int): kotlin.Unit
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun entrySet0(): kotlin.collections.(Mutable)Set<kotlin.collections.(Mutable)Map.(Mutable)Entry<kotlin.Int!, kotlin.Double!>!>!
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun get(/*0*/ key: kotlin.Int!): kotlin.Double?
|
||||
invisible_fake final override /*1*/ /*fake_override*/ fun getEntry(/*0*/ p0: kotlin.Any!): java.util.HashMap.Entry<kotlin.Int!, kotlin.Double!>!
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun getForNullKey(): kotlin.Double!
|
||||
invisible_fake final override /*1*/ /*fake_override*/ fun hash(/*0*/ p0: kotlin.Any!): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun init(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun loadFactor(): kotlin.Float
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun newEntryIterator(): kotlin.collections.(Mutable)Iterator<kotlin.collections.(Mutable)Map.(Mutable)Entry<kotlin.Int!, kotlin.Double!>!>!
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun newKeyIterator(): kotlin.collections.(Mutable)Iterator<kotlin.Int!>!
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun newValueIterator(): kotlin.collections.(Mutable)Iterator<kotlin.Double!>!
|
||||
public open override /*1*/ fun put(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Double): kotlin.Double
|
||||
@java.lang.Override() public open override /*2*/ fun put(/*0*/ key: kotlin.Int!, /*1*/ value: kotlin.Double!): kotlin.Double?
|
||||
public open override /*1*/ /*fake_override*/ fun putAll(/*0*/ from: kotlin.collections.Map<out kotlin.Int!, kotlin.Double!>): kotlin.Unit
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun putAllForCreate(/*0*/ p0: (kotlin.collections.MutableMap<out kotlin.Int!, out kotlin.Double!>..kotlin.collections.Map<out kotlin.Int!, kotlin.Double!>?)): kotlin.Unit
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun putForCreate(/*0*/ p0: kotlin.Int!, /*1*/ p1: kotlin.Double!): kotlin.Unit
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun putForNullKey(/*0*/ p0: kotlin.Double!): kotlin.Double!
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun readObject(/*0*/ p0: java.io.ObjectInputStream!): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ key: kotlin.Int!): kotlin.Double?
|
||||
invisible_fake final override /*1*/ /*fake_override*/ fun removeEntryForKey(/*0*/ p0: kotlin.Any!): java.util.HashMap.Entry<kotlin.Int!, kotlin.Double!>!
|
||||
invisible_fake final override /*1*/ /*fake_override*/ fun removeMapping(/*0*/ p0: kotlin.Any!): java.util.HashMap.Entry<kotlin.Int!, kotlin.Double!>!
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun resize(/*0*/ p0: kotlin.Int): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun transfer(/*0*/ p0: kotlin.Array<(out) java.util.HashMap.Entry<(raw) kotlin.Any!, (raw) kotlin.Any!>!>!, /*1*/ p1: kotlin.Boolean): kotlin.Unit
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun writeObject(/*0*/ p0: java.io.ObjectOutputStream!): kotlin.Unit
|
||||
|
||||
// Static members
|
||||
invisible_fake const final override /*1*/ /*fake_override*/ val ALTERNATIVE_HASHING_THRESHOLD_DEFAULT: kotlin.Int
|
||||
invisible_fake const final override /*1*/ /*fake_override*/ val DEFAULT_INITIAL_CAPACITY: kotlin.Int
|
||||
invisible_fake const final override /*1*/ /*fake_override*/ val DEFAULT_LOAD_FACTOR: kotlin.Float
|
||||
invisible_fake const final override /*1*/ /*fake_override*/ val MAXIMUM_CAPACITY: kotlin.Int
|
||||
invisible_fake const final override /*1*/ /*fake_override*/ val serialVersionUID: kotlin.Long
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun eq(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Boolean
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun indexFor(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Int
|
||||
}
|
||||
|
||||
public interface B</*0*/ T1 : kotlin.Any!, /*1*/ T2 : kotlin.Any!> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public abstract fun put(/*0*/ x: T1!, /*1*/ y: T2!): T2!
|
||||
public abstract fun put(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Double): kotlin.Double
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// FILE: A.java
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class A {
|
||||
public void foo(int x) {}
|
||||
public void bar(@NotNull Double x) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import org.jetbrains.annotations.*;
|
||||
public class B extends A {
|
||||
public void foo(@NotNull Integer x) {}
|
||||
public void bar(double x) {}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun foo(b: B) {
|
||||
// See KT-9182
|
||||
b.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1)
|
||||
b.<!OVERLOAD_RESOLUTION_AMBIGUITY!>bar<!>(2.0)
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package
|
||||
|
||||
public fun foo(/*0*/ b: B): kotlin.Unit
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
public open fun bar(/*0*/ @org.jetbrains.annotations.NotNull() x: kotlin.Double): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class B : A {
|
||||
public constructor B()
|
||||
public open fun bar(/*0*/ x: kotlin.Double): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun bar(/*0*/ @org.jetbrains.annotations.NotNull() x: kotlin.Double): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open fun foo(/*0*/ @org.jetbrains.annotations.NotNull() x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+113
@@ -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.containsKey(null)
|
||||
|
||||
x.get(2)
|
||||
x.get(null)
|
||||
|
||||
x.remove(3)
|
||||
x.remove(null)
|
||||
|
||||
x.put(4, 5.0)
|
||||
x.put(4, null)
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package
|
||||
|
||||
public fun foo(/*0*/ x: SpecializedMap): kotlin.Unit
|
||||
|
||||
public abstract class AbstractSpecializedMap : kotlin.collections.MutableMap<kotlin.Int!, kotlin.Double!> {
|
||||
public constructor AbstractSpecializedMap()
|
||||
public abstract override /*1*/ /*fake_override*/ val entries: kotlin.collections.MutableSet<kotlin.collections.MutableMap.MutableEntry<kotlin.Int!, kotlin.Double!>>
|
||||
public abstract override /*1*/ /*fake_override*/ val keys: kotlin.collections.MutableSet<kotlin.Int!>
|
||||
public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int
|
||||
public abstract override /*1*/ /*fake_override*/ val values: kotlin.collections.MutableCollection<kotlin.Double!>
|
||||
public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit
|
||||
public abstract fun containsKey(/*0*/ k: kotlin.Int): kotlin.Boolean
|
||||
public open override /*1*/ fun containsKey(/*0*/ x: kotlin.Int!): kotlin.Boolean
|
||||
public abstract fun containsValue(/*0*/ v: kotlin.Double): kotlin.Boolean
|
||||
public open override /*1*/ fun containsValue(/*0*/ x: kotlin.Double!): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract operator fun get(/*0*/ k: kotlin.Int): kotlin.Double
|
||||
public abstract override /*1*/ /*fake_override*/ fun get(/*0*/ key: kotlin.Int!): kotlin.Double?
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
|
||||
public abstract fun put(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Double): kotlin.Double
|
||||
public abstract override /*1*/ /*fake_override*/ fun put(/*0*/ key: kotlin.Int!, /*1*/ value: kotlin.Double!): kotlin.Double?
|
||||
public abstract override /*1*/ /*fake_override*/ fun putAll(/*0*/ from: kotlin.collections.Map<out kotlin.Int!, kotlin.Double!>): kotlin.Unit
|
||||
public abstract fun remove(/*0*/ k: kotlin.Int): kotlin.Double
|
||||
public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ key: kotlin.Int!): kotlin.Double?
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class SpecializedMap : AbstractSpecializedMap {
|
||||
public constructor SpecializedMap()
|
||||
public open override /*1*/ val entries: kotlin.collections.MutableSet<kotlin.collections.MutableMap.MutableEntry<kotlin.Int!, kotlin.Double!>>
|
||||
public open override /*1*/ val keys: kotlin.collections.MutableSet<kotlin.Int!>
|
||||
public open override /*1*/ val size: kotlin.Int
|
||||
public open override /*1*/ val values: kotlin.collections.MutableCollection<kotlin.Double!>
|
||||
@java.lang.Override() public open override /*1*/ fun clear(): kotlin.Unit
|
||||
public open override /*1*/ fun containsKey(/*0*/ k: kotlin.Int): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun containsKey(/*0*/ x: kotlin.Int!): kotlin.Boolean
|
||||
public open override /*1*/ fun containsValue(/*0*/ v: kotlin.Double): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun containsValue(/*0*/ x: kotlin.Double!): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ fun get(/*0*/ k: kotlin.Int): kotlin.Double
|
||||
@java.lang.Override() public open override /*1*/ fun get(/*0*/ key: kotlin.Int!): kotlin.Double?
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
@java.lang.Override() public open override /*1*/ fun isEmpty(): kotlin.Boolean
|
||||
public open override /*1*/ fun put(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Double): kotlin.Double
|
||||
@java.lang.Override() public open override /*1*/ fun put(/*0*/ key: kotlin.Int!, /*1*/ value: kotlin.Double!): kotlin.Double?
|
||||
@java.lang.Override() public open override /*1*/ fun putAll(/*0*/ from: kotlin.collections.Map<out kotlin.Int!, kotlin.Double!>): kotlin.Unit
|
||||
public open override /*1*/ fun remove(/*0*/ k: kotlin.Int): kotlin.Double
|
||||
public open override /*1*/ fun remove(/*0*/ ok: kotlin.Int!): kotlin.Double?
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -11118,6 +11118,33 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/j+k/primitiveOverrides")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PrimitiveOverrides extends AbstractDiagnosticsTest {
|
||||
public void testAllFilesPresentInPrimitiveOverrides() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/primitiveOverrides"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt11140.kt")
|
||||
public void testKt11140() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/primitiveOverrides/kt11140.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notNullAnnotated.kt")
|
||||
public void testNotNullAnnotated() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/primitiveOverrides/notNullAnnotated.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("specializedMap.kt")
|
||||
public void testSpecializedMap() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/primitiveOverrides/specializedMap.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/j+k/properties")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+12
@@ -366,6 +366,18 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/platformTypes/genericUnit.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("specializedMapFull.kt")
|
||||
public void testSpecializedMapFull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/platformTypes/specializedMapFull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("specializedMapPut.kt")
|
||||
public void testSpecializedMapPut() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/platformTypes/specializedMapPut.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxAgainstJava/property")
|
||||
|
||||
+58
-2
@@ -16,15 +16,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName.sameAsRenamedInJvmBuiltin
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.sameAsBuiltinMethodWithErasedValueParameters
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmType
|
||||
import org.jetbrains.kotlin.load.kotlin.forceSingleValueParameterBoxing
|
||||
import org.jetbrains.kotlin.load.kotlin.mapToJvmType
|
||||
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
|
||||
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isDocumentedAnnotation
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
|
||||
/**
|
||||
* This class contains Java-related overridability conditions that may force incompatibility
|
||||
@@ -39,6 +43,10 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
|
||||
return Result.INCOMPATIBLE
|
||||
}
|
||||
|
||||
if (doesJavaOverrideHaveIncompatibleValueParameterKinds(superDescriptor, subDescriptor)) {
|
||||
return Result.INCOMPATIBLE
|
||||
}
|
||||
|
||||
return Result.UNKNOWN
|
||||
}
|
||||
|
||||
@@ -84,5 +92,53 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
override fun getContract() = ExternalOverridabilityCondition.Contract.CONFLICTS_ONLY
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Checks if any pair of corresponding value parameters has different type kinds, e.g. one is primitive and another is not
|
||||
*
|
||||
* As it comes from it's name it only checks overrides in Java classes
|
||||
*/
|
||||
fun doesJavaOverrideHaveIncompatibleValueParameterKinds(
|
||||
superDescriptor: CallableDescriptor,
|
||||
subDescriptor: CallableDescriptor
|
||||
): Boolean {
|
||||
if (subDescriptor !is JavaMethodDescriptor || superDescriptor !is FunctionDescriptor) return false
|
||||
assert(subDescriptor.valueParameters.size == superDescriptor.valueParameters.size) {
|
||||
"External overridability condition with CONFLICTS_ONLY should not be run with different value parameters size"
|
||||
}
|
||||
|
||||
for ((subParameter, superParameter) in subDescriptor.original.valueParameters.zip(superDescriptor.original.valueParameters)) {
|
||||
val isSubPrimitive = mapValueParameterType(subDescriptor, subParameter) is JvmType.Primitive
|
||||
val isSuperPrimitive = mapValueParameterType(superDescriptor, superParameter) is JvmType.Primitive
|
||||
|
||||
if (isSubPrimitive != isSuperPrimitive) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun mapValueParameterType(f: FunctionDescriptor, valueParameterDescriptor: ValueParameterDescriptor) =
|
||||
if (forceSingleValueParameterBoxing(f) || isPrimitiveCompareTo(f))
|
||||
valueParameterDescriptor.type.makeNullable().mapToJvmType()
|
||||
else
|
||||
valueParameterDescriptor.type.mapToJvmType()
|
||||
|
||||
// It's useful here to suppose that 'Int.compareTo(Int)' requires boxing of it's value parameter
|
||||
// As it happens in java.lang.Integer analogue
|
||||
// It only affects additional built-ins loading (see 'testLoadBuiltIns' tests)
|
||||
private fun isPrimitiveCompareTo(f: FunctionDescriptor): Boolean {
|
||||
if (f.valueParameters.size != 1) return false
|
||||
val classDescriptor =
|
||||
f.containingDeclaration as? ClassDescriptor ?: return false
|
||||
val parameterClass =
|
||||
f.valueParameters.single().type.constructor.declarationDescriptor as? ClassDescriptor
|
||||
?: return false
|
||||
return KotlinBuiltIns.isPrimitiveClass(classDescriptor) && classDescriptor.fqNameSafe == parameterClass.fqNameSafe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -49,6 +49,7 @@ import org.jetbrains.kotlin.load.java.typeEnhancement.enhanceSignatures
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
@@ -164,9 +165,12 @@ class LazyJavaClassMemberScope(
|
||||
}
|
||||
|
||||
private fun CallableDescriptor.doesOverride(superDescriptor: CallableDescriptor): Boolean {
|
||||
return OverridingUtil.DEFAULT.isOverridableByWithoutExternalConditions(
|
||||
superDescriptor, this, /* checkReturnType = */ true
|
||||
).result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
|
||||
val commonOverridabilityResult =
|
||||
OverridingUtil.DEFAULT.isOverridableByWithoutExternalConditions(superDescriptor, this, true).result
|
||||
|
||||
return commonOverridabilityResult == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE &&
|
||||
!JavaIncompatibilityRulesOverridabilityCondition.doesJavaOverrideHaveIncompatibleValueParameterKinds(
|
||||
superDescriptor, this)
|
||||
}
|
||||
|
||||
private fun PropertyDescriptor.findGetterOverride(
|
||||
|
||||
+20
-4
@@ -17,6 +17,8 @@
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.isFromJavaOrBuiltins
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -44,6 +46,17 @@ fun FunctionDescriptor.computeJvmDescriptor()
|
||||
}
|
||||
}.toString()
|
||||
|
||||
// Boxing is only necessary for 'remove(E): Boolean' of a MutableList<Int> implementation
|
||||
// Otherwise this method will clash with 'remove(I): E' also defined in the JDK interface (mapped to kotlin 'removeAt')
|
||||
fun forceSingleValueParameterBoxing(f: FunctionDescriptor): Boolean {
|
||||
if (f.isFromJavaOrBuiltins()) return false
|
||||
|
||||
if (f.name.asString() != "remove" ||
|
||||
(f.original.valueParameters.single().type.mapToJvmType() as? JvmType.Primitive)?.jvmPrimitiveType != JvmPrimitiveType.INT) return false
|
||||
|
||||
return BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(f) != null
|
||||
}
|
||||
|
||||
// This method only returns not-null for class methods
|
||||
internal fun CallableDescriptor.computeJvmSignature(): String? = signatures {
|
||||
if (DescriptorUtils.isLocal(this@computeJvmSignature)) return null
|
||||
@@ -72,16 +85,19 @@ internal val ClassId.internalName: String
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendErasedType(type: KotlinType) {
|
||||
append(
|
||||
JvmTypeFactoryImpl.toString(
|
||||
mapType(type, JvmTypeFactoryImpl, TypeMappingMode.DEFAULT, TypeMappingConfigurationImpl, descriptorTypeWriter = null)))
|
||||
append(type.mapToJvmType())
|
||||
}
|
||||
|
||||
private sealed class JvmType {
|
||||
internal fun KotlinType.mapToJvmType() =
|
||||
mapType(this, JvmTypeFactoryImpl, TypeMappingMode.DEFAULT, TypeMappingConfigurationImpl, descriptorTypeWriter = null)
|
||||
|
||||
sealed class JvmType {
|
||||
// null means 'void'
|
||||
class Primitive(val jvmPrimitiveType: JvmPrimitiveType?) : JvmType()
|
||||
class Object(val internalName: String) : JvmType()
|
||||
class Array(val elementType: JvmType) : JvmType()
|
||||
|
||||
override fun toString() = JvmTypeFactoryImpl.toString(this)
|
||||
}
|
||||
|
||||
private object JvmTypeFactoryImpl : JvmTypeFactory<JvmType> {
|
||||
|
||||
Reference in New Issue
Block a user