JS backend: fix KT-4601 JS: compareTo doesn't work on Numbers
#KT-4601 Fixed
This commit is contained in:
@@ -65,4 +65,8 @@ public final class NumberTest extends SingleFileTranslationTest {
|
||||
Assert.assertTrue(cause.getMessage().startsWith("Unsupported long constant "));
|
||||
}
|
||||
}
|
||||
|
||||
public void testNumberCompareTo() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
}
|
||||
|
||||
+24
-2
@@ -39,7 +39,7 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.factories.NumberConversionFIF.INTEGER_NUMBER_TYPES;
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setArguments;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
|
||||
public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
INSTANCE;
|
||||
@@ -76,9 +76,26 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic NUMBER_COMPARE_TO_INTRINSIC = new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(
|
||||
@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 1;
|
||||
return JsAstUtils.compareTo(receiver, arguments.get(0), context);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final NamePredicate BINARY_OPERATIONS = new NamePredicate(OperatorConventions.BINARY_OPERATION_NAMES.values());
|
||||
private static final DescriptorPredicate PRIMITIVE_NUMBERS_BINARY_OPERATIONS = pattern(NamePredicate.PRIMITIVE_NUMBERS, BINARY_OPERATIONS);
|
||||
private static final DescriptorPredicate PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS =
|
||||
pattern(NamePredicate.PRIMITIVE_NUMBERS, "compareTo");
|
||||
private static final DescriptorPredicate INT_WITH_BIT_OPERATIONS = pattern("Int.or|and|xor|shl|shr|ushr");
|
||||
private static final DescriptorPredicate BOOLEAN_OPERATIONS = pattern("Boolean.or|and|xor");
|
||||
private static final DescriptorPredicate STRING_PLUS = pattern("String.plus");
|
||||
@@ -93,7 +110,8 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
.build();
|
||||
|
||||
private static final Predicate<FunctionDescriptor> PREDICATE = Predicates.or(PRIMITIVE_NUMBERS_BINARY_OPERATIONS, BOOLEAN_OPERATIONS,
|
||||
STRING_PLUS, INT_WITH_BIT_OPERATIONS);
|
||||
STRING_PLUS, INT_WITH_BIT_OPERATIONS,
|
||||
PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS);
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -102,6 +120,10 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS.apply(descriptor)) {
|
||||
return NUMBER_COMPARE_TO_INTRINSIC;
|
||||
}
|
||||
|
||||
if (pattern(INTEGER_NUMBER_TYPES + ".div").apply(descriptor)) {
|
||||
JetType resultType = descriptor.getReturnType();
|
||||
if (!KotlinBuiltIns.getInstance().getFloatType().equals(resultType) &&
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.k2js.translate.context.Namer;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
@@ -122,6 +123,11 @@ public final class JsAstUtils {
|
||||
return new JsBinaryOperation(JsBinaryOperator.BIT_OR, expression, context.program().getNumberLiteral(0));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression compareTo(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||
return new JsInvocation(new JsNameRef(OperatorConventions.COMPARE_TO.getIdentifier(), Namer.KOTLIN_OBJECT_REF), left, right);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsPrefixOperation negated(@NotNull JsExpression expression) {
|
||||
return new JsPrefixOperation(JsUnaryOperator.NOT, expression);
|
||||
@@ -171,6 +177,16 @@ public final class JsAstUtils {
|
||||
return new JsBinaryOperation(JsBinaryOperator.LTE, arg1, arg2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation lessThan(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.LT, arg1, arg2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation greaterThan(@NotNull JsExpression arg1, @NotNull JsExpression arg2) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.GT, arg1, arg2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression assignment(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.ASG, left, right);
|
||||
|
||||
@@ -85,6 +85,10 @@
|
||||
return "[" + a.join(", ") + "]";
|
||||
};
|
||||
|
||||
Kotlin.compareTo = function(a, b) {
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
};
|
||||
|
||||
Kotlin.intUpto = function (from, to) {
|
||||
return new Kotlin.NumberRange(from, to);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package foo
|
||||
|
||||
var global: String = ""
|
||||
|
||||
fun id(s: String, value: Int): Int {
|
||||
global += s
|
||||
return value
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
assertEquals(-1, 1.compareTo(2))
|
||||
|
||||
assertEquals(-1, 1 compareTo 2)
|
||||
assertEquals(-1, 1 compareTo (2:Short))
|
||||
assertEquals(-1, 1 compareTo (2:Byte))
|
||||
assertEquals(-1, 1 compareTo 2.0)
|
||||
assertEquals(-1, 1 compareTo 2.0f)
|
||||
|
||||
assertEquals(1, 10 compareTo 2)
|
||||
assertEquals(1, 10 compareTo (2:Short))
|
||||
assertEquals(1, 10 compareTo (2:Byte))
|
||||
assertEquals(1, 10 compareTo 2.0)
|
||||
assertEquals(1, 10 compareTo 2.0f)
|
||||
|
||||
assertEquals(0, 2 compareTo 2)
|
||||
assertEquals(0, 2 compareTo (2:Short))
|
||||
assertEquals(0, 2 compareTo (2:Byte))
|
||||
assertEquals(0, 2 compareTo 2.0)
|
||||
assertEquals(0, 2 compareTo 2.0f)
|
||||
|
||||
assertEquals(-1, (1: Short) compareTo 2)
|
||||
assertEquals(-1, (1: Short) compareTo (2:Short))
|
||||
assertEquals(-1, (1: Short) compareTo (2:Byte))
|
||||
assertEquals(-1, (1: Short) compareTo 2.0)
|
||||
assertEquals(-1, (1: Short) compareTo 2.0f)
|
||||
|
||||
assertEquals(1, (10: Byte) compareTo 2)
|
||||
assertEquals(1, (10: Byte) compareTo (2:Short))
|
||||
assertEquals(1, (10: Byte) compareTo (2:Byte))
|
||||
assertEquals(1, (10: Byte) compareTo 2.0)
|
||||
assertEquals(1, (10: Byte) compareTo 2.0f)
|
||||
|
||||
assertEquals(0, 2.0 compareTo 2)
|
||||
assertEquals(0, 2.0 compareTo (2:Short))
|
||||
assertEquals(0, 2.0 compareTo (2:Byte))
|
||||
assertEquals(0, 2.0 compareTo 2.0)
|
||||
assertEquals(0, 2.0 compareTo 2.0f)
|
||||
|
||||
assertEquals(1, 3.0f compareTo 2)
|
||||
assertEquals(1, 3.0f compareTo (2:Short))
|
||||
assertEquals(1, 3.0f compareTo (2:Byte))
|
||||
assertEquals(1, 3.0f compareTo 2.0)
|
||||
assertEquals(1, 3.0f compareTo 2.0f)
|
||||
|
||||
assertEquals(1, id("A", 10) compareTo id("B", 5))
|
||||
assertEquals("AB", global)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user