diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.java index 11a4b05dbbf..425f6d72674 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/WhenTranslator.java @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.translate.general.Translation; import org.jetbrains.kotlin.js.translate.operation.InOperationTranslator; import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; import org.jetbrains.kotlin.js.translate.utils.TranslationUtils; +import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt; @@ -208,8 +209,9 @@ public final class WhenTranslator extends AbstractTranslator { Map subjectAliases = new HashMap(); subjectAliases.put(whenExpression.getSubjectExpression(), expressionToMatch); TranslationContext callContext = context.innerContextWithAliasesForExpressions(subjectAliases); - return new InOperationTranslator(callContext, expressionToMatch, condition.getRangeExpression(), condition.getOperationReference()) - .translate(); + boolean negated = condition.getOperationReference().getReferencedNameElementType() == KtTokens.NOT_IN; + return new InOperationTranslator(callContext, expressionToMatch, condition.getRangeExpression(), condition.getOperationReference(), + negated).translate(); } @Nullable diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/InOperationTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/InOperationTranslator.java index 37ff9775cd7..376debf621e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/InOperationTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/InOperationTranslator.java @@ -43,13 +43,15 @@ public class InOperationTranslator extends AbstractTranslator { private final JsExpression left; private final KtExpression right; private final KtSimpleNameExpression operation; + private final boolean negated; public InOperationTranslator(@NotNull TranslationContext context, @NotNull JsExpression left, @NotNull KtExpression right, - @NotNull KtSimpleNameExpression operation) { + @NotNull KtSimpleNameExpression operation, boolean negated) { super(context); this.left = left; this.right = right; this.operation = operation; + this.negated = negated; } @NotNull @@ -67,7 +69,11 @@ public class InOperationTranslator extends AbstractTranslator { @NotNull private JsExpression translateGeneral(@NotNull ResolvedCall call, @NotNull JsExpression rightTranslated) { - return CallTranslator.translate(context(), call, rightTranslated); + JsExpression result = CallTranslator.translate(context(), call, rightTranslated); + if (negated) { + result = JsAstUtils.negated(result); + } + return result; } @Nullable @@ -94,8 +100,15 @@ public class InOperationTranslator extends AbstractTranslator { private JsExpression translateInt(@NotNull KtExpression lowerExpression, @NotNull KtExpression upperExpression) { JsExpression lower = Translation.translateAsExpression(lowerExpression, context()); JsExpression upper = Translation.translateAsExpression(upperExpression, context()); - JsExpression first = JsAstUtils.greaterThanEq(left, lower); - JsExpression second = JsAstUtils.lessThanEq(left, upper); - return JsAstUtils.and(first, second); + if (!negated) { + JsExpression first = JsAstUtils.greaterThanEq(left, lower); + JsExpression second = JsAstUtils.lessThanEq(left, upper); + return JsAstUtils.and(first, second); + } + else { + JsExpression first = JsAstUtils.lessThan(left, lower); + JsExpression second = JsAstUtils.greaterThan(left, upper); + return JsAstUtils.or(first, second); + } } } diff --git a/js/js.translator/testData/expression/when/cases/whenWithCustomRangeClause.kt b/js/js.translator/testData/expression/when/cases/whenWithCustomRangeClause.kt index ff8ce1a2b07..54bae10c83b 100644 --- a/js/js.translator/testData/expression/when/cases/whenWithCustomRangeClause.kt +++ b/js/js.translator/testData/expression/when/cases/whenWithCustomRangeClause.kt @@ -4,7 +4,10 @@ package foo fun box(): String { var result = testFun(-1) + testFun(0) + testFun(5) + testFun(9) + testFun(10) + testFun(150) - return if (result == "misshithithitmisshit!") "OK" else "fail" + if (result != "misshithithitmisshit!") return "fail1: $result" + result = testFun2(-1) + testFun2(0) + testFun2(9) + testFun2(10) + if (result != "hitmissmisshit") return "fail2: $result" + return "OK" } fun testFun(index: Int): String { var lower = Wrapper(0) @@ -16,6 +19,12 @@ fun testFun(index: Int): String { else -> "miss" } } +fun testFun2(index: Int): String { + return when (Wrapper(index)) { + !in Wrapper(0)..Wrapper(9) -> "hit" + else -> "miss" + } +} class Wrapper(val value: Int) : Comparable { operator fun rangeTo(upper: Wrapper) = WrapperRange(this, upper) diff --git a/js/js.translator/testData/expression/when/cases/whenWithRangeClause.kt b/js/js.translator/testData/expression/when/cases/whenWithRangeClause.kt index 9aacd416fd3..c2cb960542d 100644 --- a/js/js.translator/testData/expression/when/cases/whenWithRangeClause.kt +++ b/js/js.translator/testData/expression/when/cases/whenWithRangeClause.kt @@ -4,7 +4,10 @@ package foo fun box(): String { var result = testFun(-1) + testFun(0) + testFun(5) + testFun(9) + testFun(10) + testFun(150) + testFun(800) - return if (result == "misshithithitmisshit!@@@" && invocationCount == 7) "OK" else "fail" + if (result != "misshithithitmisshit!@@@" || invocationCount != 7) return "fail1:" + result + result = testFun2(-1) + testFun2(0) + testFun2(9) + testFun2(10) + if (result != "hitmissmisshit") return "fail2:" + result + return "OK" } fun testFun(index: Int): String { val thirdRange = 500..1000 @@ -15,6 +18,12 @@ fun testFun(index: Int): String { else -> "miss" } } +fun testFun2(index: Int): String { + return when(index) { + !in 0..9 -> "hit" + else -> "miss" + } +} fun get(value: Int): Int { invocationCount++