JS: fix unit materialization in case of null check and elvis operator

See KT-20287
This commit is contained in:
Alexey Andreev
2017-09-18 12:35:50 +03:00
parent b4c622d433
commit c5e5a43f68
4 changed files with 32 additions and 3 deletions
@@ -893,6 +893,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName);
}
@TestMetadata("unitNullCheck.kt")
public void testUnitNullCheck() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/coercion/unitNullCheck.kt");
doTest(fileName);
}
@TestMetadata("unitSafeCall.kt")
public void testUnitSafeCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/coercion/unitSafeCall.kt");
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import java.util.*
object EqualsBOIF : BinaryOperationIntrinsicFactory {
@@ -50,8 +51,12 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
val isNegated = expression.isNegated()
val anyType = context.currentModule.builtIns.anyType
if (right is JsNullLiteral || left is JsNullLiteral) {
return TranslationUtils.nullCheck(if (right is JsNullLiteral) left else right, isNegated)
val (subject, ktSubject) = if (right is JsNullLiteral) Pair(left, expression.left!!) else Pair(right, expression.right!!)
val type = context.bindingContext().getType(ktSubject) ?: anyType
val coercedSubject = TranslationUtils.coerce(context, subject, type.makeNullable())
return TranslationUtils.nullCheck(coercedSubject, isNegated)
}
val ktLeft = checkNotNull(expression.left) { "No left-hand side: " + expression.text }
@@ -78,7 +83,6 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
return JsBinaryOperation(if (isNegated) JsBinaryOperator.NEQ else JsBinaryOperator.EQ, left, right)
}
val anyType = context.currentModule.builtIns.anyType
val coercedLeft = TranslationUtils.coerce(context, left, anyType)
val coercedRight = TranslationUtils.coerce(context, right, anyType)
val result = TopLevelFIF.KOTLIN_EQUALS.apply(coercedLeft, listOf(coercedRight), context)
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
import java.util.Collections;
@@ -129,7 +130,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
assert expressionType != null;
JsExpression leftExpression = TranslationUtils.coerce(
context(), Translation.translateAsExpression(leftKtExpression, context()), expressionType);
context(), Translation.translateAsExpression(leftKtExpression, context()), TypeUtilsKt.makeNullable(expressionType));
JsBlock rightBlock = new JsBlock();
JsExpression rightExpression = TranslationUtils.coerce(
+18
View File
@@ -0,0 +1,18 @@
// EXPECTED_REACHABLE_NODES: 1027
var log = ""
fun box(): String {
foo() ?: bar()
if (foo() == null) bar()
if (log != "foo;foo;") return "fail: $log"
return "OK"
}
fun foo() {
log += "foo;"
}
fun bar() {
log += "bar;"
}