Make nullable check less verbose in JS-backend.
For check what variable is equal null or undefined enough to compare with null (or undefined). See ECMAScript specification 11.9.1, 11.9.2, 11.9.3
This commit is contained in:
@@ -45,4 +45,8 @@ public final class EqualsTest extends AbstractExpressionTest {
|
||||
public void testKt2370() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testEqualsNullOrUndefined() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -33,7 +33,7 @@ import static org.jetbrains.k2js.translate.general.Translation.translateAsExpres
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getBaseExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.notNullConditionalTestExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck;
|
||||
|
||||
|
||||
public final class UnaryOperationTranslator {
|
||||
@@ -59,7 +59,7 @@ public final class UnaryOperationTranslator {
|
||||
@NotNull
|
||||
private static JsExpression translateExclExclOperator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) {
|
||||
TemporaryVariable cachedValue = context.declareTemporary(translateAsExpression(getBaseExpression(expression), context));
|
||||
return new JsConditional(notNullConditionalTestExpression(cachedValue), cachedValue.reference(), context.namer().throwNPEFunctionCall());
|
||||
return new JsConditional(isNotNullCheck(cachedValue.assignmentExpression()), cachedValue.reference(), context.namer().throwNPEFunctionCall());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.notNullConditionalTestExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck;
|
||||
|
||||
public enum CallType {
|
||||
SAFE {
|
||||
@@ -37,7 +37,7 @@ public enum CallType {
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
TemporaryVariable cachedValue = context.declareTemporary(receiver);
|
||||
return new JsConditional(notNullConditionalTestExpression(cachedValue), constructor.construct(cachedValue.reference()), JsLiteral.NULL);
|
||||
return new JsConditional(isNotNullCheck(cachedValue.assignmentExpression()), constructor.construct(cachedValue.reference()), JsLiteral.NULL);
|
||||
}
|
||||
},
|
||||
//TODO: bang qualifier is not implemented in frontend for now
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
|
||||
@@ -32,7 +31,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
|
||||
|
||||
public final class TranslationUtils {
|
||||
private TranslationUtils() {
|
||||
@@ -64,19 +64,15 @@ public final class TranslationUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation notNullConditionalTestExpression(@NotNull TemporaryVariable cachedValue) {
|
||||
return and(inequality(cachedValue.assignmentExpression(), JsLiteral.NULL),
|
||||
inequality(cachedValue.reference(), JsLiteral.UNDEFINED));
|
||||
public static JsBinaryOperation isNotNullCheck(@NotNull JsExpression expressionToCheck) {
|
||||
return nullCheck(expressionToCheck, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation nullCheck(@NotNull JsExpression expressionToCheck, boolean isNegated) {
|
||||
JsBinaryOperator operator = isNegated ? JsBinaryOperator.REF_NEQ : JsBinaryOperator.REF_EQ;
|
||||
return new JsBinaryOperation(isNegated ? JsBinaryOperator.AND : JsBinaryOperator.OR,
|
||||
new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL),
|
||||
new JsBinaryOperation(operator, expressionToCheck, JsLiteral.UNDEFINED));
|
||||
JsBinaryOperator operator = isNegated ? JsBinaryOperator.NEQ : JsBinaryOperator.EQ;
|
||||
return new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
|
||||
@NotNull List<? extends ValueArgument> jetArguments) {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package foo
|
||||
|
||||
fun box() : String {
|
||||
val a: Int? = null
|
||||
val r = a == null
|
||||
if (!r || a != null)
|
||||
return "wrong result on simple nullable check"
|
||||
|
||||
var i = 0;
|
||||
fun foo(): Int? = ++i;
|
||||
if (foo() == null)
|
||||
return "wrong result on nullable check with side effects"
|
||||
|
||||
if (i != 1)
|
||||
return "wrong affects when using nullable check with side effects"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user