From afcbd76c9ebdd17104e879ee0c5b8c61fa9ceba3 Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Tue, 2 Apr 2019 14:02:15 -0700 Subject: [PATCH] Implement stub methods generation for Kotlin Immutable Collection classes. This change is to fill the gap between Kotlin Collection classes(immutable) and Java Collection classes(mutable), to avoid calling an unsupported operation like remove() on an immutable class in jvm. --- .../jetbrains/kotlin/backend/common/ir/Ir.kt | 16 ++ .../jetbrains/kotlin/ir/util/IrTypeUtils.kt | 25 +++ .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 1 + .../backend/jvm/lower/BridgeLowering.kt | 7 +- .../jvm/lower/CollectionStubMethodLowering.kt | 212 ++++++++++++++++++ .../box/builtinStubMethods/Collection.kt | 1 - .../codegen/box/builtinStubMethods/List.kt | 1 - .../box/builtinStubMethods/ListIterator.kt | 1 - .../ListWithAllImplementations.kt | 1 - .../ListWithAllInheritedImplementations.kt | 1 - .../codegen/box/builtinStubMethods/Map.kt | 1 - .../box/builtinStubMethods/MapEntry.kt | 1 - .../box/builtinStubMethods/SubstitutedList.kt | 1 - .../delegationToArrayList.kt | 1 - .../box/builtinStubMethods/immutableRemove.kt | 1 - .../implementationInTrait.kt | 1 - .../inheritedImplementations.kt | 1 - .../manyTypeParametersWithUpperBounds.kt | 1 - .../mapRemove/readOnlyMap.kt | 1 - .../nonTrivialSubstitution.kt | 1 - .../substitutedListWithExtraSuperInterface.kt | 1 - .../collections/noStubsInJavaSuperClass.kt | 1 - 22 files changed, 259 insertions(+), 19 deletions(-) create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt index 98012886a5d..6d6b3af5e33 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt @@ -155,6 +155,22 @@ abstract class Symbols(val context: T, private val val arrays = primitiveArrays.values + unsignedArrays.values + array + val collection = symbolTable.referenceClass(builtIns.collection) + val set = symbolTable.referenceClass(builtIns.set) + val list = symbolTable.referenceClass(builtIns.list) + val map = symbolTable.referenceClass(builtIns.map) + val mapEntry = symbolTable.referenceClass(builtIns.mapEntry) + val iterable = symbolTable.referenceClass(builtIns.iterable) + val listIterator = symbolTable.referenceClass(builtIns.listIterator) + val mutableCollection = symbolTable.referenceClass(builtIns.mutableCollection) + val mutableSet = symbolTable.referenceClass(builtIns.mutableSet) + val mutableList = symbolTable.referenceClass(builtIns.mutableList) + val mutableMap = symbolTable.referenceClass(builtIns.mutableMap) + val mutableMapEntry = symbolTable.referenceClass(builtIns.mutableMapEntry) + val mutableIterable = symbolTable.referenceClass(builtIns.mutableIterable) + val mutableIterator = symbolTable.referenceClass(builtIns.mutableIterator) + val mutableListIterator = symbolTable.referenceClass(builtIns.mutableListIterator) + abstract val copyRangeTo: Map abstract val coroutineImpl: IrClassSymbol diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt index 20cafbd60ae..813be6c5650 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/util/IrTypeUtils.kt @@ -119,3 +119,28 @@ fun IrType.substitute(substitutionMap: Map): IrTy newAnnotations ) } + +private fun getImmediateSupertypes(irClass: IrClass): List { + val originalSupertypes = irClass.superTypes + val args = irClass.defaultType.arguments.mapNotNull { (it as? IrTypeProjection)?.type } + return originalSupertypes + .filter { it.classOrNull != null } + .map { superType -> + superType.substitute(superType.classOrNull!!.owner.typeParameters, args) as IrSimpleType + } +} + +private fun collectAllSupertypes(irClass: IrClass, result: MutableSet) { + val immediateSupertypes = getImmediateSupertypes(irClass) + result.addAll(immediateSupertypes) + for (supertype in immediateSupertypes) { + supertype.classOrNull.let { collectAllSupertypes(it!!.owner, result) } + } +} + +fun getAllSupertypes(irClass: IrClass): MutableSet { + val result = HashSet() + + collectAllSupertypes(irClass, result) + return result +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 5b5d55c83c8..8cd80d679a6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -139,6 +139,7 @@ val jvmPhases = namedIrFilePhase( objectClassPhase then makeInitializersPhase(JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true) then syntheticAccessorPhase then + collectionStubMethodLowering then bridgePhase then jvmOverloadsAnnotationPhase then jvmStaticAnnotationPhase then diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index 6edbf246dc6..5642ba42fc4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -168,7 +168,7 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass addBridge( irClass, targetForCommonBridges, method, signaturesToSkip, defaultValueGenerator = null, - isSpecial = false + isSpecial = targetForCommonBridges.isCollectionStub() ) } } @@ -214,7 +214,7 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass isSpecial: Boolean, isSynthetic: Boolean ): IrSimpleFunction { - val modality = if (isSpecial) Modality.FINAL else Modality.OPEN + val modality = if (isSpecial && !target.isCollectionStub()) Modality.FINAL else Modality.OPEN val origin = if (isSynthetic) IrDeclarationOrigin.BRIDGE else IrDeclarationOrigin.BRIDGE_SPECIAL val visibility = if (signatureFunction.visibility === Visibilities.INTERNAL) Visibilities.PUBLIC else signatureFunction.visibility @@ -429,6 +429,9 @@ private data class SignatureWithSource(val signature: Method, val source: IrSimp fun IrSimpleFunction.overriddenInClasses(): Sequence = allOverridden().filter { !(it.parent.safeAs()?.isInterface ?: true) } +fun IrSimpleFunction.isCollectionStub(): Boolean = + origin == IrDeclarationOrigin.IR_BUILTINS_STUB + // TODO: At present, there is no reliable way to distinguish Java imports from Kotlin cross-module imports. val ORIGINS_FROM_JAVA = setOf(IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt new file mode 100644 index 00000000000..025284ca243 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt @@ -0,0 +1,212 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.jvm.lower + +import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.irThrow +import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.declarations.buildFun +import org.jetbrains.kotlin.ir.builders.irBlockBody +import org.jetbrains.kotlin.ir.builders.irCall +import org.jetbrains.kotlin.ir.builders.irString +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol +import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl +import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.name.FqName + +internal val collectionStubMethodLowering = makeIrFilePhase( + ::CollectionStubMethodLowering, + name = "CollectionStubMethod", + description = "Generate Collection stub methods" +) + +private class CollectionStubMethodLowering(val context: JvmBackendContext) : ClassLoweringPass { + + private val state = context.state + + private val typeMapper = state.typeMapper + + override fun lower(irClass: IrClass) { + if (irClass.isInterface) { + return + } + + val methodStubsToGenerate = generateRelevantStubMethods(irClass) + + // We don't need to generate stub for existing methods, but for FAKE_OVERRIDE methods with ABSTRACT modality, + // it means an abstract function in superclass that is not implemented yet, + // stub generation is still needed to avoid invocation error. + val existingMethodSignatures = irClass.functions.filterNot { + it.modality == Modality.ABSTRACT && it.origin == IrDeclarationOrigin.FAKE_OVERRIDE + }.associateBy { it.toSignature() } + + for (member in methodStubsToGenerate) { + val existingMethod = existingMethodSignatures[member.toSignature()] + if (existingMethod != null) { + // In the case that we find a defined method that matches the stub signature, we add the overridden symbols to that + // defined method, so that bridge lowering can still generate correct bridge for that method + existingMethod.overriddenSymbols.addAll(member.overriddenSymbols) + } else { + irClass.declarations.add(member) + } + } + } + + //TODO: replace with new typeMapper using no descriptor + private fun IrSimpleFunction.toSignature() = typeMapper.mapAsmMethod(this.descriptor).toString() + + private fun createStubMethod(function: IrSimpleFunction, irClass: IrClass, substitutionMap: Map): IrSimpleFunction { + return buildFun { + name = function.name + returnType = function.returnType.substitute(substitutionMap) + visibility = function.visibility + origin = IrDeclarationOrigin.IR_BUILTINS_STUB + modality = Modality.OPEN + }.apply { + // Replace Function metadata with the data from class + // Add the abstract function symbol to stub function for bridge lowering + overriddenSymbols.add(function.symbol) + parent = irClass + dispatchReceiverParameter = function.dispatchReceiverParameter?.copyWithSubstitution(this, substitutionMap) + extensionReceiverParameter = function.extensionReceiverParameter?.copyWithSubstitution(this, substitutionMap) + for (parameter in function.valueParameters) { + valueParameters.add(parameter.copyWithSubstitution(this, substitutionMap)) + } + val exception = context.getTopLevelClass(FqName("java.lang.UnsupportedOperationException")) + // Function body consist only of throwing UnsupportedOperationException statement + body = context.createIrBuilder(function.symbol).irBlockBody { + +irThrow( + irCall( + exception.owner.constructors.single { + it.valueParameters.size == 1 && it.valueParameters.single().type.isNullableString() + } + ).apply { + putValueArgument(0, irString("Operation is not supported for read-only collection")) + } + ) + } + } + } + + // Copy value parameter with type substitution + private fun IrValueParameter.copyWithSubstitution(target: IrSimpleFunction, substitutionMap: Map) + : IrValueParameter { + val descriptor = WrappedValueParameterDescriptor(this.descriptor.annotations) + return IrValueParameterImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + IrDeclarationOrigin.IR_BUILTINS_STUB, + IrValueParameterSymbolImpl(descriptor), + name, + index, + type.substitute(substitutionMap), + varargElementType?.substitute(substitutionMap), + isCrossinline, + isNoinline + ).apply { + descriptor.bind(this) + parent = target + } + } + + // Compute a substitution map for type parameters between source class (Mutable Collection classes) to + // target class (class currently in lowering phase), this map is later used for substituting type parameters in generated functions + private fun computeSubstitutionMap(readOnlyClass: IrClass, mutableClass: IrClass, targetClass: IrClass) + : Map { + // We find the most specific type for the immutable collection class from the inheritance chain of target class + // Perform type substitution along searching, then use the type arguments obtained from the most specific type + // for type substitution. + val readOnlyClassType = getAllSupertypes(targetClass).findMostSpecificTypeForClass(readOnlyClass.symbol) + val readOnlyClassTypeArguments = (readOnlyClassType as IrSimpleType).arguments.mapNotNull { (it as? IrTypeProjection)?.type } + + if (readOnlyClassTypeArguments.isEmpty() || readOnlyClassTypeArguments.size != mutableClass.typeParameters.size) { + throw IllegalStateException( + "Type argument mismatch between immutable class ${readOnlyClass.fqNameWhenAvailable}" + + " and mutable class ${mutableClass.fqNameWhenAvailable}, when processing" + + "class ${targetClass.fqNameWhenAvailable}" + ) + } + return mutableClass.typeParameters.map { it.symbol }.zip(readOnlyClassTypeArguments).toMap() + } + + private data class StubsForCollectionClass( + val readOnlyClass: IrClassSymbol, + val mutableClass: IrClassSymbol, + val mutableOnlyMethods: Collection + ) + + private val preComputedStubs: Collection by lazy { + with(context.ir.symbols) { + listOf( + collection to mutableCollection, + set to mutableSet, + list to mutableList, + map to mutableMap, + mapEntry to mutableMapEntry, + iterable to mutableIterable, + iterator to mutableIterator, + listIterator to mutableListIterator + ).map { (readOnlyClass, mutableClass) -> + val readOnlyMethodSignatures = readOnlyClass.functions.map { it.owner.toSignature() }.toHashSet() + val mutableMethods = mutableClass.functions + .map { it.owner } + .filter { it.toSignature() !in readOnlyMethodSignatures } + .toHashSet() + StubsForCollectionClass(readOnlyClass, mutableClass, mutableMethods) + } + } + } + + // Compute stubs that should be generated, compare based on signature + private fun generateRelevantStubMethods(irClass: IrClass): Set { + val ourStubsForCollectionClasses = preComputedStubs.filter { (readOnlyClass, mutableClass) -> + irClass.superTypes.any { supertypeSymbol -> + val supertype = supertypeSymbol.classOrNull?.owner + // We need to generate stub methods for following 2 cases: + // current class's direct super type is a java class or kotlin interface, and is an subtype of an immutable collection + supertype != null + && (supertype.comesFromJava() || supertype.isInterface) + && supertypeSymbol.isSubtypeOfClass(readOnlyClass) + && !irClass.symbol.isSubtypeOfClass(mutableClass) + } + } + + // 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 + }.flatMap { (readOnlyClass, mutableClass, mutableOnlyMethods) -> + val substitutionMap = computeSubstitutionMap(readOnlyClass.owner, mutableClass.owner, irClass) + mutableOnlyMethods.map { function -> + createStubMethod(function, irClass, substitutionMap) + } + }.toHashSet() + } + + fun IrClass.comesFromJava() = origin in ORIGINS_FROM_JAVA + + private fun Collection.findMostSpecificTypeForClass(classifier: IrClassSymbol): IrType { + val types = this.filter { it.classifierOrNull == classifier } + if (types.isEmpty()) error("No supertype of $classifier in $this") + if (types.size == 1) return types.first() + // Find the first type in the list such that it's a subtype of every other type in that list + return types.first { type -> + types.all { other -> type.isSubtypeOfClass(other.classOrNull!!) } + } + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/builtinStubMethods/Collection.kt b/compiler/testData/codegen/box/builtinStubMethods/Collection.kt index e071af62dd5..906d1129d26 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/Collection.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/Collection.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyCollection: Collection { diff --git a/compiler/testData/codegen/box/builtinStubMethods/List.kt b/compiler/testData/codegen/box/builtinStubMethods/List.kt index fa938bcc93d..4a64bf05265 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/List.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/List.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyList: List { diff --git a/compiler/testData/codegen/box/builtinStubMethods/ListIterator.kt b/compiler/testData/codegen/box/builtinStubMethods/ListIterator.kt index 839f08e4b3a..c3bd9a90ea8 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/ListIterator.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/ListIterator.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyListIterator : ListIterator { diff --git a/compiler/testData/codegen/box/builtinStubMethods/ListWithAllImplementations.kt b/compiler/testData/codegen/box/builtinStubMethods/ListWithAllImplementations.kt index b1d2a484440..8f5988e87df 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/ListWithAllImplementations.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/ListWithAllImplementations.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyList(val v: T): List { diff --git a/compiler/testData/codegen/box/builtinStubMethods/ListWithAllInheritedImplementations.kt b/compiler/testData/codegen/box/builtinStubMethods/ListWithAllInheritedImplementations.kt index 9922ca36d41..cb1af1b6572 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/ListWithAllInheritedImplementations.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/ListWithAllInheritedImplementations.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM open class Super(val v: T) { diff --git a/compiler/testData/codegen/box/builtinStubMethods/Map.kt b/compiler/testData/codegen/box/builtinStubMethods/Map.kt index d755fc15fb7..c0324984796 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/Map.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/Map.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyMap: Map { diff --git a/compiler/testData/codegen/box/builtinStubMethods/MapEntry.kt b/compiler/testData/codegen/box/builtinStubMethods/MapEntry.kt index 9554ec2caaf..8c315a34b8d 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/MapEntry.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/MapEntry.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyMapEntry: Map.Entry { diff --git a/compiler/testData/codegen/box/builtinStubMethods/SubstitutedList.kt b/compiler/testData/codegen/box/builtinStubMethods/SubstitutedList.kt index 7d05421df5c..1ff2647b030 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/SubstitutedList.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/SubstitutedList.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyList: List { diff --git a/compiler/testData/codegen/box/builtinStubMethods/delegationToArrayList.kt b/compiler/testData/codegen/box/builtinStubMethods/delegationToArrayList.kt index 450c5cc9d1d..b9436fab469 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/delegationToArrayList.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/delegationToArrayList.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM import java.util.ArrayList diff --git a/compiler/testData/codegen/box/builtinStubMethods/immutableRemove.kt b/compiler/testData/codegen/box/builtinStubMethods/immutableRemove.kt index 286fc906a5c..32aa73212f8 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/immutableRemove.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/immutableRemove.kt @@ -1,5 +1,4 @@ // SKIP_JDK6 -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FULL_JDK // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/builtinStubMethods/implementationInTrait.kt b/compiler/testData/codegen/box/builtinStubMethods/implementationInTrait.kt index e19d8c1b4ed..c1b21f6b745 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/implementationInTrait.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/implementationInTrait.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM interface Addable { diff --git a/compiler/testData/codegen/box/builtinStubMethods/inheritedImplementations.kt b/compiler/testData/codegen/box/builtinStubMethods/inheritedImplementations.kt index bcada743b40..fd9a690ffe6 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/inheritedImplementations.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/inheritedImplementations.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM open class SetStringImpl { diff --git a/compiler/testData/codegen/box/builtinStubMethods/manyTypeParametersWithUpperBounds.kt b/compiler/testData/codegen/box/builtinStubMethods/manyTypeParametersWithUpperBounds.kt index 5feb5671a89..f906f817cce 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/manyTypeParametersWithUpperBounds.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/manyTypeParametersWithUpperBounds.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/builtinStubMethods/mapRemove/readOnlyMap.kt b/compiler/testData/codegen/box/builtinStubMethods/mapRemove/readOnlyMap.kt index 97ce3cdd5e8..3cd772bc264 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/mapRemove/readOnlyMap.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/mapRemove/readOnlyMap.kt @@ -1,5 +1,4 @@ // SKIP_JDK6 -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FULL_JDK // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/builtinStubMethods/nonTrivialSubstitution.kt b/compiler/testData/codegen/box/builtinStubMethods/nonTrivialSubstitution.kt index d968a704e2e..cdc268b382c 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/nonTrivialSubstitution.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/nonTrivialSubstitution.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM class MyCollection : Collection>> { diff --git a/compiler/testData/codegen/box/builtinStubMethods/substitutedListWithExtraSuperInterface.kt b/compiler/testData/codegen/box/builtinStubMethods/substitutedListWithExtraSuperInterface.kt index 9ce6652c196..ac7e2b3e248 100644 --- a/compiler/testData/codegen/box/builtinStubMethods/substitutedListWithExtraSuperInterface.kt +++ b/compiler/testData/codegen/box/builtinStubMethods/substitutedListWithExtraSuperInterface.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: Test.java diff --git a/compiler/testData/codegen/box/collections/noStubsInJavaSuperClass.kt b/compiler/testData/codegen/box/collections/noStubsInJavaSuperClass.kt index 533b8b3c667..465a923efeb 100644 --- a/compiler/testData/codegen/box/collections/noStubsInJavaSuperClass.kt +++ b/compiler/testData/codegen/box/collections/noStubsInJavaSuperClass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: B.java