Convert BinaryOperationIntrinsic to Java @FunctionInterface

Also some minor renamings and visibility changes
This commit is contained in:
Anton Bannykh
2018-03-21 12:55:17 +03:00
parent 3a7518cad2
commit e1233beddc
7 changed files with 33 additions and 16 deletions
@@ -0,0 +1,22 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.translate.intrinsic.operation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.psi.KtBinaryExpression;
@FunctionalInterface
public interface BinaryOperationIntrinsic {
@NotNull
JsExpression invoke(
@NotNull KtBinaryExpression expression,
@NotNull JsExpression left,
@NotNull JsExpression right,
@NotNull TranslationContext context
);
}
@@ -35,7 +35,7 @@ object CompareToBOIF : BinaryOperationIntrinsicFactory {
pattern("Int|Short|Byte|Float|Double.compareTo(Long)") to binaryIntrinsic(toRight = { r, _ -> longToNumber(r) }), pattern("Int|Short|Byte|Float|Double.compareTo(Long)") to binaryIntrinsic(toRight = { r, _ -> longToNumber(r) }),
pattern("Long.compareTo(Int|Short|Byte|Float|Double)") to binaryIntrinsic(toLeft = { l, _ -> longToNumber(l) }), pattern("Long.compareTo(Int|Short|Byte|Float|Double)") to binaryIntrinsic(toLeft = { l, _ -> longToNumber(l) }),
// L.compareTo(R) OP 0 // L.compareTo(R) OP 0
pattern("Long.compareTo(Long)") to intrinsic({ l, r, _ -> compareForObject(l, r) }, { _, _, _-> JsIntLiteral(0) }) pattern("Long.compareTo(Long)") to complexBinaryIntrinsic({ l, r, _ -> compareForObject(l, r) }, { _, _, _-> JsIntLiteral(0) })
) )
override fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic? { override fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic? {
@@ -50,7 +50,7 @@ object CompareToBOIF : BinaryOperationIntrinsicFactory {
binaryIntrinsic(coerceTo(leftType), coerceTo(rightType)) binaryIntrinsic(coerceTo(leftType), coerceTo(rightType))
} else { } else {
// Kotlin.compareTo(L, R) OP 0 // Kotlin.compareTo(L, R) OP 0
intrinsic({ l, r, _ -> compareTo(l, r) }, { _, _, _ -> JsIntLiteral(0) }) complexBinaryIntrinsic({ l, r, _ -> compareTo(l, r) }, { _, _, _ -> JsIntLiteral(0) })
} }
} }
} }
@@ -36,12 +36,12 @@ import org.jetbrains.kotlin.types.isDynamic
object EqualsBOIF : BinaryOperationIntrinsicFactory { object EqualsBOIF : BinaryOperationIntrinsicFactory {
override fun getSupportTokens() = OperatorConventions.EQUALS_OPERATIONS!! override fun getSupportTokens() = OperatorConventions.EQUALS_OPERATIONS!!
private val equalsNullIntrinsic: BinaryOperationIntrinsic = { expression, left, right, context -> private val equalsNullIntrinsic = BinaryOperationIntrinsic { expression, left, right, context ->
val (subject, ktSubject) = if (right is JsNullLiteral) Pair(left, expression.left!!) else Pair(right, expression.right!!) val (subject, ktSubject) = if (right is JsNullLiteral) Pair(left, expression.left!!) else Pair(right, expression.right!!)
TranslationUtils.nullCheck(ktSubject, subject, context, isNegatedOperation(expression)) TranslationUtils.nullCheck(ktSubject, subject, context, isNegatedOperation(expression))
} }
private val kotlinEqualsIntrinsic: BinaryOperationIntrinsic = { expression, left, right, context -> private val kotlinEqualsIntrinsic = BinaryOperationIntrinsic { expression, left, right, context ->
val coercedLeft = TranslationUtils.coerce(context, left, context.currentModule.builtIns.anyType) val coercedLeft = TranslationUtils.coerce(context, left, context.currentModule.builtIns.anyType)
val coercedRight = TranslationUtils.coerce(context, right, context.currentModule.builtIns.anyType) val coercedRight = TranslationUtils.coerce(context, right, context.currentModule.builtIns.anyType)
val result = TopLevelFIF.KOTLIN_EQUALS.apply(coercedLeft, listOf(coercedRight), context) val result = TopLevelFIF.KOTLIN_EQUALS.apply(coercedLeft, listOf(coercedRight), context)
@@ -103,7 +103,7 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
isEnumEqualsIntrinsicApplicable(descriptor, leftType, rightType) -> refEqIntrinsic isEnumEqualsIntrinsicApplicable(descriptor, leftType, rightType) -> refEqIntrinsic
KotlinBuiltIns.isBuiltIn(descriptor) || TopLevelFIF.EQUALS_IN_ANY.test(descriptor) -> { expression, left, right, context -> KotlinBuiltIns.isBuiltIn(descriptor) || TopLevelFIF.EQUALS_IN_ANY.test(descriptor) -> BinaryOperationIntrinsic { expression, left, right, context ->
when { when {
left is JsNullLiteral || right is JsNullLiteral -> equalsNullIntrinsic left is JsNullLiteral || right is JsNullLiteral -> equalsNullIntrinsic
leftType.primitive && rightType.primitive -> primitiveTypes(leftType, rightType) leftType.primitive && rightType.primitive -> primitiveTypes(leftType, rightType)
@@ -32,9 +32,6 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
typealias BinaryOperationIntrinsic
= (expression: KtBinaryExpression, left: JsExpression, right: JsExpression, context: TranslationContext) -> JsExpression
class BinaryOperationIntrinsics { class BinaryOperationIntrinsics {
private data class IntrinsicKey( private data class IntrinsicKey(
@@ -95,11 +92,11 @@ typealias OperatorSelector = (KtBinaryExpression) -> JsBinaryOperator
val defaultOperatorSelector: OperatorSelector = { OperatorTable.getBinaryOperator(getOperationToken(it)) } val defaultOperatorSelector: OperatorSelector = { OperatorTable.getBinaryOperator(getOperationToken(it)) }
// toLeft(L, R) OP toRight(L, R) // toLeft(L, R) OP toRight(L, R)
fun intrinsic( fun complexBinaryIntrinsic(
toLeft: (JsExpression, JsExpression, TranslationContext) -> JsExpression, toLeft: (JsExpression, JsExpression, TranslationContext) -> JsExpression,
toRight: (JsExpression, JsExpression, TranslationContext) -> JsExpression, toRight: (JsExpression, JsExpression, TranslationContext) -> JsExpression,
operator: (KtBinaryExpression) -> JsBinaryOperator = defaultOperatorSelector operator: (KtBinaryExpression) -> JsBinaryOperator = defaultOperatorSelector
): BinaryOperationIntrinsic = { expression, left, right, context -> ) = BinaryOperationIntrinsic { expression, left, right, context ->
JsBinaryOperation(operator(expression), toLeft(left, right, context), toRight(left, right, context)) JsBinaryOperation(operator(expression), toLeft(left, right, context), toRight(left, right, context))
} }
@@ -108,7 +105,7 @@ fun binaryIntrinsic(
toLeft: (JsExpression, TranslationContext) -> JsExpression = { l, _ -> l }, toLeft: (JsExpression, TranslationContext) -> JsExpression = { l, _ -> l },
toRight: (JsExpression, TranslationContext) -> JsExpression = { r, _ -> r }, toRight: (JsExpression, TranslationContext) -> JsExpression = { r, _ -> r },
operator: OperatorSelector = defaultOperatorSelector operator: OperatorSelector = defaultOperatorSelector
): BinaryOperationIntrinsic = intrinsic({ l, _, c -> toLeft(l, c) }, { _, r, c -> toRight(r, c) }, operator) ) = complexBinaryIntrinsic({ l, _, c -> toLeft(l, c) }, { _, r, c -> toRight(r, c) }, operator)
fun coerceTo(type: KotlinType): (JsExpression, TranslationContext) -> JsExpression = fun coerceTo(type: KotlinType): (JsExpression, TranslationContext) -> JsExpression =
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.js.translate.operation; package org.jetbrains.kotlin.js.translate.operation;
import kotlin.jvm.functions.Function4;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.CallableDescriptor;
@@ -28,6 +27,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator; import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.general.Translation; import org.jetbrains.kotlin.js.translate.general.Translation;
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF; import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF;
import org.jetbrains.kotlin.js.translate.intrinsic.operation.BinaryOperationIntrinsic;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils; import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
import org.jetbrains.kotlin.lexer.KtToken; import org.jetbrains.kotlin.lexer.KtToken;
@@ -160,7 +160,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
@Nullable @Nullable
private JsExpression tryApplyIntrinsic() { private JsExpression tryApplyIntrinsic() {
Function4<KtBinaryExpression, JsExpression, JsExpression, TranslationContext, JsExpression> intrinsic = BinaryOperationIntrinsic intrinsic =
context().intrinsics().getBinaryOperationIntrinsic(expression, context()); context().intrinsics().getBinaryOperationIntrinsic(expression, context());
if (intrinsic == null) return null; if (intrinsic == null) return null;
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions;
import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.isAssignment; import static org.jetbrains.kotlin.js.translate.utils.PsiUtils.isAssignment;
import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.coerce;
import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.isSimpleNameExpressionNotDelegatedLocalVar; import static org.jetbrains.kotlin.js.translate.utils.TranslationUtils.isSimpleNameExpressionNotDelegatedLocalVar;
public final class IntrinsicAssignmentTranslator extends AssignmentTranslator { public final class IntrinsicAssignmentTranslator extends AssignmentTranslator {
@@ -63,7 +62,6 @@ public final class IntrinsicAssignmentTranslator extends AssignmentTranslator {
JsExpression result = TranslationUtils.translateRightExpression(context, expression, rightBlock); JsExpression result = TranslationUtils.translateRightExpression(context, expression, rightBlock);
KotlinType leftType = context.bindingContext().getType(expression.getLeft()); KotlinType leftType = context.bindingContext().getType(expression.getLeft());
KotlinType rightType = context.bindingContext().getType(expression.getRight()); KotlinType rightType = context.bindingContext().getType(expression.getRight());
if (rightType != null && KotlinBuiltIns.isCharOrNullableChar(rightType)) { if (rightType != null && KotlinBuiltIns.isCharOrNullableChar(rightType)) {
if (leftType != null && KotlinBuiltIns.isStringOrNullableString(leftType)) { if (leftType != null && KotlinBuiltIns.isStringOrNullableString(leftType)) {
result = JsAstUtils.charToString(result); result = JsAstUtils.charToString(result);
@@ -526,7 +526,7 @@ public final class TranslationUtils {
} }
@NotNull @NotNull
public static JsExpression voidToUnit(@NotNull TranslationContext context, @NotNull JsExpression expression) { private static JsExpression voidToUnit(@NotNull TranslationContext context, @NotNull JsExpression expression) {
ClassDescriptor unit = context.getCurrentModule().getBuiltIns().getUnit(); ClassDescriptor unit = context.getCurrentModule().getBuiltIns().getUnit();
JsExpression unitRef = ReferenceTranslator.translateAsValueReference(unit, context); JsExpression unitRef = ReferenceTranslator.translateAsValueReference(unit, context);
return JsAstUtils.newSequence(Arrays.asList(expression, unitRef)); return JsAstUtils.newSequence(Arrays.asList(expression, unitRef));