JS backend: support for char type

This commit is contained in:
Michael Nedzelsky
2014-09-24 18:24:59 +04:00
parent 2e4e5c5d1d
commit 6aff9803c4
14 changed files with 298 additions and 9 deletions
@@ -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";
}
@@ -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) {
@@ -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) ->
@@ -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,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);
}
}
}
@@ -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;
@@ -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());
@@ -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 ->
@@ -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;
+71 -4
View File
@@ -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