JS backend: support for char type
This commit is contained in:
@@ -38,10 +38,12 @@ public final class Namer {
|
||||
public static final String EQUALS_METHOD_NAME = getStableMangledNameForDescriptor(KotlinBuiltIns.getInstance().getAny(), "equals");
|
||||
public static final String COMPARE_TO_METHOD_NAME = getStableMangledNameForDescriptor(KotlinBuiltIns.getInstance().getComparable(), "compareTo");
|
||||
public static final String NUMBER_RANGE = "NumberRange";
|
||||
public static final String CHAR_RANGE = "CharRange";
|
||||
public static final String LONG_FROM_NUMBER = "fromNumber";
|
||||
public static final String LONG_TO_NUMBER = "toNumber";
|
||||
public static final String LONG_FROM_INT = "fromInt";
|
||||
public static final String PRIMITIVE_COMPARE_TO = "primitiveCompareTo";
|
||||
public static final String IS_CHAR = "isChar";
|
||||
public static final String IS_NUMBER = "isNumber";
|
||||
|
||||
public static final String CALLEE_NAME = "$fun";
|
||||
|
||||
@@ -101,12 +101,18 @@ public final class StandardClasses {
|
||||
standardClasses.declare().forFQ("kotlin.LongRange").kotlinClass("LongRange")
|
||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||
|
||||
standardClasses.declare().forFQ("kotlin.CharRange").kotlinClass("CharRange")
|
||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||
|
||||
standardClasses.declare().forFQ("kotlin.IntProgression").kotlinClass("NumberProgression")
|
||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||
|
||||
standardClasses.declare().forFQ("kotlin.LongProgression").kotlinClass("LongProgression")
|
||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||
|
||||
standardClasses.declare().forFQ("kotlin.CharProgression").kotlinClass("CharProgression")
|
||||
.methods("iterator", "contains").properties("start", "end", "increment");
|
||||
|
||||
standardClasses.declare().forFQ("kotlin.Enum").kotlinClass("Enum");
|
||||
|
||||
standardClasses.declare().forFQ("kotlin.Comparable").kotlinClass("Comparable");
|
||||
|
||||
@@ -99,6 +99,9 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
else if (NamePredicate.NUMBER.apply(typeName)) {
|
||||
return JsAstUtils.isNumber(expressionToMatch);
|
||||
}
|
||||
else if (NamePredicate.CHAR.apply(typeName)) {
|
||||
return JsAstUtils.isChar(expressionToMatch);
|
||||
}
|
||||
else if (NamePredicate.PRIMITIVE_NUMBERS_MAPPED_TO_PRIMITIVE_JS.apply(typeName)) {
|
||||
jsSTypeName = "number";
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public final class FunctionIntrinsics {
|
||||
register(StringOperationFIF.INSTANCE);
|
||||
register(ArrayFIF.INSTANCE);
|
||||
register(TopLevelFIF.INSTANCE);
|
||||
register(NumberConversionFIF.INSTANCE$);
|
||||
register(NumberAndCharConversionFIF.INSTANCE$);
|
||||
}
|
||||
|
||||
private void register(@NotNull FunctionIntrinsicFactory instance) {
|
||||
|
||||
+6
@@ -34,6 +34,8 @@ public object LongOperationFIF : FunctionIntrinsicFactory {
|
||||
val LONG_BINARY_OPERATION_INTEGER = pattern("Long.compareTo|rangeTo|plus|minus|times|div|mod(Int|Short|Byte)")
|
||||
val LONG_BINARY_OPERATION_FLOATING_POINT = pattern("Long.compareTo|rangeTo|plus|minus|times|div|mod(Double|Float)")
|
||||
val INTEGER_BINARY_OPERATION_LONG = pattern("Int|Short|Byte.compareTo|rangeTo|plus|minus|times|div|mod(Long)")
|
||||
val CHAR_BINARY_OPERATION_LONG = pattern("Char.compareTo|rangeTo|plus|minus|times|div|mod(Long)")
|
||||
val LONG_BINARY_OPERATION_CHAR = pattern("Long.compareTo|rangeTo|plus|minus|times|div|mod(Char)")
|
||||
val FLOATING_POINT_BINARY_OPERATION_LONG = pattern("Double|Float.compareTo|rangeTo|plus|minus|times|div|mod(Long)")
|
||||
|
||||
private val longBinaryIntrinsics =
|
||||
@@ -89,6 +91,10 @@ public object LongOperationFIF : FunctionIntrinsicFactory {
|
||||
wrapIntrinsicIfPresent(longBinaryIntrinsics[operationName], { longFromInt(it) }, ID)
|
||||
LONG_BINARY_OPERATION_INTEGER.apply(descriptor) ->
|
||||
wrapIntrinsicIfPresent(longBinaryIntrinsics[operationName], ID, { longFromInt(it) })
|
||||
CHAR_BINARY_OPERATION_LONG.apply(descriptor) ->
|
||||
wrapIntrinsicIfPresent(longBinaryIntrinsics[operationName], { longFromInt(charToInt(it)) }, ID)
|
||||
LONG_BINARY_OPERATION_CHAR.apply(descriptor) ->
|
||||
wrapIntrinsicIfPresent(longBinaryIntrinsics[operationName], ID, { longFromInt(charToInt(it)) })
|
||||
FLOATING_POINT_BINARY_OPERATION_LONG.apply(descriptor) ->
|
||||
wrapIntrinsicIfPresent(floatBinaryIntrinsics[operationName], ID, { invokeMethod(it, Namer.LONG_TO_NUMBER) })
|
||||
LONG_BINARY_OPERATION_FLOATING_POINT.apply(descriptor) ->
|
||||
|
||||
+12
-2
@@ -24,7 +24,7 @@ import org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.
|
||||
import org.jetbrains.k2js.translate.utils.ID
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils.*
|
||||
|
||||
public object NumberConversionFIF : CompositeFIF() {
|
||||
public object NumberAndCharConversionFIF : CompositeFIF() {
|
||||
val USE_AS_IS = Predicates.or(
|
||||
pattern("Int.toInt|toFloat|toDouble"), pattern("Short.toShort|toInt|toFloat|toDouble"),
|
||||
pattern("Byte.toByte|toShort|toInt|toFloat|toDouble"), pattern("Float|Double.toFloat|toDouble"),
|
||||
@@ -40,16 +40,26 @@ public object NumberConversionFIF : CompositeFIF() {
|
||||
"Int|Short|Byte.toLong" to ConversionUnaryIntrinsic { longFromInt(it) },
|
||||
"Float|Double.toLong" to ConversionUnaryIntrinsic { longFromNumber(it) },
|
||||
|
||||
"Char.toDouble|toFloat|toInt" to ConversionUnaryIntrinsic { charToInt(it) },
|
||||
"Char.toShort" to ConversionUnaryIntrinsic { toShort(charToInt(it)) },
|
||||
"Char.toByte" to ConversionUnaryIntrinsic { toByte(charToInt(it)) },
|
||||
"Char.toLong" to ConversionUnaryIntrinsic { longFromInt(charToInt(it)) },
|
||||
|
||||
"Number.toInt" to ConversionUnaryIntrinsic { invokeKotlinFunction("numberToInt", it) },
|
||||
"Number.toShort" to ConversionUnaryIntrinsic { invokeKotlinFunction("numberToShort", it) },
|
||||
"Number.toByte" to ConversionUnaryIntrinsic { invokeKotlinFunction("numberToByte", it) },
|
||||
"Number.toChar" to ConversionUnaryIntrinsic { invokeKotlinFunction("numberToChar", it) },
|
||||
"Number.toFloat|toDouble" to ConversionUnaryIntrinsic { invokeKotlinFunction("numberToDouble", it) },
|
||||
"Number.toLong" to ConversionUnaryIntrinsic { invokeKotlinFunction("numberToLong", it) },
|
||||
|
||||
"Int|Short|Byte|Float|Double.toChar" to ConversionUnaryIntrinsic { toChar(it) },
|
||||
|
||||
"Long.toFloat|toDouble" to ConversionUnaryIntrinsic { invokeMethod(it, "toNumber") },
|
||||
"Long.toInt" to ConversionUnaryIntrinsic { invokeMethod(it, "toInt") },
|
||||
"Long.toShort" to ConversionUnaryIntrinsic { toShort(invokeMethod(it, "toInt")) },
|
||||
"Long.toByte" to ConversionUnaryIntrinsic { toByte(invokeMethod(it, "toInt")) }
|
||||
"Long.toByte" to ConversionUnaryIntrinsic { toByte(invokeMethod(it, "toInt")) },
|
||||
"Long.toChar" to ConversionUnaryIntrinsic { toChar(invokeMethod(it, "toInt")) }
|
||||
|
||||
)
|
||||
|
||||
class ConversionUnaryIntrinsic(val applyFun: (receiver: JsExpression) -> JsExpression) : FunctionIntrinsic() {
|
||||
+69
-1
@@ -69,6 +69,16 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final BinaryOperationInstrinsicBase CHAR_RANGE_TO_INTRINSIC = new BinaryOperationInstrinsicBase() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression doApply(@NotNull JsExpression left, @NotNull JsExpression right, @NotNull TranslationContext context) {
|
||||
//TODO: add tests and correct expression for reversed ranges.
|
||||
return JsAstUtils.charRangeTo(left, right);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final BinaryOperationInstrinsicBase INTEGER_DIVISION_INTRINSIC = new BinaryOperationInstrinsicBase() {
|
||||
@NotNull
|
||||
@@ -124,6 +134,18 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
@Nullable
|
||||
@Override
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
if (pattern("Int|Short|Byte|Double|Float.compareTo(Char)").apply(descriptor)) {
|
||||
return new WithCharAsSecondOperandFunctionIntrinsic(PRIMITIVE_NUMBER_COMPARE_TO_INTRINSIC);
|
||||
}
|
||||
|
||||
if (pattern("Char.compareTo(Int|Short|Byte|Double|Float)").apply(descriptor)) {
|
||||
return new WithCharAsFirstOperandFunctionIntrinsic(PRIMITIVE_NUMBER_COMPARE_TO_INTRINSIC);
|
||||
}
|
||||
|
||||
if (pattern("Char.rangeTo(Char)").apply(descriptor)) {
|
||||
return CHAR_RANGE_TO_INTRINSIC;
|
||||
}
|
||||
|
||||
if (PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS.apply(descriptor)) {
|
||||
return PRIMITIVE_NUMBER_COMPARE_TO_INTRINSIC;
|
||||
}
|
||||
@@ -141,6 +163,12 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
if (pattern("Int|Short|Byte.div(Int|Short|Byte)").apply(descriptor)) {
|
||||
return INTEGER_DIVISION_INTRINSIC;
|
||||
}
|
||||
if (pattern("Char.div(Int|Short|Byte)").apply(descriptor)) {
|
||||
return new WithCharAsFirstOperandFunctionIntrinsic(INTEGER_DIVISION_INTRINSIC);
|
||||
}
|
||||
if (pattern("Int|Short|Byte.div(Char)").apply(descriptor)) {
|
||||
return new WithCharAsSecondOperandFunctionIntrinsic(INTEGER_DIVISION_INTRINSIC);
|
||||
}
|
||||
if (descriptor.getName().equals(Name.identifier("rangeTo"))) {
|
||||
return RANGE_TO_INTRINSIC;
|
||||
}
|
||||
@@ -151,7 +179,15 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
}
|
||||
}
|
||||
JsBinaryOperator operator = getOperator(descriptor);
|
||||
return new PrimitiveBinaryOperationFunctionIntrinsic(operator);
|
||||
BinaryOperationInstrinsicBase result = new PrimitiveBinaryOperationFunctionIntrinsic(operator);
|
||||
|
||||
if (pattern("Char.plus|minus|times|div|mod(Int|Short|Byte|Double|Float)").apply(descriptor)) {
|
||||
return new WithCharAsFirstOperandFunctionIntrinsic(result);
|
||||
}
|
||||
if (pattern("Int|Short|Byte|Double|Float.plus|minus|times|div|mod(Char)").apply(descriptor)) {
|
||||
return new WithCharAsSecondOperandFunctionIntrinsic(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -182,4 +218,36 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
return new JsBinaryOperation(operator, left, right);
|
||||
}
|
||||
}
|
||||
|
||||
private static class WithCharAsFirstOperandFunctionIntrinsic extends BinaryOperationInstrinsicBase {
|
||||
|
||||
@NotNull
|
||||
private final BinaryOperationInstrinsicBase functionIntrinsic;
|
||||
|
||||
private WithCharAsFirstOperandFunctionIntrinsic(@NotNull BinaryOperationInstrinsicBase functionIntrinsic) {
|
||||
this.functionIntrinsic = functionIntrinsic;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression doApply(@NotNull JsExpression left, @NotNull JsExpression right, @NotNull TranslationContext context) {
|
||||
return functionIntrinsic.doApply(JsAstUtils.charToInt(left), right, context);
|
||||
}
|
||||
}
|
||||
|
||||
private static class WithCharAsSecondOperandFunctionIntrinsic extends BinaryOperationInstrinsicBase {
|
||||
|
||||
@NotNull
|
||||
private final BinaryOperationInstrinsicBase functionIntrinsic;
|
||||
|
||||
private WithCharAsSecondOperandFunctionIntrinsic(@NotNull BinaryOperationInstrinsicBase functionIntrinsic) {
|
||||
this.functionIntrinsic = functionIntrinsic;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression doApply(@NotNull JsExpression left, @NotNull JsExpression right, @NotNull TranslationContext context) {
|
||||
return functionIntrinsic.doApply(left, JsAstUtils.charToInt(right), context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+77
@@ -30,10 +30,12 @@ import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.DescriptorPredicate;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate.PRIMITIVE_NUMBERS;
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||
|
||||
public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
@@ -94,6 +96,67 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
}
|
||||
};
|
||||
|
||||
private static abstract class UnaryOperationInstrinsicBase extends FunctionIntrinsic {
|
||||
@NotNull
|
||||
public abstract JsExpression doApply(@NotNull JsExpression receiver, @NotNull TranslationContext context);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(
|
||||
@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 0;
|
||||
return doApply(receiver, context);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic CHAR_PLUS = new UnaryOperationInstrinsicBase() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression doApply(
|
||||
@NotNull JsExpression receiver, @NotNull TranslationContext context
|
||||
) {
|
||||
return JsAstUtils.charToInt(receiver);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic CHAR_MINUS = new UnaryOperationInstrinsicBase() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression doApply(
|
||||
@NotNull JsExpression receiver, @NotNull TranslationContext context
|
||||
) {
|
||||
return new JsPrefixOperation(JsUnaryOperator.NEG, JsAstUtils.charToInt(receiver));
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic CHAR_INC = new UnaryOperationInstrinsicBase() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression doApply(
|
||||
@NotNull JsExpression receiver, @NotNull TranslationContext context
|
||||
) {
|
||||
return JsAstUtils.invokeKotlinFunction("charInc", receiver);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic CHAR_DEC = new UnaryOperationInstrinsicBase() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression doApply(
|
||||
@NotNull JsExpression receiver, @NotNull TranslationContext context
|
||||
) {
|
||||
return JsAstUtils.invokeKotlinFunction("charDec", receiver);
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
@@ -101,6 +164,19 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (pattern("Char.plus()").apply(descriptor)) {
|
||||
return CHAR_PLUS;
|
||||
}
|
||||
if (pattern("Char.minus()").apply(descriptor)) {
|
||||
return CHAR_MINUS;
|
||||
}
|
||||
if (pattern("Char.inc()").apply(descriptor)) {
|
||||
return CHAR_INC;
|
||||
}
|
||||
if (pattern("Char.dec()").apply(descriptor)) {
|
||||
return CHAR_DEC;
|
||||
}
|
||||
|
||||
if (INC_OPERATION_FOR_PRIMITIVE_NUMBER.apply(descriptor)) {
|
||||
return NUMBER_INC_INTRINSIC;
|
||||
}
|
||||
@@ -108,6 +184,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
return NUMBER_DEC_INTRINSIC;
|
||||
}
|
||||
|
||||
|
||||
Name name = descriptor.getName();
|
||||
|
||||
JsUnaryOperator jsOperator;
|
||||
|
||||
+3
@@ -59,6 +59,9 @@ public final class NamePredicate implements Predicate<Name> {
|
||||
@NotNull
|
||||
public static final NamePredicate NUMBER = new NamePredicate("Number");
|
||||
|
||||
@NotNull
|
||||
public static final NamePredicate CHAR = new NamePredicate(PrimitiveType.CHAR.getTypeName());
|
||||
|
||||
@NotNull
|
||||
public static final NamePredicate LONG = new NamePredicate(PrimitiveType.LONG.getTypeName());
|
||||
|
||||
|
||||
+20
@@ -31,6 +31,8 @@ import org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken
|
||||
|
||||
|
||||
object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||
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 PRIMITIVE_COMPARE_TO = pattern("Int|Short|Byte|Double|Float|Char|String.compareTo")
|
||||
|
||||
private object CompareToIntrinsic : AbstractBinaryOperationIntrinsic() {
|
||||
@@ -40,6 +42,20 @@ object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private object CompareToCharIntrinsic : AbstractBinaryOperationIntrinsic() {
|
||||
override fun apply(expression: JetBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
||||
val operator = OperatorTable.getBinaryOperator(getOperationToken(expression))
|
||||
return JsBinaryOperation(operator, left, JsAstUtils.charToInt(right))
|
||||
}
|
||||
}
|
||||
|
||||
private object CompareCharToPrimitiveIntrinsic : AbstractBinaryOperationIntrinsic() {
|
||||
override fun apply(expression: JetBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
||||
val operator = OperatorTable.getBinaryOperator(getOperationToken(expression))
|
||||
return JsBinaryOperation(operator, JsAstUtils.charToInt(left), right)
|
||||
}
|
||||
}
|
||||
|
||||
private object CompareToFunctionIntrinsic : AbstractBinaryOperationIntrinsic() {
|
||||
override fun apply(expression: JetBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression {
|
||||
val operator = OperatorTable.getBinaryOperator(getOperationToken(expression))
|
||||
@@ -53,6 +69,10 @@ object CompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||
override public fun getIntrinsic(descriptor: FunctionDescriptor): BinaryOperationIntrinsic? {
|
||||
if (JsDescriptorUtils.isBuiltin(descriptor))
|
||||
when {
|
||||
COMPARE_TO_CHAR.apply(descriptor) ->
|
||||
return CompareToCharIntrinsic
|
||||
CHAR_COMPARE_TO.apply(descriptor) ->
|
||||
return CompareCharToPrimitiveIntrinsic
|
||||
PRIMITIVE_COMPARE_TO.apply(descriptor) ->
|
||||
return CompareToIntrinsic
|
||||
else ->
|
||||
|
||||
+6
@@ -36,7 +36,9 @@ public object LongCompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||
val FLOATING_POINT_COMPARE_TO_LONG_PATTERN = pattern("Double|Float.compareTo(Long)")
|
||||
val LONG_COMPARE_TO_FLOATING_POINT_PATTERN = pattern("Long.compareTo(Float|Double)")
|
||||
val INTEGER_COMPARE_TO_LONG_PATTERN = pattern("Int|Short|Byte.compareTo(Long)")
|
||||
val CHAR_COMPARE_TO_LONG_PATTERN = pattern("Char.compareTo(Long)")
|
||||
val LONG_COMPARE_TO_INTEGER_PATTERN = pattern("Long.compareTo(Int|Short|Byte)")
|
||||
val LONG_COMPARE_TO_CHAR_PATTERN = pattern("Long.compareTo(Char)")
|
||||
val LONG_COMPARE_TO_LONG_PATTERN = pattern("Long.compareTo(Long)")
|
||||
|
||||
private object FLOATING_POINT_COMPARE_TO_LONG : AbstractBinaryOperationIntrinsic() {
|
||||
@@ -62,7 +64,9 @@ public object LongCompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||
}
|
||||
|
||||
private val INTEGER_COMPARE_TO_LONG = CompareToBinaryIntrinsic( { longFromInt(it) }, ID)
|
||||
private val CHAR_COMPARE_TO_LONG = CompareToBinaryIntrinsic( { longFromInt(charToInt(it)) }, ID)
|
||||
private val LONG_COMPARE_TO_INTEGER = CompareToBinaryIntrinsic( ID, { longFromInt(it) })
|
||||
private val LONG_COMPARE_TO_CHAR = CompareToBinaryIntrinsic( ID, { longFromInt(charToInt(it)) })
|
||||
private val LONG_COMPARE_TO_LONG = CompareToBinaryIntrinsic( ID, ID )
|
||||
|
||||
override public fun getSupportTokens(): ImmutableSet<JetToken> = OperatorConventions.COMPARISON_OPERATIONS
|
||||
@@ -73,7 +77,9 @@ public object LongCompareToBOIF : BinaryOperationIntrinsicFactory {
|
||||
FLOATING_POINT_COMPARE_TO_LONG_PATTERN.apply(descriptor) -> FLOATING_POINT_COMPARE_TO_LONG
|
||||
LONG_COMPARE_TO_FLOATING_POINT_PATTERN.apply(descriptor) -> LONG_COMPARE_TO_FLOATING_POINT
|
||||
INTEGER_COMPARE_TO_LONG_PATTERN.apply(descriptor) -> INTEGER_COMPARE_TO_LONG
|
||||
CHAR_COMPARE_TO_LONG_PATTERN.apply(descriptor) -> CHAR_COMPARE_TO_LONG
|
||||
LONG_COMPARE_TO_INTEGER_PATTERN.apply(descriptor) -> LONG_COMPARE_TO_INTEGER
|
||||
LONG_COMPARE_TO_CHAR_PATTERN.apply(descriptor) -> LONG_COMPARE_TO_CHAR
|
||||
LONG_COMPARE_TO_LONG_PATTERN.apply(descriptor) -> LONG_COMPARE_TO_LONG
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -133,6 +133,11 @@ public final class JsAstUtils {
|
||||
return new JsBinaryOperation(JsBinaryOperator.BIT_OR, expression, JsNumberLiteral.ZERO);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression charToInt(@NotNull JsExpression expression) {
|
||||
return invokeMethod(expression, "charCodeAt", JsNumberLiteral.ZERO);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression toShort(@NotNull JsExpression expression) {
|
||||
return invokeKotlinFunction(OperatorConventions.SHORT.getIdentifier(), expression);
|
||||
@@ -148,6 +153,11 @@ public final class JsAstUtils {
|
||||
return invokeKotlinFunction(OperatorConventions.LONG.getIdentifier(), expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression toChar(@NotNull JsExpression expression) {
|
||||
return invokeKotlinFunction(OperatorConventions.CHAR.getIdentifier(), expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression compareTo(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||
return invokeKotlinFunction(OperatorConventions.COMPARE_TO.getIdentifier(), left, right);
|
||||
@@ -163,6 +173,11 @@ public final class JsAstUtils {
|
||||
return invokeKotlinFunction(Namer.IS_NUMBER, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression isChar(@NotNull JsExpression expression) {
|
||||
return invokeKotlinFunction(Namer.IS_CHAR, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsExpression rangeTo(@NotNull String rangeClassName, @NotNull JsExpression rangeStart, @NotNull JsExpression rangeEnd) {
|
||||
JsNameRef expr = new JsNameRef(rangeClassName, Namer.KOTLIN_NAME);
|
||||
@@ -176,6 +191,11 @@ public final class JsAstUtils {
|
||||
return rangeTo(Namer.NUMBER_RANGE, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression charRangeTo(@NotNull JsExpression rangeStart, @NotNull JsExpression rangeEnd) {
|
||||
return rangeTo(Namer.CHAR_RANGE, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static final JsNameRef kotlinLongNameRef = new JsNameRef("Long", Namer.KOTLIN_OBJECT_REF);
|
||||
|
||||
|
||||
@@ -389,7 +389,8 @@ public final class TranslationUtils {
|
||||
if (operationDescriptor == null || !(operationDescriptor instanceof FunctionDescriptor)) return true;
|
||||
|
||||
JetType returnType = operationDescriptor.getReturnType();
|
||||
if (returnType != null && returnType.equals(KotlinBuiltIns.getInstance().getLongType())) return false;
|
||||
if (returnType != null &&
|
||||
KotlinBuiltIns.getInstance().getCharType().equals(returnType) || (KotlinBuiltIns.getInstance().getLongType().equals(returnType))) return false;
|
||||
|
||||
if (context.intrinsics().getFunctionIntrinsics().getIntrinsic((FunctionDescriptor) operationDescriptor).exists()) return true;
|
||||
|
||||
|
||||
@@ -86,8 +86,15 @@
|
||||
};
|
||||
|
||||
Kotlin.compareTo = function (a, b) {
|
||||
var type = typeof a;
|
||||
if (type == "number" || type == "string") {
|
||||
var typeA = typeof a;
|
||||
var typeB = typeof a;
|
||||
if (Kotlin.isChar(a) && typeB == "number") {
|
||||
return Kotlin.primitiveCompareTo(a.charCodeAt(0), b);
|
||||
}
|
||||
if (typeA == "number" && Kotlin.isChar(b)) {
|
||||
return Kotlin.primitiveCompareTo(a, b.charCodeAt(0));
|
||||
}
|
||||
if (typeA == "number" || typeA == "string") {
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
return a.compareTo_za3rmp$(b);
|
||||
@@ -101,8 +108,16 @@
|
||||
return typeof a == "number" || a instanceof Kotlin.Long;
|
||||
};
|
||||
|
||||
Kotlin.toInt = function (a) {
|
||||
return a | 0;
|
||||
Kotlin.isChar = function (value) {
|
||||
return (typeof value) == "string" && value.length == 1;
|
||||
};
|
||||
|
||||
Kotlin.charInc = function (value) {
|
||||
return String.fromCharCode(value.charCodeAt(0)+1);
|
||||
};
|
||||
|
||||
Kotlin.charDec = function (value) {
|
||||
return String.fromCharCode(value.charCodeAt(0)-1);
|
||||
};
|
||||
|
||||
Kotlin.toShort = function (a) {
|
||||
@@ -113,6 +128,10 @@
|
||||
return (a & 0xFF) << 24 >> 24;
|
||||
};
|
||||
|
||||
Kotlin.toChar = function (a) {
|
||||
return String.fromCharCode((((a | 0) % 65536) & 0xFFFF) << 16 >>> 16);
|
||||
};
|
||||
|
||||
Kotlin.numberToLong = function (a) {
|
||||
return a instanceof Kotlin.Long ? a : Kotlin.Long.fromNumber(a);
|
||||
};
|
||||
@@ -133,6 +152,10 @@
|
||||
return +a;
|
||||
};
|
||||
|
||||
Kotlin.numberToChar = function (a) {
|
||||
return Kotlin.toChar(Kotlin.numberToInt(a));
|
||||
};
|
||||
|
||||
Kotlin.intUpto = function (from, to) {
|
||||
return new Kotlin.NumberRange(from, to);
|
||||
};
|
||||
@@ -647,6 +670,50 @@
|
||||
}
|
||||
});
|
||||
|
||||
Kotlin.CharRangeIterator = Kotlin.createClassNow(Kotlin.RangeIterator,
|
||||
function (start, end, increment) {
|
||||
Kotlin.RangeIterator.call(this, start, end, increment);
|
||||
}, {
|
||||
next: function () {
|
||||
var value = this.i;
|
||||
this.i = this.i + this.increment;
|
||||
return String.fromCharCode(value);
|
||||
},
|
||||
});
|
||||
|
||||
Kotlin.CharRange = Kotlin.createClassNow(null,
|
||||
function (start, end) {
|
||||
this.start = start.charCodeAt(0);
|
||||
this.end = end.charCodeAt(0);
|
||||
this.increment = 1;
|
||||
}, {
|
||||
contains: function (char) {
|
||||
var code = char.charCodeAt(0)
|
||||
return this.start <= code && code <= this.end;
|
||||
},
|
||||
iterator: function () {
|
||||
return new Kotlin.CharRangeIterator(this.start, this.end, this.increment);
|
||||
},
|
||||
isEmpty: function () {
|
||||
return this.start > this.end;
|
||||
},
|
||||
equals_za3rmp$: isSameNotNullRanges
|
||||
});
|
||||
|
||||
Kotlin.CharNumberProgression = Kotlin.createClassNow(null,
|
||||
function (start, end, increment) {
|
||||
this.start = start.charCodeAt(0);
|
||||
this.end = end.charCodeAt(0);
|
||||
this.increment = increment;
|
||||
}, {
|
||||
iterator: function () {
|
||||
return new Kotlin.CharRangeIterator(this.start, this.end, this.increment);
|
||||
},
|
||||
isEmpty: function() {
|
||||
return this.increment > 0 ? this.start > this.end : this.start < this.end;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @template T
|
||||
|
||||
Reference in New Issue
Block a user