JS Back-end does not handle complex patterns any more
#KT-2359 In Progress
This commit is contained in:
@@ -48,10 +48,6 @@ public final class PatternMatchingTest extends SingleFileTranslationTest {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testWhenNotValue() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testWhenValueOrType() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
+19
-39
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user