Optimize method count for collection stubs
Do not generate stubs if they're already present in superclasses #KT-13698 In Progress
This commit is contained in:
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERR
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.isBuiltinWithSpecialDescriptorInJvm
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.isFromBuiltins
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
@@ -32,10 +33,10 @@ import org.jetbrains.kotlin.resolve.OverridingStrategy
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeCheckerImpl
|
||||
@@ -63,10 +64,15 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
|
||||
private fun computeTasksToGenerate(): TasksToGenerate {
|
||||
if (descriptor.kind == ClassKind.INTERFACE) return NO_TASKS
|
||||
if (descriptor.kind == ClassKind.INTERFACE || descriptor is JavaClassDescriptor) return NO_TASKS
|
||||
val superCollectionClasses = findRelevantSuperCollectionClasses()
|
||||
if (superCollectionClasses.isEmpty()) return NO_TASKS
|
||||
|
||||
val existingMethodsInSuperclasses = descriptor.getAllSuperclassesWithoutAny().flatMap {
|
||||
val tasksFromSuperClass = CollectionStubMethodGenerator(typeMapper, it).computeTasksToGenerate()
|
||||
(tasksFromSuperClass.methodStubsToGenerate + tasksFromSuperClass.syntheticStubsToGenerate).map { it.asmMethod }
|
||||
}
|
||||
|
||||
val methodStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
|
||||
val syntheticStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
|
||||
val bridgesToGenerate = LinkedHashSet<FunctionDescriptor>()
|
||||
@@ -139,10 +145,19 @@ class CollectionStubMethodGenerator(
|
||||
method.signature()
|
||||
}
|
||||
|
||||
methodStubsToGenerate.add(commonSignature)
|
||||
if (commonSignature.asmMethod !in existingMethodsInSuperclasses &&
|
||||
// If original method already defined in a superclass we mustn't care about specialized version
|
||||
// The same way we do not generate specialized version in a common case like:
|
||||
// open class A<T> : MutableList<T> {
|
||||
// fun add(x: T) = true
|
||||
// }
|
||||
// class B : A<String>() // No 'B.add(String)Z'
|
||||
originalSignature.asmMethod !in existingMethodsInSuperclasses) {
|
||||
methodStubsToGenerate.add(commonSignature)
|
||||
|
||||
if (originalSignature.asmMethod != commonSignature.asmMethod) {
|
||||
syntheticStubsToGenerate.add(originalSignature)
|
||||
if (originalSignature.asmMethod != commonSignature.asmMethod) {
|
||||
syntheticStubsToGenerate.add(originalSignature)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+1
-14
@@ -16,12 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.lazy.descriptors
|
||||
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.ThrowingLexicalScope
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
@@ -75,18 +74,6 @@ class ClassResolutionScopesSupport(
|
||||
}
|
||||
}
|
||||
|
||||
fun ClassDescriptor.getAllSuperclassesWithoutAny(): List<ClassDescriptor> {
|
||||
val superClasses = SmartList<ClassDescriptor>()
|
||||
var parent: ClassDescriptor? = getSuperClassNotAny()
|
||||
|
||||
while(parent != null && parent != this) {
|
||||
superClasses.add(parent)
|
||||
parent = parent.getSuperClassNotAny()
|
||||
}
|
||||
|
||||
return superClasses
|
||||
}
|
||||
|
||||
private fun createInheritanceScope(
|
||||
parent: LexicalScope,
|
||||
ownerDescriptor: DeclarationDescriptor,
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// FILE: B.java
|
||||
public abstract class B<E> extends A<E> implements L<E> {
|
||||
public String callIndexAdd(int x) {
|
||||
add(0, null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
open class A<T> : Collection<T> {
|
||||
override val size: Int
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override fun contains(element: T): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
interface L<Q> : List<Q>
|
||||
|
||||
// 'add(Int; Object)' method must be present in C though it has supeclass that is subclass of List
|
||||
class C<F> : B<F>() {
|
||||
override fun get(index: Int): F {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun indexOf(element: F): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun lastIndexOf(element: F): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(): ListIterator<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(index: Int): ListIterator<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = try {
|
||||
C<String>().callIndexAdd(1)
|
||||
throw RuntimeException("fail 1")
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
if (e.message != "Operation is not supported for read-only collection") throw RuntimeException("fail 2")
|
||||
"OK"
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
// FILE: test/B.java
|
||||
package test;
|
||||
|
||||
public abstract class B<E> extends A<E> implements L<E> {
|
||||
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
package test
|
||||
open class A<T> : Collection<T> {
|
||||
override val size: Int
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override fun contains(element: T): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
interface L<Q> : List<Q>
|
||||
|
||||
// 'remove(Int)' method must be present in C though it has supeclass that is subclass of List
|
||||
class C<F> : B<F>() {
|
||||
override fun get(index: Int): F {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun indexOf(element: F): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun lastIndexOf(element: F): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(): ListIterator<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(index: Int): ListIterator<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
@kotlin.Metadata
|
||||
public class test/A {
|
||||
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 method contains(p0: java.lang.Object): boolean
|
||||
public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean
|
||||
public method getSize(): int
|
||||
public method isEmpty(): boolean
|
||||
public @org.jetbrains.annotations.NotNull 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 final method size(): int
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class test/C {
|
||||
public method <init>(): void
|
||||
public method add(p0: int, p1: java.lang.Object): void
|
||||
public method addAll(p0: int, p1: java.util.Collection): boolean
|
||||
public method get(p0: int): java.lang.Object
|
||||
public method indexOf(p0: java.lang.Object): int
|
||||
public method lastIndexOf(p0: java.lang.Object): int
|
||||
public @org.jetbrains.annotations.NotNull method listIterator(): java.util.ListIterator
|
||||
public @org.jetbrains.annotations.NotNull method listIterator(p0: int): java.util.ListIterator
|
||||
public method remove(p0: int): java.lang.Object
|
||||
public method set(p0: int, p1: java.lang.Object): java.lang.Object
|
||||
public @org.jetbrains.annotations.NotNull 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 interface test/L
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
open class A<T> : Collection<T> {
|
||||
override val size: Int
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override fun contains(element: T): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
open class B<E> : A<E>()
|
||||
class C<F> : B<F>(), List<F> {
|
||||
override fun get(index: Int): F {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun indexOf(element: F): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun lastIndexOf(element: F): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(): ListIterator<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(index: Int): ListIterator<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<F> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
@kotlin.Metadata
|
||||
public class A {
|
||||
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 method contains(p0: java.lang.Object): boolean
|
||||
public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean
|
||||
public method getSize(): int
|
||||
public method isEmpty(): boolean
|
||||
public @org.jetbrains.annotations.NotNull 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 final method size(): int
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public class B {
|
||||
public method <init>(): void
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class C {
|
||||
public method <init>(): void
|
||||
public method add(p0: int, p1: java.lang.Object): void
|
||||
public method addAll(p0: int, p1: java.util.Collection): boolean
|
||||
public method get(p0: int): java.lang.Object
|
||||
public method indexOf(p0: java.lang.Object): int
|
||||
public method lastIndexOf(p0: java.lang.Object): int
|
||||
public @org.jetbrains.annotations.NotNull method listIterator(): java.util.ListIterator
|
||||
public @org.jetbrains.annotations.NotNull method listIterator(p0: int): java.util.ListIterator
|
||||
public method remove(p0: int): java.lang.Object
|
||||
public method set(p0: int, p1: java.lang.Object): java.lang.Object
|
||||
public @org.jetbrains.annotations.NotNull 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[]
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
open class A<T> : Collection<T> {
|
||||
override val size: Int
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override fun contains(element: T): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<T> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
open class B<E : CharSequence> : A<E>()
|
||||
class C : B<CharSequence>(), List<CharSequence> {
|
||||
override fun get(index: Int): CharSequence {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun indexOf(element: CharSequence): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun lastIndexOf(element: CharSequence): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(): ListIterator<CharSequence> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun listIterator(index: Int): ListIterator<CharSequence> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): List<CharSequence> {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
@kotlin.Metadata
|
||||
public class A {
|
||||
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 method contains(p0: java.lang.Object): boolean
|
||||
public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean
|
||||
public method getSize(): int
|
||||
public method isEmpty(): boolean
|
||||
public @org.jetbrains.annotations.NotNull 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 final method size(): int
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public class B {
|
||||
public method <init>(): void
|
||||
public method contains(p0: java.lang.CharSequence): boolean
|
||||
public final method contains(p0: java.lang.Object): boolean
|
||||
public method toArray(): java.lang.Object[]
|
||||
public method toArray(p0: java.lang.Object[]): java.lang.Object[]
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class C {
|
||||
public method <init>(): void
|
||||
public method add(p0: int, p1: java.lang.CharSequence): void
|
||||
public synthetic method add(p0: int, p1: java.lang.Object): void
|
||||
public method addAll(p0: int, p1: java.util.Collection): boolean
|
||||
public @org.jetbrains.annotations.NotNull method get(p0: int): java.lang.CharSequence
|
||||
public synthetic method get(p0: int): java.lang.Object
|
||||
public method indexOf(@org.jetbrains.annotations.NotNull p0: java.lang.CharSequence): int
|
||||
public final method indexOf(p0: java.lang.Object): int
|
||||
public method lastIndexOf(@org.jetbrains.annotations.NotNull p0: java.lang.CharSequence): int
|
||||
public final method lastIndexOf(p0: java.lang.Object): int
|
||||
public @org.jetbrains.annotations.NotNull method listIterator(): java.util.ListIterator
|
||||
public @org.jetbrains.annotations.NotNull method listIterator(p0: int): java.util.ListIterator
|
||||
public method remove(p0: int): java.lang.CharSequence
|
||||
public synthetic method remove(p0: int): java.lang.Object
|
||||
public method set(p0: int, p1: java.lang.CharSequence): java.lang.CharSequence
|
||||
public synthetic method set(p0: int, p1: java.lang.Object): java.lang.Object
|
||||
public @org.jetbrains.annotations.NotNull 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[]
|
||||
}
|
||||
@@ -25,12 +25,14 @@ import java.io.File
|
||||
abstract class AbstractBytecodeListingTest : CodegenTestCase() {
|
||||
protected open val classBuilderFactory: ClassBuilderFactory
|
||||
get() = ClassBuilderFactories.TEST
|
||||
|
||||
override fun doTest(filename: String) {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL)
|
||||
loadFileByFullPath(filename)
|
||||
val ktFile = File(filename)
|
||||
val txtFile = File(ktFile.parentFile, ktFile.nameWithoutExtension + ".txt")
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
val javaSources = javaFilesDir?.let { arrayOf(it) } ?: emptyArray()
|
||||
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources)
|
||||
loadMultiFiles(files)
|
||||
|
||||
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
|
||||
val generatedFiles = CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory)
|
||||
.getClassFiles()
|
||||
.sortedBy { it.relativePath }
|
||||
|
||||
@@ -3586,6 +3586,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsInJavaSuperClass.kt")
|
||||
public void testNoStubsInJavaSuperClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/collections/noStubsInJavaSuperClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("platformValueContains.kt")
|
||||
public void testPlatformValueContains() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/collections/platformValueContains.kt");
|
||||
|
||||
@@ -140,6 +140,33 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeListing/collectionStubs")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CollectionStubs extends AbstractBytecodeListingTest {
|
||||
public void testAllFilesPresentInCollectionStubs() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/collectionStubs"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("noStubsInJavaSuperClass.kt")
|
||||
public void testNoStubsInJavaSuperClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/collectionStubs/noStubsInJavaSuperClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stubsFromSuperclass.kt")
|
||||
public void testStubsFromSuperclass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/collectionStubs/stubsFromSuperclass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stubsFromSuperclassNoBridges.kt")
|
||||
public void testStubsFromSuperclassNoBridges() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/collectionStubs/stubsFromSuperclassNoBridges.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeListing/specialBridges")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor = companionObjectDescriptor ?: this
|
||||
@@ -322,3 +323,6 @@ private fun ClassDescriptor.getAllSuperClassesTypesIncludeItself(): List<KotlinT
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun ClassDescriptor.getAllSuperclassesWithoutAny() =
|
||||
generateSequence(getSuperClassNotAny(), ClassDescriptor::getSuperClassNotAny).toCollection(SmartList<ClassDescriptor>())
|
||||
|
||||
Reference in New Issue
Block a user