From 5212ee4b008f4d45e96d5765455551eb087682a1 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Wed, 30 Nov 2011 22:49:38 +0400 Subject: [PATCH] work on intrinsic implementation: binary intrinsics --- .../intrinsic/BinaryOperationIntrinsic.java | 36 +++++++++++-------- .../jetbrains/k2js/intrinsic/Intrinsic.java | 4 +-- .../jetbrains/k2js/intrinsic/Intrinsics.java | 35 ++++++++++-------- .../expression/ExpressionVisitor.java | 4 +-- .../IntrinsicBinaryOperationTranslator.java | 11 ++++-- .../operation/OperationTranslator.java | 33 ++++++++++++++--- .../OverloadedBinaryOperationTranslator.java | 11 ++++-- 7 files changed, 90 insertions(+), 44 deletions(-) diff --git a/translator/src/org/jetbrains/k2js/intrinsic/BinaryOperationIntrinsic.java b/translator/src/org/jetbrains/k2js/intrinsic/BinaryOperationIntrinsic.java index 86e9a915319..d3a5947a94b 100644 --- a/translator/src/org/jetbrains/k2js/intrinsic/BinaryOperationIntrinsic.java +++ b/translator/src/org/jetbrains/k2js/intrinsic/BinaryOperationIntrinsic.java @@ -1,19 +1,27 @@ package org.jetbrains.k2js.intrinsic; +import com.google.dart.compiler.backend.js.ast.JsExpression; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetBinaryExpression; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.k2js.translate.general.TranslationContext; +import org.jetbrains.k2js.translate.operation.IntrinsicBinaryOperationTranslator; + /** * @author Talanov Pavel */ -//public final class BinaryOperationIntrinsic implements Intrinsic { -// -// @NotNull -// private final JsBinaryOperator operator; -// -// /*package*/ BinaryOperationIntrinsic() {} -// -// @NotNull -// @Override -// public JsExpression apply(@NotNull JetExpression receiver, @NotNull List arguments, -// @NotNull TranslationContext context) { -// //return BinaryOperationTranslator.translate() -// } -//} +public enum BinaryOperationIntrinsic implements Intrinsic { + + INSTANCE; + + /*package*/ BinaryOperationIntrinsic() { + } + + @NotNull + @Override + public JsExpression apply(@NotNull JetExpression expression, + @NotNull TranslationContext context) { + assert expression instanceof JetBinaryExpression : "This intrinsic must be applied to binary operations."; + return IntrinsicBinaryOperationTranslator.translate((JetBinaryExpression) expression, context); + } +} diff --git a/translator/src/org/jetbrains/k2js/intrinsic/Intrinsic.java b/translator/src/org/jetbrains/k2js/intrinsic/Intrinsic.java index f76f5023253..e8164019356 100644 --- a/translator/src/org/jetbrains/k2js/intrinsic/Intrinsic.java +++ b/translator/src/org/jetbrains/k2js/intrinsic/Intrinsic.java @@ -5,15 +5,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.k2js.translate.general.TranslationContext; -import java.util.List; - /** * @author Talanov Pavel */ public interface Intrinsic { @NotNull - public JsExpression apply(@NotNull JetExpression receiver, @NotNull List arguments, + public JsExpression apply(@NotNull JetExpression expression, @NotNull TranslationContext context); } diff --git a/translator/src/org/jetbrains/k2js/intrinsic/Intrinsics.java b/translator/src/org/jetbrains/k2js/intrinsic/Intrinsics.java index 984537904d9..1f419ef4d5f 100644 --- a/translator/src/org/jetbrains/k2js/intrinsic/Intrinsics.java +++ b/translator/src/org/jetbrains/k2js/intrinsic/Intrinsics.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.types.JetStandardLibrary; +import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import java.util.HashMap; import java.util.Map; @@ -14,8 +15,8 @@ import java.util.Map; public final class Intrinsics { @NotNull - private final Map descriptorToIntrinsicMap = - new HashMap(); + private final Map descriptorToIntrinsicMap = + new HashMap(); public static Intrinsics standardLibraryIntrinsics(@NotNull JetStandardLibrary library) { return new Intrinsics(library); @@ -28,13 +29,13 @@ public final class Intrinsics { } } - /*package*/ void declareIntrinsic(@NotNull FunctionDescriptor descriptor) { + /*package*/ void declareIntrinsic(@NotNull DeclarationDescriptor descriptor) { //TODO: this is a hack -// addBinaryIntrinsics(descriptor); + descriptorToIntrinsicMap.put(descriptor, null); + addBinaryIntrinsics(descriptor); // addUnaryIntrinsics(descriptor); // addAssignmentIntrinsics(descriptor); // addEqualsIntrinsics(descriptor); - descriptorToIntrinsicMap.put(descriptor, null); } // private void addEqualsIntrinsics(FunctionDescriptor descriptor) { @@ -53,16 +54,14 @@ public final class Intrinsics { // } // } // -// private void addBinaryIntrinsics(@NotNull FunctionDescriptor descriptor) { -// String functionName = descriptor.getName(); -// if (OperatorConventions.BINARY_OPERATION_NAMES.containsValue(functionName)) { -// JetToken token = OperatorConventions.getTokenForMethodName(functionName); -//// BinaryOperationIntrinsic binaryOperationIntrinsic = -//// new BinaryOperationIntrinsic(OperatorTable.getBinaryOperator(token)); -//// descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic); -// } -// } -// + private void addBinaryIntrinsics(@NotNull DeclarationDescriptor descriptor) { + String functionName = descriptor.getName(); + if (OperatorConventions.BINARY_OPERATION_NAMES.containsValue(functionName)) { + descriptorToIntrinsicMap.put(descriptor, BinaryOperationIntrinsic.INSTANCE); + } + } + + // // private void addAssignmentIntrinsics(@NotNull FunctionDescriptor descriptor) { // String functionName = descriptor.getName(); // if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsValue(functionName)) { @@ -78,4 +77,10 @@ public final class Intrinsics { } return false; } + + public Intrinsic getIntrinsic(@NotNull DeclarationDescriptor descriptor) { + Intrinsic intrinsic = descriptorToIntrinsicMap.get(descriptor); +// assert intrinsic != null; + return intrinsic; + } } diff --git a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java index af065100aae..77f4219f188 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java @@ -11,7 +11,7 @@ import org.jetbrains.jet.lang.resolve.constants.NullValue; import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.general.TranslationContext; import org.jetbrains.k2js.translate.general.TranslatorVisitor; -import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator; +import org.jetbrains.k2js.translate.operation.OperationTranslator; import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator; import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator; import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator; @@ -94,7 +94,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull public JsNode visitBinaryExpression(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) { - return BinaryOperationTranslator.translate(expression, context); + return OperationTranslator.translate(expression, context); } @Override diff --git a/translator/src/org/jetbrains/k2js/translate/operation/IntrinsicBinaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/IntrinsicBinaryOperationTranslator.java index dcd6b1caab9..a759347cd7a 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/IntrinsicBinaryOperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/IntrinsicBinaryOperationTranslator.java @@ -12,8 +12,15 @@ import org.jetbrains.k2js.translate.general.TranslationContext; */ public final class IntrinsicBinaryOperationTranslator extends BinaryOperationTranslator { - protected IntrinsicBinaryOperationTranslator(@NotNull JetBinaryExpression expression, - @NotNull TranslationContext context) { + + @NotNull + public static JsExpression translate(@NotNull JetBinaryExpression expression, + @NotNull TranslationContext context) { + return (new IntrinsicBinaryOperationTranslator(expression, context)).translate(); + } + + private IntrinsicBinaryOperationTranslator(@NotNull JetBinaryExpression expression, + @NotNull TranslationContext context) { super(expression, context); } diff --git a/translator/src/org/jetbrains/k2js/translate/operation/OperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/OperationTranslator.java index f8c477f81f5..06a86a7834d 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/OperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/OperationTranslator.java @@ -10,6 +10,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.k2js.intrinsic.Intrinsic; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.TranslationContext; import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator; @@ -25,18 +26,40 @@ public class OperationTranslator extends AbstractTranslator { @NotNull static public JsExpression translate(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) { - //TODO: move to translation + JsExpression result = tryToApplyIntrinsic(expression, context); + if (result != null) return result; + if (ArrayAccessTranslator.canBeArraySetterCall(expression)) { return ArrayAccessTranslator.translateAsArraySetterCall(expression, context); } + return translateAsBinary(expression, context); + } - BinaryOperationTranslator translator; + @NotNull + private static JsExpression translateAsBinary(@NotNull JetBinaryExpression expression, + @NotNull TranslationContext context) { if (TranslationUtils.isIntrinsicOperation(context, expression.getOperationReference())) { - translator = new IntrinsicBinaryOperationTranslator(expression, context); + return IntrinsicBinaryOperationTranslator.translate(expression, context); } else { - translator = new OverloadedBinaryOperationTranslator(expression, context); + return OverloadedBinaryOperationTranslator.translate(expression, context); } - return translator.translate(); + } + + @Nullable + private static JsExpression tryToApplyIntrinsic(@NotNull JetBinaryExpression expression, + @NotNull TranslationContext context) { + DeclarationDescriptor descriptor = BindingUtils.getDescriptorForReferenceExpression + (context.bindingContext(), expression.getOperationReference()); + if (descriptor == null) { + return null; + } + if (!context.intrinsics().hasDescriptor(descriptor)) { + return null; + } + //TODO: should be no nulls here + Intrinsic intrinsic = context.intrinsics().getIntrinsic(descriptor); + if (intrinsic == null) return null; + return intrinsic.apply(expression, context); } protected OperationTranslator(@NotNull TranslationContext context) { diff --git a/translator/src/org/jetbrains/k2js/translate/operation/OverloadedBinaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/OverloadedBinaryOperationTranslator.java index 862c71fa944..951018f9583 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/OverloadedBinaryOperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/OverloadedBinaryOperationTranslator.java @@ -13,12 +13,17 @@ import org.jetbrains.k2js.translate.general.TranslationContext; */ public final class OverloadedBinaryOperationTranslator extends BinaryOperationTranslator { + @NotNull + public static JsExpression translate(@NotNull JetBinaryExpression expression, + @NotNull TranslationContext context) { + return (new OverloadedBinaryOperationTranslator(expression, context)).translate(); + } + @NotNull private final JsNameRef operationReference; - - protected OverloadedBinaryOperationTranslator(@NotNull JetBinaryExpression expression, - @NotNull TranslationContext context) { + private OverloadedBinaryOperationTranslator(@NotNull JetBinaryExpression expression, + @NotNull TranslationContext context) { super(expression, context); JsNameRef overloadedOperationReference = getOverloadedOperationReference(expression.getOperationReference()); assert overloadedOperationReference != null;