Implement hack to support both remove() and removeAt() in MutableList<Int>
Also add couple of tests about CharSequence.get
This commit is contained in:
@@ -934,6 +934,7 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : valueParameters) {
|
for (ValueParameterDescriptor parameter : valueParameters) {
|
||||||
|
if (writeCustomParameter(f, parameter, sw)) continue;
|
||||||
writeParameter(sw, parameter.getType());
|
writeParameter(sw, parameter.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -957,6 +958,23 @@ public class JetTypeMapper {
|
|||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean writeCustomParameter(
|
||||||
|
@NotNull FunctionDescriptor f,
|
||||||
|
@NotNull ValueParameterDescriptor parameter,
|
||||||
|
@NotNull BothSignatureWriter sw
|
||||||
|
) {
|
||||||
|
FunctionDescriptor overridden = BuiltinsPropertiesUtilKt.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(f);
|
||||||
|
if (overridden == null) return false;
|
||||||
|
if (BuiltinsPropertiesUtilKt.isFromJavaOrBuiltins(f)) return false;
|
||||||
|
|
||||||
|
if (overridden.getName().asString().equals("remove") && mapType(parameter.getType()).getSort() == Type.INT) {
|
||||||
|
writeParameter(sw, TypeUtils.makeNullable(parameter.getType()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String getDefaultDescriptor(@NotNull Method method, @Nullable String dispatchReceiverDescriptor, boolean isExtension) {
|
public static String getDefaultDescriptor(@NotNull Method method, @Nullable String dispatchReceiverDescriptor, boolean isExtension) {
|
||||||
String descriptor = method.getDescriptor();
|
String descriptor = method.getDescriptor();
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class J {
|
||||||
|
|
||||||
|
public static class B extends A {
|
||||||
|
public char get(int index) {
|
||||||
|
if (index == 1) return 'a';
|
||||||
|
return super.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String foo() {
|
||||||
|
B b = new B();
|
||||||
|
CharSequence cs = (CharSequence) b;
|
||||||
|
|
||||||
|
if (cs.charAt(0) != 'z') return "fail 1";
|
||||||
|
if (b.get(0) != 'z') return "fail 2";
|
||||||
|
|
||||||
|
if (cs.charAt(1) != 'a') return "fail 3";
|
||||||
|
if (b.get(1) != 'a') return "fail 4";
|
||||||
|
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
open class A : CharSequence {
|
||||||
|
override fun length(): Int {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(index: Int) = 'z';
|
||||||
|
|
||||||
|
override fun subSequence(start: Int, end: Int): CharSequence {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val b = J.B()
|
||||||
|
val a = A()
|
||||||
|
|
||||||
|
if (b[0] != 'z') return "fail 6"
|
||||||
|
if (a[0] != 'z') return "fail 7"
|
||||||
|
if (b[1] != 'a') return "fail 8"
|
||||||
|
if (a[0] != 'z') return "fail 9"
|
||||||
|
|
||||||
|
if (b.get(0) != 'z') return "fail 10"
|
||||||
|
if (a.get(0) != 'z') return "fail 11"
|
||||||
|
if (b.get(1) != 'a') return "fail 12"
|
||||||
|
if (a.get(1) != 'z') return "fail 13"
|
||||||
|
|
||||||
|
return J.foo();
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class J {
|
||||||
|
|
||||||
|
private static class MyList extends A {}
|
||||||
|
|
||||||
|
public static String foo() {
|
||||||
|
MyList myList = new MyList();
|
||||||
|
List<Integer> list = (List<Integer>) myList;
|
||||||
|
|
||||||
|
if (!list.remove((Integer) 1)) return "fail 1";
|
||||||
|
if (list.remove((int) 1) != 123) return "fail 2";
|
||||||
|
|
||||||
|
if (!myList.remove((Integer) 1)) return "fail 3";
|
||||||
|
if (myList.remove((int) 1) != 123) return "fail 4";
|
||||||
|
|
||||||
|
if (myList.removeAt(1) != 123) return "fail 5";
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
open class A : MutableList<Int> {
|
||||||
|
override val size: Int
|
||||||
|
get() = throw UnsupportedOperationException()
|
||||||
|
override val isEmpty: Boolean
|
||||||
|
get() = throw UnsupportedOperationException()
|
||||||
|
|
||||||
|
override fun contains(o: Int): Boolean {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containsAll(c: Collection<Int>): Boolean {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(index: Int): Int {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun indexOf(o: Any?): Int {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun lastIndexOf(o: Any?): Int {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun add(e: Int): Boolean {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(o: Int) = true
|
||||||
|
|
||||||
|
override fun removeAt(index: Int): Int = 123
|
||||||
|
|
||||||
|
override fun addAll(c: Collection<Int>): Boolean {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addAll(index: Int, c: Collection<Int>): 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(index: Int, element: Int): Int {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun add(index: Int, element: Int) {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun listIterator(): MutableListIterator<Int> {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun listIterator(index: Int): MutableListIterator<Int> {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun subList(fromIndex: Int, toIndex: Int): MutableList<Int> {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): MutableIterator<Int> {
|
||||||
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = J.foo()
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
abstract class A1 : CharSequence {}
|
||||||
|
|
||||||
|
abstract class A2 : CharSequence {
|
||||||
|
override fun get(index: Int) = 'z';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 public final bridge charAt
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
abstract class A1<T> : MutableList<T> {
|
||||||
|
override fun remove(x: T): Boolean = true
|
||||||
|
override fun removeAt(index: Int): T = null!!
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class A2 : MutableList<String> {
|
||||||
|
override fun remove(x: String): Boolean = true
|
||||||
|
override fun removeAt(index: Int): String = null!!
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class A3 : java.util.AbstractList<String>() {
|
||||||
|
override fun remove(x: String): Boolean = true
|
||||||
|
override fun removeAt(index: Int): String = null!!
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class A4 : java.util.AbstractList<String>() {
|
||||||
|
override abstract fun remove(x: String): Boolean
|
||||||
|
override abstract fun removeAt(index: Int): String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class A5 : java.util.ArrayList<String>() {
|
||||||
|
override fun remove(x: String): Boolean = true
|
||||||
|
override fun removeAt(index: Int): String = null!!
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class A6 : java.util.ArrayList<String>() {
|
||||||
|
override abstract fun remove(x: String): Boolean
|
||||||
|
override abstract fun removeAt(index: Int): String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class A7 : MutableList<String>
|
||||||
|
abstract class A8 : java.util.ArrayList<String>()
|
||||||
|
|
||||||
|
interface A9 : MutableList<String> {}
|
||||||
|
|
||||||
|
abstract class A10 : MutableList<Int> {
|
||||||
|
override fun remove(x: Int): Boolean = true
|
||||||
|
override fun removeAt(index: Int): Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(
|
||||||
|
a1: A1<String>,
|
||||||
|
a2: A2,
|
||||||
|
a3: A3,
|
||||||
|
a4: A4,
|
||||||
|
a5: A5,
|
||||||
|
a6: A6,
|
||||||
|
a7: A7,
|
||||||
|
a8: A8,
|
||||||
|
a9: A9,
|
||||||
|
a10: A10,
|
||||||
|
c1: MutableList<String>,
|
||||||
|
c2: MutableList<Int>
|
||||||
|
) {
|
||||||
|
a1.removeAt(1)
|
||||||
|
a1.remove("")
|
||||||
|
|
||||||
|
a2.removeAt(1)
|
||||||
|
a2.remove("")
|
||||||
|
|
||||||
|
a3.removeAt(1)
|
||||||
|
a3.remove("")
|
||||||
|
|
||||||
|
a4.removeAt(1)
|
||||||
|
a4.remove("")
|
||||||
|
|
||||||
|
a5.removeAt(1)
|
||||||
|
a5.remove("")
|
||||||
|
|
||||||
|
a6.removeAt(1)
|
||||||
|
a6.remove("")
|
||||||
|
|
||||||
|
a7.removeAt(1)
|
||||||
|
a7.remove("")
|
||||||
|
|
||||||
|
a8.removeAt(1)
|
||||||
|
a8.remove("")
|
||||||
|
|
||||||
|
a9.removeAt(1)
|
||||||
|
a9.remove("")
|
||||||
|
|
||||||
|
a10.removeAt(1)
|
||||||
|
a10.remove(2)
|
||||||
|
|
||||||
|
c1.removeAt(1)
|
||||||
|
c1.remove("")
|
||||||
|
|
||||||
|
c2.removeAt(1)
|
||||||
|
c2.remove(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
9 public final bridge remove\(I\) -> Bridges for removeAt from A2-A10
|
||||||
|
7 public synthetic bridge remove\(I\)Ljava/lang/Object; -> Synthetic bridges from A2-A9
|
||||||
|
16 INVOKEVIRTUAL A[0-9]+.removeAt \(I\) -> calls in bridges
|
||||||
|
1 public remove\(Ljava/lang/Integer;\)Z -> implementation in A10
|
||||||
|
3 public abstract removeAt\(I\) -> A4, A6, A7
|
||||||
|
1 INVOKEINTERFACE A9\.remove \(I\) -> call A9.removeAt
|
||||||
|
1 INVOKEINTERFACE A9\.remove \(Ljava/lang/Object;\) -> call A9.remove
|
||||||
|
9 INVOKEVIRTUAL A[0-9]+\.remove \(I\) -> calls to A1-A9.removeAt
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 9 public final bridge remove\(I\)
|
||||||
|
// 7 public synthetic bridge remove\(I\)Ljava/lang/Object;
|
||||||
|
// 1 public remove\(Ljava/lang/Integer;\)Z
|
||||||
|
// 3 public abstract removeAt\(I\)
|
||||||
|
// 16 INVOKEVIRTUAL A[0-9]+.removeAt \(I\)
|
||||||
|
// 1 INVOKEINTERFACE A9\.remove \(I\)
|
||||||
|
// 1 INVOKEINTERFACE A9\.remove \(Ljava/lang/Object;\)
|
||||||
|
// 9 INVOKEVIRTUAL A[0-9]+\.remove \(I\)
|
||||||
|
// 1 INVOKEVIRTUAL A10\.remove \(I\)
|
||||||
|
// 9 INVOKEVIRTUAL A[0-9]+\.remove \(I\)
|
||||||
|
// 1 INVOKEVIRTUAL A10\.remove \(I\)
|
||||||
|
// 2 INVOKEINTERFACE java\/util\/List.remove \(I\)
|
||||||
|
// 2 INVOKEINTERFACE java\/util\/List.remove \(Ljava/lang/Object;\)
|
||||||
|
|
||||||
@@ -367,12 +367,24 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/builtinFunctions"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/builtinFunctions"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("charSequence.kt")
|
||||||
|
public void testCharSequence() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/builtinFunctions/charSequence.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("contains.kt")
|
@TestMetadata("contains.kt")
|
||||||
public void testContains() throws Exception {
|
public void testContains() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/builtinFunctions/contains.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/builtinFunctions/contains.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("removeAt.kt")
|
||||||
|
public void testRemoveAt() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/builtinFunctions/removeAt.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("size.kt")
|
@TestMetadata("size.kt")
|
||||||
public void testSize() throws Exception {
|
public void testSize() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/builtinFunctions/size.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/builtinFunctions/size.kt");
|
||||||
|
|||||||
+12
@@ -179,12 +179,24 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/collections"), Pattern.compile("^([^\\.]+)$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava/collections"), Pattern.compile("^([^\\.]+)$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("charSequence")
|
||||||
|
public void testCharSequence() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/charSequence/");
|
||||||
|
doTestWithJava(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mutableList")
|
@TestMetadata("mutableList")
|
||||||
public void testMutableList() throws Exception {
|
public void testMutableList() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/mutableList/");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/mutableList/");
|
||||||
doTestWithJava(fileName);
|
doTestWithJava(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("removeAtInt")
|
||||||
|
public void testRemoveAtInt() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/removeAtInt/");
|
||||||
|
doTestWithJava(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("strList")
|
@TestMetadata("strList")
|
||||||
public void testStrList() throws Exception {
|
public void testStrList() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/strList/");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/strList/");
|
||||||
|
|||||||
+3
-1
@@ -115,11 +115,13 @@ public fun CallableMemberDescriptor.getJvmMethodNameIfSpecial(): String? {
|
|||||||
private fun CallableMemberDescriptor.getBuiltinOverriddenThatAffectsJvmName(): CallableMemberDescriptor? {
|
private fun CallableMemberDescriptor.getBuiltinOverriddenThatAffectsJvmName(): CallableMemberDescriptor? {
|
||||||
val overriddenBuiltin = getBuiltinSpecialOverridden() ?: return null
|
val overriddenBuiltin = getBuiltinSpecialOverridden() ?: return null
|
||||||
|
|
||||||
if (isFromJava || isFromBuiltins()) return overriddenBuiltin
|
if (isFromJavaOrBuiltins()) return overriddenBuiltin
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun CallableMemberDescriptor.isFromJavaOrBuiltins() = isFromJava || isFromBuiltins()
|
||||||
|
|
||||||
private fun CallableMemberDescriptor.specialJvmName(): Name? {
|
private fun CallableMemberDescriptor.specialJvmName(): Name? {
|
||||||
return BuiltinSpecialMethods.FQ_NAMES_TO_JVM_MAP[fqNameOrNull() ?: return null]
|
return BuiltinSpecialMethods.FQ_NAMES_TO_JVM_MAP[fqNameOrNull() ?: return null]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user