JS Back-end does not handle complex patterns any more

#KT-2359 In Progress
This commit is contained in:
Andrey Breslav
2012-09-05 12:53:48 +04:00
parent 4dd0b27e93
commit 1b65ba644e
9 changed files with 64 additions and 93 deletions
@@ -48,10 +48,6 @@ public final class PatternMatchingTest extends SingleFileTranslationTest {
fooBoxTest();
}
public void testWhenNotValue() throws Exception {
fooBoxTest();
}
public void testWhenValueOrType() throws Exception {
fooBoxTest();
}
@@ -31,8 +31,6 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getPattern;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getTypeReference;
/**
* @author Pavel Talanov
@@ -51,45 +49,30 @@ public final class PatternTranslator extends AbstractTranslator {
@NotNull
public JsExpression translateIsExpression(@NotNull JetIsExpression expression) {
JsExpression left = Translation.translateAsExpression(expression.getLeftHandSide(), context());
JetPattern pattern = getPattern(expression);
JsExpression resultingExpression = translatePattern(pattern, left);
JetTypeReference typeReference = expression.getTypeRef();
assert typeReference != null;
JsExpression result = translateIsCheck(left, typeReference);
if (expression.isNegated()) {
return negated(resultingExpression);
return negated(result);
}
return resultingExpression;
return result;
}
@NotNull
public JsExpression translatePattern(@NotNull JetPattern pattern, @Nullable JsExpression expressionToMatch) {
if (expressionToMatch == null) {
assert pattern instanceof JetExpressionPattern : "When using when without parameters we can have only expression patterns";
return translateExpressionForExpressionPattern((JetExpressionPattern)pattern);
}
if (pattern instanceof JetTypePattern) {
return translateTypePattern(expressionToMatch, (JetTypePattern)pattern);
}
if (pattern instanceof JetExpressionPattern) {
return translateExpressionPattern(expressionToMatch, (JetExpressionPattern)pattern);
}
throw new AssertionError("Unsupported pattern type " + pattern.getClass());
}
@NotNull
private JsExpression translateTypePattern(@NotNull JsExpression expressionToMatch,
@NotNull JetTypePattern pattern) {
JsExpression result = translateAsIntrinsicTypeCheck(expressionToMatch, pattern);
public JsExpression translateIsCheck(@NotNull JsExpression subject, @NotNull JetTypeReference typeReference) {
JsExpression result = translateAsIntrinsicTypeCheck(subject, typeReference);
if (result != null) {
return result;
}
return translateAsIsCheck(expressionToMatch, pattern);
return translateAsIsCheck(subject, typeReference);
}
@NotNull
private JsExpression translateAsIsCheck(@NotNull JsExpression expressionToMatch,
@NotNull JetTypePattern pattern) {
@NotNull JetTypeReference typeReference) {
JsInvocation isCheck = new JsInvocation(context().namer().isOperationReference(),
expressionToMatch, getClassReference(pattern));
if (isNullable(pattern)) {
expressionToMatch, getClassReference(typeReference));
if (isNullable(typeReference)) {
return addNullCheck(expressionToMatch, isCheck);
}
return isCheck;
@@ -97,9 +80,9 @@ public final class PatternTranslator extends AbstractTranslator {
@Nullable
private JsExpression translateAsIntrinsicTypeCheck(@NotNull JsExpression expressionToMatch,
@NotNull JetTypePattern pattern) {
@NotNull JetTypeReference typeReference) {
JsExpression result = null;
JsName className = getClassReference(pattern).getName();
JsName className = getClassReference(typeReference).getName();
if (className.getIdent().equals("String")) {
result = typeof(expressionToMatch, program().getStringLiteral("string"));
}
@@ -114,13 +97,12 @@ public final class PatternTranslator extends AbstractTranslator {
return or(TranslationUtils.isNullCheck(expressionToMatch), isCheck);
}
private boolean isNullable(JetTypePattern pattern) {
return BindingUtils.getTypeByReference(bindingContext(), getTypeReference(pattern)).isNullable();
private boolean isNullable(JetTypeReference typeReference) {
return BindingUtils.getTypeByReference(bindingContext(), typeReference).isNullable();
}
@NotNull
private JsNameRef getClassReference(@NotNull JetTypePattern pattern) {
JetTypeReference typeReference = getTypeReference(pattern);
private JsNameRef getClassReference(@NotNull JetTypeReference typeReference) {
return getClassNameReferenceForTypeReference(typeReference);
}
@@ -132,15 +114,13 @@ public final class PatternTranslator extends AbstractTranslator {
}
@NotNull
private JsExpression translateExpressionPattern(@NotNull JsExpression expressionToMatch, JetExpressionPattern pattern) {
JsExpression expressionToMatchAgainst = translateExpressionForExpressionPattern(pattern);
public JsExpression translateExpressionPattern(@NotNull JsExpression expressionToMatch, @NotNull JetExpression patternExpression) {
JsExpression expressionToMatchAgainst = translateExpressionForExpressionPattern(patternExpression);
return equality(expressionToMatch, expressionToMatchAgainst);
}
@NotNull
private JsExpression translateExpressionForExpressionPattern(@NotNull JetExpressionPattern pattern) {
JetExpression patternExpression = pattern.getExpression();
assert patternExpression != null : "Expression patter should have an expression.";
public JsExpression translateExpressionForExpressionPattern(@NotNull JetExpression patternExpression) {
return Translation.translateAsExpression(patternExpression, context());
}
}
@@ -182,14 +182,49 @@ public final class WhenTranslator extends AbstractTranslator {
@NotNull
private JsExpression translatePatternCondition(@NotNull JetWhenCondition condition) {
JsExpression patternMatchExpression = Translation.patternTranslator(context()).
translatePattern(getPattern(condition), getExpressionToMatch());
JsExpression patternMatchExpression = translateWhenConditionToBooleanExpression(condition);
if (isNegated(condition)) {
return negated(patternMatchExpression);
}
return patternMatchExpression;
}
@NotNull
private JsExpression translateWhenConditionToBooleanExpression(@NotNull JetWhenCondition condition) {
if (condition instanceof JetWhenConditionIsPattern) {
return translateIsCondition((JetWhenConditionIsPattern) condition);
}
else if (condition instanceof JetWhenConditionWithExpression) {
return translateExpressionCondition((JetWhenConditionWithExpression) condition);
}
throw new AssertionError("Wrong type of JetWhenCondition");
}
@NotNull
private JsExpression translateIsCondition(@NotNull JetWhenConditionIsPattern conditionIsPattern) {
JsExpression expressionToMatch = getExpressionToMatch();
assert expressionToMatch != null : "An is-check is not allowed in when() without subject.";
JetTypeReference typeReference = conditionIsPattern.getTypeRef();
assert typeReference != null : "An is-check must have a type reference.";
return Translation.patternTranslator(context()).translateIsCheck(expressionToMatch, typeReference);
}
@NotNull
private JsExpression translateExpressionCondition(@NotNull JetWhenConditionWithExpression condition) {
JetExpression patternExpression = condition.getExpression();
assert patternExpression != null : "Expression pattern should have an expression.";
JsExpression expressionToMatch = getExpressionToMatch();
if (expressionToMatch == null) {
return Translation.patternTranslator(context()).translateExpressionForExpressionPattern(patternExpression);
}
else {
return Translation.patternTranslator(context()).translateExpressionPattern(expressionToMatch, patternExpression);
}
}
@Nullable
private JsExpression getExpressionToMatch() {
return expressionToMatch != null ? expressionToMatch.reference() : null;
@@ -202,22 +237,6 @@ public final class WhenTranslator extends AbstractTranslator {
return false;
}
@NotNull
private static JetPattern getPattern(@NotNull JetWhenCondition condition) {
JetPattern pattern;
if (condition instanceof JetWhenConditionIsPattern) {
pattern = ((JetWhenConditionIsPattern)condition).getPattern();
}
else if (condition instanceof JetWhenConditionWithExpression) {
pattern = ((JetWhenConditionWithExpression)condition).getPattern();
}
else {
throw new AssertionError("Wrong type of JetWhenCondition");
}
assert pattern != null : "Condition should have a non null pattern.";
return pattern;
}
@Nullable
private JsExpression translateExpressionToMatch(@NotNull JetWhenExpression expression) {
JetExpression subject = expression.getSubjectExpression();
@@ -153,17 +153,4 @@ public final class PsiUtils {
return rangeExpression;
}
@NotNull
public static JetPattern getPattern(@NotNull JetIsExpression expression) {
JetPattern pattern = expression.getPattern();
assert pattern != null : "Pattern should not be null";
return pattern;
}
@NotNull
public static JetTypeReference getTypeReference(@NotNull JetTypePattern pattern) {
JetTypeReference typeReference = pattern.getTypeReference();
assert typeReference != null : "Type pattern should contain a type reference";
return typeReference;
}
}
@@ -5,12 +5,12 @@ fun box() : Int {
val d = 5
var z = 0
when(c) {
is 5, is 3 -> z++;
5, 3 -> z++;
else -> {z = -1000;}
}
when(d) {
is 5, is 3 -> z++;
5, 3 -> z++;
else -> {z = -1000;}
}
return z
@@ -4,8 +4,8 @@ package foo
fun box() : Boolean {
return (when(1) {
is 2 -> 3
is 1 -> 1
2 -> 3
1 -> 1
else -> 5
} == 1)
@@ -1,11 +0,0 @@
package foo
fun box() : Boolean {
var a = 4
when(a) {
!is 3 -> {a = 10;}
!is 4 -> {a = 20;}
else -> {a = 30;}
}
return (a == 10)
}
@@ -3,8 +3,8 @@ package foo
fun box() : Boolean {
var a = 4
when(a) {
is 3 -> {a = 10;}
is 4 -> {a = 20;}
3 -> {a = 10;}
4 -> {a = 20;}
else -> {a = 30;}
}
return (a == 20)
@@ -13,13 +13,13 @@ fun box() : Boolean {
var a = A() : Any?
var b = null : Any?
when(a) {
is null -> c = 10;
null -> c = 10;
is B -> c = 10000
is A -> c = 20;
else -> c = 1000
}
when(b) {
is null -> c += 5
null -> c += 5
is B -> c += 100
else -> c = 1000
}