From 1b65ba644e2d880c16812e99fb1b4a0b37b44aae Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 5 Sep 2012 12:53:48 +0400 Subject: [PATCH] JS Back-end does not handle complex patterns any more #KT-2359 In Progress --- .../test/semantics/PatternMatchingTest.java | 4 -- .../expression/PatternTranslator.java | 58 ++++++------------- .../translate/expression/WhenTranslator.java | 55 ++++++++++++------ .../k2js/translate/utils/PsiUtils.java | 13 ----- .../patternMatching/cases/multipleCases.kt | 4 +- .../patternMatching/cases/whenAsExpression.kt | 4 +- .../patternMatching/cases/whenNotValue.kt | 11 ---- .../patternMatching/cases/whenValue.kt | 4 +- .../patternMatching/cases/whenValueOrType.kt | 4 +- 9 files changed, 64 insertions(+), 93 deletions(-) delete mode 100644 js/js.translator/testFiles/patternMatching/cases/whenNotValue.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java index eca4d605d06..b37723f5170 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java @@ -48,10 +48,6 @@ public final class PatternMatchingTest extends SingleFileTranslationTest { fooBoxTest(); } - public void testWhenNotValue() throws Exception { - fooBoxTest(); - } - public void testWhenValueOrType() throws Exception { fooBoxTest(); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java index e9094fbd2df..ac5e564fad4 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java @@ -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()); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java index 5d5a8d0131b..bb950e631ab 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java @@ -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(); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java index 7aeb7b2882d..a98009af986 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java @@ -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; - } } diff --git a/js/js.translator/testFiles/patternMatching/cases/multipleCases.kt b/js/js.translator/testFiles/patternMatching/cases/multipleCases.kt index 7fb88010fb9..de35c3d1c8c 100644 --- a/js/js.translator/testFiles/patternMatching/cases/multipleCases.kt +++ b/js/js.translator/testFiles/patternMatching/cases/multipleCases.kt @@ -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 diff --git a/js/js.translator/testFiles/patternMatching/cases/whenAsExpression.kt b/js/js.translator/testFiles/patternMatching/cases/whenAsExpression.kt index 0287799ac78..c56b7b5ed02 100644 --- a/js/js.translator/testFiles/patternMatching/cases/whenAsExpression.kt +++ b/js/js.translator/testFiles/patternMatching/cases/whenAsExpression.kt @@ -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) diff --git a/js/js.translator/testFiles/patternMatching/cases/whenNotValue.kt b/js/js.translator/testFiles/patternMatching/cases/whenNotValue.kt deleted file mode 100644 index 5cd11718413..00000000000 --- a/js/js.translator/testFiles/patternMatching/cases/whenNotValue.kt +++ /dev/null @@ -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) -} \ No newline at end of file diff --git a/js/js.translator/testFiles/patternMatching/cases/whenValue.kt b/js/js.translator/testFiles/patternMatching/cases/whenValue.kt index 73bbc0484b0..fe86c6e9a1d 100644 --- a/js/js.translator/testFiles/patternMatching/cases/whenValue.kt +++ b/js/js.translator/testFiles/patternMatching/cases/whenValue.kt @@ -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) diff --git a/js/js.translator/testFiles/patternMatching/cases/whenValueOrType.kt b/js/js.translator/testFiles/patternMatching/cases/whenValueOrType.kt index 880a7d17ed5..de255e489a3 100644 --- a/js/js.translator/testFiles/patternMatching/cases/whenValueOrType.kt +++ b/js/js.translator/testFiles/patternMatching/cases/whenValueOrType.kt @@ -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 }