diff --git a/.idea/workspace.xml b/.idea/workspace.xml index a717a31f30b..07c4a12e6cc 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -8,24 +8,21 @@ - - - + - - + + + + + - - - + + - - - @@ -110,19 +107,6 @@ - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - + + + + + + + + + + + + @@ -282,7 +214,66 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -292,15 +283,6 @@ - - - - - - - - - @@ -337,7 +319,7 @@ - + @@ -382,6 +364,15 @@ + + + + + + + + + @@ -403,22 +394,22 @@ @@ -639,6 +630,72 @@ - + @@ -1059,13 +1116,13 @@ - + - - + + @@ -1109,7 +1166,7 @@ @@ -1156,120 +1213,129 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/BinaryOperationIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/BinaryOperationIntrinsic.java index a552032247e..483acdd6d30 100644 --- a/translator/src/org/jetbrains/k2js/translate/intrinsic/BinaryOperationIntrinsic.java +++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/BinaryOperationIntrinsic.java @@ -13,7 +13,7 @@ import java.util.List; /** * @author Talanov Pavel */ -public class BinaryOperationIntrinsic implements Intrinsic { +public class BinaryOperationIntrinsic extends FunctionIntrinsic { @NotNull /*package*/ static BinaryOperationIntrinsic newInstance(@NotNull JetToken token) { diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java new file mode 100644 index 00000000000..9380edbd67b --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java @@ -0,0 +1,8 @@ +package org.jetbrains.k2js.translate.intrinsic; + +/** + * @author Talanov Pavel + */ +public abstract class FunctionIntrinsic implements Intrinsic { + +} diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsic.java index 7dbe85cb0c9..8fff51f930c 100644 --- a/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsic.java +++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsic.java @@ -12,7 +12,6 @@ import java.util.List; public interface Intrinsic { @NotNull - public JsExpression apply(@NotNull JsExpression receiver, @NotNull List arguments, - @NotNull TranslationContext context); - + JsExpression apply(@NotNull JsExpression receiver, @NotNull List arguments, + @NotNull TranslationContext context); } diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java index d51c548c85a..08195efa500 100644 --- a/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java @@ -30,7 +30,7 @@ public final class IntrinsicDeclarationVisitor extends DeclarationDescriptorVisi @Override public Void visitFunctionDescriptor(@NotNull FunctionDescriptor descriptor, @Nullable Void nothing) { - if (!intrinsics.hasDescriptor(descriptor)) { + if (!intrinsics.isIntrinsic(descriptor)) { intrinsics.declareIntrinsic(descriptor); } return null; diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java index a3b1f7b1cc0..1e003035f5a 100644 --- a/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java +++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java @@ -19,8 +19,17 @@ import java.util.Map; public final class Intrinsics { @NotNull - private final Map descriptorToIntrinsicMap = - new HashMap(); + private final Map functionIntrinsics = + new HashMap(); + + @NotNull + private final Map equalsIntrinsics = + new HashMap(); + + + @NotNull + private final Map compareToIntrinsics = + new HashMap(); public static Intrinsics standardLibraryIntrinsics(@NotNull JetStandardLibrary library) { return new Intrinsics(library); @@ -38,54 +47,65 @@ public final class Intrinsics { addEqualsIntrinsics(descriptor); addUnaryIntrinsics(descriptor); addBinaryIntrinsics(descriptor); - } private void addCompareToIntrinsics(@NotNull FunctionDescriptor descriptor) { String functionName = descriptor.getName(); if (functionName.equals("compareTo")) { - descriptorToIntrinsicMap.put(descriptor, PrimitiveCompareToIntrinsic.newInstance()); + compareToIntrinsics.put(descriptor, PrimitiveCompareToIntrinsic.newInstance()); } } private void addEqualsIntrinsics(@NotNull FunctionDescriptor descriptor) { String functionName = descriptor.getName(); if (functionName.equals("equals")) { - descriptorToIntrinsicMap.put(descriptor, PrimitiveEqualsIntrinsic.newInstance()); + equalsIntrinsics.put(descriptor, PrimitiveEqualsIntrinsic.newInstance()); } } private void addUnaryIntrinsics(@NotNull FunctionDescriptor descriptor) { String functionName = descriptor.getName(); JetToken token = OperatorConventions.UNARY_OPERATION_NAMES.inverse().get(functionName); + if (token == null) return; boolean isUnary = !DescriptorUtils.hasParameters(descriptor); - if (isUnary && (token != null)) { - descriptorToIntrinsicMap.put(descriptor, UnaryOperationIntrinsic.newInstance(token)); - } + if (!isUnary) return; + functionIntrinsics.put(descriptor, UnaryOperationIntrinsic.newInstance(token)); } private void addBinaryIntrinsics(@NotNull FunctionDescriptor descriptor) { String functionName = descriptor.getName(); boolean isUnary = !DescriptorUtils.hasParameters(descriptor); + if (isUnary) return; JetToken token = OperatorConventions.BINARY_OPERATION_NAMES.inverse().get(functionName); - if (token != null && OperatorTable.hasCorrespondingBinaryOperator(token) && (!isUnary)) { - descriptorToIntrinsicMap.put(descriptor, BinaryOperationIntrinsic.newInstance(token)); - } + if (token == null) return; + //TODO: implement range and contains intrinsic + if (!OperatorTable.hasCorrespondingBinaryOperator(token)) return; + functionIntrinsics.put(descriptor, BinaryOperationIntrinsic.newInstance(token)); } - public boolean hasDescriptor(@NotNull DeclarationDescriptor descriptor) { + public boolean isIntrinsic(@NotNull DeclarationDescriptor descriptor) { + //NOTE: that if we want to add other intrinsics we have to modify this method if (descriptor instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor.getOriginal(); - return (descriptorToIntrinsicMap.get(functionDescriptor) != null); + return (equalsIntrinsics.containsKey(functionDescriptor) || + compareToIntrinsics.containsKey(functionDescriptor) || + functionIntrinsics.containsKey(functionDescriptor)); } return false; } + @NotNull + public FunctionIntrinsic getFunctionIntrinsic(@NotNull FunctionDescriptor descriptor) { + return functionIntrinsics.get(descriptor); + } @NotNull - public Intrinsic getIntrinsic(@NotNull DeclarationDescriptor descriptor) { - assert descriptor instanceof FunctionDescriptor; - Intrinsic intrinsic = descriptorToIntrinsicMap.get(descriptor); - return intrinsic; + public CompareToIntrinsic getCompareToIntrinsic(@NotNull FunctionDescriptor descriptor) { + return compareToIntrinsics.get(descriptor); + } + + @NotNull + public EqualsIntrinsic getEqualsIntrinsic(@NotNull FunctionDescriptor descriptor) { + return equalsIntrinsics.get(descriptor); } } diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/UnaryOperationIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/UnaryOperationIntrinsic.java index fd092c00873..ea73ee38794 100644 --- a/translator/src/org/jetbrains/k2js/translate/intrinsic/UnaryOperationIntrinsic.java +++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/UnaryOperationIntrinsic.java @@ -13,7 +13,7 @@ import java.util.List; /** * @author Talanov Pavel */ -public class UnaryOperationIntrinsic implements Intrinsic { +public class UnaryOperationIntrinsic extends FunctionIntrinsic { @NotNull /*package*/ static UnaryOperationIntrinsic newInstance(@NotNull JetToken token) { diff --git a/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java index 99e51614f8a..a33d8cb7a8f 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java @@ -13,7 +13,6 @@ import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic; -import org.jetbrains.k2js.translate.intrinsic.Intrinsic; import org.jetbrains.k2js.translate.reference.CallTranslator; import java.util.Arrays; @@ -70,9 +69,8 @@ public final class BinaryOperationTranslator extends AbstractTranslator { @NotNull private JsExpression translateAsEqualsCall() { assert operationDescriptor != null : "Equals operation must resolve to descriptor."; - Intrinsic intrinsic = context().intrinsics().getIntrinsic(operationDescriptor); - //TODO - ((EqualsIntrinsic) intrinsic).setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ)); + EqualsIntrinsic intrinsic = context().intrinsics().getEqualsIntrinsic(operationDescriptor); + intrinsic.setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ)); JsExpression left = translateLeftExpression(context(), expression); JsExpression right = translateRightExpression(context(), expression); return intrinsic.apply(left, Arrays.asList(right), context()); diff --git a/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java index b01f9d5ba5f..f82e7bd885c 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java @@ -12,7 +12,6 @@ import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic; -import org.jetbrains.k2js.translate.intrinsic.Intrinsic; import org.jetbrains.k2js.translate.reference.CallTranslator; import java.util.Arrays; @@ -82,8 +81,8 @@ public final class CompareToTranslator extends AbstractTranslator { @NotNull private JsExpression intrinsicCompareTo() { - Intrinsic intrinsic = context().intrinsics().getIntrinsic(descriptor); - ((CompareToIntrinsic) intrinsic).setComparisonToken((JetToken) expression.getOperationToken()); + CompareToIntrinsic intrinsic = context().intrinsics().getCompareToIntrinsic(descriptor); + intrinsic.setComparisonToken((JetToken) expression.getOperationToken()); JsExpression left = translateLeftExpression(context(), expression); JsExpression right = translateRightExpression(context(), expression); return intrinsic.apply(left, Arrays.asList(right), context()); diff --git a/translator/src/org/jetbrains/k2js/translate/operation/OperatorTable.java b/translator/src/org/jetbrains/k2js/translate/operation/OperatorTable.java index af4d2d3835e..ad5bf083298 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/OperatorTable.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/OperatorTable.java @@ -25,7 +25,7 @@ public final class OperatorTable { unaryOperatorsMap.put(JetTokens.PLUS, JsUnaryOperator.POS); //+ } - //TODO : not all operators + //TODO : not all operators , add and test bit operators static { binaryOperatorsMap.put(JetTokens.PLUS, JsBinaryOperator.ADD); binaryOperatorsMap.put(JetTokens.MINUS, JsBinaryOperator.SUB); diff --git a/translator/src/org/jetbrains/k2js/translate/operation/OverloadedAssignmentTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/OverloadedAssignmentTranslator.java index 5344f9ae3a5..0a9eae420cb 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/OverloadedAssignmentTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/OverloadedAssignmentTranslator.java @@ -4,11 +4,10 @@ import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsNameRef; import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.k2js.translate.context.TranslationContext; -import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; +import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMethodReferenceForOverloadedOperation; /** * @author Talanov Pavel @@ -27,13 +26,7 @@ public final class OverloadedAssignmentTranslator extends AssignmentTranslator { private OverloadedAssignmentTranslator(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) { super(expression, context); - //TODO: util - DeclarationDescriptor overloadedOperationDescriptor = getDescriptorForReferenceExpression - (context.bindingContext(), expression.getOperation()); - assert overloadedOperationDescriptor != null; - JsNameRef overloadedOperationReference = context().getNameForDescriptor(overloadedOperationDescriptor).makeRef(); - assert overloadedOperationReference != null; - this.operationReference = overloadedOperationReference; + this.operationReference = getMethodReferenceForOverloadedOperation(context, expression); } @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/operation/OverloadedIncrementTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/OverloadedIncrementTranslator.java index 9cbd5893327..dd4de34b907 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/OverloadedIncrementTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/OverloadedIncrementTranslator.java @@ -4,10 +4,10 @@ import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsNameRef; import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetUnaryExpression; import org.jetbrains.k2js.translate.context.TranslationContext; -import org.jetbrains.k2js.translate.utils.BindingUtils; + +import static org.jetbrains.k2js.translate.utils.TranslationUtils.getMethodReferenceForOverloadedOperation; /** * @author Talanov Pavel @@ -28,13 +28,7 @@ public final class OverloadedIncrementTranslator extends IncrementTranslator { private OverloadedIncrementTranslator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) { super(expression, context); - //TODO: DUBLICATE CODE - DeclarationDescriptor overloadedOperationDescriptor = BindingUtils.getDescriptorForReferenceExpression - (context.bindingContext(), expression.getOperation()); - assert overloadedOperationDescriptor != null; - JsNameRef overloadedOperationReference = context().getNameForDescriptor(overloadedOperationDescriptor).makeRef(); - assert overloadedOperationReference != null; - this.operationReference = overloadedOperationReference; + this.operationReference = getMethodReferenceForOverloadedOperation(context, expression); } @Override diff --git a/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java index f95bc8a4470..1c3fefca3c5 100644 --- a/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java @@ -10,7 +10,6 @@ import org.jetbrains.k2js.translate.reference.CallTranslator; * @author Talanov Pavel */ -//TODO: merge with binary operation public final class UnaryOperationTranslator { @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index 5b1f4085962..d9654503ba7 100644 --- a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -12,7 +12,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; -import org.jetbrains.k2js.translate.intrinsic.Intrinsic; +import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic; import org.jetbrains.k2js.translate.utils.TranslationUtils; import java.util.Arrays; @@ -99,10 +99,10 @@ public final class CallTranslator extends AbstractTranslator { @NotNull private JsExpression translate() { - if (context().intrinsics().hasDescriptor(descriptor)) { - Intrinsic intrinsic = context().intrinsics().getIntrinsic(descriptor); - assert receiver != null : "Functions that have intrinsic implementation should have a receiver."; - return intrinsic.apply(receiver, arguments, context()); + if (context().intrinsics().isIntrinsic(descriptor)) { + FunctionIntrinsic functionIntrinsic = context().intrinsics().getFunctionIntrinsic(descriptor); + assert receiver != null : "Functions that have functionIntrinsic implementation should have a receiver."; + return functionIntrinsic.apply(receiver, arguments, context()); } if (isConstructorDescriptor(descriptor)) { return constructorCall(); diff --git a/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index 357a4b276ff..ab6010c5125 100644 --- a/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -15,6 +15,8 @@ import org.jetbrains.k2js.translate.general.Translation; import java.util.ArrayList; import java.util.List; +import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; + /** * @author Talanov Pavel */ @@ -202,8 +204,20 @@ public final class TranslationUtils { BindingUtils.getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); if (operationDescriptor == null) return true; - if (context.intrinsics().hasDescriptor(operationDescriptor)) return true; + if (context.intrinsics().isIntrinsic(operationDescriptor)) return true; return false; } + + @NotNull + public static JsNameRef getMethodReferenceForOverloadedOperation(@NotNull TranslationContext context, + @NotNull JetOperationExpression expression) { + FunctionDescriptor overloadedOperationDescriptor = getFunctionDescriptorForOperationExpression + (context.bindingContext(), expression); + assert overloadedOperationDescriptor != null; + JsNameRef overloadedOperationReference = context.getNameForDescriptor(overloadedOperationDescriptor).makeRef(); + assert overloadedOperationReference != null; + return overloadedOperationReference; + } + }