Fix some Unit materialization bugs
This commit is contained in:
+2
-2
@@ -280,13 +280,13 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
EqualityType matchEquality = equalityType(subjectType);
|
||||
EqualityType patternEquality = equalityType(patternType);
|
||||
|
||||
JsExpression expressionToMatchAgainst = translateExpressionForExpressionPattern(patternExpression);
|
||||
JsExpression expressionToMatchAgainst = TranslationUtils.coerce(context(), translateExpressionForExpressionPattern(patternExpression), subjectType);
|
||||
|
||||
if (matchEquality == EqualityType.PRIMITIVE && patternEquality == EqualityType.PRIMITIVE) {
|
||||
return equality(expressionToMatch, expressionToMatchAgainst);
|
||||
}
|
||||
else if (expressionToMatchAgainst instanceof JsNullLiteral) {
|
||||
return TranslationUtils.nullCheck(expressionToMatch, false);
|
||||
return TranslationUtils.nullCheck(subjectExpression, expressionToMatch, context(), false);
|
||||
}
|
||||
else {
|
||||
return TopLevelFIF.KOTLIN_EQUALS.apply(expressionToMatch, Collections.singletonList(expressionToMatchAgainst), context());
|
||||
|
||||
+2
-4
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getOperationToken
|
||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.isNegatedOperation
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
@@ -36,7 +37,6 @@ 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 {
|
||||
@@ -49,9 +49,7 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
|
||||
val anyType = context.currentModule.builtIns.anyType
|
||||
if (right is JsNullLiteral || left is JsNullLiteral) {
|
||||
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)
|
||||
return TranslationUtils.nullCheck(ktSubject, subject, context, isNegatedOperation(expression))
|
||||
}
|
||||
|
||||
val (leftKotlinType, rightKotlinType) = binaryOperationTypes(expression, context)
|
||||
|
||||
+2
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
|
||||
import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getOperationToken;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.isAssignment;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.coerce;
|
||||
import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.isSimpleNameExpressionNotDelegatedLocalVar;
|
||||
|
||||
public final class IntrinsicAssignmentTranslator extends AssignmentTranslator {
|
||||
@@ -62,6 +63,7 @@ public final class IntrinsicAssignmentTranslator extends AssignmentTranslator {
|
||||
JsExpression result = TranslationUtils.translateRightExpression(context, expression, rightBlock);
|
||||
KotlinType leftType = context.bindingContext().getType(expression.getLeft());
|
||||
KotlinType rightType = context.bindingContext().getType(expression.getRight());
|
||||
|
||||
if (rightType != null && KotlinBuiltIns.isCharOrNullableChar(rightType)) {
|
||||
if (leftType != null && KotlinBuiltIns.isStringOrNullableString(leftType)) {
|
||||
result = JsAstUtils.charToString(result);
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public final class UnaryOperationTranslator {
|
||||
if (operationToken == KtTokens.EXCLEXCL) {
|
||||
KtExpression baseExpression = getBaseExpression(expression);
|
||||
JsExpression translatedExpression = translateAsExpression(baseExpression, context);
|
||||
return sure(translatedExpression, context);
|
||||
return sure(baseExpression, translatedExpression, context);
|
||||
}
|
||||
|
||||
if (operationToken == KtTokens.MINUS) {
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||
import org.jetbrains.kotlin.types.DynamicTypesKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -157,6 +158,30 @@ public final class TranslationUtils {
|
||||
return new JsBinaryOperation(operator, expressionToCheck, new JsNullLiteral());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsExpression prepareForNullCheck(
|
||||
@NotNull KtExpression ktSubject,
|
||||
@NotNull JsExpression expression,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
KotlinType type = context.bindingContext().getType(ktSubject);
|
||||
if (type == null) {
|
||||
type = context.getCurrentModule().getBuiltIns().getAnyType();
|
||||
}
|
||||
|
||||
return coerce(context, expression, TypeUtils.makeNullable(type));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation nullCheck(
|
||||
@NotNull KtExpression ktSubject,
|
||||
@NotNull JsExpression expressionToCheck,
|
||||
@NotNull TranslationContext context,
|
||||
boolean isNegated
|
||||
) {
|
||||
return nullCheck(prepareForNullCheck(ktSubject, expressionToCheck, context), isNegated);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsConditional notNullConditional(
|
||||
@NotNull JsExpression expression,
|
||||
@@ -310,8 +335,9 @@ public final class TranslationUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression sure(@NotNull JsExpression expression, @NotNull TranslationContext context) {
|
||||
return new JsInvocation(context.getReferenceToIntrinsic(Namer.NULL_CHECK_INTRINSIC_NAME), expression);
|
||||
public static JsExpression sure(@NotNull KtExpression ktExpression, @NotNull JsExpression expression, @NotNull TranslationContext context) {
|
||||
return new JsInvocation(context.getReferenceToIntrinsic(Namer.NULL_CHECK_INTRINSIC_NAME),
|
||||
prepareForNullCheck(ktExpression, expression, context));
|
||||
}
|
||||
|
||||
public static boolean isSimpleNameExpressionNotDelegatedLocalVar(@Nullable KtExpression expression, @NotNull TranslationContext context) {
|
||||
@@ -491,9 +517,7 @@ public final class TranslationUtils {
|
||||
}
|
||||
else if (KotlinBuiltIns.isUnit(from)) {
|
||||
if (!KotlinBuiltIns.isUnit(to) && !MetadataProperties.isUnit(value)) {
|
||||
ClassDescriptor unit = context.getCurrentModule().getBuiltIns().getUnit();
|
||||
JsExpression unitRef = ReferenceTranslator.translateAsValueReference(unit, context);
|
||||
value = JsAstUtils.newSequence(Arrays.asList(value, unitRef));
|
||||
value = voidToUnit(context, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,6 +525,13 @@ public final class TranslationUtils {
|
||||
return value;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression voidToUnit(@NotNull TranslationContext context, @NotNull JsExpression expression) {
|
||||
ClassDescriptor unit = context.getCurrentModule().getBuiltIns().getUnit();
|
||||
JsExpression unitRef = ReferenceTranslator.translateAsValueReference(unit, context);
|
||||
return JsAstUtils.newSequence(Arrays.asList(expression, unitRef));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsExpression unitToVoid(@NotNull JsExpression expression) {
|
||||
if (expression instanceof JsBinaryOperation) {
|
||||
|
||||
+20
-12
@@ -1,18 +1,26 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1132
|
||||
var log = ""
|
||||
|
||||
fun box(): String {
|
||||
foo() ?: bar()
|
||||
if (foo() == null) bar()
|
||||
fun log(msg: String) {
|
||||
log += "$msg;"
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
log("!!")!!
|
||||
|
||||
log("elvis-left") ?: log("elvis-right")
|
||||
|
||||
if (log("if") == null) log("then")
|
||||
|
||||
when (null) {
|
||||
log("when-pattern") -> log("when-body-1")
|
||||
}
|
||||
|
||||
when (log("when-subject")) {
|
||||
null -> log("when-body-2")
|
||||
}
|
||||
|
||||
if (log != "!!;elvis-left;if;when-pattern;when-subject;") return "fail: $log"
|
||||
|
||||
if (log != "foo;foo;") return "fail: $log"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
log += "foo;"
|
||||
}
|
||||
|
||||
fun bar() {
|
||||
log += "bar;"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user