From 2d84d17555ca5f6ac9580a75278fc11233516b25 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Fri, 18 Nov 2011 19:47:46 +0400 Subject: [PATCH] Supported overloading plus operator. --- .../k2js/translate/BindingUtils.java | 9 ++++++- .../k2js/translate/ExpressionVisitor.java | 2 +- .../k2js/translate/OperationTranslator.java | 26 +++++++++++++++++++ .../translate/PropertyAccessTranslator.java | 3 +-- .../k2js/test/OperatorOverloadingTest.java | 21 +++++++++++++++ .../operatorOverloading/cases/plusOverload.kt | 12 +++++++++ 6 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java create mode 100644 translator/testFiles/operatorOverloading/cases/plusOverload.kt diff --git a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java index e75af9b0327..6859bd95209 100644 --- a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.types.JetType; import java.util.ArrayList; @@ -139,7 +140,7 @@ public final class BindingUtils { //TODO move unrelated utils to other class @Nullable - public static ClassDescriptor findAncestorClass(@NotNull List superclassDescriptors) { + static public ClassDescriptor findAncestorClass(@NotNull List superclassDescriptors) { for (ClassDescriptor descriptor : superclassDescriptors) { if (descriptor.getKind() == ClassKind.CLASS) { return descriptor; @@ -147,4 +148,10 @@ public final class BindingUtils { } return null; } + + @Nullable + static public ResolvedCall getResolvedCall(@NotNull BindingContext context, + @NotNull JetExpression expression) { + return (context.get(BindingContext.RESOLVED_CALL, expression)); + } } diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java index f74bfd8f81d..8ba794bbe0f 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java @@ -109,7 +109,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { private boolean isConstructorInvocation(@NotNull JetCallExpression expression, @NotNull TranslationContext context) { ResolvedCall resolvedCall = - (context.bindingContext().get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression())); + BindingUtils.getResolvedCall(context.bindingContext(), expression.getCalleeExpression()); if (resolvedCall == null) { return false; } diff --git a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java index b725ffbc856..e114768b72c 100644 --- a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java @@ -1,9 +1,11 @@ package org.jetbrains.k2js.translate; import com.google.dart.compiler.backend.js.ast.*; +import com.google.dart.compiler.util.AstUtil; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetToken; @@ -81,8 +83,14 @@ public final class OperationTranslator extends AbstractTranslator { @NotNull private JsExpression translateAsBinaryOperation(@NotNull JetBinaryExpression expression) { + JsExpression left = Translation.translateAsExpression(expression.getLeft(), translationContext()); JsExpression right = translateRightExpression(expression); + + JsNameRef operationReference = getOverloadedOperationReference(expression); + if (operationReference != null) { + return overloadedMethodInvocation(left, right, operationReference); + } JetToken token = getOperationToken(expression); if (OperatorTable.hasCorrespondingBinaryOperator(token)) { return new JsBinaryOperation(OperatorTable.getBinaryOperator(token), left, right); @@ -95,6 +103,24 @@ public final class OperationTranslator extends AbstractTranslator { throw new AssertionError("Unsupported token encountered: " + token.toString()); } + private JsExpression overloadedMethodInvocation(JsExpression left, JsExpression right, JsNameRef operationReference) { + operationReference.setQualifier(left); + return AstUtil.newInvocation(operationReference, right); + } + + @Nullable + private JsNameRef getOverloadedOperationReference(@NotNull JetBinaryExpression expression) { + DeclarationDescriptor operationDescriptor = BindingUtils.getDescriptorForReferenceExpression + (translationContext().bindingContext(), expression.getOperationReference()); + if (operationDescriptor == null) { + return null; + } + if (!translationContext().isDeclared(operationDescriptor)) { + return null; + } + return translationContext().getNameForDescriptor(operationDescriptor).makeRef(); + } + @NotNull private JsExpression translateRightExpression(@NotNull JetBinaryExpression expression) { JetExpression rightExpression = expression.getRight(); diff --git a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java index 048b2a11fc1..d2998abc05b 100644 --- a/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/PropertyAccessTranslator.java @@ -15,7 +15,6 @@ import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetQualifiedExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; -import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; /** @@ -123,7 +122,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator { @Nullable private PropertyDescriptor getPropertyDescriptor(@NotNull JetExpression expression) { ResolvedCall resolvedCall = - translationContext().bindingContext().get(BindingContext.RESOLVED_CALL, expression); + BindingUtils.getResolvedCall(translationContext().bindingContext(), expression); if (resolvedCall != null) { DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor(); if (descriptor instanceof PropertyDescriptor) { diff --git a/translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java b/translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java new file mode 100644 index 00000000000..37baf029cda --- /dev/null +++ b/translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java @@ -0,0 +1,21 @@ +package org.jetbrains.k2js.test; + +import org.junit.Test; + +/** + * @author Talanov Pavel + */ +public class OperatorOverloadingTest extends IncludeLibraryTest { + + final private static String MAIN = "operatorOverloading/"; + + @Override + protected String mainDirectory() { + return MAIN; + } + + @Test + public void plusOverload() throws Exception { + testFooBoxIsTrue("plusOverload.kt"); + } +} diff --git a/translator/testFiles/operatorOverloading/cases/plusOverload.kt b/translator/testFiles/operatorOverloading/cases/plusOverload.kt new file mode 100644 index 00000000000..3b7a0e718a1 --- /dev/null +++ b/translator/testFiles/operatorOverloading/cases/plusOverload.kt @@ -0,0 +1,12 @@ +namespace foo + + class myInt(a : Int) { + val value = a; + + fun plus(other : myInt) : myInt = myInt(value + other.value) + } + +fun box() : Boolean { + + return (myInt(3) + myInt(5)).value == 8 +} \ No newline at end of file