diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index 69cde767cc9..c1ba8855c10 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -89,6 +89,7 @@ fun JsIrBackendContext.lower(file: IrFile) { PropertiesLowering().lower(file) InitializersLowering(this, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).runOnFilePostfix(file) MultipleCatchesLowering(this).lower(file) + BridgesConstruction(this).runOnFilePostfix(file) TypeOperatorLowering(this).lower(file) BlockDecomposerLowering(this).runOnFilePostfix(file) SecondaryCtorLowering(this).runOnFilePostfix(file) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt new file mode 100644 index 00000000000..163ccd823da --- /dev/null +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt @@ -0,0 +1,191 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.ir.backend.js.lower + +import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.bridges.Bridge +import org.jetbrains.kotlin.backend.common.bridges.FunctionHandle +import org.jetbrains.kotlin.backend.common.bridges.generateBridges +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.irBlockBody +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.isStatic +import org.jetbrains.kotlin.ir.builders.irCall +import org.jetbrains.kotlin.ir.builders.irGet +import org.jetbrains.kotlin.ir.builders.irReturn +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.types.toKotlinType +import org.jetbrains.kotlin.ir.util.createParameterDeclarations +import org.jetbrains.kotlin.ir.util.isInterface +import org.jetbrains.kotlin.ir.util.isReal +import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.DescriptorUtils + +// Constructs bridges for inherited generic functions +// +// Example: for given class hierarchy +// +// class C { +// fun foo(t: T) = ... +// } +// +// class D : C { +// override fun foo(t: Int) = impl +// } +// +// it adds method D that delegates generic calls to implementation: +// +// class D : C { +// override fun foo(t: Int) = impl +// fun foo(t: Any?) = foo(t as Int) // Constructed bridge +// } +// +class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass { + + override fun lower(irClass: IrClass) { + irClass.declarations + .filterIsInstance() + .filter { !it.isStatic } + .forEach { generateBridges(it, irClass) } + + irClass.declarations + .filterIsInstance() + .flatMap { listOfNotNull(it.getter, it.setter) } + .forEach { generateBridges(it, irClass) } + } + + private fun generateBridges(function: IrSimpleFunction, irClass: IrClass) { + // equals(Any?), hashCode(), toString() never need bridges + if (DescriptorUtils.isMethodOfAny(function.descriptor)) + return + + val bridgesToGenerate = generateBridges( + function = IrBasedFunctionHandle(function), + signature = { FunctionAndSignature(it.function) } + ) + + for ((from, to) in bridgesToGenerate) { + if (to.function.visibility == Visibilities.INVISIBLE_FAKE) + continue + + if (!from.function.parentAsClass.isInterface && + from.function.isReal && + from.function.modality != Modality.ABSTRACT && + !to.function.isReal + ) { + continue + } + + irClass.declarations.add(createBridge(function, from.function, to.function)) + } + } + + // Ported from from jvm.lower.BridgeLowering + private fun createBridge( + function: IrSimpleFunction, + bridge: IrSimpleFunction, + delegateTo: IrSimpleFunction + ): IrFunction { + val containingClass = function.parentAsClass.descriptor + + val bridgeDescriptorForIrFunction = SimpleFunctionDescriptorImpl.create( + containingClass, + Annotations.EMPTY, + bridge.name, + CallableMemberDescriptor.Kind.SYNTHESIZED, + function.descriptor.source) + + // TODO: should copy modality + bridgeDescriptorForIrFunction.initialize( + bridge.descriptor.extensionReceiverParameter?.returnType, containingClass.thisAsReceiverParameter, + bridge.descriptor.typeParameters, + bridge.descriptor.valueParameters.map { it.copy(bridgeDescriptorForIrFunction, it.name, it.index) }, + bridge.descriptor.returnType, Modality.OPEN, function.visibility + ) + + // TODO: Support offsets for debug info + val irFunction = IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.DEFINED, bridgeDescriptorForIrFunction) + irFunction.createParameterDeclarations() + + // TODO: Add type casts + context.createIrBuilder(irFunction.symbol).irBlockBody(irFunction) { + val call = irCall(delegateTo.symbol) + call.dispatchReceiver = irGet(irFunction.dispatchReceiverParameter!!) + irFunction.extensionReceiverParameter?.let { + call.extensionReceiver = irGet(it) + } + irFunction.valueParameters.mapIndexed { i, valueParameter -> + call.putValueArgument(i, irGet(valueParameter)) + } + +irReturn(call) + }.apply { + irFunction.body = this + } + + return irFunction + } +} + +// Handle for common.bridges +data class IrBasedFunctionHandle(val function: IrSimpleFunction) : FunctionHandle { + + override val isDeclaration: Boolean = true + + override val isAbstract: Boolean = + function.modality == Modality.ABSTRACT + + override val isInterfaceDeclaration= + function.parentAsClass.isInterface + + override fun getOverridden()= + function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) } +} + +// Wrapper around function that compares and hashCodes it based on signature +// Designed to be used as a Signature type parameter in backend.common.bridges +class FunctionAndSignature(val function: IrSimpleFunction) { + + // TODO: Use type-upper-bound-based signature instead of Strings + // Currently strings are used for compatibility with a hack-based name generator + + private data class Signature( + val name: Name, + val extensionReceiverType: String?, + val valueParameters: List + ) + + private val signature = Signature( + function.name, + function.extensionReceiverParameter?.type?.toKotlinType()?.toString(), + function.valueParameters.map { it.type.toKotlinType()?.toString() } + ) + + override fun equals(other: Any?) = + signature == (other as FunctionAndSignature).signature + + override fun hashCode(): Int = signature.hashCode() +} + + diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt index 3a9f724c7f5..30f21df1e58 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt @@ -34,6 +34,5 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin { interface JvmLoweredStatementOrigin : IrStatementOrigin { object DEFAULT_IMPLS_DELEGATION : IrStatementOriginImpl("DEFAULT_IMPL_DELEGATION") - object BRIDGE_DELEGATION : IrStatementOriginImpl("BRIDGE_DELEGATION") object TO_ARRAY : IrDeclarationOriginImpl("TO_ARRAY") } \ No newline at end of file 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 4a0905475d2..fbaf4e3cae4 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 @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.jvm.JvmBackendContext -import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl import org.jetbrains.kotlin.codegen.AsmUtil.isAbstractMethod @@ -37,6 +36,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl @@ -219,7 +219,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass { implementation.returnType!!.toIrType()!!, implementation, implementation.typeParametersCount, - JvmLoweredStatementOrigin.BRIDGE_DELEGATION, + IrStatementOrigin.BRIDGE_DELEGATION, if (isStubDeclarationWithDelegationToSuper) getSuperClassDescriptor( descriptor.containingDeclaration as ClassDescriptor ) else null @@ -228,14 +228,14 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass { UNDEFINED_OFFSET, UNDEFINED_OFFSET, irFunction.dispatchReceiverParameter!!.symbol, - JvmLoweredStatementOrigin.BRIDGE_DELEGATION + IrStatementOrigin.BRIDGE_DELEGATION ) irFunction.extensionReceiverParameter?.let { call.extensionReceiver = IrGetValueImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, it.symbol, - JvmLoweredStatementOrigin.BRIDGE_DELEGATION + IrStatementOrigin.BRIDGE_DELEGATION ) } irFunction.valueParameters.mapIndexed { i, valueParameter -> @@ -245,7 +245,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass { UNDEFINED_OFFSET, UNDEFINED_OFFSET, valueParameter.symbol, - JvmLoweredStatementOrigin.BRIDGE_DELEGATION + IrStatementOrigin.BRIDGE_DELEGATION ) ) } @@ -279,7 +279,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass { UNDEFINED_OFFSET, UNDEFINED_OFFSET, bridgeFunction.valueParameters[i].symbol, - JvmLoweredStatementOrigin.BRIDGE_DELEGATION + IrStatementOrigin.BRIDGE_DELEGATION ) if (delegateParameterTypes == null || OBJECT_TYPE == delegateParameterTypes[i]) { irNotEquals(checkValue, irNull()) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrStatementOrigin.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrStatementOrigin.kt index 9842be8e3b5..183cd84d0a3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrStatementOrigin.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrStatementOrigin.kt @@ -93,6 +93,8 @@ interface IrStatementOrigin { object PROPERTY_REFERENCE_FOR_DELEGATE : IrStatementOriginImpl("PROPERTY_REFERENCE_FOR_DELEGATE") + object BRIDGE_DELEGATION : IrStatementOriginImpl("BRIDGE_DELEGATION") + data class COMPONENT_N private constructor(val index: Int) : IrStatementOriginImpl("COMPONENT_$index") { companion object { private val precreatedComponents = Array(32) { i -> COMPONENT_N(i + 1) } diff --git a/compiler/testData/codegen/box/bridges/diamond.kt b/compiler/testData/codegen/box/bridges/diamond.kt index e5e7e843f24..ef1990bf937 100644 --- a/compiler/testData/codegen/box/bridges/diamond.kt +++ b/compiler/testData/codegen/box/bridges/diamond.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T, u: U) = "A" } diff --git a/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverride.kt b/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverride.kt index 7f52b44cb7b..ffff9f297e4 100644 --- a/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverride.kt +++ b/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverride.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR // KT-3985 interface Trait { diff --git a/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverrideWithDelegation.kt b/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverrideWithDelegation.kt index bd2a97b96df..450ad185175 100644 --- a/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverrideWithDelegation.kt +++ b/compiler/testData/codegen/box/bridges/fakeGenericCovariantOverrideWithDelegation.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T): String } diff --git a/compiler/testData/codegen/box/bridges/kt12416.kt b/compiler/testData/codegen/box/bridges/kt12416.kt index 422f70ed161..c50c81671f5 100644 --- a/compiler/testData/codegen/box/bridges/kt12416.kt +++ b/compiler/testData/codegen/box/bridges/kt12416.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T, u: Int) = "A" } diff --git a/compiler/testData/codegen/box/bridges/longChainOneBridge.kt b/compiler/testData/codegen/box/bridges/longChainOneBridge.kt index 9b5a244afe1..6d1d79c28e7 100644 --- a/compiler/testData/codegen/box/bridges/longChainOneBridge.kt +++ b/compiler/testData/codegen/box/bridges/longChainOneBridge.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/manyTypeArgumentsSubstitutedSuccessively.kt b/compiler/testData/codegen/box/bridges/manyTypeArgumentsSubstitutedSuccessively.kt index 077e60bf322..82306ddf3f4 100644 --- a/compiler/testData/codegen/box/bridges/manyTypeArgumentsSubstitutedSuccessively.kt +++ b/compiler/testData/codegen/box/bridges/manyTypeArgumentsSubstitutedSuccessively.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T, u: U, v: V) = "A" } diff --git a/compiler/testData/codegen/box/bridges/methodFromTrait.kt b/compiler/testData/codegen/box/bridges/methodFromTrait.kt index 3faa6038eb3..058109901d1 100644 --- a/compiler/testData/codegen/box/bridges/methodFromTrait.kt +++ b/compiler/testData/codegen/box/bridges/methodFromTrait.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T, u: U) = "A" } diff --git a/compiler/testData/codegen/box/bridges/simple.kt b/compiler/testData/codegen/box/bridges/simple.kt index 819e361471e..284d7cbb44c 100644 --- a/compiler/testData/codegen/box/bridges/simple.kt +++ b/compiler/testData/codegen/box/bridges/simple.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/simpleGenericMethod.kt b/compiler/testData/codegen/box/bridges/simpleGenericMethod.kt index 597d682e040..81e6c8607c1 100644 --- a/compiler/testData/codegen/box/bridges/simpleGenericMethod.kt +++ b/compiler/testData/codegen/box/bridges/simpleGenericMethod.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T, u: U) = "A" } diff --git a/compiler/testData/codegen/box/bridges/simpleObject.kt b/compiler/testData/codegen/box/bridges/simpleObject.kt index e32b332e83f..5ff3c8177e6 100644 --- a/compiler/testData/codegen/box/bridges/simpleObject.kt +++ b/compiler/testData/codegen/box/bridges/simpleObject.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/simpleTraitImpl.kt b/compiler/testData/codegen/box/bridges/simpleTraitImpl.kt index 828605ce31a..1e1ccbab17e 100644 --- a/compiler/testData/codegen/box/bridges/simpleTraitImpl.kt +++ b/compiler/testData/codegen/box/bridges/simpleTraitImpl.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/simpleUpperBound.kt b/compiler/testData/codegen/box/bridges/simpleUpperBound.kt index 6b306462de1..dea1f7eb647 100644 --- a/compiler/testData/codegen/box/bridges/simpleUpperBound.kt +++ b/compiler/testData/codegen/box/bridges/simpleUpperBound.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/abstractFun.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/abstractFun.kt index ee45f260fe8..39e1b1935f0 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/abstractFun.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/abstractFun.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR abstract class A { abstract fun foo(t: T): String } diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/boundedTypeArguments.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/boundedTypeArguments.kt index b02e0bb502f..3db4852ed2b 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/boundedTypeArguments.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/boundedTypeArguments.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T, u: U) = "A" } diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/delegation.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/delegation.kt index 7bb33feace2..3d80f6523ea 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/delegation.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/delegation.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun id(t: T): T } diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt index e1b49f1be0c..473cee266e1 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/differentErasureInSuperClassComplex.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR public open class A { fun foo(x: T) = "O" fun foo(x: A) = "K" diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/genericMethod.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/genericMethod.kt index 257ffdbaeb7..0119eba58a8 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/genericMethod.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/genericMethod.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T, u: U) = "A" } diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/object.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/object.kt index 185f76e59f3..c7c95464c59 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/object.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/object.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/simple.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/simple.kt index c124469dd6a..c6c2637ef22 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/simple.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/simple.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/upperBound.kt b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/upperBound.kt index 52e65d0eff4..f6d4dccfc40 100644 --- a/compiler/testData/codegen/box/bridges/substitutionInSuperClass/upperBound.kt +++ b/compiler/testData/codegen/box/bridges/substitutionInSuperClass/upperBound.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR open class A { open fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges.kt b/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges.kt index 0ee334f2132..38d7cb2431f 100644 --- a/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges.kt +++ b/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T, u: Int) = "A" } diff --git a/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges2.kt b/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges2.kt index ea34ebf2d76..07af5afaa4e 100644 --- a/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges2.kt +++ b/compiler/testData/codegen/box/bridges/twoParentsWithDifferentMethodsTwoBridges2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T, u: Int) = "A" } diff --git a/compiler/testData/codegen/box/bridges/twoParentsWithTheSameMethodOneBridge.kt b/compiler/testData/codegen/box/bridges/twoParentsWithTheSameMethodOneBridge.kt index 22e22cb7e13..de57467d8b1 100644 --- a/compiler/testData/codegen/box/bridges/twoParentsWithTheSameMethodOneBridge.kt +++ b/compiler/testData/codegen/box/bridges/twoParentsWithTheSameMethodOneBridge.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T) = "A" } diff --git a/compiler/testData/codegen/box/classes/delegationGenericArg.kt b/compiler/testData/codegen/box/classes/delegationGenericArg.kt index a7535184b00..f298e834f79 100644 --- a/compiler/testData/codegen/box/classes/delegationGenericArg.kt +++ b/compiler/testData/codegen/box/classes/delegationGenericArg.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T): String } diff --git a/compiler/testData/codegen/box/classes/delegationGenericArgUpperBound.kt b/compiler/testData/codegen/box/classes/delegationGenericArgUpperBound.kt index 9c0f5c37431..72e541b7f3b 100644 --- a/compiler/testData/codegen/box/classes/delegationGenericArgUpperBound.kt +++ b/compiler/testData/codegen/box/classes/delegationGenericArgUpperBound.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND: JS_IR interface A { fun foo(t: T): String } diff --git a/compiler/testData/codegen/box/classes/kt500.kt b/compiler/testData/codegen/box/classes/kt500.kt index 6b5e4f62232..b9c66165f9e 100644 --- a/compiler/testData/codegen/box/classes/kt500.kt +++ b/compiler/testData/codegen/box/classes/kt500.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR var GUEST_USER_ID = 3 val USER_ID = try { diff --git a/compiler/testData/codegen/box/closures/kt3738.kt b/compiler/testData/codegen/box/closures/kt3738.kt index cad17eed6e0..a05dbde0ae1 100644 --- a/compiler/testData/codegen/box/closures/kt3738.kt +++ b/compiler/testData/codegen/box/closures/kt3738.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR class A { fun foo() {} fun bar(f: A.() -> Unit = {}) {} diff --git a/compiler/testData/codegen/box/defaultArguments/signature/kt9924.kt b/compiler/testData/codegen/box/defaultArguments/signature/kt9924.kt index b6c352c2e32..8366f26008e 100644 --- a/compiler/testData/codegen/box/defaultArguments/signature/kt9924.kt +++ b/compiler/testData/codegen/box/defaultArguments/signature/kt9924.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR abstract class A { abstract fun test(a: T, b:Boolean = false) : String } diff --git a/compiler/testData/codegen/box/finally/notChainCatch.kt b/compiler/testData/codegen/box/finally/notChainCatch.kt index 2292949fed0..18e5573b318 100644 --- a/compiler/testData/codegen/box/finally/notChainCatch.kt +++ b/compiler/testData/codegen/box/finally/notChainCatch.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR fun unsupportedEx() { if (true) throw UnsupportedOperationException() } diff --git a/compiler/testData/codegen/box/finally/tryFinally.kt b/compiler/testData/codegen/box/finally/tryFinally.kt index 16bbf455cfb..39928fbec60 100644 --- a/compiler/testData/codegen/box/finally/tryFinally.kt +++ b/compiler/testData/codegen/box/finally/tryFinally.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR fun unsupportedEx() { if (true) throw UnsupportedOperationException() } diff --git a/compiler/testData/codegen/box/localClasses/kt3210.kt b/compiler/testData/codegen/box/localClasses/kt3210.kt index 87474c1e3fc..12c9b1cba6e 100644 --- a/compiler/testData/codegen/box/localClasses/kt3210.kt +++ b/compiler/testData/codegen/box/localClasses/kt3210.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// IGNORE_BACKEND: JS_IR package org.example interface SomeTrait {} diff --git a/compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt b/compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt index 04b5e5c50cf..2b5c62666e6 100644 --- a/compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt +++ b/compiler/testData/codegen/box/localClasses/localClassInParameterInitializer.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR class A( val a: String = { open class B() { diff --git a/compiler/testData/codegen/box/secondaryConstructors/defaultParametersNotDuplicated.kt b/compiler/testData/codegen/box/secondaryConstructors/defaultParametersNotDuplicated.kt index ebcac9ecc01..409e42f9ec0 100644 --- a/compiler/testData/codegen/box/secondaryConstructors/defaultParametersNotDuplicated.kt +++ b/compiler/testData/codegen/box/secondaryConstructors/defaultParametersNotDuplicated.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR var global = 0 fun sideEffect() = global++ diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index c9e2f790a92..52116ec2677 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import java.util.*; import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isAny; +import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*; import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getBuiltIns; @@ -634,4 +635,15 @@ public class DescriptorUtils { : descriptor; } + public static boolean isMethodOfAny(@NotNull FunctionDescriptor descriptor) { + String name = descriptor.getName().asString(); + List parameters = descriptor.getValueParameters(); + if (parameters.isEmpty()) { + return name.equals("hashCode") || name.equals("toString"); + } + else if (parameters.size() == 1 && name.equals("equals")) { + return isNullableAny(parameters.get(0).getType()); + } + return false; + } } diff --git a/js/js.translator/testData/box/delegation/delegationGenericArg.kt b/js/js.translator/testData/box/delegation/delegationGenericArg.kt index 0d1f8e3d0b7..6a7dedbde52 100644 --- a/js/js.translator/testData/box/delegation/delegationGenericArg.kt +++ b/js/js.translator/testData/box/delegation/delegationGenericArg.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JS_IR // EXPECTED_REACHABLE_NODES: 1118 // This test was adapted from compiler/testData/codegen/box/classes package foo diff --git a/libraries/stdlib/js/irRuntime/exceptions.kt b/libraries/stdlib/js/irRuntime/exceptions.kt index 81501c9343f..e08ae6ac4d7 100644 --- a/libraries/stdlib/js/irRuntime/exceptions.kt +++ b/libraries/stdlib/js/irRuntime/exceptions.kt @@ -49,6 +49,11 @@ open class AssertionError(message: String?, cause: Throwable?) : Exception(messa } +open class UnsupportedOperationException(message: String?, cause: Throwable?) : RuntimeException(message, cause) { + constructor() : this(null, null) + constructor(message: String?) : this(message, null) + constructor(cause: Throwable?) : this(null, cause) +} // TODO: fix function names to satisfy style convention (depends on built-in names) fun THROW_CCE() {