JS: fix unit materialization in case of null check and elvis operator
See KT-20287
This commit is contained in:
@@ -893,6 +893,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("unitSafeCall.kt")
|
||||||
public void testUnitSafeCall() throws Exception {
|
public void testUnitSafeCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/coercion/unitSafeCall.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/coercion/unitSafeCall.kt");
|
||||||
|
|||||||
+6
-2
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.types.isDynamic
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object EqualsBOIF : BinaryOperationIntrinsicFactory {
|
object EqualsBOIF : BinaryOperationIntrinsicFactory {
|
||||||
@@ -50,8 +51,12 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
|
|||||||
|
|
||||||
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
||||||
val isNegated = expression.isNegated()
|
val isNegated = expression.isNegated()
|
||||||
|
val anyType = context.currentModule.builtIns.anyType
|
||||||
if (right is JsNullLiteral || left is JsNullLiteral) {
|
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 }
|
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)
|
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 coercedLeft = TranslationUtils.coerce(context, left, anyType)
|
||||||
val coercedRight = TranslationUtils.coerce(context, right, anyType)
|
val coercedRight = TranslationUtils.coerce(context, right, anyType)
|
||||||
val result = TopLevelFIF.KOTLIN_EQUALS.apply(coercedLeft, listOf(coercedRight), context)
|
val result = TopLevelFIF.KOTLIN_EQUALS.apply(coercedLeft, listOf(coercedRight), context)
|
||||||
|
|||||||
+2
-1
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
|||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
import org.jetbrains.kotlin.types.TypeUtils;
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
|
|||||||
assert expressionType != null;
|
assert expressionType != null;
|
||||||
|
|
||||||
JsExpression leftExpression = TranslationUtils.coerce(
|
JsExpression leftExpression = TranslationUtils.coerce(
|
||||||
context(), Translation.translateAsExpression(leftKtExpression, context()), expressionType);
|
context(), Translation.translateAsExpression(leftKtExpression, context()), TypeUtilsKt.makeNullable(expressionType));
|
||||||
|
|
||||||
JsBlock rightBlock = new JsBlock();
|
JsBlock rightBlock = new JsBlock();
|
||||||
JsExpression rightExpression = TranslationUtils.coerce(
|
JsExpression rightExpression = TranslationUtils.coerce(
|
||||||
|
|||||||
@@ -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;"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user