diff --git a/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java b/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java index 8c3904f52af..5ee90c76468 100644 --- a/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java +++ b/build-common/test/org/jetbrains/kotlin/serialization/js/ast/DebugJsAstProtoBuf.java @@ -203,6 +203,14 @@ public final class DebugJsAstProtoBuf { * WRAP_FUNCTION = 2; */ WRAP_FUNCTION(1, 2), + /** + * TO_BOXED_CHAR = 3; + */ + TO_BOXED_CHAR(2, 3), + /** + * UNBOX_CHAR = 4; + */ + UNBOX_CHAR(3, 4), ; /** @@ -213,6 +221,14 @@ public final class DebugJsAstProtoBuf { * WRAP_FUNCTION = 2; */ public static final int WRAP_FUNCTION_VALUE = 2; + /** + * TO_BOXED_CHAR = 3; + */ + public static final int TO_BOXED_CHAR_VALUE = 3; + /** + * UNBOX_CHAR = 4; + */ + public static final int UNBOX_CHAR_VALUE = 4; public final int getNumber() { return value; } @@ -221,6 +237,8 @@ public final class DebugJsAstProtoBuf { switch (value) { case 1: return DEFINE_INLINE_FUNCTION; case 2: return WRAP_FUNCTION; + case 3: return TO_BOXED_CHAR; + case 4: return UNBOX_CHAR; default: return null; } } @@ -49343,9 +49361,10 @@ public final class DebugJsAstProtoBuf { "t.Fragment*@\n\013SideEffects\022\021\n\rAFFECTS_STA" + "TE\020\001\022\024\n\020DEPENDS_ON_STATE\020\002\022\010\n\004PURE\020\003*?\n\016" + "InlineStrategy\022\017\n\013AS_FUNCTION\020\000\022\014\n\010IN_PL" + - "ACE\020\001\022\016\n\nNOT_INLINE\020\002*@\n\017SpecialFunction" + + "ACE\020\001\022\016\n\nNOT_INLINE\020\002*c\n\017SpecialFunction" + "\022\032\n\026DEFINE_INLINE_FUNCTION\020\001\022\021\n\rWRAP_FUN" + - "CTION\020\002B\024B\022DebugJsAstProtoBuf" + "CTION\020\002\022\021\n\rTO_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHAR" + + "\020\004B\024B\022DebugJsAstProtoBuf" }; org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { diff --git a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt index 8ffed53d6a0..9e552a7df79 100644 --- a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt +++ b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt @@ -139,5 +139,7 @@ enum class SideEffectKind { enum class SpecialFunction(val suggestedName: String) { DEFINE_INLINE_FUNCTION("defineInlineFunction"), - WRAP_FUNCTION("wrapFunction") + WRAP_FUNCTION("wrapFunction"), + TO_BOXED_CHAR("toBoxedChar"), + UNBOX_CHAR("unboxChar"), } \ No newline at end of file diff --git a/js/js.serializer/src/js-ast.proto b/js/js.serializer/src/js-ast.proto index 986becd6d64..6a904c7dee3 100644 --- a/js/js.serializer/src/js-ast.proto +++ b/js/js.serializer/src/js-ast.proto @@ -433,6 +433,8 @@ message Name { enum SpecialFunction { DEFINE_INLINE_FUNCTION = 1; WRAP_FUNCTION = 2; + TO_BOXED_CHAR = 3; + UNBOX_CHAR = 4; } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt index 16526238bb3..686dbe9c8c7 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstDeserializer.kt @@ -520,6 +520,8 @@ class JsAstDeserializer(program: JsProgram, private val sourceRoots: Iterable SpecialFunction.DEFINE_INLINE_FUNCTION JsAstProtoBuf.SpecialFunction.WRAP_FUNCTION -> SpecialFunction.WRAP_FUNCTION + JsAstProtoBuf.SpecialFunction.TO_BOXED_CHAR -> SpecialFunction.TO_BOXED_CHAR + JsAstProtoBuf.SpecialFunction.UNBOX_CHAR -> SpecialFunction.UNBOX_CHAR } private fun withLocation(fileId: Int?, location: Location?, action: () -> T): T { diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstProtoBuf.java b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstProtoBuf.java index b1f8c70568c..21c70d3290c 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstProtoBuf.java +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstProtoBuf.java @@ -151,6 +151,14 @@ public final class JsAstProtoBuf { * WRAP_FUNCTION = 2; */ WRAP_FUNCTION(1, 2), + /** + * TO_BOXED_CHAR = 3; + */ + TO_BOXED_CHAR(2, 3), + /** + * UNBOX_CHAR = 4; + */ + UNBOX_CHAR(3, 4), ; /** @@ -161,6 +169,14 @@ public final class JsAstProtoBuf { * WRAP_FUNCTION = 2; */ public static final int WRAP_FUNCTION_VALUE = 2; + /** + * TO_BOXED_CHAR = 3; + */ + public static final int TO_BOXED_CHAR_VALUE = 3; + /** + * UNBOX_CHAR = 4; + */ + public static final int UNBOX_CHAR_VALUE = 4; public final int getNumber() { return value; } @@ -169,6 +185,8 @@ public final class JsAstProtoBuf { switch (value) { case 1: return DEFINE_INLINE_FUNCTION; case 2: return WRAP_FUNCTION; + case 3: return TO_BOXED_CHAR; + case 4: return UNBOX_CHAR; default: return null; } } diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt index 1f843447645..46ac9253136 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/ast/JsAstSerializer.kt @@ -556,6 +556,8 @@ class JsAstSerializer(private val pathResolver: (File) -> String) { private fun map(specialFunction: SpecialFunction) = when (specialFunction) { SpecialFunction.DEFINE_INLINE_FUNCTION -> JsAstProtoBuf.SpecialFunction.DEFINE_INLINE_FUNCTION SpecialFunction.WRAP_FUNCTION -> JsAstProtoBuf.SpecialFunction.WRAP_FUNCTION + SpecialFunction.TO_BOXED_CHAR -> JsAstProtoBuf.SpecialFunction.TO_BOXED_CHAR + SpecialFunction.UNBOX_CHAR -> JsAstProtoBuf.SpecialFunction.UNBOX_CHAR } private fun serialize(name: JsName): Int = nameMap.getOrPut(name) { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt index fa72d6e3ad7..99754cf6a5d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt @@ -99,8 +99,8 @@ fun TranslationContext.getCallInfo( return FunctionCallInfo(callInfo, argumentsInfo) } -private fun boxIfNeedeed(v: ReceiverValue?, d: ReceiverParameterDescriptor?, r: JsExpression?): JsExpression? { - return r?.let { TranslationUtils.boxCastIfNeeded(it, v?.type, d?.type) } +private fun TranslationContext.boxIfNeedeed(v: ReceiverValue?, d: ReceiverParameterDescriptor?, r: JsExpression?): JsExpression? { + return r?.let { receiver -> TranslationUtils.boxCastIfNeeded(this, receiver, v?.type, d?.type) } } private fun TranslationContext.getDispatchReceiver(receiverValue: ReceiverValue): JsExpression { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java index 9e4a655f0ec..8c935830ff5 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java @@ -353,12 +353,12 @@ public final class Namer { } @NotNull - public static JsNameRef createInlineFunction() { + private static JsNameRef createInlineFunction() { return pureFqn(DEFINE_INLINE_FUNCTION, kotlinObject()); } @NotNull - public static JsNameRef wrapFunction() { + private static JsNameRef wrapFunction() { return pureFqn(WRAP_FUNCTION, kotlinObject()); } @@ -369,6 +369,10 @@ public final class Namer { return createInlineFunction(); case WRAP_FUNCTION: return wrapFunction(); + case TO_BOXED_CHAR: + return pureFqn("toBoxedChar", kotlinObject()); + case UNBOX_CHAR: + return pureFqn("unboxChar", kotlinObject()); default: throw new IllegalArgumentException("Unknown function: " + specialFunction); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java index 72fcc981aa7..5d20892488b 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java @@ -84,7 +84,8 @@ public class DestructuringDeclarationTranslator extends AbstractTranslator { setInlineCallMetadata(entryInitializer, entry, entryInitCall, context()); } - entryInitializer = TranslationUtils.boxCastIfNeeded(entryInitializer, candidateDescriptor.getReturnType(), descriptor.getType()); + entryInitializer = TranslationUtils.boxCastIfNeeded(context(), entryInitializer, candidateDescriptor.getReturnType(), + descriptor.getType()); JsName name = context().getNameForDescriptor(descriptor); if (isVarCapturedInClosure(context().bindingContext(), descriptor)) { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java index 24ccc9f2ffb..65324bb84d6 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java @@ -148,7 +148,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { if (KotlinBuiltIns.isCharOrNullableChar(returnedType) && TranslationUtils.shouldBoxReturnValue((CallableDescriptor)context.getDeclarationDescriptor())) { - jsReturnExpression = JsAstUtils.charToBoxedChar(jsReturnExpression); + jsReturnExpression = TranslationUtils.charToBoxedChar(context, jsReturnExpression); } jsReturn = new JsReturn(jsReturnExpression); @@ -247,7 +247,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { JsExpression receiver = translateAsExpression(receiverExpression, context); KotlinType type = context.bindingContext().getType(receiverExpression); if (type != null && KotlinBuiltIns.isChar(type)) { - receiver = JsAstUtils.charToBoxedChar(receiver); + receiver = TranslationUtils.charToBoxedChar(context, receiver); } return new JsInvocation(context.namer().kotlin(GET_KCLASS_FROM_EXPRESSION), receiver); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java index 8502cf40378..188ec4fb0d9 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java @@ -83,7 +83,7 @@ public final class PatternTranslator extends AbstractTranslator { KotlinType leftType = context().bindingContext().getType(left); if (leftType != null && KotlinBuiltIns.isChar(leftType)) { - expressionToCast = JsAstUtils.charToBoxedChar(expressionToCast); + expressionToCast = TranslationUtils.charToBoxedChar(context(), expressionToCast); } TemporaryVariable temporary = context().declareTemporary(expressionToCast, expression); @@ -104,7 +104,7 @@ public final class PatternTranslator extends AbstractTranslator { KotlinType expressionType = context().bindingContext().getType(expression); if (expressionType != null && KotlinBuiltIns.isCharOrNullableChar(expressionType)) { - result = JsAstUtils.boxedCharToChar(result); + result = TranslationUtils.boxedCharToChar(context(), result); } return result; @@ -117,7 +117,7 @@ public final class PatternTranslator extends AbstractTranslator { KotlinType leftType = context().bindingContext().getType(left); if (leftType != null && KotlinBuiltIns.isChar(leftType)) { - expressionToCheck = JsAstUtils.charToBoxedChar(expressionToCheck); + expressionToCheck = TranslationUtils.charToBoxedChar(context(), expressionToCheck); } KtTypeReference typeReference = expression.getTypeReference(); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java index 52b6ce8e17f..1396a2ca67a 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.js.translate.test.JSTestGenerator; import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils; import org.jetbrains.kotlin.js.translate.utils.BindingUtils; import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; +import org.jetbrains.kotlin.js.translate.utils.TranslationUtils; import org.jetbrains.kotlin.js.translate.utils.mutator.AssignToExpressionMutator; import org.jetbrains.kotlin.psi.KtDeclaration; import org.jetbrains.kotlin.psi.KtExpression; @@ -188,7 +189,8 @@ public final class Translation { JsNode jsNode = translateExpression(expression, context, block); if (jsNode instanceof JsExpression) { KotlinType expressionType = context.bindingContext().getType(expression); - return unboxIfNeeded((JsExpression) jsNode, expressionType != null && KotlinBuiltIns.isCharOrNullableChar(expressionType)); + return unboxIfNeeded(context, (JsExpression) jsNode, + expressionType != null && KotlinBuiltIns.isCharOrNullableChar(expressionType)); } assert jsNode instanceof JsStatement : "Unexpected node of type: " + jsNode.getClass().toString(); @@ -204,11 +206,15 @@ public final class Translation { } @NotNull - public static JsExpression unboxIfNeeded(@NotNull JsExpression expression, boolean charOrNullableChar) { + public static JsExpression unboxIfNeeded( + @NotNull TranslationContext context, + @NotNull JsExpression expression, + boolean charOrNullableChar + ) { if (charOrNullableChar && (expression instanceof JsInvocation || expression instanceof JsNameRef || expression instanceof JsArrayAccess) ) { - expression = JsAstUtils.boxedCharToChar(expression); + expression = TranslationUtils.boxedCharToChar(context, expression); } return expression; } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/AssignmentBOIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/AssignmentBOIF.kt index 80786ed92ae..66293a8dbba 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/AssignmentBOIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/AssignmentBOIF.kt @@ -23,8 +23,8 @@ import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation import org.jetbrains.kotlin.js.backend.ast.JsExpression import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.operation.OperatorTable -import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.PsiUtils +import org.jetbrains.kotlin.js.translate.utils.TranslationUtils import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.types.KotlinType @@ -34,7 +34,7 @@ object AssignmentBOIF : BinaryOperationIntrinsicFactory { private object CharAssignmentIntrinsic : AbstractBinaryOperationIntrinsic() { override fun apply(expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext): JsExpression { val operator = OperatorTable.getBinaryOperator(PsiUtils.getOperationToken(expression)) - return JsBinaryOperation(operator, left, JsAstUtils.charToBoxedChar(right)) + return JsBinaryOperation(operator, left, TranslationUtils.charToBoxedChar(context, right)) } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/EqualsBOIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/EqualsBOIF.kt index a30dfb8e5dd..27c501eb556 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/EqualsBOIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/operation/EqualsBOIF.kt @@ -62,8 +62,8 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory { if (leftType != null && (leftType in SIMPLE_PRIMITIVES || leftType == rightType && leftType != PrimitiveType.LONG)) { return JsBinaryOperation(if (isNegated) JsBinaryOperator.REF_NEQ else JsBinaryOperator.REF_EQ, - Translation.unboxIfNeeded(left, leftType == PrimitiveType.CHAR), - Translation.unboxIfNeeded(right, rightType == PrimitiveType.CHAR)) + Translation.unboxIfNeeded(context, left, leftType == PrimitiveType.CHAR), + Translation.unboxIfNeeded(context, right, rightType == PrimitiveType.CHAR)) } val resolvedCall = expression.getResolvedCall(context.bindingContext()) @@ -77,8 +77,8 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory { return JsBinaryOperation(if (isNegated) JsBinaryOperator.NEQ else JsBinaryOperator.EQ, left, right) } - val maybeBoxedLeft = if (leftType == PrimitiveType.CHAR) JsAstUtils.charToBoxedChar(left) else left - val maybeBoxedRight = if (rightType == PrimitiveType.CHAR) JsAstUtils.charToBoxedChar(right) else right + val maybeBoxedLeft = if (leftType == PrimitiveType.CHAR) TranslationUtils.charToBoxedChar(context, left) else left + val maybeBoxedRight = if (rightType == PrimitiveType.CHAR) TranslationUtils.charToBoxedChar(context, right) else right val result = TopLevelFIF.KOTLIN_EQUALS.apply(maybeBoxedLeft, Arrays.asList(maybeBoxedRight), context) return if (isNegated) JsAstUtils.not(result) else result diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/BinaryOperationTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/BinaryOperationTranslator.java index cecae5837b7..5910183bc29 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/BinaryOperationTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/BinaryOperationTranslator.java @@ -127,15 +127,14 @@ public final class BinaryOperationTranslator extends AbstractTranslator { private JsExpression translateElvis() { KotlinType expressionType = context().bindingContext().getType(expression); - JsExpression leftExpression = TranslationUtils.boxCastIfNeeded(Translation.translateAsExpression(leftKtExpression, context()), - context().bindingContext().getType(leftKtExpression), - expressionType); + JsExpression leftExpression = TranslationUtils.boxCastIfNeeded( + context(), Translation.translateAsExpression(leftKtExpression, context()), + context().bindingContext().getType(leftKtExpression), expressionType); JsBlock rightBlock = new JsBlock(); - JsExpression rightExpression = - TranslationUtils.boxCastIfNeeded(Translation.translateAsExpression(rightKtExpression, context(), rightBlock), - context().bindingContext().getType(rightKtExpression), - expressionType); + JsExpression rightExpression = TranslationUtils.boxCastIfNeeded( + context(),Translation.translateAsExpression(rightKtExpression, context(), rightBlock), + context().bindingContext().getType(rightKtExpression), expressionType); if (rightBlock.isEmpty()) { return TranslationUtils.notNullConditional(leftExpression, rightExpression, context()); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicAssignmentTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicAssignmentTranslator.java index fe59733ec0a..5c8c01eed08 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicAssignmentTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicAssignmentTranslator.java @@ -67,7 +67,7 @@ public final class IntrinsicAssignmentTranslator extends AssignmentTranslator { result = JsAstUtils.charToString(result); } else if (leftType == null || !KotlinBuiltIns.isCharOrNullableChar(leftType)) { - result = JsAstUtils.charToBoxedChar(result); + result = TranslationUtils.charToBoxedChar(context, result); } } return result; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt index 0c6668096c6..ff0a042213d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt @@ -106,7 +106,7 @@ class CallArgumentTranslator private constructor( if (hasSpreadOperator) { if (isNativeFunctionCall) { argsBeforeVararg = result - result = mutableListOf() + result = mutableListOf() concatArguments = prepareConcatArguments(arguments, translateResolvedArgument(actualArgument, argsToJsExpr), null) @@ -196,7 +196,7 @@ class CallArgumentTranslator private constructor( val argJs = Translation.translateAsExpression(parenthisedArgumentExpression, argumentContext) - arg to TranslationUtils.boxCastIfNeeded(argJs, argType, parameterType) + arg to TranslationUtils.boxCastIfNeeded(context, argJs, argType, parameterType) } val resolvedOrder = resolvedCall.valueArgumentsByIndex.orEmpty() @@ -229,7 +229,7 @@ class CallArgumentTranslator private constructor( val arguments = resolvedArgument.arguments if (arguments.isEmpty()) { return if (shouldWrapVarargInArray) { - return listOf(toArray(varargPrimitiveType, listOf())) + return listOf(toArray(varargPrimitiveType, listOf())) } else { listOf() @@ -266,14 +266,14 @@ class CallArgumentTranslator private constructor( var lastArrayContent = mutableListOf() val size = arguments.size - for (index in 0..size - 1) { + for (index in 0 until size) { val valueArgument = arguments[index] val expressionArgument = list[index] if (valueArgument.getSpreadElement() != null) { if (lastArrayContent.size > 0) { concatArguments.add(toArray(varargPrimitiveType, lastArrayContent)) - lastArrayContent = mutableListOf() + lastArrayContent = mutableListOf() } concatArguments.add(expressionArgument) } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java index 4d1176c71e7..56e2105a416 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java @@ -149,7 +149,7 @@ public final class FunctionBodyTranslator extends AbstractTranslator { KotlinType bodyType = context().bindingContext().getType(declaration.getBodyExpression()); if (bodyType == null && KotlinBuiltIns.isCharOrNullableChar(descriptor.getReturnType()) || bodyType != null && KotlinBuiltIns.isCharOrNullableChar(bodyType) && TranslationUtils.shouldBoxReturnValue(descriptor)) { - node = JsAstUtils.charToBoxedChar((JsExpression) node); + node = TranslationUtils.charToBoxedChar(context(), (JsExpression) node); } JsReturn jsReturn = new JsReturn((JsExpression) node); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java index ef5af84498a..3fe60f3ed13 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java @@ -157,34 +157,6 @@ public final class JsAstUtils { return new JsInvocation(new JsNameRef("fromCharCode", new JsNameRef("String")), expression); } - @NotNull - public static JsExpression charToBoxedChar(@NotNull JsExpression expression) { - JsInvocation invocation = invokeKotlinFunction("toBoxedChar", unnestBoxing(expression)); - invocation.setSource(expression.getSource()); - return withBoxingMetadata(invocation); - } - - @NotNull - public static JsExpression boxedCharToChar(@NotNull JsExpression expression) { - JsInvocation invocation = invokeKotlinFunction("unboxChar", unnestBoxing(expression)); - invocation.setSource(expression.getSource()); - return withBoxingMetadata(invocation); - } - - @NotNull - private static JsExpression unnestBoxing(@NotNull JsExpression expression) { - if (expression instanceof JsInvocation && MetadataProperties.getBoxing((JsInvocation) expression)) { - return ((JsInvocation) expression).getArguments().get(0); - } - return expression; - } - - @NotNull - private static JsInvocation withBoxingMetadata(@NotNull JsInvocation call) { - MetadataProperties.setBoxing(call, true); - return call; - } - @NotNull public static JsExpression toShort(@NotNull JsExpression expression) { return invokeKotlinFunction(OperatorConventions.SHORT.getIdentifier(), expression); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java index 11d069ffaa1..b5c224d02ab 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.js.backend.ast.*; +import org.jetbrains.kotlin.js.backend.ast.metadata.MetadataProperties; import org.jetbrains.kotlin.js.backend.ast.metadata.SpecialFunction; import org.jetbrains.kotlin.js.translate.context.Namer; import org.jetbrains.kotlin.js.translate.context.TemporaryConstVariable; @@ -52,6 +53,7 @@ import static org.jetbrains.kotlin.js.backend.ast.JsBinaryOperator.*; import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression; import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.assignment; import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.createDataDescriptor; +import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn; public final class TranslationUtils { @@ -206,7 +208,7 @@ public final class TranslationUtils { KotlinType propertyType = BindingContextUtils.getNotNull(context.bindingContext(), BindingContext.VARIABLE, declaration).getType(); KotlinType initType = context.bindingContext().getType(initializer); - jsInitExpression = boxCastIfNeeded(jsInitExpression, initType, propertyType); + jsInitExpression = boxCastIfNeeded(context, jsInitExpression, initType, propertyType); } return jsInitExpression; } @@ -408,15 +410,56 @@ public final class TranslationUtils { } @NotNull - public static JsExpression boxCastIfNeeded(@NotNull JsExpression e, @Nullable KotlinType castFrom, @Nullable KotlinType castTo) { + public static JsExpression boxCastIfNeeded( + @NotNull TranslationContext context, + @NotNull JsExpression e, + @Nullable KotlinType castFrom, @Nullable KotlinType castTo + ) { if (castFrom != null && KotlinBuiltIns.isCharOrNullableChar(castFrom) && castTo != null && !KotlinBuiltIns.isCharOrNullableChar(castTo) ) { - return JsAstUtils.charToBoxedChar(e); + return charToBoxedChar(context, e); } return e; } + @NotNull + public static JsExpression charToBoxedChar(@NotNull TranslationContext context, @NotNull JsExpression expression) { + JsInvocation invocation = invokeSpecialFunction(context, SpecialFunction.TO_BOXED_CHAR, unnestBoxing(expression)); + invocation.setSource(expression.getSource()); + return withBoxingMetadata(invocation); + } + + @NotNull + public static JsExpression boxedCharToChar(@NotNull TranslationContext context, @NotNull JsExpression expression) { + JsInvocation invocation = invokeSpecialFunction(context, SpecialFunction.UNBOX_CHAR, unnestBoxing(expression)); + invocation.setSource(expression.getSource()); + return withBoxingMetadata(invocation); + } + + @NotNull + private static JsExpression unnestBoxing(@NotNull JsExpression expression) { + if (expression instanceof JsInvocation && MetadataProperties.getBoxing((JsInvocation) expression)) { + return ((JsInvocation) expression).getArguments().get(0); + } + return expression; + } + + @NotNull + private static JsInvocation withBoxingMetadata(@NotNull JsInvocation call) { + MetadataProperties.setBoxing(call, true); + return call; + } + + @NotNull + private static JsInvocation invokeSpecialFunction( + @NotNull TranslationContext context, + @NotNull SpecialFunction function, @NotNull JsExpression... arguments + ) { + JsName name = context.getNameForSpecialFunction(function); + return new JsInvocation(pureFqn(name, null), arguments); + } + @NotNull public static String getTagForSpecialFunction(@NotNull SpecialFunction specialFunction) { return "special:" + specialFunction.name();