diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt index 4a1456275db..bfa305129b8 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsBridgesConstruction.kt @@ -9,18 +9,16 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.varargParameterIndex -import org.jetbrains.kotlin.ir.backend.js.utils.eraseGenerics -import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName import org.jetbrains.kotlin.ir.backend.js.utils.hasStableJsName +import org.jetbrains.kotlin.ir.backend.js.utils.jsFunctionSignature import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration +import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classifierOrNull -import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.isEffectivelyExternal -import org.jetbrains.kotlin.ir.util.render -import org.jetbrains.kotlin.name.Name class JsBridgesConstruction(context: JsIrBackendContext) : BridgesConstruction(context) { @@ -35,21 +33,8 @@ class JsBridgesConstruction(context: JsIrBackendContext) : BridgesConstruction, - val returnType: IrType?, -) : JsSignature { - override fun toString(): String { - val er = extensionReceiverType?.let { "(er: ${it.render()}) " } ?: "" - val parameters = valueParametersType.joinToString(", ") { it.render() } - return "[$er$name($parameters) -> ${returnType?.let { " -> ${it.render()}" } ?: ""}]" - } -} - -data class JsStableNameSignature( - override val name: Name, -) : JsSignature diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt index fbf362e6fcc..9d33262bbbf 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.compilationException import org.jetbrains.kotlin.backend.common.ir.isPure import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder @@ -19,7 +18,6 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol @@ -229,37 +227,13 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass { * └─────────────┻─────────────────────────────┴───────────────────────────────┘ * ``` * Note: advanced check is performed when casting to primitive types, array types, function types, or interfaces. - * - * If we statically know that this is an upcast, we try to generate no checks. - * In this case, the following logic is applied: - * ``` - * ┌─────────────┬─────────────┐ - * │ to non-null │ to nullable │ - * ┌─────────────╋━━━━━━━━━━━━━┻━━━━━━━━━━━━━┫ - * │from non-null┃ true │ - * ├─────────────╋─────────────┬─────────────┤ - * │from nullable┃ null check │ true │ - * └─────────────┻─────────────┴─────────────┘ - * ``` */ private fun generateTypeCheck(argument: () -> IrExpression, toType: IrType): IrExpression { val toNotNullable = toType.makeNotNull() val argumentInstance = argument() - val fromType = argumentInstance.type - val fromNotNullable = fromType.makeNotNull() - - val isFromNullable = fromType.isNullable() - val isToNullable = toType.isNullable() - - if (fromNotNullable !is IrDynamicType && fromNotNullable.isSubtypeOf(toNotNullable, context.typeSystem)) { - // This is an upcast - return when { - isFromNullable && !isToNullable -> calculator.run { not(nullCheck(argument())) } - else -> IrConstImpl.constTrue(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.booleanType) - } - } - val instanceCheck = generateTypeCheckNonNull(argumentInstance, toNotNullable) + val isFromNullable = argumentInstance.type.isNullable() + val isToNullable = toType.isNullable() val isNativeCheck = !advancedCheckRequired(toNotNullable) return when { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt index d16335ddcad..eb082206c3b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/NameTables.kt @@ -14,7 +14,11 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol import org.jetbrains.kotlin.ir.types.isUnit -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.util.file +import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable +import org.jetbrains.kotlin.ir.util.isEffectivelyExternal +import org.jetbrains.kotlin.ir.util.isInterface +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.js.common.isES5IdentifierPart @@ -137,17 +141,22 @@ fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): S val nameBuilder = StringBuilder() nameBuilder.append(declarationName) + // TODO should we skip type parameters and use upper bound of type parameter when print type of value parameters? + declaration.typeParameters.ifNotEmpty { + nameBuilder.append("_\$t") + joinTo(nameBuilder, "") { "_${it.name.asString()}" } + } declaration.extensionReceiverParameter?.let { - nameBuilder.append("_r$${it.type.eraseGenerics(context.irBuiltIns).asString()}") + nameBuilder.append("_r$${it.type.asString()}") } declaration.valueParameters.ifNotEmpty { - joinTo(nameBuilder, "") { "_${it.type.eraseGenerics(context.irBuiltIns).asString()}" } + joinTo(nameBuilder, "") { "_${it.type.asString()}" } } declaration.returnType.let { // Return type is only used in signature for inline class and Unit types because // they are binary incompatible with supertypes. if (context.inlineClassesUtils.isTypeInlined(it) || it.isUnit()) { - nameBuilder.append("_ret$${it.eraseGenerics(context.irBuiltIns).asString()}") + nameBuilder.append("_ret$${it.asString()}") } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/TypeTranformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/TypeTranformer.kt index f3b100a223b..25a00839e3e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/TypeTranformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/TypeTranformer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ diff --git a/compiler/testData/codegen/boxError/semantic/missedBody.kt b/compiler/testData/codegen/boxError/semantic/missedBody.kt index 17aa09f87fe..1572e7dac24 100644 --- a/compiler/testData/codegen/boxError/semantic/missedBody.kt +++ b/compiler/testData/codegen/boxError/semantic/missedBody.kt @@ -4,9 +4,9 @@ // MODULE: lib // FILE: t.kt -fun bar(a: String, b: String): Any +fun bar(a: String, b: String): String -fun foo(): Any { +fun foo(): String { return bar("O", "K") } @@ -17,4 +17,4 @@ fun box(): String { val r = foo() if (r is String) return r return "OK" -} +} \ No newline at end of file diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java index ee99ae02cb9..c65eb0d97bc 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java @@ -2287,12 +2287,6 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/expression/cast/primitiveToClass.kt"); } - @Test - @TestMetadata("redundantCast.kt") - public void testRedundantCast() throws Exception { - runTest("js/js.translator/testData/box/expression/cast/redundantCast.kt"); - } - @Test @TestMetadata("reifiedToNotNull.kt") public void testReifiedToNotNull() throws Exception { @@ -2352,6 +2346,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { public void testSmartCastInFunction() throws Exception { runTest("js/js.translator/testData/box/expression/cast/smartCastInFunction.kt"); } + + @Test + @TestMetadata("unsafeVarianceCast.kt") + public void testUnsafeVarianceCast() throws Exception { + runTest("js/js.translator/testData/box/expression/cast/unsafeVarianceCast.kt"); + } } @Nested @@ -3013,6 +3013,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/expression/function/overloadClassConstructorByFactoryMethod.kt"); } + @Test + @TestMetadata("overloadGeneric.kt") + public void testOverloadGeneric() throws Exception { + runTest("js/js.translator/testData/box/expression/function/overloadGeneric.kt"); + } + @Test @TestMetadata("overloadOverridenFun.kt") public void testOverloadOverridenFun() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java index a1f5d382688..52d8087d7dc 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java @@ -2683,12 +2683,6 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/expression/cast/primitiveToClass.kt"); } - @Test - @TestMetadata("redundantCast.kt") - public void testRedundantCast() throws Exception { - runTest("js/js.translator/testData/box/expression/cast/redundantCast.kt"); - } - @Test @TestMetadata("reifiedToNotNull.kt") public void testReifiedToNotNull() throws Exception { @@ -2748,6 +2742,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { public void testSmartCastInFunction() throws Exception { runTest("js/js.translator/testData/box/expression/cast/smartCastInFunction.kt"); } + + @Test + @TestMetadata("unsafeVarianceCast.kt") + public void testUnsafeVarianceCast() throws Exception { + runTest("js/js.translator/testData/box/expression/cast/unsafeVarianceCast.kt"); + } } @Nested @@ -3397,6 +3397,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/expression/function/overloadClassConstructorByFactoryMethod.kt"); } + @Test + @TestMetadata("overloadGeneric.kt") + public void testOverloadGeneric() throws Exception { + runTest("js/js.translator/testData/box/expression/function/overloadGeneric.kt"); + } + @Test @TestMetadata("overloadOverridenFun.kt") public void testOverloadOverridenFun() throws Exception { diff --git a/js/js.translator/testData/box/expression/cast/redundantCast.kt b/js/js.translator/testData/box/expression/cast/redundantCast.kt deleted file mode 100644 index 9de4a3aed1a..00000000000 --- a/js/js.translator/testData/box/expression/cast/redundantCast.kt +++ /dev/null @@ -1,150 +0,0 @@ -// EXPECTED_REACHABLE_NODES: 1306 - -// Test that upcasts are optimized away - -open class Base - -class Derived: Base() - -var counter = 0 -var _derived = Derived() - -@JsExport -fun getDerived(): Derived { - counter += 1 - return _derived -} - -@JsExport -fun getDerivedNullable(): Derived? { - counter += 1 - return _derived -} - -@JsExport -fun getDerivedNull(): Derived? { - counter += 1 - return null -} - -// CHECK_CONTAINS_NO_CALLS: upcast1 except=getDerived IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast1 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast1 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=upcast1 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun upcast1() = getDerived() as Base - -// CHECK_CONTAINS_NO_CALLS: upcast2 except=getDerived IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast2 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast2 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=upcast2 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun upcast2() = getDerived() as Base? - -// CHECK_BINOP_COUNT: function=upcast3 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun upcast3() = getDerivedNullable() as Base - -// CHECK_CONTAINS_NO_CALLS: upcast4 except=getDerivedNullable IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast4 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast4 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=upcast1 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun upcast4() = getDerivedNullable() as Base? - -// CHECK_BINOP_COUNT: function=upcast5 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun upcast5() = getDerivedNull() as Base - -// CHECK_CONTAINS_NO_CALLS: upcast6 except=getDerivedNull IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast6 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast6 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=upcast6 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun upcast6() = getDerivedNull() as Base? - -// CHECK_CONTAINS_NO_CALLS: safeCast1 except=getDerived IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=safeCast1 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=safeCast1 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=safeCast1 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun safeCast1() = getDerived() as? Base - -// CHECK_CONTAINS_NO_CALLS: safeCast2 except=getDerived IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=safeCast1 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=safeCast1 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=safeCast2 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun safeCast2() = getDerived() as? Base? - -// CHECK_BINOP_COUNT: function=safeCast3 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun safeCast3() = getDerivedNullable() as? Base - -// CHECK_CONTAINS_NO_CALLS: safeCast4 except=getDerivedNullable IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=safeCast4 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=safeCast4 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=safeCast4 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun safeCast4() = getDerivedNullable() as? Base? - -// CHECK_BINOP_COUNT: function=safeCast5 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun safeCast5() = getDerivedNull() as? Base - -// CHECK_CONTAINS_NO_CALLS: safeCast6 except=getDerivedNull IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=safeCast6 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=safeCast6 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=safeCast6 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun safeCast6() = getDerivedNull() as? Base? - -// CHECK_CONTAINS_NO_CALLS: upcast1 except=getDerived IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast1 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast1 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=instanceCheck1 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun instanceCheck1() = getDerived() is Base - -// CHECK_CONTAINS_NO_CALLS: upcast2 except=getDerived IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast2 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast2 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=instanceCheck2 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun instanceCheck2() = getDerived() is Base? - -// CHECK_BINOP_COUNT: function=instanceCheck3 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun instanceCheck3() = getDerivedNullable() is Base - -// CHECK_CONTAINS_NO_CALLS: upcast4 except=getDerivedNullable IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast4 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast4 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=instanceCheck4 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun instanceCheck4() = getDerivedNullable() is Base? - -// CHECK_BINOP_COUNT: function=instanceCheck5 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun instanceCheck5() = getDerivedNull() is Base - -// CHECK_CONTAINS_NO_CALLS: upcast6 except=getDerivedNull IGNORED_BACKENDS=JS -// CHECK_TERNARY_OPERATOR_COUNT: function=upcast6 count=0 IGNORED_BACKENDS=JS -// CHECK_IF_COUNT: function=upcast6 count=0 IGNORED_BACKENDS=JS -// CHECK_BINOP_COUNT: function=instanceCheck6 count=0 symbol=instanceof IGNORED_BACKENDS=JS -fun instanceCheck6() = getDerivedNull() is Base? - -fun box(): String { - assertSame(_derived, upcast1(), "upcast1()") - assertSame(_derived, upcast2(), "upcast2()") - assertSame(_derived, upcast3(), "upcast3()") - assertSame(_derived, upcast4(), "upcast4()") - failsClassCast("upcast5()") { upcast5() } - assertSame(null, upcast6(), "upcast6()") - assertEquals(6, counter) - - counter = 0 - - assertSame(_derived, safeCast1(), "safeCast1()") - assertSame(_derived, safeCast2(), "safeCast2()") - assertSame(_derived, safeCast3(), "safeCast3()") - assertSame(_derived, safeCast4(), "safeCast4()") - assertSame(null, safeCast5(), "safeCast5()") - assertSame(null, safeCast6(), "safeCast6()") - assertEquals(6, counter) - - counter = 0 - - assertTrue(instanceCheck1(), "instanceCheck1()") - assertTrue(instanceCheck2(), "instanceCheck2()") - assertTrue(instanceCheck3(), "instanceCheck3()") - assertTrue(instanceCheck4(), "instanceCheck4()") - assertFalse(instanceCheck5(), "instanceCheck5()") - assertTrue(instanceCheck6(), "instanceCheck6()") - assertEquals(6, counter) - - return "OK" -} diff --git a/js/js.translator/testData/box/expression/cast/unsafeVarianceCast.kt b/js/js.translator/testData/box/expression/cast/unsafeVarianceCast.kt new file mode 100644 index 00000000000..5f286bd4a5a --- /dev/null +++ b/js/js.translator/testData/box/expression/cast/unsafeVarianceCast.kt @@ -0,0 +1,21 @@ +abstract class Foo { + abstract fun foo(element: @UnsafeVariance E): Boolean +} + +class Bar : Foo() { + override fun foo(element: E): Boolean { + if (element !is C?) return false + return true + } +} + +open class C + +open class D : C() + +fun box(): String { + val a = (object{}) + val foo: Foo = Bar() + if (foo.foo(a as Any?)) return "fail" + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/expression/function/overloadGeneric.kt b/js/js.translator/testData/box/expression/function/overloadGeneric.kt new file mode 100644 index 00000000000..e397cfe8319 --- /dev/null +++ b/js/js.translator/testData/box/expression/function/overloadGeneric.kt @@ -0,0 +1,82 @@ +// KJS_WITH_FULL_RUNTIME + +class L + +class A { + fun foo(a: L) = "Int" + fun foo(a: L) = "String" + fun L.bar() = "Int2" + fun L.bar() = "String2" +} + +fun foo(a: L) = "Int" +fun foo(a: L) = "String" + +private class TestClass { + private val data = mutableListOf>() + fun withData(data: List>) = apply { this.data.addAll(data) } + fun withData(row: List) = apply { + data.add(row) + } + + fun getCols(): Int { + return data.firstOrNull()?.size ?: return 0 + } +} + +object B { + fun baz(vararg v: B) = "[A]" + + fun baz(vararg v: String) = "[S]" + + fun baz(v: Array) = "Array" +} + +class C { + fun bac(c: T): String { + return "T4" + } + + fun bac(c: Int): String { + return "Int5" + } + + fun bac(c: List): String { + return "ListT4" + } + + fun bac(c: List): String { + return "ListInt4" + } + + fun bac(c: List<*>): String { + return "ListStar4" + } +} + +fun box(): String { + if (A().foo(L()) != "Int") return "fail1" + A().apply { + if (L().bar() != "Int2") return "fail2" + } + if (foo(L()) != "Int") return "fail3" + + val b = TestClass() + val data = mutableListOf>() + data.add(listOf("a", "b", "c")) + data.add(listOf("d", "e", "f")) + b.withData(data) + if (b.getCols() != 3) return "fail4" + + if (B.baz(B) != "[A]") return "fail5" + if (B.baz("a") != "[S]") return "fail6" + if (B.baz(arrayOf("b")) != "Array") return "fail7" + + if(C().bac("a") != "T4") return "fail8" + if(C().bac(5) != "Int5") return "fail9" + if(C().bac(listOf("a", "b")) != "ListT4") return "fail10" + if(C().bac(listOf(5, 6)) != "ListInt4") return "fail11" + if(C().bac(listOf(Any(), Any())) != "ListStar4") return "fail12" + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/reified/isTNullable.kt b/js/js.translator/testData/box/reified/isTNullable.kt index 34d5b6426dd..b3532f33f6d 100644 --- a/js/js.translator/testData/box/reified/isTNullable.kt +++ b/js/js.translator/testData/box/reified/isTNullable.kt @@ -3,8 +3,7 @@ package foo // CHECK_NOT_CALLED: isTypeOfOrNull // CHECK_NULLS_COUNT: function=box count=10 TARGET_BACKENDS=JS -// CHECK_NULLS_COUNT: function=box count=0 IGNORED_BACKENDS=JS -// CHECK_CONTAINS_NO_CALLS: box except=assertEquals;A IGNORED_BACKENDS=JS +// CHECK_NULLS_COUNT: function=box count=6 IGNORED_BACKENDS=JS inline fun Any?.isTypeOfOrNull() = this is T? diff --git a/js/js.translator/testData/box/standardClasses/any.kt b/js/js.translator/testData/box/standardClasses/any.kt index fb6fb192a90..7fb71144b36 100644 --- a/js/js.translator/testData/box/standardClasses/any.kt +++ b/js/js.translator/testData/box/standardClasses/any.kt @@ -1,5 +1,6 @@ // EXPECTED_REACHABLE_NODES: 1285 // CHECK_CALLED_IN_SCOPE: function=isType scope=box TARGET_BACKENDS=JS +// CHECK_CALLED_IN_SCOPE: function=isObject scope=box IGNORED_BACKENDS=JS package foo class A : Any() @@ -15,11 +16,9 @@ fun box(): String { if (arrayOf(1, 2, 3).asAny() !is Any) return "fail3" - if (testUtils.isLegacyBackend()) { - if (createNakedObject() is Any) return "fail4" - } + if (createNakedObject() is Any) return "fail4" - if (({ }).asAny() !is Any) return "fail5" + if (({ }).asAny() !is Any) return "fail5" if ((23).asAny() !is Any) return "fail6" @@ -32,4 +31,4 @@ fun box(): String { return "OK" } -fun createNakedObject(): Any? = js("Object.create(null)") +fun createNakedObject(): Any? = js("Object.create(null)") \ No newline at end of file diff --git a/js/js.translator/testData/lineNumbers/whenIs.kt b/js/js.translator/testData/lineNumbers/whenIs.kt index e742b06bf97..540a0d82b4d 100644 --- a/js/js.translator/testData/lineNumbers/whenIs.kt +++ b/js/js.translator/testData/lineNumbers/whenIs.kt @@ -14,4 +14,4 @@ open class A open class B : A() // LINES(JS): 1 10 2 2 2 2 3 3 4 4 5 5 6 6 8 8 12 * 14 14 -// LINES(JS_IR): 2 2 4 4 * 14 +// LINES(JS_IR): 2 2 3 4 4 5 6 6 8 8 * 14 diff --git a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/ReplTest.kt b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/ReplTest.kt index 5afad240a84..09ea7c378a6 100644 --- a/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/ReplTest.kt +++ b/libraries/scripting/js-test/test/org/jetbrains/kotlin/scripting/repl/js/test/ReplTest.kt @@ -122,6 +122,8 @@ abstract class AbstractReplTestRunner : TestCase() { Assert.assertEquals("OK", compileAndEval(lines)) } + /* Ignore annotation doesn't work, so comment it + @Ignore("we use Object.assign inside type checks and nashorn does not support it") @Test fun testInstanceOf() { val lines = listOf( @@ -134,6 +136,7 @@ abstract class AbstractReplTestRunner : TestCase() { ) Assert.assertEquals("truetrue", compileAndEval(lines)) } + */ @Test fun testScopes() {