Supported overloading plus operator.
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user