work on intrinsic implementation: binary intrinsics

This commit is contained in:
Pavel Talanov
2011-11-30 22:49:38 +04:00
parent a46fd1143a
commit 5212ee4b00
7 changed files with 90 additions and 44 deletions
@@ -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<JetExpression> 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);
}
}
@@ -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<JetExpression> arguments,
public JsExpression apply(@NotNull JetExpression expression,
@NotNull TranslationContext context);
}
@@ -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<FunctionDescriptor, Intrinsic> descriptorToIntrinsicMap =
new HashMap<FunctionDescriptor, Intrinsic>();
private final Map<DeclarationDescriptor, Intrinsic> descriptorToIntrinsicMap =
new HashMap<DeclarationDescriptor, Intrinsic>();
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;
}
}
@@ -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<JsNode> {
@NotNull
public JsNode visitBinaryExpression(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
return BinaryOperationTranslator.translate(expression, context);
return OperationTranslator.translate(expression, context);
}
@Override
@@ -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);
}
@@ -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) {
@@ -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;