Supported overloading plus operator.

This commit is contained in:
Pavel Talanov
2011-11-18 19:47:46 +04:00
parent db02cd168b
commit 2d84d17555
6 changed files with 69 additions and 4 deletions
@@ -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<ClassDescriptor> superclassDescriptors) {
static public ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> 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));
}
}
@@ -109,7 +109,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
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;
}
@@ -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();
@@ -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) {
@@ -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");
}
}
@@ -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
}