Added support for nullable types in is check.

This commit is contained in:
Pavel Talanov
2011-11-18 18:26:29 +04:00
parent ebf29263f1
commit db02cd168b
7 changed files with 84 additions and 9 deletions
@@ -281,4 +281,12 @@ public class AstUtil {
assert statement instanceof JsExprStmt : "Cannot extract exprssion form statement: " + statement;
return (((JsExprStmt) statement).getExpression());
}
public static JsBinaryOperation and(JsExpression op1, JsExpression op2) {
return new JsBinaryOperation(JsBinaryOperator.AND, op1, op2);
}
public static JsBinaryOperation or(JsExpression op1, JsExpression op2) {
return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2);
}
}
@@ -342,10 +342,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull TranslationContext context) {
JsExpression receiver = translateReceiver(expression, context);
JsNullLiteral nullLiteral = context.program().getNullLiteral();
JsBinaryOperation nullCheck = new JsBinaryOperation
(JsBinaryOperator.NEQ, receiver, nullLiteral);
JsExpression thenExpression = translateQualifiedExpression(expression, context);
return new JsConditional(nullCheck, thenExpression, nullLiteral);
return new JsConditional(TranslationUtils.notNullCheck(receiver, context),
thenExpression, nullLiteral);
}
@Override
@@ -52,14 +52,36 @@ public final class PatternTranslator extends AbstractTranslator {
@NotNull
private JsExpression translateTypePattern(@NotNull JsExpression expressionToMatch,
@NotNull JetTypePattern pattern) {
return AstUtil.newInvocation(Namer.isOperationReference(), expressionToMatch, getClassReference(pattern));
JsInvocation isCheck = AstUtil.newInvocation(Namer.isOperationReference(),
expressionToMatch, getClassReference(pattern));
if (isNullable(pattern)) {
return addNullCheck(expressionToMatch, isCheck);
}
return isCheck;
}
@NotNull
private JsExpression addNullCheck(@NotNull JsExpression expressionToMatch, @NotNull JsInvocation isCheck) {
return AstUtil.or(TranslationUtils.isNullCheck(expressionToMatch, translationContext()), isCheck);
}
private boolean isNullable(JetTypePattern pattern) {
return BindingUtils.getTypeByReference(translationContext().bindingContext(),
getTypeReference(pattern)).isNullable();
}
@NotNull
private JsExpression getClassReference(@NotNull JetTypePattern pattern) {
JetTypeReference typeReference = getTypeReference(pattern);
return getClassNameReferenceForTypeReference(typeReference);
}
@NotNull
private JetTypeReference getTypeReference(@NotNull JetTypePattern pattern) {
JetTypeReference typeReference = pattern.getTypeReference();
assert typeReference != null : "Type pattern should contain a type reference";
return getClassNameReferenceForTypeReference(typeReference);
return typeReference;
}
@NotNull
@@ -0,0 +1,30 @@
package org.jetbrains.k2js.translate;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNullLiteral;
import org.jetbrains.annotations.NotNull;
/**
* @author Talanov Pavel
*/
public final class TranslationUtils {
@NotNull
static public JsBinaryOperation notNullCheck(@NotNull JsExpression expressionToCheck,
@NotNull TranslationContext context) {
JsNullLiteral nullLiteral = context.program().getNullLiteral();
return new JsBinaryOperation
(JsBinaryOperator.NEQ, expressionToCheck, nullLiteral);
}
@NotNull
static public JsBinaryOperation isNullCheck(@NotNull JsExpression expressionToCheck,
@NotNull TranslationContext context) {
JsNullLiteral nullLiteral = context.program().getNullLiteral();
return new JsBinaryOperation
(JsBinaryOperator.REF_EQ, expressionToCheck, nullLiteral);
}
}
@@ -103,7 +103,6 @@ public class WhenTranslator extends AbstractTranslator {
return Translation.translateAsStatement(expressionToExecute, translationContext());
}
//TODO: ask what these conditions mean
@NotNull
private JsExpression translateConditions(@NotNull JetWhenEntry entry) {
List<JsExpression> conditions = new ArrayList<JsExpression>();
@@ -127,11 +126,10 @@ public class WhenTranslator extends AbstractTranslator {
@NotNull
private JsExpression addCaseCondition(@Nullable JsExpression current, @NotNull JsExpression condition) {
if (current == null) {
current = condition;
return condition;
} else {
current = new JsBinaryOperation(JsBinaryOperator.OR, current, condition);
return AstUtil.or(current, condition);
}
return current;
}
@@ -49,4 +49,9 @@ public final class PatternMatchingTest extends IncludeLibraryTest {
testFunctionOutput("multipleCases.kt", "foo", "box", 2.0);
}
@Test
public void matchNullableType() throws Exception {
testFooBoxIsTrue("matchNullableType.kt");
}
}
@@ -0,0 +1,13 @@
namespace foo
class A() {
}
fun box() : Boolean {
var a = null : A?
when(a) {
is A? => return true
else => return false
}
}