Fix comparison of boolean values in JS BE
See KT-16984
This commit is contained in:
@@ -1,6 +1,3 @@
|
|||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
|
|
||||||
fun checkLess(x: Boolean, y: Boolean) = when {
|
fun checkLess(x: Boolean, y: Boolean) = when {
|
||||||
x >= y -> "Fail $x >= $y"
|
x >= y -> "Fail $x >= $y"
|
||||||
!(x < y) -> "Fail !($x < $y)"
|
!(x < y) -> "Fail !($x < $y)"
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ object OperatorNameConventions {
|
|||||||
internal val SIMPLE_UNARY_OPERATION_NAMES = setOf(UNARY_PLUS, UNARY_MINUS, NOT)
|
internal val SIMPLE_UNARY_OPERATION_NAMES = setOf(UNARY_PLUS, UNARY_MINUS, NOT)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
internal val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, REM, RANGE_TO)
|
val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, REM, RANGE_TO)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
internal val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, REM_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN)
|
internal val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, REM_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN)
|
||||||
|
|||||||
@@ -17,14 +17,14 @@
|
|||||||
Kotlin.compareTo = function (a, b) {
|
Kotlin.compareTo = function (a, b) {
|
||||||
var typeA = typeof a;
|
var typeA = typeof a;
|
||||||
var typeB = typeof a;
|
var typeB = typeof a;
|
||||||
if (Kotlin.isChar(a) && typeB == "number") {
|
if (Kotlin.isChar(a) && typeB === "number") {
|
||||||
return Kotlin.primitiveCompareTo(a.charCodeAt(0), b);
|
return Kotlin.primitiveCompareTo(a.charCodeAt(0), b);
|
||||||
}
|
}
|
||||||
if (typeA == "number" && Kotlin.isChar(b)) {
|
if (typeA === "number" && Kotlin.isChar(b)) {
|
||||||
return Kotlin.primitiveCompareTo(a, b.charCodeAt(0));
|
return Kotlin.primitiveCompareTo(a, b.charCodeAt(0));
|
||||||
}
|
}
|
||||||
if (typeA == "number" || typeA == "string") {
|
if (typeA === "number" || typeA === "string" || typeA === "boolean") {
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
return Kotlin.primitiveCompareTo(a, b);
|
||||||
}
|
}
|
||||||
return a.compareTo_11rb$(b);
|
return a.compareTo_11rb$(b);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1882,6 +1882,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/expression/compareTo"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/expression/compareTo"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("booleanCompareTo.kt")
|
||||||
|
public void testBooleanCompareTo() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/compareTo/booleanCompareTo.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("customCompareToMethod.kt")
|
@TestMetadata("customCompareToMethod.kt")
|
||||||
public void testCustomCompareToMethod() throws Exception {
|
public void testCustomCompareToMethod() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/compareTo/customCompareToMethod.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/compareTo/customCompareToMethod.kt");
|
||||||
|
|||||||
+1
-7
@@ -13222,13 +13222,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("boolean.kt")
|
@TestMetadata("boolean.kt")
|
||||||
public void testBoolean() throws Exception {
|
public void testBoolean() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/compareTo/boolean.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/compareTo/boolean.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("comparable.kt")
|
@TestMetadata("comparable.kt")
|
||||||
|
|||||||
+3
-2
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
|||||||
import org.jetbrains.kotlin.js.translate.operation.OperatorTable
|
import org.jetbrains.kotlin.js.translate.operation.OperatorTable
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getOperationToken
|
import org.jetbrains.kotlin.js.translate.utils.PsiUtils.getOperationToken
|
||||||
|
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -34,7 +35,7 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
|||||||
object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||||
val COMPARE_TO_CHAR = pattern("Int|Short|Byte|Double|Float.compareTo(Char)")
|
val COMPARE_TO_CHAR = pattern("Int|Short|Byte|Double|Float.compareTo(Char)")
|
||||||
val CHAR_COMPARE_TO = pattern("Char.compareTo(Int|Short|Byte|Double|Float)")
|
val CHAR_COMPARE_TO = pattern("Char.compareTo(Int|Short|Byte|Double|Float)")
|
||||||
val PRIMITIVE_COMPARE_TO = pattern("Int|Short|Byte|Double|Float|Char|String.compareTo")
|
val PRIMITIVE_COMPARE_TO = pattern("Int|Short|Byte|Double|Float|Char|String|Boolean.compareTo")
|
||||||
|
|
||||||
private object CompareToIntrinsic : AbstractBinaryOperationIntrinsic() {
|
private object CompareToIntrinsic : AbstractBinaryOperationIntrinsic() {
|
||||||
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
||||||
@@ -65,7 +66,7 @@ object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSupportTokens() = OperatorConventions.COMPARISON_OPERATIONS
|
override fun getSupportTokens(): Set<KtSingleValueToken> = OperatorConventions.COMPARISON_OPERATIONS
|
||||||
|
|
||||||
override fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic? {
|
override fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic? {
|
||||||
if (descriptor.isDynamic()) return CompareToIntrinsic
|
if (descriptor.isDynamic()) return CompareToIntrinsic
|
||||||
|
|||||||
+1
-1
@@ -76,7 +76,7 @@ private data class IntrinsicKey(
|
|||||||
|
|
||||||
interface BinaryOperationIntrinsicFactory {
|
interface BinaryOperationIntrinsicFactory {
|
||||||
|
|
||||||
fun getSupportTokens(): ImmutableSet<out KtToken>
|
fun getSupportTokens(): Set<KtToken>
|
||||||
|
|
||||||
fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic?
|
fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// EXPECTED_REACHABLE_NODES: 489
|
||||||
|
fun box(): String {
|
||||||
|
val r1 = trueFun() > falseFun()
|
||||||
|
if (!r1) return "fail1"
|
||||||
|
|
||||||
|
if (falseFun() > trueFun()) return "fail2"
|
||||||
|
|
||||||
|
if (trueFun() > trueFun()) return "fail3"
|
||||||
|
|
||||||
|
if (trueFun() < falseFun()) return "fail4"
|
||||||
|
|
||||||
|
val x: Comparable<Boolean> = trueFun()
|
||||||
|
val y: Comparable<Boolean> = falseFun()
|
||||||
|
|
||||||
|
if (x.compareTo(false) <= 0) return "fail5"
|
||||||
|
if (y.compareTo(true) >= 0) return "fail6"
|
||||||
|
if (y.compareTo(false) != 0) return "fail7"
|
||||||
|
|
||||||
|
if ((true).compareTo(false) <= 0) return "fail8"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun trueFun() = true
|
||||||
|
|
||||||
|
fun falseFun() = false
|
||||||
Reference in New Issue
Block a user