JS backend: fix KT-5772 wrong code generated when <,<=,>,>= are used with explicit Comparable type
#KT-5772 Fixed
This commit is contained in:
@@ -31,11 +31,6 @@ public trait Runnable {
|
|||||||
public open fun run() : Unit;
|
public open fun run() : Unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
library
|
|
||||||
public trait Comparable<T> {
|
|
||||||
public fun compareTo(that: T): Int
|
|
||||||
}
|
|
||||||
|
|
||||||
library
|
library
|
||||||
public trait Appendable {
|
public trait Appendable {
|
||||||
public open fun append(csq: CharSequence?): Appendable
|
public open fun append(csq: CharSequence?): Appendable
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ public final class StandardClasses {
|
|||||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||||
|
|
||||||
standardClasses.declare().forFQ("kotlin.Enum").kotlinClass("Enum");
|
standardClasses.declare().forFQ("kotlin.Enum").kotlinClass("Enum");
|
||||||
|
|
||||||
|
standardClasses.declare().forFQ("kotlin.Comparable").kotlinClass("Comparable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
|||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
|
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
|
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getTypeByReference;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getTypeByReference;
|
||||||
@@ -92,6 +93,9 @@ public final class PatternTranslator extends AbstractTranslator {
|
|||||||
if (NamePredicate.STRING.apply(typeName)) {
|
if (NamePredicate.STRING.apply(typeName)) {
|
||||||
jsSTypeName = "string";
|
jsSTypeName = "string";
|
||||||
}
|
}
|
||||||
|
else if (NamePredicate.NUMBER.apply(typeName)) {
|
||||||
|
return JsAstUtils.isNumber(expressionToMatch);
|
||||||
|
}
|
||||||
else if (NamePredicate.PRIMITIVE_NUMBERS.apply(typeName)) {
|
else if (NamePredicate.PRIMITIVE_NUMBERS.apply(typeName)) {
|
||||||
jsSTypeName = "number";
|
jsSTypeName = "number";
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-5
@@ -34,11 +34,12 @@ import org.jetbrains.k2js.translate.intrinsic.functions.patterns.DescriptorPredi
|
|||||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
|
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
|
||||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||||
|
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setArguments;
|
||||||
|
|
||||||
public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
@@ -76,7 +77,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final FunctionIntrinsic NUMBER_COMPARE_TO_INTRINSIC = new FunctionIntrinsic() {
|
private static final FunctionIntrinsic BUILTINS_COMPARE_TO_INTRINSIC = new FunctionIntrinsic() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JsExpression apply(
|
public JsExpression apply(
|
||||||
@@ -90,6 +91,21 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static final FunctionIntrinsic PRIMITIVE_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.primitiveCompareTo(receiver, arguments.get(0));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final NamePredicate BINARY_OPERATIONS = new NamePredicate(OperatorConventions.BINARY_OPERATION_NAMES.values());
|
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_BINARY_OPERATIONS = pattern(NamePredicate.PRIMITIVE_NUMBERS, BINARY_OPERATIONS);
|
||||||
@@ -115,13 +131,18 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||||
|
if (PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS.apply(descriptor)) {
|
||||||
|
return PRIMITIVE_NUMBER_COMPARE_TO_INTRINSIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JsDescriptorUtils.isBuiltin(descriptor) && descriptor.getName().equals(OperatorConventions.COMPARE_TO)) {
|
||||||
|
return BUILTINS_COMPARE_TO_INTRINSIC;
|
||||||
|
}
|
||||||
|
|
||||||
if (!PREDICATE.apply(descriptor)) {
|
if (!PREDICATE.apply(descriptor)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS.apply(descriptor)) {
|
|
||||||
return NUMBER_COMPARE_TO_INTRINSIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pattern("Int|Short|Byte.div").apply(descriptor)) {
|
if (pattern("Int|Short|Byte.div").apply(descriptor)) {
|
||||||
JetType resultType = descriptor.getReturnType();
|
JetType resultType = descriptor.getReturnType();
|
||||||
|
|||||||
+3
@@ -45,6 +45,9 @@ public final class NamePredicate implements Predicate<Name> {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static final NamePredicate STRING = new NamePredicate("String");
|
public static final NamePredicate STRING = new NamePredicate("String");
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static final NamePredicate NUMBER = new NamePredicate("Number");
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Set<Name> validNames = Sets.newHashSet();
|
private final Set<Name> validNames = Sets.newHashSet();
|
||||||
|
|
||||||
|
|||||||
+24
-9
@@ -16,18 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.intrinsic.operation
|
package org.jetbrains.k2js.translate.intrinsic.operation
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet
|
||||||
import com.google.dart.compiler.backend.js.ast.*
|
import com.google.dart.compiler.backend.js.ast.*
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression
|
||||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext
|
|
||||||
import org.jetbrains.k2js.translate.operation.OperatorTable
|
|
||||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils
|
|
||||||
|
|
||||||
import org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken
|
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.jet.lexer.JetToken
|
import org.jetbrains.jet.lexer.JetToken
|
||||||
import com.google.common.collect.ImmutableSet
|
import org.jetbrains.k2js.translate.context.TranslationContext
|
||||||
|
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern
|
||||||
|
import org.jetbrains.k2js.translate.operation.OperatorTable
|
||||||
|
import org.jetbrains.k2js.translate.utils.JsAstUtils
|
||||||
|
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils
|
||||||
|
import org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken
|
||||||
|
|
||||||
|
|
||||||
object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||||
@@ -39,9 +39,24 @@ object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private object CompareToFunctionIntrinsic : AbstractBinaryOperationIntrinsic() {
|
||||||
|
override fun apply(expression: JetBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
||||||
|
val operator = OperatorTable.getBinaryOperator(getOperationToken(expression))
|
||||||
|
val compareTo = JsAstUtils.compareTo(left, right)
|
||||||
|
return JsBinaryOperation(operator, compareTo, context.program().getNumberLiteral(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override public fun getSupportTokens(): ImmutableSet<JetToken> = OperatorConventions.COMPARISON_OPERATIONS
|
override public fun getSupportTokens(): ImmutableSet<JetToken> = OperatorConventions.COMPARISON_OPERATIONS
|
||||||
|
|
||||||
override public fun getIntrinsic(descriptor: FunctionDescriptor): BinaryOperationIntrinsic? {
|
override public fun getIntrinsic(descriptor: FunctionDescriptor): BinaryOperationIntrinsic? {
|
||||||
return if (JsDescriptorUtils.isBuiltin(descriptor)) CompareToIntrinsic else null
|
if (JsDescriptorUtils.isBuiltin(descriptor))
|
||||||
|
when {
|
||||||
|
pattern("Int|Short|Byte|Double|Float|Char|String|Long.compareTo").apply(descriptor) ->
|
||||||
|
return CompareToIntrinsic
|
||||||
|
else ->
|
||||||
|
return CompareToFunctionIntrinsic
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,6 +138,16 @@ public final class JsAstUtils {
|
|||||||
return new JsInvocation(new JsNameRef(OperatorConventions.COMPARE_TO.getIdentifier(), Namer.KOTLIN_OBJECT_REF), left, right);
|
return new JsInvocation(new JsNameRef(OperatorConventions.COMPARE_TO.getIdentifier(), Namer.KOTLIN_OBJECT_REF), left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression primitiveCompareTo(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||||
|
return new JsInvocation(new JsNameRef("primitiveCompareTo", Namer.KOTLIN_OBJECT_REF), left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression isNumber(@NotNull JsExpression expression) {
|
||||||
|
return new JsInvocation(new JsNameRef("isNumber", Namer.KOTLIN_OBJECT_REF), expression);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsPrefixOperation negated(@NotNull JsExpression expression) {
|
public static JsPrefixOperation negated(@NotNull JsExpression expression) {
|
||||||
return new JsPrefixOperation(JsUnaryOperator.NOT, expression);
|
return new JsPrefixOperation(JsUnaryOperator.NOT, expression);
|
||||||
|
|||||||
@@ -86,9 +86,21 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.compareTo = function(a, b) {
|
Kotlin.compareTo = function(a, b) {
|
||||||
|
var type = typeof a;
|
||||||
|
if (type == "number" || type == "string") {
|
||||||
|
return a < b ? -1 : a > b ? 1 : 0;
|
||||||
|
}
|
||||||
|
return a.compareTo_za3rmp$(b);
|
||||||
|
};
|
||||||
|
|
||||||
|
Kotlin.primitiveCompareTo = function(a, b) {
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
return a < b ? -1 : a > b ? 1 : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Kotlin.isNumber = function (a) {
|
||||||
|
return typeof a == "number";
|
||||||
|
};
|
||||||
|
|
||||||
Kotlin.toShort = function(a) {
|
Kotlin.toShort = function(a) {
|
||||||
return (a & 0xFFFF) << 16 >> 16;
|
return (a & 0xFFFF) << 16 >> 16;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user