refactoring CallTranslator:
introduce CallBuilder remove CallTranslator.Builder introduce CallExpressionTranslator
This commit is contained in:
@@ -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';
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -132,7 +132,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+47
-3
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
|
||||
+18
-2
@@ -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.<JsExpression>emptyList())
|
||||
.resolvedCall(getResolvedCall(context.bindingContext(), expression.getOperationReference()))
|
||||
.type(CallType.NORMAL).translate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<JsExpression> 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<JsExpression> 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<JsExpression> 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<JsExpression> 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<JsExpression> 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<JsExpression> translateArgumentsForCallExpression(@NotNull JetCallExpression callExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
List<JsExpression> result = new ArrayList<JsExpression>();
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
|
||||
Map<ValueParameterDescriptor, ResolvedValueArgument> 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<JetExpression> 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<JetExpression> arguments) {
|
||||
JsArrayLiteral varargArgument = new JsArrayLiteral();
|
||||
for (JetExpression argument : arguments) {
|
||||
varargArgument.getExpressions().add(Translation.translateAsExpression(argument, context));
|
||||
}
|
||||
return varargArgument;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@@ -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<JsExpression> translateArguments() {
|
||||
List<JsExpression> result = new ArrayList<JsExpression>();
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallForCallExpression(context().bindingContext(), expression);
|
||||
Map<ValueParameterDescriptor, ResolvedValueArgument> 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<JetExpression> 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<JetExpression> arguments) {
|
||||
JsArrayLiteral varargArgument = new JsArrayLiteral();
|
||||
for (JetExpression argument : arguments) {
|
||||
varargArgument.getExpressions().add(Translation.translateAsExpression(argument, context()));
|
||||
}
|
||||
return varargArgument;
|
||||
}
|
||||
}
|
||||
@@ -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<JsExpression> 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<JsExpression> 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<JsExpression> 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<JsExpression> translateArgumentsForCallExpression(@NotNull JetCallExpression callExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
List<JsExpression> result = new ArrayList<JsExpression>();
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallForCallExpression(context.bindingContext(), callExpression);
|
||||
Map<ValueParameterDescriptor, ResolvedValueArgument> 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<JetExpression> 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<JetExpression> 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.<JsExpression>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<JsExpression> 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<JsExpression> 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();
|
||||
}
|
||||
|
||||
+1
-1
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user