work on intrinsic implementation: split binary expression translation into 2 classes
This commit is contained in:
@@ -1,31 +1,19 @@
|
||||
package org.jetbrains.k2js.intrinsic;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsThisRef;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public final class BinaryOperationIntrinsic implements Intrinsic {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@NotNull FunctionDescriptor descriptor, @NotNull JetExpression receiver,
|
||||
@NotNull List<JetExpression> arguments) {
|
||||
//TODO: implement
|
||||
//public final class BinaryOperationIntrinsic implements Intrinsic {
|
||||
//
|
||||
// JetToken correspondingToken = OperatorConventions.getTokenForMethodName(descriptor.getName());
|
||||
// JsBinaryOperator operator = OperatorTable.getBinaryOperator(correspondingToken);
|
||||
// @NotNull
|
||||
// private final JsBinaryOperator operator;
|
||||
//
|
||||
// assert arguments.size() == 1 : "Binary operations expects 2 arguments.";
|
||||
// JsExpression argument = arguments.get(0);
|
||||
// assert argument != null;
|
||||
// /*package*/ BinaryOperationIntrinsic() {}
|
||||
//
|
||||
// return new JsBinaryOperation(operator, receiver, argument);
|
||||
return new JsThisRef();
|
||||
}
|
||||
}
|
||||
// @NotNull
|
||||
// @Override
|
||||
// public JsExpression apply(@NotNull JetExpression receiver, @NotNull List<JetExpression> arguments,
|
||||
// @NotNull TranslationContext context) {
|
||||
// //return BinaryOperationTranslator.translate()
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -2,8 +2,8 @@ package org.jetbrains.k2js.intrinsic;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.List;
|
||||
public interface Intrinsic {
|
||||
|
||||
@NotNull
|
||||
JsExpression apply(@NotNull FunctionDescriptor descriptor, @NotNull JetExpression receiver,
|
||||
@NotNull List<JetExpression> arguments);
|
||||
public JsExpression apply(@NotNull JetExpression receiver, @NotNull List<JetExpression> arguments,
|
||||
@NotNull TranslationContext context);
|
||||
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public final class IntrinsicDeclarationVisitor extends DeclarationDescriptorVisi
|
||||
|
||||
@Override
|
||||
public Void visitFunctionDescriptor(@NotNull FunctionDescriptor descriptor, @Nullable Void nothing) {
|
||||
if (!intrinsics.isIntrinsic(descriptor)) {
|
||||
if (!intrinsics.hasDescriptor(descriptor)) {
|
||||
intrinsics.declareIntrinsic(descriptor);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.jetbrains.k2js.intrinsic;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public final class IntrinsicFactory {
|
||||
|
||||
@NotNull
|
||||
private final Intrinsics intrinsics;
|
||||
|
||||
private IntrinsicFactory(@NotNull Intrinsics intrinsics) {
|
||||
this.intrinsics = intrinsics;
|
||||
}
|
||||
|
||||
// public Intrinsic getIntrinsicForExpression(@NotNull FunctionDescriptor descriptor,
|
||||
// @NotNull JetExpression expression,
|
||||
// @NotNull TranslationContext context) {
|
||||
// assert intrinsics.hasDescriptor(descriptor);
|
||||
// if (JetExpression instanceof JetBinaryExpression) {
|
||||
// return new BinaryOperationIntrinsic()
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ 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;
|
||||
@@ -35,43 +34,44 @@ public final class Intrinsics {
|
||||
// addUnaryIntrinsics(descriptor);
|
||||
// addAssignmentIntrinsics(descriptor);
|
||||
// addEqualsIntrinsics(descriptor);
|
||||
BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
descriptorToIntrinsicMap.put(descriptor, null);
|
||||
}
|
||||
|
||||
private void addEqualsIntrinsics(FunctionDescriptor descriptor) {
|
||||
BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
String functionName = descriptor.getName();
|
||||
if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsValue(functionName)) {
|
||||
descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
}
|
||||
}
|
||||
|
||||
private void addUnaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||
BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
String functionName = descriptor.getName();
|
||||
if (OperatorConventions.UNARY_OPERATION_NAMES.containsValue(functionName)) {
|
||||
descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBinaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||
String functionName = descriptor.getName();
|
||||
if (OperatorConventions.BINARY_OPERATION_NAMES.containsValue(functionName)) {
|
||||
BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAssignmentIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||
String functionName = descriptor.getName();
|
||||
if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsValue(functionName)) {
|
||||
BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIntrinsic(@NotNull DeclarationDescriptor descriptor) {
|
||||
// private void addEqualsIntrinsics(FunctionDescriptor descriptor) {
|
||||
// //BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
// String functionName = descriptor.getName();
|
||||
// if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsValue(functionName)) {
|
||||
// descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void addUnaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||
// BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
// String functionName = descriptor.getName();
|
||||
// if (OperatorConventions.UNARY_OPERATION_NAMES.containsValue(functionName)) {
|
||||
// descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// 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 addAssignmentIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||
// String functionName = descriptor.getName();
|
||||
// if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsValue(functionName)) {
|
||||
// BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
||||
// descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
public boolean hasDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor.getOriginal();
|
||||
return descriptorToIntrinsicMap.containsKey(functionDescriptor);
|
||||
|
||||
@@ -16,7 +16,7 @@ public class Aliaser {
|
||||
static public Aliaser aliasesForStandardClasses(@NotNull JetStandardLibrary standardLibrary,
|
||||
@NotNull Namer namer) {
|
||||
Aliaser result = new Aliaser();
|
||||
result.setAliasForDescriptor(standardLibrary.getArray(), namer.declareStandardClass("Array"));
|
||||
// result.setAliasForDescriptor(standardLibrary.getArray(), namer.declareStandardClass("Array"));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+13
-106
@@ -1,141 +1,48 @@
|
||||
package org.jetbrains.k2js.translate.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public final class BinaryOperationTranslator extends OperationTranslator {
|
||||
|
||||
@NotNull
|
||||
static public JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return (new BinaryOperationTranslator(expression, context)).translate();
|
||||
}
|
||||
public abstract class BinaryOperationTranslator extends OperationTranslator {
|
||||
|
||||
@NotNull
|
||||
private final JetBinaryExpression expression;
|
||||
private final boolean isPropertyOnTheLeft;
|
||||
private final boolean isVariableReassignment;
|
||||
protected final boolean isPropertyOnTheLeft;
|
||||
protected final boolean isVariableReassignment;
|
||||
@NotNull
|
||||
private final JsExpression left;
|
||||
protected final JsExpression left;
|
||||
@NotNull
|
||||
private final JsExpression right;
|
||||
@Nullable
|
||||
private final JsNameRef operationReference;
|
||||
protected final JsExpression right;
|
||||
|
||||
private BinaryOperationTranslator(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
protected BinaryOperationTranslator(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.expression = expression;
|
||||
this.isPropertyOnTheLeft = isPropertyAccess(expression.getLeft());
|
||||
this.isVariableReassignment = isVariableReassignment(expression);
|
||||
this.operationReference = getOverloadedOperationReference(expression.getOperationReference());
|
||||
|
||||
this.right = translateRightExpression();
|
||||
//TODO: decide whether it is harmful to possibly translateNamespace left expression more than once
|
||||
this.left = translateLeftExpression();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
JsExpression translate() {
|
||||
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
|
||||
return ArrayAccessTranslator.translateAsArraySetterCall(expression, context());
|
||||
}
|
||||
if (isCompareTo()) {
|
||||
return asCompareToOverload();
|
||||
}
|
||||
if (isOverloadedCall()) {
|
||||
return asOverloadedMethodCall();
|
||||
}
|
||||
return asBinaryOperation();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression asCompareToOverload() {
|
||||
JetToken operationToken = getOperationToken();
|
||||
assert (OperatorConventions.COMPARISON_OPERATIONS.contains(operationToken));
|
||||
JsNumberLiteral zeroLiteral = program().getNumberLiteral(0);
|
||||
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(operationToken);
|
||||
return new JsBinaryOperation(correspondingOperator, overloadedMethodInvocation(), zeroLiteral);
|
||||
}
|
||||
|
||||
private boolean isOverloadedCall() {
|
||||
return operationReference != null;
|
||||
}
|
||||
|
||||
private boolean isCompareTo() {
|
||||
if (operationReference == null) {
|
||||
return false;
|
||||
}
|
||||
String nameForOperationSymbol = OperatorConventions.getNameForOperationSymbol(getOperationToken());
|
||||
assert nameForOperationSymbol != null : "Must have a name for overloaded operator";
|
||||
return (nameForOperationSymbol.equals("compareTo"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression asOverloadedMethodCall() {
|
||||
if (isPropertyOnTheLeft) {
|
||||
return overloadOnProperty();
|
||||
}
|
||||
if (isVariableReassignment) {
|
||||
return nonPropertyReassignment();
|
||||
}
|
||||
return overloadedMethodInvocation();
|
||||
}
|
||||
|
||||
private JsExpression nonPropertyReassignment() {
|
||||
assert left instanceof JsNameRef : "Reassignment should be called on l-value.";
|
||||
return AstUtil.newAssignment((JsNameRef) left, overloadedMethodInvocation());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression overloadOnProperty() {
|
||||
if (isVariableReassignment) {
|
||||
return setterCall(overloadedMethodInvocation());
|
||||
} else {
|
||||
return overloadedMethodInvocation();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: refactor
|
||||
@NotNull
|
||||
private JsExpression asBinaryOperation() {
|
||||
if (isPropertyOnTheLeft && OperatorTable.isAssignment(getOperationToken())) {
|
||||
return setterCall(right);
|
||||
}
|
||||
JetToken token = getOperationToken();
|
||||
if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
|
||||
return new JsBinaryOperation(OperatorTable.getBinaryOperator(token), left, right);
|
||||
}
|
||||
if (OperatorTable.hasCorrespondingFunctionInvocation(token)) {
|
||||
JsInvocation functionInvocation = OperatorTable.getCorrespondingFunctionInvocation(token);
|
||||
functionInvocation.setArguments(left, right);
|
||||
return functionInvocation;
|
||||
}
|
||||
throw new AssertionError("Unsupported token encountered: " + token.toString());
|
||||
}
|
||||
abstract protected JsExpression translate();
|
||||
|
||||
private JsExpression translateLeftExpression() {
|
||||
return Translation.translateAsExpression(expression.getLeft(), context());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression overloadedMethodInvocation() {
|
||||
AstUtil.setQualifier(operationReference, left);
|
||||
return AstUtil.newInvocation(operationReference, right);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateRightExpression() {
|
||||
JetExpression rightExpression = expression.getRight();
|
||||
@@ -144,12 +51,12 @@ public final class BinaryOperationTranslator extends OperationTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JetToken getOperationToken() {
|
||||
protected JetToken getOperationToken() {
|
||||
return (JetToken) expression.getOperationToken();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsInvocation setterCall(@NotNull JsExpression assignTo) {
|
||||
protected JsInvocation setterCall(@NotNull JsExpression assignTo) {
|
||||
JsInvocation setterCall =
|
||||
PropertyAccessTranslator.translateAsPropertySetterCall(expression.getLeft(), context());
|
||||
setterCall.setArguments(assignTo);
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package org.jetbrains.k2js.translate.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
|
||||
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.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public final class IntrinsicBinaryOperationTranslator extends BinaryOperationTranslator {
|
||||
|
||||
protected IntrinsicBinaryOperationTranslator(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
super(expression, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JsExpression translate() {
|
||||
return asBinaryOperation();
|
||||
}
|
||||
|
||||
//TODO: refactor
|
||||
@NotNull
|
||||
private JsExpression asBinaryOperation() {
|
||||
if (isPropertyOnTheLeft && OperatorTable.isAssignment(getOperationToken())) {
|
||||
return setterCall(right);
|
||||
}
|
||||
JetToken token = getOperationToken();
|
||||
if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
|
||||
return new JsBinaryOperation(OperatorTable.getBinaryOperator(token), left, right);
|
||||
}
|
||||
//TODO: implement using intrinsic mechanism
|
||||
// if (OperatorTable.hasCorrespondingFunctionInvocation(token)) {
|
||||
// JsInvocation functionInvocation = OperatorTable.getCorrespondingFunctionInvocation(token);
|
||||
// functionInvocation.setArguments(left, right);
|
||||
// return functionInvocation;
|
||||
// }
|
||||
throw new AssertionError("Unsupported token encountered: " + token.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,18 +7,38 @@ import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public class OperationTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
static public JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
//TODO: move to translation
|
||||
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
|
||||
return ArrayAccessTranslator.translateAsArraySetterCall(expression, context);
|
||||
}
|
||||
|
||||
BinaryOperationTranslator translator;
|
||||
if (TranslationUtils.isIntrinsicOperation(context, expression.getOperationReference())) {
|
||||
translator = new IntrinsicBinaryOperationTranslator(expression, context);
|
||||
} else {
|
||||
translator = new OverloadedBinaryOperationTranslator(expression, context);
|
||||
}
|
||||
return translator.translate();
|
||||
}
|
||||
|
||||
protected OperationTranslator(@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
}
|
||||
@@ -29,7 +49,7 @@ public class OperationTranslator extends AbstractTranslator {
|
||||
if (operationDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
if (context().intrinsics().isIntrinsic(operationDescriptor)) {
|
||||
if (context().intrinsics().hasDescriptor(operationDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
if (!context().isDeclared(operationDescriptor)) {
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package org.jetbrains.k2js.translate.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public final class OverloadedBinaryOperationTranslator extends BinaryOperationTranslator {
|
||||
|
||||
@NotNull
|
||||
private final JsNameRef operationReference;
|
||||
|
||||
|
||||
protected OverloadedBinaryOperationTranslator(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
super(expression, context);
|
||||
JsNameRef overloadedOperationReference = getOverloadedOperationReference(expression.getOperationReference());
|
||||
assert overloadedOperationReference != null;
|
||||
this.operationReference = overloadedOperationReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected JsExpression translate() {
|
||||
if (isCompareTo()) {
|
||||
return asCompareToOverload();
|
||||
}
|
||||
return asOverloadedMethodCall();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression asCompareToOverload() {
|
||||
JetToken operationToken = getOperationToken();
|
||||
assert (OperatorConventions.COMPARISON_OPERATIONS.contains(operationToken));
|
||||
JsNumberLiteral zeroLiteral = program().getNumberLiteral(0);
|
||||
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(operationToken);
|
||||
return new JsBinaryOperation(correspondingOperator, overloadedMethodInvocation(), zeroLiteral);
|
||||
}
|
||||
|
||||
private boolean isCompareTo() {
|
||||
String nameForOperationSymbol = OperatorConventions.getNameForOperationSymbol(getOperationToken());
|
||||
assert nameForOperationSymbol != null : "Must have a name for overloaded operator";
|
||||
return (nameForOperationSymbol.equals("compareTo"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression asOverloadedMethodCall() {
|
||||
if (isPropertyOnTheLeft && isVariableReassignment) {
|
||||
return propertyReassignment();
|
||||
}
|
||||
if (isVariableReassignment) {
|
||||
return nonPropertyReassignment();
|
||||
}
|
||||
return overloadedMethodInvocation();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsInvocation propertyReassignment() {
|
||||
return setterCall(overloadedMethodInvocation());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression nonPropertyReassignment() {
|
||||
assert left instanceof JsNameRef : "Reassignment should be called on l-value.";
|
||||
return AstUtil.newAssignment((JsNameRef) left, overloadedMethodInvocation());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression overloadedMethodInvocation() {
|
||||
AstUtil.setQualifier(operationReference, left);
|
||||
return AstUtil.newInvocation(operationReference, right);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public final class ArrayAccessTranslator extends AbstractTranslator {
|
||||
|
||||
|
||||
public static boolean canBeArraySetterCall(@NotNull JetBinaryExpression expression) {
|
||||
//TODO: move unsafe cat to util
|
||||
//TODO: move unsafe call to util
|
||||
return (OperatorTable.isAssignment((JetToken) expression.getOperationToken())
|
||||
&& (expression.getLeft() instanceof JetArrayAccessExpression));
|
||||
}
|
||||
|
||||
@@ -8,10 +8,7 @@ import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
import org.jetbrains.jet.lang.psi.ValueArgument;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
@@ -25,28 +22,28 @@ import java.util.List;
|
||||
public final class TranslationUtils {
|
||||
|
||||
@NotNull
|
||||
static public JsBinaryOperation notNullCheck(@NotNull TranslationContext context,
|
||||
public static JsBinaryOperation notNullCheck(@NotNull TranslationContext context,
|
||||
@NotNull JsExpression expressionToCheck) {
|
||||
JsNullLiteral nullLiteral = context.program().getNullLiteral();
|
||||
return AstUtil.notEqual(expressionToCheck, nullLiteral);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public JsBinaryOperation isNullCheck(@NotNull TranslationContext context,
|
||||
public static JsBinaryOperation isNullCheck(@NotNull TranslationContext context,
|
||||
@NotNull JsExpression expressionToCheck) {
|
||||
JsNullLiteral nullLiteral = context.program().getNullLiteral();
|
||||
return AstUtil.equals(expressionToCheck, nullLiteral);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static public JsName getLocalReferencedName(@NotNull TranslationContext context,
|
||||
public static JsName getLocalReferencedName(@NotNull TranslationContext context,
|
||||
@NotNull String name) {
|
||||
return context.enclosingScope().findExistingName(name);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
static public List<JsExpression> translateArgumentList(@NotNull List<? extends ValueArgument> jetArguments,
|
||||
public static List<JsExpression> translateArgumentList(@NotNull List<? extends ValueArgument> jetArguments,
|
||||
@NotNull TranslationContext context) {
|
||||
List<JsExpression> jsArguments = new ArrayList<JsExpression>();
|
||||
for (ValueArgument argument : jetArguments) {
|
||||
@@ -56,7 +53,7 @@ public final class TranslationUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public JsExpression translateArgument(@NotNull TranslationContext context, @NotNull ValueArgument argument) {
|
||||
public static JsExpression translateArgument(@NotNull TranslationContext context, @NotNull ValueArgument argument) {
|
||||
JetExpression jetExpression = argument.getArgumentExpression();
|
||||
if (jetExpression == null) {
|
||||
throw new AssertionError("Argument with no expression encountered!");
|
||||
@@ -65,21 +62,21 @@ public final class TranslationUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public JsNameRef backingFieldReference(@NotNull TranslationContext context,
|
||||
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
|
||||
@NotNull JetProperty expression) {
|
||||
JsName backingFieldName = getBackingFieldName(getPropertyName(expression), context);
|
||||
return getThisQualifiedNameReference(context, backingFieldName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public JsNameRef backingFieldReference(@NotNull TranslationContext context,
|
||||
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
|
||||
@NotNull PropertyDescriptor descriptor) {
|
||||
JsName backingFieldName = getBackingFieldName(descriptor.getName(), context);
|
||||
return getThisQualifiedNameReference(context, backingFieldName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public String getPropertyName(@NotNull JetProperty expression) {
|
||||
public static String getPropertyName(@NotNull JetProperty expression) {
|
||||
String propertyName = expression.getName();
|
||||
if (propertyName == null) {
|
||||
throw new AssertionError("Property with no name encountered!");
|
||||
@@ -177,4 +174,14 @@ public final class TranslationUtils {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
|
||||
@NotNull JetReferenceExpression expression) {
|
||||
DeclarationDescriptor descriptor =
|
||||
BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression);
|
||||
|
||||
if (descriptor == null) return true;
|
||||
|
||||
return (context.intrinsics().hasDescriptor(descriptor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ fun box() : Boolean {
|
||||
val a = Array<Int>(4)
|
||||
a[1] = 2
|
||||
a[2] = 3
|
||||
return a.get(1) == 2
|
||||
return (a[1] == 2) && (a[2] == 3)
|
||||
}
|
||||
Reference in New Issue
Block a user