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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -139,7 +140,7 @@ public final class BindingUtils {
|
|||||||
|
|
||||||
//TODO move unrelated utils to other class
|
//TODO move unrelated utils to other class
|
||||||
@Nullable
|
@Nullable
|
||||||
public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
static public ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||||
for (ClassDescriptor descriptor : superclassDescriptors) {
|
for (ClassDescriptor descriptor : superclassDescriptors) {
|
||||||
if (descriptor.getKind() == ClassKind.CLASS) {
|
if (descriptor.getKind() == ClassKind.CLASS) {
|
||||||
return descriptor;
|
return descriptor;
|
||||||
@@ -147,4 +148,10 @@ public final class BindingUtils {
|
|||||||
}
|
}
|
||||||
return null;
|
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,
|
private boolean isConstructorInvocation(@NotNull JetCallExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
ResolvedCall<?> resolvedCall =
|
ResolvedCall<?> resolvedCall =
|
||||||
(context.bindingContext().get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()));
|
BindingUtils.getResolvedCall(context.bindingContext(), expression.getCalleeExpression());
|
||||||
if (resolvedCall == null) {
|
if (resolvedCall == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package org.jetbrains.k2js.translate;
|
package org.jetbrains.k2js.translate;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lexer.JetToken;
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
|
|
||||||
@@ -81,8 +83,14 @@ public final class OperationTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression translateAsBinaryOperation(@NotNull JetBinaryExpression expression) {
|
private JsExpression translateAsBinaryOperation(@NotNull JetBinaryExpression expression) {
|
||||||
|
|
||||||
JsExpression left = Translation.translateAsExpression(expression.getLeft(), translationContext());
|
JsExpression left = Translation.translateAsExpression(expression.getLeft(), translationContext());
|
||||||
JsExpression right = translateRightExpression(expression);
|
JsExpression right = translateRightExpression(expression);
|
||||||
|
|
||||||
|
JsNameRef operationReference = getOverloadedOperationReference(expression);
|
||||||
|
if (operationReference != null) {
|
||||||
|
return overloadedMethodInvocation(left, right, operationReference);
|
||||||
|
}
|
||||||
JetToken token = getOperationToken(expression);
|
JetToken token = getOperationToken(expression);
|
||||||
if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
|
if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
|
||||||
return new JsBinaryOperation(OperatorTable.getBinaryOperator(token), left, right);
|
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());
|
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
|
@NotNull
|
||||||
private JsExpression translateRightExpression(@NotNull JetBinaryExpression expression) {
|
private JsExpression translateRightExpression(@NotNull JetBinaryExpression expression) {
|
||||||
JetExpression rightExpression = expression.getRight();
|
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.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,7 +122,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private PropertyDescriptor getPropertyDescriptor(@NotNull JetExpression expression) {
|
private PropertyDescriptor getPropertyDescriptor(@NotNull JetExpression expression) {
|
||||||
ResolvedCall<?> resolvedCall =
|
ResolvedCall<?> resolvedCall =
|
||||||
translationContext().bindingContext().get(BindingContext.RESOLVED_CALL, expression);
|
BindingUtils.getResolvedCall(translationContext().bindingContext(), expression);
|
||||||
if (resolvedCall != null) {
|
if (resolvedCall != null) {
|
||||||
DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor();
|
DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor();
|
||||||
if (descriptor instanceof PropertyDescriptor) {
|
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