Do not generate collection stubs for Kotlin-specific signatures

#KT-14188 Fixed
This commit is contained in:
Denis Zharkov
2016-10-05 14:07:29 +03:00
parent d2de4579de
commit 8ee568105c
5 changed files with 72 additions and 11 deletions
@@ -101,10 +101,6 @@ class CollectionStubMethodGenerator(
// present in the bytecode (abstract) and we don't want a duplicate signature error
if (method.findOverriddenFromDirectSuperClass(descriptor)?.kind == DECLARATION) continue
// Otherwise we can safely generate the stub with the substituted signature
val signature = method.signature()
methodStubsToGenerate.add(signature)
// If the substituted signature differs from the original one in MutableCollection, we should also generate a stub with
// the original (erased) signature. It doesn't really matter if this is a bridge method delegating to the first stub or
// a method with its own exception-throwing code, for simplicity we do the latter here.
@@ -114,9 +110,8 @@ class CollectionStubMethodGenerator(
// methods which need to be generated with the ACC_SYNTHETIC flag
val overriddenMethod = method.findOverriddenFromDirectSuperClass(mutableClass)!!
val originalSignature = overriddenMethod.original.signature()
var specialSignature: JvmMethodSignature? = null
if (overriddenMethod.isBuiltinWithSpecialDescriptorInJvm()) {
val commonSignature = if (overriddenMethod.isBuiltinWithSpecialDescriptorInJvm()) {
// Stubs for remove(Ljava/lang/Object;)Z and remove(I) should not be synthetic
// Otherwise Javac will not see it
val overriddenMethodSignature = overriddenMethod.signature()
@@ -134,16 +129,19 @@ class CollectionStubMethodGenerator(
else
Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters)
specialSignature = JvmMethodGenericSignature(
JvmMethodGenericSignature(
asmMethod,
valueParameters,
specialGenericSignature
)
methodStubsToGenerate.add(specialSignature)
}
else {
method.signature()
}
if (originalSignature.asmMethod != signature.asmMethod && originalSignature.asmMethod != specialSignature?.asmMethod) {
methodStubsToGenerate.add(commonSignature)
if (originalSignature.asmMethod != commonSignature.asmMethod) {
syntheticStubsToGenerate.add(originalSignature)
}
}
@@ -0,0 +1,2 @@
abstract class A<T> : List<T>
abstract class B : List<Int>
@@ -0,0 +1,56 @@
@kotlin.Metadata
public abstract class A {
public method <init>(): void
public method add(p0: int, p1: java.lang.Object): void
public method add(p0: java.lang.Object): boolean
public method addAll(p0: int, p1: java.util.Collection): boolean
public method addAll(p0: java.util.Collection): boolean
public method clear(): void
public abstract method contains(p0: java.lang.Object): boolean
public abstract method getSize(): int
public abstract method indexOf(p0: java.lang.Object): int
public abstract method lastIndexOf(p0: java.lang.Object): int
public method listIterator(): java.util.ListIterator
public method listIterator(p0: int): java.util.ListIterator
public method remove(p0: int): java.lang.Object
public method remove(p0: java.lang.Object): boolean
public method removeAll(p0: java.util.Collection): boolean
public method retainAll(p0: java.util.Collection): boolean
public method set(p0: int, p1: java.lang.Object): java.lang.Object
public final method size(): int
public method subList(p0: int, p1: int): java.util.List
public method toArray(): java.lang.Object[]
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
}
@kotlin.Metadata
public abstract class B {
public method <init>(): void
public method add(p0: int): boolean
public method add(p0: int, p1: int): void
public synthetic method add(p0: int, p1: java.lang.Object): void
public synthetic method add(p0: java.lang.Object): boolean
public method addAll(p0: int, p1: java.util.Collection): boolean
public method addAll(p0: java.util.Collection): boolean
public method clear(): void
public abstract method contains(p0: int): boolean
public final method contains(p0: java.lang.Object): boolean
public abstract method getSize(): int
public abstract method indexOf(p0: int): int
public final method indexOf(p0: java.lang.Object): int
public abstract method lastIndexOf(p0: int): int
public final method lastIndexOf(p0: java.lang.Object): int
public method listIterator(): java.util.ListIterator
public method listIterator(p0: int): java.util.ListIterator
public method remove(p0: int): int
public synthetic method remove(p0: int): java.lang.Object
public method remove(p0: java.lang.Object): boolean
public method removeAll(p0: java.util.Collection): boolean
public method retainAll(p0: java.util.Collection): boolean
public method set(p0: int, p1: int): java.lang.Integer
public synthetic method set(p0: int, p1: java.lang.Object): java.lang.Object
public final method size(): int
public method subList(p0: int, p1: int): java.util.List
public method toArray(): java.lang.Object[]
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
}
@@ -18,7 +18,6 @@ public final class A2 {
public method isEmpty(): boolean
public @org.jetbrains.annotations.NotNull method iterator(): java.util.Iterator
public method remove(p0: java.lang.Object): boolean
public method remove(p0: java.lang.String): boolean
public method removeAll(p0: java.util.Collection): boolean
public method retainAll(p0: java.util.Collection): boolean
public final method size(): int
@@ -83,6 +83,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
doTest(fileName);
}
@TestMetadata("noRemoveAtInReadOnly.kt")
public void testNoRemoveAtInReadOnly() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/noRemoveAtInReadOnly.kt");
doTest(fileName);
}
@TestMetadata("samAdapterAndInlinedOne.kt")
public void testSamAdapterAndInlinedOne() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");