diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/RttiTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/RttiTestGenerated.java index e61bc04fb42..fc8528dbaa5 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/RttiTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/RttiTestGenerated.java @@ -77,6 +77,18 @@ public class RttiTestGenerated extends AbstractRttiTest { doTest(fileName); } + @TestMetadata("sideEffectMethod.kt") + public void testSideEffectMethod() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/rtti/cases/sideEffectMethod.kt"); + doTest(fileName); + } + + @TestMetadata("sideEffectProperty.kt") + public void testSideEffectProperty() throws Exception { + String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/rtti/cases/sideEffectProperty.kt"); + doTest(fileName); + } + @TestMetadata("stdlibEmptyListClass.kt") public void testStdlibEmptyListClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/rtti/cases/stdlibEmptyListClass.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt index 25d143f49a5..ef59ed36c83 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt @@ -20,9 +20,7 @@ import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.metadata.TypeCheck import com.google.dart.compiler.backend.js.ast.metadata.typeCheck import org.jetbrains.kotlin.js.translate.context.TranslationContext -import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.or -import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.typeOfIs -import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.isNullCheck +import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.* import java.util.* fun expandIsCalls(node: JsNode, context: TranslationContext) { @@ -71,9 +69,16 @@ private class TypeCheckRewritingVisitor(private val context: TranslationContext) TypeCheck.INSTANCEOF -> context.namer().isInstanceOf(argument, calleeArgument) - // Kotlin.orNull(calleeArgument)(argument) -> argument === null || calleeArgument(argument) - TypeCheck.OR_NULL -> - or(isNullCheck(argument), JsInvocation(calleeArgument, argument)) + // Kotlin.orNull(calleeArgument)(argument) -> (tmp = argument) == null || calleeArgument(tmp) + TypeCheck.OR_NULL -> { + val currentScope = scopes.peek() + val tmp = currentScope.declareTemporary() + val statementContext = lastStatementLevelContext + statementContext.addPrevious(newVar(tmp, null)) + val assignment = assignment(tmp.makeRef(), argument) + val tmpIsNull = TranslationUtils.isNullCheck(assignment) + or(tmpIsNull, JsInvocation(calleeArgument, tmp.makeRef())) + } else -> null diff --git a/js/js.translator/testData/rtti/cases/sideEffectMethod.kt b/js/js.translator/testData/rtti/cases/sideEffectMethod.kt new file mode 100644 index 00000000000..615becffb55 --- /dev/null +++ b/js/js.translator/testData/rtti/cases/sideEffectMethod.kt @@ -0,0 +1,21 @@ +package foo + +var counter = 0 + +class A { + fun getCounter(): Any? = + when (counter++) { + 0 -> "0" + 1 -> null + else -> counter + } +} + +fun box(): String { + assertEquals(false, A().getCounter() is Int?, "(1)") + assertEquals(true, A().getCounter() is Int?, "(2)") + assertEquals(true, A().getCounter() is Int?, "(3)") + assertEquals(3, counter) + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/rtti/cases/sideEffectProperty.kt b/js/js.translator/testData/rtti/cases/sideEffectProperty.kt new file mode 100644 index 00000000000..5c609176a24 --- /dev/null +++ b/js/js.translator/testData/rtti/cases/sideEffectProperty.kt @@ -0,0 +1,22 @@ +package foo + +var counter = 0 + +class A { + val x: Any? + get() = + when (counter++) { + 0 -> "0" + 1 -> null + else -> counter + } +} + +fun box(): String { + assertEquals(false, A().x is Int?, "(1)") + assertEquals(true, A().x is Int?, "(2)") + assertEquals(true, A().x is Int?, "(3)") + assertEquals(3, counter) + + return "OK" +} \ No newline at end of file