diff --git a/compiler/testData/codegen/box/exclExcl/genericNull.kt b/compiler/testData/codegen/box/exclExcl/genericNull.kt index e8712197eac..0d4f831dfb7 100644 --- a/compiler/testData/codegen/box/exclExcl/genericNull.kt +++ b/compiler/testData/codegen/box/exclExcl/genericNull.kt @@ -1,6 +1,3 @@ -// TODO: muted automatically, investigate should it be ran for JS or not -// IGNORE_BACKEND: JS - fun foo(t: T) { t!! } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 412e2562a33..835e3772f7e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -1753,6 +1753,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("explicitUpcast.kt") + public void testExplicitUpcast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/cast/explicitUpcast.kt"); + doTest(fileName); + } + @TestMetadata("implicitCastToLong.kt") public void testImplicitCastToLong() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/cast/implicitCastToLong.kt"); @@ -6887,6 +6893,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/safeCall"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true); } + @TestMetadata("redundantSafeAccess.kt") + public void testRedundantSafeAccess() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/safeCall/redundantSafeAccess.kt"); + doTest(fileName); + } + @TestMetadata("safeAccess.kt") public void testSafeAccess() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/safeCall/safeAccess.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 03fb3e3748b..cbd281a9eb5 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -7851,13 +7851,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { @TestMetadata("genericNull.kt") public void testGenericNull() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/exclExcl/genericNull.kt"); - try { - doTest(fileName); - } - catch (Throwable ignore) { - return; - } - throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + doTest(fileName); } @TestMetadata("primitive.kt") diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/UnaryOperationTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/UnaryOperationTranslator.java index 2e20722f22a..0e7664d5e1a 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/UnaryOperationTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/UnaryOperationTranslator.java @@ -29,12 +29,10 @@ import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.psi.KtConstantExpression; import org.jetbrains.kotlin.psi.KtExpression; import org.jetbrains.kotlin.psi.KtUnaryExpression; -import org.jetbrains.kotlin.resolve.BindingContextUtils; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; -import org.jetbrains.kotlin.types.KotlinType; import static org.jetbrains.kotlin.js.translate.general.Translation.translateAsExpression; import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getCompileTimeValue; @@ -55,9 +53,8 @@ public final class UnaryOperationTranslator { IElementType operationToken = expression.getOperationReference().getReferencedNameElementType(); if (operationToken == KtTokens.EXCLEXCL) { KtExpression baseExpression = getBaseExpression(expression); - KotlinType type = BindingContextUtils.getTypeNotNull(context.bindingContext(), baseExpression); JsExpression translatedExpression = translateAsExpression(baseExpression, context); - return type.isMarkedNullable() ? sure(translatedExpression, context) : translatedExpression; + return sure(translatedExpression, context); } if (operationToken == KtTokens.MINUS) { diff --git a/js/js.translator/testData/box/expression/cast/explicitUpcast.js b/js/js.translator/testData/box/expression/cast/explicitUpcast.js new file mode 100644 index 00000000000..8217e075b0e --- /dev/null +++ b/js/js.translator/testData/box/expression/cast/explicitUpcast.js @@ -0,0 +1,3 @@ +function createWrongObject() { + return new (JS_TESTS.foo.C); +} \ No newline at end of file diff --git a/js/js.translator/testData/box/expression/cast/explicitUpcast.kt b/js/js.translator/testData/box/expression/cast/explicitUpcast.kt new file mode 100644 index 00000000000..5a6ea35bd39 --- /dev/null +++ b/js/js.translator/testData/box/expression/cast/explicitUpcast.kt @@ -0,0 +1,34 @@ +package foo + +open class A + +class B : A() + +class C + +fun box(): String { + var b: B = createWrongObject() + if (b is A) return "fail1: is" + if (b as? A != null) return "fail1: as?" + try { + println(b as A) + return "fail1: as" + } + catch (e: ClassCastException) { + // It's expected + } + + b = B() + if (b !is A) return "fail2: is" + if (b as? A == null) return "fail2: as?" + try { + if ((b as A) != b) return "fail2: as" + } + catch (e: ClassCastException) { + return "fail2a: as" + } + + return "OK" +} + +external fun createWrongObject(): B \ No newline at end of file diff --git a/js/js.translator/testData/box/safeCall/redundantSafeAccess.js b/js/js.translator/testData/box/safeCall/redundantSafeAccess.js new file mode 100644 index 00000000000..bee74b59b4a --- /dev/null +++ b/js/js.translator/testData/box/safeCall/redundantSafeAccess.js @@ -0,0 +1,3 @@ +function createWrongObject() { + return null +} \ No newline at end of file diff --git a/js/js.translator/testData/box/safeCall/redundantSafeAccess.kt b/js/js.translator/testData/box/safeCall/redundantSafeAccess.kt new file mode 100644 index 00000000000..917d28e1086 --- /dev/null +++ b/js/js.translator/testData/box/safeCall/redundantSafeAccess.kt @@ -0,0 +1,32 @@ +package foo + +class A(val x: String) { + fun foo() = x +} + +fun box(): String { + var b: A = createWrongObject() + if (b?.x != null) return "fail1: ?." + if (b?.foo() != null) return "fail1a: ?." + try { + println(b!!.x) + return "fail1: !!" + } + catch (e: NullPointerException) { + // It's expected + } + + b = A("OK") + if (b?.x != "OK") return "fail2: ?." + if (b?.foo() != "OK") return "fail2a: ?." + try { + if (b!!.x != "OK") return "fail2: !!" + } + catch (e: NullPointerException) { + return "fail2a: !!" + } + + return "OK" +} + +external fun createWrongObject(): A \ No newline at end of file