JVM_IR KT-36994 don't generate stub if present in superclass
This commit is contained in:
+22
-15
@@ -294,25 +294,32 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl
|
||||
|
||||
// Compute stubs that should be generated, compare based on signature
|
||||
private fun generateRelevantStubMethods(irClass: IrClass): List<IrSimpleFunction> {
|
||||
val ourStubsForCollectionClasses = collectionStubComputer.stubsForCollectionClasses(irClass)
|
||||
val superStubClasses = irClass.superClass?.superClassChain?.map { superClass ->
|
||||
collectionStubComputer.stubsForCollectionClasses(superClass).map { it.readOnlyClass }
|
||||
}?.fold(emptySet<IrClassSymbol>(), { a, b -> a union b }) ?: emptySet()
|
||||
|
||||
// do a second filtering to ensure only most relevant classes are included.
|
||||
val redundantClasses = ourStubsForCollectionClasses.filter { (readOnlyClass) ->
|
||||
ourStubsForCollectionClasses.any { readOnlyClass != it.readOnlyClass && it.readOnlyClass.isSubtypeOfClass(readOnlyClass) }
|
||||
}.map { it.readOnlyClass }
|
||||
|
||||
// perform type substitution and type erasure here
|
||||
return ourStubsForCollectionClasses.filter { (readOnlyClass) ->
|
||||
readOnlyClass !in redundantClasses && readOnlyClass !in superStubClasses
|
||||
}.flatMap { (readOnlyClass, mutableClass, mutableOnlyMethods) ->
|
||||
fun createStubFuns(stubs: CollectionStubComputer.StubsForCollectionClass): List<IrSimpleFunction> {
|
||||
val (readOnlyClass, mutableClass, mutableOnlyMethods) = stubs
|
||||
val substitutionMap = computeSubstitutionMap(readOnlyClass.owner, mutableClass.owner, irClass)
|
||||
mutableOnlyMethods.map { function ->
|
||||
return mutableOnlyMethods.map { function ->
|
||||
createStubMethod(function, irClass, substitutionMap)
|
||||
}
|
||||
}
|
||||
|
||||
val classStubs = collectionStubComputer.stubsForCollectionClasses(irClass)
|
||||
|
||||
val superClassesStubs = irClass.superClass?.run {
|
||||
superClassChain.flatMap { superClass ->
|
||||
collectionStubComputer.stubsForCollectionClasses(superClass)
|
||||
}.toList()
|
||||
} ?: emptyList()
|
||||
|
||||
val relevantStubs =
|
||||
classStubs.filter { (readOnlyClass) ->
|
||||
classStubs.none { readOnlyClass != it.readOnlyClass && it.readOnlyClass.isSubtypeOfClass(readOnlyClass) } &&
|
||||
superClassesStubs.none { it.readOnlyClass == readOnlyClass }
|
||||
}
|
||||
|
||||
val classStubFuns = relevantStubs.flatMap { createStubFuns(it) }
|
||||
val superClassStubSignatures = superClassesStubs.flatMap { createStubFuns(it) }.mapTo(HashSet()) { it.toJvmSignature() }
|
||||
|
||||
return classStubFuns.filter { it.toJvmSignature() !in superClassStubSignatures }
|
||||
}
|
||||
|
||||
private fun Collection<IrType>.findMostSpecificTypeForClass(classifier: IrClassSymbol): IrType {
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
abstract class AC<X> : Collection<X>
|
||||
|
||||
abstract class ASet<T> : AC<T>(), Set<T>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class AC {
|
||||
// source: 'extendingAbstractCollection.kt'
|
||||
public method <init>(): void
|
||||
public method add(p0: java.lang.Object): 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 method iterator(): java.util.Iterator
|
||||
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 bridge final method size(): int
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public abstract class ASet {
|
||||
// source: 'extendingAbstractCollection.kt'
|
||||
public method <init>(): void
|
||||
}
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class AC {
|
||||
// source: 'extendingAbstractCollection.kt'
|
||||
public method <init>(): void
|
||||
public method add(p0: java.lang.Object): boolean
|
||||
public method addAll(p0: java.util.Collection): boolean
|
||||
public method clear(): void
|
||||
public abstract method getSize(): int
|
||||
public method iterator(): java.util.Iterator
|
||||
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 bridge final method size(): int
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public abstract class ASet {
|
||||
// source: 'extendingAbstractCollection.kt'
|
||||
public method <init>(): void
|
||||
}
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: test/B.java
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// WITH_RUNTIME
|
||||
// IGNORE_BACKEND: JVM
|
||||
// ^ see KT-42179
|
||||
|
||||
// FILE: test/JC.java
|
||||
package test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class JC<E> implements Collection<E> {
|
||||
}
|
||||
|
||||
// FILE: noStubsInJavaSuperClass2.kt
|
||||
package test
|
||||
|
||||
abstract class KSet<E> : JC<E>(), Set<E>
|
||||
|
||||
abstract class KList<E> : JC<E>(), List<E>
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
@kotlin.Metadata
|
||||
public abstract class test/KList {
|
||||
// source: 'noStubsInJavaSuperClass2.kt'
|
||||
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 getSize(): 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 bridge 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 test/KSet {
|
||||
// source: 'noStubsInJavaSuperClass2.kt'
|
||||
public method <init>(): void
|
||||
public method add(p0: java.lang.Object): boolean
|
||||
public method addAll(p0: java.util.Collection): boolean
|
||||
public method clear(): void
|
||||
public abstract method getSize(): int
|
||||
public method iterator(): java.util.Iterator
|
||||
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 bridge final method size(): int
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
|
||||
open class A<T> : Collection<T> {
|
||||
|
||||
+10
@@ -254,6 +254,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/emptyList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extendingAbstractCollection.kt")
|
||||
public void testExtendingAbstractCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/extendingAbstractCollection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsForCollection.kt")
|
||||
public void testNoStubsForCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsForCollection.kt");
|
||||
@@ -284,6 +289,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsInJavaSuperClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsInJavaSuperClass2.kt")
|
||||
public void testNoStubsInJavaSuperClass2() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsInJavaSuperClass2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsInMutableIterable.kt")
|
||||
public void testNoStubsInMutableIterable() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsInMutableIterable.kt");
|
||||
|
||||
+10
@@ -254,6 +254,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/emptyList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extendingAbstractCollection.kt")
|
||||
public void testExtendingAbstractCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/extendingAbstractCollection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsForCollection.kt")
|
||||
public void testNoStubsForCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsForCollection.kt");
|
||||
@@ -284,6 +289,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsInJavaSuperClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsInJavaSuperClass2.kt")
|
||||
public void testNoStubsInJavaSuperClass2() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsInJavaSuperClass2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsInMutableIterable.kt")
|
||||
public void testNoStubsInMutableIterable() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsInMutableIterable.kt");
|
||||
|
||||
Reference in New Issue
Block a user