diff --git a/examplesForWebDemo/src/html5/floatingText/hello.js b/examplesForWebDemo/src/html5/floatingText/hello.js
index bb40ff1059c..79dfcec9f3e 100644
--- a/examplesForWebDemo/src/html5/floatingText/hello.js
+++ b/examplesForWebDemo/src/html5/floatingText/hello.js
@@ -5,7 +5,7 @@
this.$relY = 0.4 + 0.2 * Math.random();
this.$relXVelocity = this.randomVelocity();
this.$relYVelocity = this.randomVelocity();
- this.$message = 'Hello Kotlin';
+ this.$message = 'Hello, Kotlin!';
this.$textHeightInPixels = 60;
{
hello.get_context().font = 'bold ' + this.get_textHeightInPixels() + 'px Georgia, serif';
diff --git a/examplesForWebDemo/src/html5/floatingText/test.kt b/examplesForWebDemo/src/html5/floatingText/test.kt
index 06e9afb5229..e5bca3ea4d9 100644
--- a/examplesForWebDemo/src/html5/floatingText/test.kt
+++ b/examplesForWebDemo/src/html5/floatingText/test.kt
@@ -25,7 +25,7 @@ class HelloKotlin() {
var relYVelocity = randomVelocity()
- val message = "Hello Kotlin"
+ val message = "Hello, Kotlin!"
val textHeightInPixels = 60
{
context.font = "bold ${textHeightInPixels}px Georgia, serif"
diff --git a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
index b51d6bf5243..fc6c62c44a9 100644
--- a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
+++ b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
@@ -132,7 +132,7 @@ public final class ExpressionVisitor extends TranslatorVisitor {
@NotNull
public JsNode visitCallExpression(@NotNull JetCallExpression expression,
@NotNull TranslationContext context) {
- return CallTranslator.translate(expression, null, CallType.NORMAL, context);
+ return CallExpressionTranslator.translate(expression, null, CallType.NORMAL, context);
}
@Override
diff --git a/translator/src/org/jetbrains/k2js/translate/expression/ForTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/ForTranslator.java
index 6ea2cbe90b4..7d8522cadfd 100644
--- a/translator/src/org/jetbrains/k2js/translate/expression/ForTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/expression/ForTranslator.java
@@ -3,6 +3,7 @@ package org.jetbrains.k2js.translate.expression;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
@@ -12,8 +13,7 @@ import org.jetbrains.k2js.translate.context.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
-import org.jetbrains.k2js.translate.reference.CallTranslator;
-import org.jetbrains.k2js.translate.reference.CallType;
+import org.jetbrains.k2js.translate.reference.CallBuilder;
import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
@@ -67,13 +67,13 @@ public final class ForTranslator extends AbstractTranslator {
@NotNull
private JsExpression nextMethodInvocation(@NotNull TemporaryVariable iterator) {
FunctionDescriptor nextFunction = getNextFunction(context().bindingContext(), getLoopRange());
- return CallTranslator.translate(iterator.nameReference(), nextFunction, CallType.NORMAL, context());
+ return translateMethodInvocation(iterator.nameReference(), nextFunction);
}
@NotNull
private JsExpression hasNextMethodInvocation(@NotNull TemporaryVariable iterator) {
CallableDescriptor hasNextFunction = getHasNextCallable(context().bindingContext(), getLoopRange());
- return CallTranslator.translate(iterator.nameReference(), hasNextFunction, CallType.NORMAL, context());
+ return translateMethodInvocation(iterator.nameReference(), hasNextFunction);
}
@NotNull
@@ -81,7 +81,7 @@ public final class ForTranslator extends AbstractTranslator {
JetExpression rangeExpression = getLoopRange();
JsExpression range = Translation.translateAsExpression(rangeExpression, context());
FunctionDescriptor iteratorFunction = getIteratorFunction(context().bindingContext(), rangeExpression);
- return CallTranslator.translate(range, iteratorFunction, CallType.NORMAL, context());
+ return translateMethodInvocation(range, iteratorFunction);
}
@NotNull
@@ -90,4 +90,13 @@ public final class ForTranslator extends AbstractTranslator {
assert rangeExpression != null;
return rangeExpression;
}
+
+ @NotNull
+ private JsExpression translateMethodInvocation(@Nullable JsExpression receiver,
+ @NotNull CallableDescriptor descriptor) {
+ return CallBuilder.build(context())
+ .receiver(receiver)
+ .descriptor(descriptor)
+ .translate();
+ }
}
diff --git a/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java
index f1c3c98e315..21df9ae95b5 100644
--- a/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/operation/BinaryOperationTranslator.java
@@ -7,21 +7,25 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
+import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken;
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.reference.CallTranslator;
+import org.jetbrains.k2js.translate.reference.CallBuilder;
+import org.jetbrains.k2js.translate.reference.CallType;
import java.util.Arrays;
+import static com.google.dart.compiler.util.AstUtil.not;
import static org.jetbrains.k2js.translate.operation.AssignmentTranslator.isAssignmentOperator;
import static org.jetbrains.k2js.translate.operation.CompareToTranslator.isCompareToCall;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
+import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isEquals;
-import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
+import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
@@ -37,6 +41,12 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
return (new BinaryOperationTranslator(expression, context).translate());
}
+ @NotNull
+ /*package*/ static JsExpression translateAsOverloadedCall(@NotNull JetBinaryExpression expression,
+ @NotNull TranslationContext context) {
+ return (new BinaryOperationTranslator(expression, context)).translateAsOverloadedBinaryOperation();
+ }
+
@NotNull
private final JetBinaryExpression expression;
@@ -67,7 +77,7 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
if (isEquals(operationDescriptor)) {
return translateAsEqualsCall();
}
- return CallTranslator.translate(expression, context());
+ return translateAsOverloadedBinaryOperation();
}
private boolean isNotOverloadable() {
@@ -94,4 +104,38 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
return new JsBinaryOperation(operator, left, right);
}
+
+ @NotNull
+ private JsExpression translateAsOverloadedBinaryOperation() {
+ CallBuilder callBuilder = setReceiverAndArguments();
+ ResolvedCall> resolvedCall1 =
+ getResolvedCall(context().bindingContext(), expression.getOperationReference());
+ JsExpression result = callBuilder.resolvedCall(resolvedCall1)
+ .type(CallType.NORMAL).translate();
+ return mayBeWrapWithNegation(result);
+ }
+
+ @NotNull
+ private CallBuilder setReceiverAndArguments() {
+ CallBuilder callBuilder = CallBuilder.build(context());
+
+ JsExpression leftExpression = translateLeftExpression(context(), expression);
+ JsExpression rightExpression = translateRightExpression(context(), expression);
+
+ if (isInOrNotInOperation(expression)) {
+ return callBuilder.receiver(rightExpression).args(leftExpression);
+ } else {
+ return callBuilder.receiver(leftExpression).args(rightExpression);
+ }
+ }
+
+ @NotNull
+ private JsExpression mayBeWrapWithNegation(@NotNull JsExpression result) {
+ if (isNotInOperation(expression)) {
+ return not(result);
+ } else {
+ return result;
+ }
+ }
+
}
diff --git a/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
index 60773d42b3d..c9a40343684 100644
--- a/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
@@ -11,7 +11,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.reference.CallTranslator;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.Arrays;
@@ -70,7 +69,7 @@ public final class CompareToTranslator extends AbstractTranslator {
@NotNull
private JsExpression overloadedCompareTo() {
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(getOperationToken(expression));
- JsExpression methodCall = CallTranslator.translate(expression, context());
+ JsExpression methodCall = BinaryOperationTranslator.translateAsOverloadedCall(expression, context());
return new JsBinaryOperation(correspondingOperator, methodCall, TranslationUtils.zeroLiteral(context()));
}
diff --git a/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java
index 02d888a79e7..51fdf4eb571 100644
--- a/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java
@@ -4,7 +4,13 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
-import org.jetbrains.k2js.translate.reference.CallTranslator;
+import org.jetbrains.k2js.translate.reference.CallBuilder;
+import org.jetbrains.k2js.translate.reference.CallType;
+import org.jetbrains.k2js.translate.utils.TranslationUtils;
+
+import java.util.Collections;
+
+import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
/**
* @author Pavel Talanov
@@ -18,6 +24,16 @@ public final class UnaryOperationTranslator {
if (IncrementTranslator.isIncrement(expression)) {
return IncrementTranslator.translate(expression, context);
}
- return CallTranslator.translate(expression, context);
+ return translateAsCall(expression, context);
+ }
+
+ @NotNull
+ private static JsExpression translateAsCall(@NotNull JetUnaryExpression expression,
+ @NotNull TranslationContext context) {
+ return CallBuilder.build(context)
+ .receiver(TranslationUtils.translateBaseExpression(context, expression))
+ .args(Collections.emptyList())
+ .resolvedCall(getResolvedCall(context.bindingContext(), expression.getOperationReference()))
+ .type(CallType.NORMAL).translate();
}
}
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallBuilder.java b/translator/src/org/jetbrains/k2js/translate/reference/CallBuilder.java
new file mode 100644
index 00000000000..03b2d2c0d16
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/reference/CallBuilder.java
@@ -0,0 +1,192 @@
+package org.jetbrains.k2js.translate.reference;
+
+import com.google.common.collect.Lists;
+import com.google.dart.compiler.backend.js.ast.JsExpression;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
+import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
+import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
+import org.jetbrains.k2js.translate.context.TranslationContext;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Pavel Talanov
+ */
+public final class CallBuilder {
+
+ public static CallBuilder build(@NotNull TranslationContext context) {
+ return new CallBuilder(context);
+ }
+
+ @NotNull
+ private final TranslationContext context;
+ @Nullable
+ private /*var*/ JsExpression receiver = null;
+ @NotNull
+ private final List args = Lists.newArrayList();
+ @NotNull
+ private /*var*/ CallType callType = CallType.NORMAL;
+ @Nullable
+ private /*var*/ ResolvedCall> resolvedCall = null;
+ @Nullable
+ private /*var*/ CallableDescriptor descriptor = null;
+ @Nullable
+ private /*var*/ JsExpression callee = null;
+
+
+ private CallBuilder(@NotNull TranslationContext context) {
+ this.context = context;
+ }
+
+ @NotNull
+ public CallBuilder receiver(@Nullable JsExpression receiver) {
+ this.receiver = receiver;
+ return this;
+ }
+
+ @NotNull
+ public CallBuilder args(@NotNull List args) {
+ assert this.args.isEmpty();
+ this.args.addAll(args);
+ return this;
+ }
+
+ @NotNull
+ public CallBuilder args(@NotNull JsExpression... args) {
+ return args(Arrays.asList(args));
+ }
+
+ @NotNull
+ public CallBuilder descriptor(@NotNull CallableDescriptor descriptor) {
+ this.descriptor = descriptor;
+ return this;
+ }
+
+ @NotNull
+ public CallBuilder callee(@Nullable JsExpression callee) {
+ this.callee = callee;
+ return this;
+ }
+
+ @NotNull
+ public CallBuilder resolvedCall(@NotNull ResolvedCall> call) {
+ this.resolvedCall = call;
+ return this;
+ }
+
+ @NotNull
+ public CallBuilder type(@NotNull CallType type) {
+ this.callType = type;
+ return this;
+ }
+
+ //TODO: must be private
+ @NotNull
+ public CallTranslator finish() {
+ if (resolvedCall == null) {
+ assert descriptor != null;
+ resolvedCall = ResolvedCallImpl.create(descriptor);
+ }
+ if (descriptor == null) {
+ descriptor = resolvedCall.getCandidateDescriptor().getOriginal();
+ }
+ assert resolvedCall != null;
+ return new CallTranslator(receiver, callee, args, resolvedCall, descriptor, callType, context);
+ }
+
+ @NotNull
+ public JsExpression translate() {
+ return finish().translate();
+ }
+ /*
+ @NotNull
+ private CallTranslator buildFromUnary(@NotNull JetUnaryExpression unaryExpression) {
+ JsExpression receiver = TranslationUtils.translateBaseExpression(context, unaryExpression);
+ List arguments = Collections.emptyList();
+ ResolvedCall> resolvedCall =
+ getResolvedCall(context.bindingContext(), unaryExpression.getOperationReference());
+ return new CallTranslator(receiver, null, arguments, resolvedCall, null, CallType.NORMAL, context);
+ }
+
+ //TODO: method too long
+ @NotNull
+ private CallTranslator buildFromBinary(@NotNull JetBinaryExpression binaryExpression,
+ boolean swapReceiverAndArgument) {
+
+ JsExpression leftExpression = translateLeftExpression(context, binaryExpression);
+ JsExpression rightExpression = translateRightExpression(context, binaryExpression);
+
+ JsExpression receiver;
+ List arguments;
+ if (swapReceiverAndArgument) {
+ receiver = rightExpression;
+ arguments = Arrays.asList(leftExpression);
+ } else {
+ receiver = leftExpression;
+ arguments = Arrays.asList(rightExpression);
+ }
+
+ ResolvedCall> resolvedCall =
+ getResolvedCall(context.bindingContext(), binaryExpression.getOperationReference());
+ return new CallTranslator(receiver, null, arguments, resolvedCall, null, CallType.NORMAL, context);
+ }
+
+ @NotNull
+ private CallTranslator buildFromCallExpression(@NotNull JetCallExpression callExpression,
+ @Nullable JsExpression receiver,
+ @NotNull CallType callType) {
+ ResolvedCall> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
+ List arguments = translateArgumentsForCallExpression(callExpression, context);
+ JsExpression callee = null;
+ if (resolvedCall.getCandidateDescriptor() instanceof ExpressionAsFunctionDescriptor) {
+ callee = Translation.translateAsExpression(getCallee(callExpression), context);
+ }
+ return new CallTranslator(receiver, callee, arguments, resolvedCall, null, callType, context);
+ }
+
+ @NotNull
+ private List translateArgumentsForCallExpression(@NotNull JetCallExpression callExpression,
+ @NotNull TranslationContext context) {
+ List result = new ArrayList();
+ ResolvedCall> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
+ Map formalToActualArguments = resolvedCall.getValueArguments();
+ for (ValueParameterDescriptor parameterDescriptor : resolvedCall.getResultingDescriptor().getValueParameters()) {
+ ResolvedValueArgument actualArgument = formalToActualArguments.get(parameterDescriptor);
+ result.add(translateSingleArgument(actualArgument, parameterDescriptor));
+ }
+ return result;
+ }
+
+
+ //TODO: refactor
+ @NotNull
+ private JsExpression translateSingleArgument(@NotNull ResolvedValueArgument actualArgument,
+ @NotNull ValueParameterDescriptor parameterDescriptor) {
+ List argumentExpressions = actualArgument.getArgumentExpressions();
+ if (actualArgument instanceof VarargValueArgument) {
+ return translateVarargArgument(argumentExpressions);
+ }
+ if (actualArgument instanceof DefaultValueArgument) {
+ JetExpression defaultArgument = getDefaultArgument(context.bindingContext(), parameterDescriptor);
+ return Translation.translateAsExpression(defaultArgument, context);
+ }
+ assert actualArgument instanceof ExpressionValueArgument;
+ assert argumentExpressions.size() == 1;
+ return Translation.translateAsExpression(argumentExpressions.get(0), context);
+ }
+
+ @NotNull
+ private JsExpression translateVarargArgument(@NotNull List arguments) {
+ JsArrayLiteral varargArgument = new JsArrayLiteral();
+ for (JetExpression argument : arguments) {
+ varargArgument.getExpressions().add(Translation.translateAsExpression(argument, context));
+ }
+ return varargArgument;
+ }
+ */
+
+
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java
new file mode 100644
index 00000000000..428382b0b21
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java
@@ -0,0 +1,102 @@
+package org.jetbrains.k2js.translate.reference;
+
+import com.google.dart.compiler.backend.js.ast.JsArrayLiteral;
+import com.google.dart.compiler.backend.js.ast.JsExpression;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
+import org.jetbrains.jet.lang.psi.JetCallExpression;
+import org.jetbrains.jet.lang.psi.JetExpression;
+import org.jetbrains.jet.lang.resolve.calls.*;
+import org.jetbrains.k2js.translate.context.TranslationContext;
+import org.jetbrains.k2js.translate.general.AbstractTranslator;
+import org.jetbrains.k2js.translate.general.Translation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static org.jetbrains.k2js.translate.utils.BindingUtils.getDefaultArgument;
+import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCallForCallExpression;
+import static org.jetbrains.k2js.translate.utils.PsiUtils.getCallee;
+
+/**
+ * @author Pavel Talanov
+ */
+public final class CallExpressionTranslator extends AbstractTranslator {
+
+ @NotNull
+ public static JsExpression translate(@NotNull JetCallExpression expression,
+ @Nullable JsExpression receiver,
+ @NotNull CallType callType,
+ @NotNull TranslationContext context) {
+ return (new CallExpressionTranslator(expression, context)).translate(receiver, callType);
+ }
+
+ @NotNull
+ private final JetCallExpression expression;
+
+ private CallExpressionTranslator(@NotNull JetCallExpression expression,
+ @NotNull TranslationContext context) {
+ super(context);
+ this.expression = expression;
+ }
+
+ @NotNull
+ private JsExpression translate(@Nullable JsExpression receiver,
+ @NotNull CallType callType) {
+ ResolvedCall> resolvedCall = getResolvedCallForCallExpression(context().bindingContext(), expression);
+ return CallBuilder.build(context())
+ .receiver(receiver)
+ .callee(getCalleeExpression(resolvedCall))
+ .args(translateArguments())
+ .resolvedCall(resolvedCall)
+ .type(callType)
+ .translate();
+ }
+
+ @Nullable
+ private JsExpression getCalleeExpression(@NotNull ResolvedCall> resolvedCall) {
+ if (resolvedCall.getCandidateDescriptor() instanceof ExpressionAsFunctionDescriptor) {
+ return Translation.translateAsExpression(getCallee(expression), context());
+ }
+ return null;
+ }
+
+ @NotNull
+ private List translateArguments() {
+ List result = new ArrayList();
+ ResolvedCall> resolvedCall = getResolvedCallForCallExpression(context().bindingContext(), expression);
+ Map formalToActualArguments = resolvedCall.getValueArguments();
+ for (ValueParameterDescriptor parameterDescriptor : resolvedCall.getResultingDescriptor().getValueParameters()) {
+ ResolvedValueArgument actualArgument = formalToActualArguments.get(parameterDescriptor);
+ result.add(translateSingleArgument(actualArgument, parameterDescriptor));
+ }
+ return result;
+ }
+
+ @NotNull
+ private JsExpression translateSingleArgument(@NotNull ResolvedValueArgument actualArgument,
+ @NotNull ValueParameterDescriptor parameterDescriptor) {
+ List argumentExpressions = actualArgument.getArgumentExpressions();
+ if (actualArgument instanceof VarargValueArgument) {
+ return translateVarargArgument(argumentExpressions);
+ }
+ if (actualArgument instanceof DefaultValueArgument) {
+ JetExpression defaultArgument = getDefaultArgument(context().bindingContext(), parameterDescriptor);
+ return Translation.translateAsExpression(defaultArgument, context());
+ }
+ assert actualArgument instanceof ExpressionValueArgument;
+ assert argumentExpressions.size() == 1;
+ return Translation.translateAsExpression(argumentExpressions.get(0), context());
+ }
+
+ @NotNull
+ private JsExpression translateVarargArgument(@NotNull List arguments) {
+ JsArrayLiteral varargArgument = new JsArrayLiteral();
+ for (JetExpression argument : arguments) {
+ varargArgument.getExpressions().add(Translation.translateAsExpression(argument, context()));
+ }
+ return varargArgument;
+ }
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
index 07bdc8f8b66..fe2e2f9f9c5 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
@@ -1,35 +1,32 @@
package org.jetbrains.k2js.translate.reference;
-import com.google.dart.compiler.backend.js.ast.*;
+import com.google.dart.compiler.backend.js.ast.JsExpression;
+import com.google.dart.compiler.backend.js.ast.JsInvocation;
+import com.google.dart.compiler.backend.js.ast.JsNameRef;
+import com.google.dart.compiler.backend.js.ast.JsNew;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
-import org.jetbrains.jet.lang.psi.JetBinaryExpression;
-import org.jetbrains.jet.lang.psi.JetCallExpression;
-import org.jetbrains.jet.lang.psi.JetExpression;
-import org.jetbrains.jet.lang.psi.JetUnaryExpression;
-import org.jetbrains.jet.lang.resolve.calls.*;
+import org.jetbrains.jet.lang.resolve.calls.ExpressionAsFunctionDescriptor;
+import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
-import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
-import static com.google.dart.compiler.util.AstUtil.not;
-import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
-import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
-import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
+import static org.jetbrains.k2js.translate.utils.TranslationUtils.getThisObject;
/**
* @author Pavel Talanov
*/
//TODO: write tests on calling backing fields as functions
-//TODO: constructor receives too many parameters
//TODO: reorder methods properly
public final class CallTranslator extends AbstractTranslator {
@@ -46,110 +43,6 @@ public final class CallTranslator extends AbstractTranslator {
public /*var*/ JsExpression functionReference;
}
- private static final class Builder {
-
- @NotNull
- private final TranslationContext context;
-
- private Builder(@NotNull TranslationContext context) {
- this.context = context;
- }
-
- @NotNull
- private CallTranslator buildFromUnary(@NotNull JetUnaryExpression unaryExpression) {
- JsExpression receiver = TranslationUtils.translateBaseExpression(context, unaryExpression);
- List arguments = Collections.emptyList();
- ResolvedCall> resolvedCall =
- getResolvedCall(context.bindingContext(), unaryExpression.getOperationReference());
- return new CallTranslator(receiver, null, arguments, resolvedCall, null, CallType.NORMAL, context);
- }
-
- //TODO: method too long
- @NotNull
- private CallTranslator buildFromBinary(@NotNull JetBinaryExpression binaryExpression,
- boolean swapReceiverAndArgument) {
-
- JsExpression leftExpression = translateLeftExpression(context, binaryExpression);
- JsExpression rightExpression = translateRightExpression(context, binaryExpression);
-
- JsExpression receiver;
- List arguments;
- if (swapReceiverAndArgument) {
- receiver = rightExpression;
- arguments = Arrays.asList(leftExpression);
- } else {
- receiver = leftExpression;
- arguments = Arrays.asList(rightExpression);
- }
-
- ResolvedCall> resolvedCall =
- getResolvedCall(context.bindingContext(), binaryExpression.getOperationReference());
- return new CallTranslator(receiver, null, arguments, resolvedCall, null, CallType.NORMAL, context);
- }
-
- @NotNull
- private CallTranslator buildFromCallExpression(@NotNull JetCallExpression callExpression,
- @Nullable JsExpression receiver,
- @NotNull CallType callType) {
- ResolvedCall> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
- List arguments = translateArgumentsForCallExpression(callExpression, context);
- JsExpression callee = null;
- if (resolvedCall.getCandidateDescriptor() instanceof ExpressionAsFunctionDescriptor) {
- callee = Translation.translateAsExpression(getCallee(callExpression), context);
- }
- return new CallTranslator(receiver, callee, arguments, resolvedCall, null, callType, context);
- }
-
- @NotNull
- private List translateArgumentsForCallExpression(@NotNull JetCallExpression callExpression,
- @NotNull TranslationContext context) {
- List result = new ArrayList();
- ResolvedCall> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
- Map formalToActualArguments = resolvedCall.getValueArguments();
- for (ValueParameterDescriptor parameterDescriptor : resolvedCall.getResultingDescriptor().getValueParameters()) {
- ResolvedValueArgument actualArgument = formalToActualArguments.get(parameterDescriptor);
- result.add(translateSingleArgument(actualArgument, parameterDescriptor));
- }
- return result;
- }
-
-
- //TODO: refactor
- @NotNull
- private JsExpression translateSingleArgument(@NotNull ResolvedValueArgument actualArgument,
- @NotNull ValueParameterDescriptor parameterDescriptor) {
- List argumentExpressions = actualArgument.getArgumentExpressions();
- if (actualArgument instanceof VarargValueArgument) {
- return translateVarargArgument(argumentExpressions);
- }
- if (actualArgument instanceof DefaultValueArgument) {
- JetExpression defaultArgument = getDefaultArgument(context.bindingContext(), parameterDescriptor);
- return Translation.translateAsExpression(defaultArgument, context);
- }
- assert actualArgument instanceof ExpressionValueArgument;
- assert argumentExpressions.size() == 1;
- return Translation.translateAsExpression(argumentExpressions.get(0), context);
- }
-
- @NotNull
- private JsExpression translateVarargArgument(@NotNull List arguments) {
- JsArrayLiteral varargArgument = new JsArrayLiteral();
- for (JetExpression argument : arguments) {
- varargArgument.getExpressions().add(Translation.translateAsExpression(argument, context));
- }
- return varargArgument;
- }
- }
-
- @NotNull
- public static JsExpression translate(@Nullable JsExpression receiver,
- @NotNull CallableDescriptor descriptor,
- @NotNull CallType callType,
- @NotNull TranslationContext context) {
- return translate(receiver, Collections.emptyList(),
- ResolvedCallImpl.create(descriptor), null, callType, context);
- }
-
@NotNull
public static JsExpression translate(@Nullable JsExpression receiver,
@NotNull ResolvedCall> resolvedCall,
@@ -169,41 +62,6 @@ public final class CallTranslator extends AbstractTranslator {
return (new CallTranslator(receiver, null, arguments, resolvedCall, descriptorToCall, callType, context)).translate();
}
- @NotNull
- public static JsExpression translate(@NotNull JetUnaryExpression unaryExpression,
- @NotNull TranslationContext context) {
- return (new Builder(context).buildFromUnary(unaryExpression)).translate();
- }
-
- @NotNull
- public static JsExpression translate(@NotNull JetCallExpression callExpression,
- @Nullable JsExpression receiver,
- @NotNull CallType callType,
- @NotNull TranslationContext context) {
- return (new Builder(context).buildFromCallExpression(callExpression, receiver, callType)).translate();
- }
-
- @NotNull
- public static JsExpression translate(@NotNull JetBinaryExpression binaryExpression,
- @NotNull TranslationContext context) {
- boolean shouldSwapReceiverAndArgument = isInOrNotInOperation(binaryExpression);
- JsExpression result = (new Builder(context))
- .buildFromBinary(binaryExpression, shouldSwapReceiverAndArgument).translate();
- if (isInOrNotInOperation(binaryExpression)) {
- return mayBeWrapWithNegation(result, isNotInOperation(binaryExpression));
- }
- return result;
- }
-
- @NotNull
- private static JsExpression mayBeWrapWithNegation(@NotNull JsExpression expression, boolean shouldWrap) {
- if (shouldWrap) {
- return not(expression);
- } else {
- return expression;
- }
- }
-
@Nullable
private /*var*/ JsExpression receiver;
@@ -222,27 +80,23 @@ public final class CallTranslator extends AbstractTranslator {
@NotNull
private final CallType callType;
- private CallTranslator(@Nullable JsExpression receiver, @Nullable JsExpression callee,
- @NotNull List arguments,
- @NotNull ResolvedCall extends CallableDescriptor> resolvedCall,
- @Nullable CallableDescriptor descriptorToCall,
- @NotNull CallType callType,
- @NotNull TranslationContext context) {
+ /*package*/ CallTranslator(@Nullable JsExpression receiver, @Nullable JsExpression callee,
+ @NotNull List arguments,
+ @NotNull ResolvedCall extends CallableDescriptor> resolvedCall,
+ @NotNull CallableDescriptor descriptorToCall,
+ @NotNull CallType callType,
+ @NotNull TranslationContext context) {
super(context);
this.receiver = receiver;
this.arguments = arguments;
this.resolvedCall = resolvedCall;
this.callType = callType;
- if (descriptorToCall != null) {
- this.descriptor = descriptorToCall;
- } else {
- this.descriptor = resolvedCall.getCandidateDescriptor().getOriginal();
- }
+ this.descriptor = descriptorToCall;
this.callee = callee;
}
@NotNull
- private JsExpression translate() {
+ /*package*/ JsExpression translate() {
if (isIntrinsic()) {
return intrinsicInvocation();
}
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java
index 38b577b126b..ae2f3e6d351 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/QualifiedExpressionTranslator.java
@@ -52,7 +52,7 @@ public final class QualifiedExpressionTranslator {
((JetSimpleNameExpression) selector, receiver, callType, context);
}
if (selector instanceof JetCallExpression) {
- return CallTranslator.translate((JetCallExpression) selector, receiver, callType, context);
+ return CallExpressionTranslator.translate((JetCallExpression) selector, receiver, callType, context);
}
throw new AssertionError("Unexpected qualified expression");
}