Overloading operations via extension functions.
Also inline useless TranslationUtils#zeroLiteral. Eliminate dead code.
This commit is contained in:
@@ -103,4 +103,20 @@ public final class OperatorOverloadingTest extends SingleFileTranslationTest {
|
||||
public void testOverloadPlusAssignArrayList() throws Exception {
|
||||
checkFooBoxIsOk("overloadPlusAssignArrayList.kt");
|
||||
}
|
||||
|
||||
public void testOverloadPlusAssignViaExtensionFunction() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testOverloadPlusViaExtensionFunction() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testOverloadPlusAssignViaPlusExtensionFunction() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
|
||||
public void testOverloadUnaryOperationsViaExtensionFunctions() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isCompareTo;
|
||||
@@ -69,6 +68,6 @@ public final class CompareToTranslator extends AbstractTranslator {
|
||||
private JsExpression translate() {
|
||||
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(getOperationToken(expression));
|
||||
JsExpression methodCall = BinaryOperationTranslator.translateAsOverloadedCall(expression, context());
|
||||
return new JsBinaryOperation(correspondingOperator, methodCall, TranslationUtils.zeroLiteral(context()));
|
||||
return new JsBinaryOperation(correspondingOperator, methodCall, context().program().getNumberLiteral(0));
|
||||
}
|
||||
}
|
||||
|
||||
+15
-12
@@ -17,14 +17,12 @@
|
||||
package org.jetbrains.k2js.translate.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMethodReferenceForOverloadedOperation;
|
||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -33,17 +31,20 @@ public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
|
||||
|
||||
@NotNull
|
||||
public static JsExpression doTranslate(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull TranslationContext context) {
|
||||
return (new OverloadedAssignmentTranslator(expression, context)).translate();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final JsNameRef operationReference;
|
||||
private final FunctionDescriptor operationDescriptor;
|
||||
|
||||
private OverloadedAssignmentTranslator(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull TranslationContext context) {
|
||||
super(expression, context);
|
||||
this.operationReference = getMethodReferenceForOverloadedOperation(context, expression);
|
||||
FunctionDescriptor functionDescriptor =
|
||||
BindingUtils.getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
assert functionDescriptor != null : "";
|
||||
this.operationDescriptor = functionDescriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -61,8 +62,10 @@ public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression overloadedMethodInvocation() {
|
||||
setQualifier(operationReference, accessTranslator.translateAsGet());
|
||||
return AstUtil.newInvocation(operationReference, right);
|
||||
return CallBuilder.build(context())
|
||||
.descriptor(operationDescriptor)
|
||||
.receiver(accessTranslator.translateAsGet())
|
||||
.args(right)
|
||||
.translate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-8
@@ -17,14 +17,13 @@
|
||||
package org.jetbrains.k2js.translate.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMethodReferenceForOverloadedOperation;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -32,20 +31,24 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMethodRefer
|
||||
public final class OverloadedIncrementTranslator extends IncrementTranslator {
|
||||
|
||||
@NotNull
|
||||
private final JsNameRef operationReference;
|
||||
private final FunctionDescriptor operationDescriptor;
|
||||
|
||||
/*package*/ OverloadedIncrementTranslator(@NotNull JetUnaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
super(expression, context);
|
||||
this.operationReference = getMethodReferenceForOverloadedOperation(context, expression);
|
||||
FunctionDescriptor functionDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
assert functionDescriptor != null : "Descriptor should not be null for overloaded increment expression.";
|
||||
this.operationDescriptor = functionDescriptor;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected JsExpression operationExpression(@NotNull JsExpression receiver) {
|
||||
setQualifier(operationReference, receiver);
|
||||
return AstUtil.newInvocation(operationReference);
|
||||
return CallBuilder.build(context())
|
||||
.receiver(receiver)
|
||||
.descriptor(operationDescriptor)
|
||||
.translate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -84,17 +84,6 @@ public final class TranslationUtils {
|
||||
return or(isNull, isUndefined);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation nullCheck(@NotNull TranslationContext context,
|
||||
@NotNull JsExpression expressionToCheck, boolean shouldBeNull) {
|
||||
if (shouldBeNull) {
|
||||
return isNullCheck(context, expressionToCheck);
|
||||
}
|
||||
else {
|
||||
return notNullCheck(context, expressionToCheck);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
|
||||
@NotNull List<? extends ValueArgument> jetArguments) {
|
||||
@@ -213,22 +202,6 @@ public final class TranslationUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsNameRef getMethodReferenceForOverloadedOperation(@NotNull TranslationContext context,
|
||||
@NotNull JetOperationExpression expression) {
|
||||
FunctionDescriptor overloadedOperationDescriptor = getFunctionDescriptorForOperationExpression
|
||||
(context.bindingContext(), expression);
|
||||
assert overloadedOperationDescriptor != null;
|
||||
JsNameRef overloadedOperationReference = context.getNameForDescriptor(overloadedOperationDescriptor).makeRef();
|
||||
assert overloadedOperationReference != null;
|
||||
return overloadedOperationReference;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsNumberLiteral zeroLiteral(@NotNull TranslationContext context) {
|
||||
return context.program().getNumberLiteral(0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JsExpression resolveThisObjectForResolvedCall(@NotNull ResolvedCall<?> call,
|
||||
@NotNull TranslationContext context) {
|
||||
@@ -240,10 +213,6 @@ public final class TranslationUtils {
|
||||
return getThisObject(context, expectedThisDescriptor);
|
||||
}
|
||||
|
||||
public static boolean isNullLiteral(@NotNull TranslationContext context, @NotNull JsExpression expression) {
|
||||
return expression.equals(context.program().getNullLiteral());
|
||||
}
|
||||
|
||||
public static void defineModule(@NotNull TranslationContext context, @NotNull List<JsStatement> statements,
|
||||
String moduleId) {
|
||||
statements.add(AstUtil.newInvocation(context.namer().kotlin("defineModule"),
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package foo
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun <T> ArrayList<T>.plusAssign(other: Collection<T>) {
|
||||
addAll(other)
|
||||
}
|
||||
|
||||
fun box(): Boolean {
|
||||
var v1 = ArrayList<String>()
|
||||
val v2 = ArrayList<String>()
|
||||
v1.add("foo")
|
||||
v2.add("bar")
|
||||
v1 += v2
|
||||
return (v1.size() == 2 && v1[0] == "foo" && v1[1] == "bar")
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package foo
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun <T> ArrayList<T>.plus(other: Collection<T>): List<T> {
|
||||
val c = ArrayList<T>()
|
||||
c.addAll(this)
|
||||
c.addAll(other)
|
||||
return c
|
||||
}
|
||||
|
||||
fun box(): Boolean {
|
||||
var v1 = ArrayList<String>()
|
||||
val v2 = ArrayList<String>()
|
||||
v1.add("foo")
|
||||
v2.add("bar")
|
||||
v1 += v2
|
||||
return (v1.size() == 2 && v1[0] == "foo" && v1[1] == "bar")
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package foo
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun <T> ArrayList<T>.plus(other: Collection<T>): List<T> {
|
||||
val c = ArrayList<T>()
|
||||
c.addAll(this)
|
||||
c.addAll(other)
|
||||
return c
|
||||
}
|
||||
|
||||
fun box(): Boolean {
|
||||
var v1 = ArrayList<String>()
|
||||
v1.add("foo")
|
||||
val v2 = ArrayList<String>()
|
||||
v2.add("bar")
|
||||
val v = v1 + v2
|
||||
|
||||
return (v.size() == 2 && v[0] == "foo" && v[1] == "bar")
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package foo
|
||||
|
||||
class A(val c: Int) {}
|
||||
|
||||
|
||||
fun A.inc() = A(5)
|
||||
fun A.dec() = A(10)
|
||||
|
||||
fun box(): Boolean {
|
||||
var a = A(1)
|
||||
return ((++a).c == 5 && (a++).c == 5 && (--a).c == 10 && (a--).c == 10)
|
||||
}
|
||||
Reference in New Issue
Block a user