imolement most of the intrinsic logic. test fixes to follow

This commit is contained in:
Pavel Talanov
2011-12-02 16:28:47 +04:00
parent cb071e3f74
commit 3b97bb6129
53 changed files with 1218 additions and 1000 deletions
+534 -439
View File
File diff suppressed because it is too large Load Diff
@@ -5,7 +5,7 @@ import com.google.dart.compiler.backend.js.ast.JsScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.k2js.translate.utils.Namer;
import org.jetbrains.k2js.translate.context.Namer;
/**
* @author Talanov Pavel
@@ -1,4 +1,4 @@
package org.jetbrains.k2js.translate.general;
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
@@ -6,7 +6,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.k2js.translate.utils.Namer;
import java.util.HashMap;
import java.util.Map;
@@ -1,4 +1,4 @@
package org.jetbrains.k2js.translate.utils;
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
@@ -1,4 +1,4 @@
package org.jetbrains.k2js.translate.general;
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsProgram;
@@ -11,7 +11,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.k2js.declarations.Declarations;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.Namer;
public class StaticContext {
@@ -1,4 +1,4 @@
package org.jetbrains.k2js.translate.general;
package org.jetbrains.k2js.translate.context;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsProgram;
@@ -10,7 +10,6 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.k2js.declarations.Declarations;
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.Namer;
/**
* @author Talanov Pavel
@@ -8,11 +8,11 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.k2js.translate.context.Namer;
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.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.Namer;
import org.jetbrains.k2js.utils.ClassSorter;
import java.util.ArrayList;
@@ -12,9 +12,9 @@ import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetParameter;
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.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.ArrayList;
@@ -4,8 +4,8 @@ import com.google.dart.compiler.backend.js.ast.JsPropertyInitializer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
import org.jetbrains.k2js.translate.utils.BindingUtils;
@@ -4,10 +4,10 @@ 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.JetNamespace;
import org.jetbrains.k2js.translate.context.Namer;
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.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.Namer;
import java.util.ArrayList;
import java.util.List;
@@ -9,9 +9,9 @@ import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
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.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.ArrayList;
@@ -8,12 +8,13 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.NullValue;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
import org.jetbrains.k2js.translate.operation.OperationTranslator;
import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator;
import org.jetbrains.k2js.translate.operation.IncrementTranslator;
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
import org.jetbrains.k2js.translate.reference.AccessTranslator;
import org.jetbrains.k2js.translate.reference.CallTranslator;
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
@@ -95,7 +96,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsNode visitBinaryExpression(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
return OperationTranslator.translate(expression, context);
return BinaryOperationTranslator.translate(expression, context);
}
@Override
@@ -302,7 +303,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsNode visitPostfixExpression(@NotNull JetPostfixExpression expression,
@NotNull TranslationContext context) {
return UnaryOperationTranslator.translate(expression, context);
return IncrementTranslator.translate(expression, context);
}
@Override
@@ -372,9 +373,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@Override
@NotNull
public JsInvocation visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return ArrayAccessTranslator.translateAsArrayGetterCall(expression, context);
public JsNode visitArrayAccessExpression(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return AccessTranslator.translateAsGet(expression, context);
}
@@ -4,9 +4,9 @@ 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.*;
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.general.TranslationContext;
import java.util.ArrayList;
import java.util.List;
@@ -7,9 +7,9 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -5,9 +5,9 @@ import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import java.util.ArrayList;
import java.util.List;
@@ -2,6 +2,7 @@ package org.jetbrains.k2js.translate.general;
import com.google.dart.compiler.backend.js.ast.JsProgram;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.translate.context.TranslationContext;
/**
* @author Talanov Pavel
@@ -8,6 +8,8 @@ import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.k2js.translate.context.StaticContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.declaration.ClassTranslator;
import org.jetbrains.k2js.translate.declaration.NamespaceTranslator;
import org.jetbrains.k2js.translate.expression.ExpressionVisitor;
@@ -3,6 +3,7 @@ package org.jetbrains.k2js.translate.general;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetVisitor;
import org.jetbrains.k2js.translate.context.TranslationContext;
/**
* @author Talanov Pavel
@@ -6,9 +6,9 @@ import com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.backend.js.ast.JsStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.Namer;
import java.util.List;
@@ -9,9 +9,9 @@ import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.Namer;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.ArrayList;
@@ -5,8 +5,8 @@ import com.google.dart.compiler.backend.js.ast.JsStatement;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -5,7 +5,7 @@ import com.google.dart.compiler.backend.js.ast.JsScope;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
/**
* @author Talanov Pavel
@@ -5,7 +5,7 @@ import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import java.util.List;
@@ -2,7 +2,7 @@ package org.jetbrains.k2js.translate.intrinsic;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
import java.util.List;
@@ -7,6 +7,7 @@ import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import java.util.HashMap;
import java.util.Map;
@@ -57,15 +58,17 @@ public final class Intrinsics {
private void addUnaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
String functionName = descriptor.getName();
JetToken token = OperatorConventions.UNARY_OPERATION_NAMES.inverse().get(functionName);
if (token != null) {
boolean isUnary = !DescriptorUtils.hasParameters(descriptor);
if (isUnary && (token != null)) {
descriptorToIntrinsicMap.put(descriptor, UnaryOperationIntrinsic.newInstance(token));
}
}
private void addBinaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
String functionName = descriptor.getName();
boolean isUnary = !DescriptorUtils.hasParameters(descriptor);
JetToken token = OperatorConventions.BINARY_OPERATION_NAMES.inverse().get(functionName);
if (token != null && OperatorTable.hasCorrespondingBinaryOperator(token)) {
if (token != null && OperatorTable.hasCorrespondingBinaryOperator(token) && (!isUnary)) {
descriptorToIntrinsicMap.put(descriptor, BinaryOperationIntrinsic.newInstance(token));
}
}
@@ -4,7 +4,7 @@ import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import java.util.List;
@@ -3,7 +3,7 @@ package org.jetbrains.k2js.translate.intrinsic;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
import java.util.List;
@@ -5,7 +5,7 @@ import com.google.dart.compiler.backend.js.ast.JsPrefixOperation;
import com.google.dart.compiler.backend.js.ast.JsUnaryOperator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import java.util.List;
@@ -0,0 +1,56 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
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.reference.AccessTranslator;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
/**
* @author Talanov Pavel
*/
public abstract class AssignmentTranslator extends AbstractTranslator {
public static boolean isAssignmentOperator(JetBinaryExpression expression) {
JetToken operationToken = getOperationToken(expression);
return (OperatorConventions.ASSIGNMENT_OPERATIONS.keySet().contains(operationToken)
|| OperatorTable.isAssignment(operationToken));
}
@NotNull
public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
if (isIntrinsicOperation(context, expression)) {
return IntrinsicAssignmentTranslator.translate(expression, context);
}
return OverloadedAssignmentTranslator.translate(expression, context);
}
@NotNull
protected final JetBinaryExpression expression;
protected final AccessTranslator accessTranslator;
protected final boolean isVariableReassignment;
@NotNull
protected final JsExpression right;
protected AssignmentTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
this.accessTranslator = AccessTranslator.getAccessTranslator(expression.getLeft(), context());
this.right = translateRightExpression(context(), expression);
}
@NotNull
abstract protected JsExpression translate();
}
@@ -1,14 +1,29 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
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.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetOperationExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
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.CompareToIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import org.jetbrains.k2js.translate.reference.CallTranslator;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
import java.util.Arrays;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
@@ -16,44 +31,98 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRight
/**
* @author Talanov Pavel
*/
public abstract class BinaryOperationTranslator extends OperationTranslator {
public final class BinaryOperationTranslator extends AbstractTranslator {
//TODO: move to utils
@NotNull
private static DeclarationDescriptor getOperationDescriptor(@NotNull JetOperationExpression expression,
@NotNull TranslationContext context) {
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
(context.bindingContext(), expression.getOperation());
assert descriptorForReferenceExpression != null;
return descriptorForReferenceExpression;
}
@NotNull
public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
return (new BinaryOperationTranslator(expression, context).translate());
}
private BinaryOperationTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
this.operationDescriptor =
getFunctionDescriptorForOperationExpression(context().bindingContext(), expression);
}
@NotNull
private final JetBinaryExpression expression;
protected final boolean isPropertyOnTheLeft;
protected final boolean isVariableReassignment;
@NotNull
protected final JsExpression left;
@NotNull
protected final JsExpression right;
protected BinaryOperationTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
this.isPropertyOnTheLeft = isPropertyAccess(expression.getLeft());
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
@Nullable
private final FunctionDescriptor operationDescriptor;
this.right = translateRightExpression(context(), expression);
//TODO: decide whether it is harmful to possibly translateNamespace left expression more than once
this.left = translateLeftExpression(context(), expression);
@NotNull
private JsExpression translate() {
if (AssignmentTranslator.isAssignmentOperator(expression)) {
return AssignmentTranslator.translate(expression, context());
}
if (operationDescriptor == null) {
return translateAsUnOverloadableBinaryOperation();
}
if (isEqualsCall()) {
return translateAsEqualsCall();
}
if (isCompareToCall()) {
return translateAsCompareToCall();
}
return CallTranslator.translate(expression, context());
}
private boolean isEqualsCall() {
//TODO: add descriptor is equals utils
assert operationDescriptor != null;
boolean isEquals = operationDescriptor.getName().equals("equals");
boolean isIntrinsic = context().intrinsics().hasDescriptor(operationDescriptor);
return isEquals && isIntrinsic;
}
@NotNull
abstract protected JsExpression translate();
private JsExpression translateAsEqualsCall() {
Intrinsic intrinsic = context().intrinsics().
getIntrinsic(getOperationDescriptor(expression, context()));
//TODO
((EqualsIntrinsic) intrinsic).setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ));
JsExpression left = translateLeftExpression(context(), expression);
JsExpression right = translateRightExpression(context(), expression);
return intrinsic.apply(left, Arrays.asList(right), context());
}
@NotNull
protected JetToken getOperationToken() {
return (JetToken) expression.getOperationToken();
private boolean isCompareToCall() {
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression, context());
return (operationDescriptor.getName().equals("compareTo")
&& (context().intrinsics().hasDescriptor(operationDescriptor)));
}
@NotNull
protected JsInvocation setterCall(@NotNull JsExpression assignTo) {
JsInvocation setterCall =
PropertyAccessTranslator.translateAsPropertySetterCall(expression.getLeft(), context());
setterCall.setArguments(assignTo);
return setterCall;
private JsExpression translateAsCompareToCall() {
Intrinsic intrinsic = context().intrinsics().
getIntrinsic(getOperationDescriptor(expression, context()));
((CompareToIntrinsic) intrinsic).setComparisonToken((JetToken) expression.getOperationToken());
return intrinsic.apply(translateLeftExpression(context(), expression),
Arrays.asList(translateRightExpression(context(), expression)), context());
}
@NotNull
private JsExpression translateAsUnOverloadableBinaryOperation() {
JetToken token = getOperationToken(expression);
JsBinaryOperator operator = OperatorTable.getBinaryOperator(token);
assert OperatorConventions.NOT_OVERLOADABLE.contains(token);
JsExpression left = translateLeftExpression(context(), expression);
JsExpression right = translateRightExpression(context(), expression);
return new JsBinaryOperation(operator, left, right);
}
}
@@ -1,9 +0,0 @@
package org.jetbrains.k2js.translate.operation;
/**
* @author Talanov Pavel
*/
public final class EqualsTranslator {
}
@@ -0,0 +1,152 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetPrefixExpression;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.reference.AccessTranslator;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isStatement;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
/**
* @author Talanov Pavel
*/
//TODO: reexamine class, see if can be clearer
public abstract class IncrementTranslator extends AbstractTranslator {
public static boolean isIncrement(@NotNull JetUnaryExpression expression) {
return OperatorConventions.INCREMENT_OPERATIONS.contains(getOperationToken(expression));
}
@NotNull
public static JsExpression translate(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
if (isIntrinsicOperation(context, expression)) {
return IntrinsicIncrementTranslator.translate(expression, context);
}
return OverloadedIncrementTranslator.translate(expression, context);
}
@NotNull
protected final JetUnaryExpression expression;
@NotNull
protected final AccessTranslator accessTranslator;
protected final boolean isPrefix;
private final boolean isVariableReassignment;
private final boolean isStatement;
protected IncrementTranslator(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
this.isPrefix = isPrefix(expression);
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
this.isStatement = isStatement(context().bindingContext(), expression);
//TODO: use util method
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
this.accessTranslator = AccessTranslator.getAccessTranslator(baseExpression, context());
}
@NotNull
protected abstract JsExpression translate();
@NotNull
protected JsExpression translateAsMethodCall() {
if (isStatement || isPrefix) {
return asPrefix();
}
if (isVariableReassignment) {
return asPostfixWithReassignment();
} else {
return asPostfixWithNoReassignment();
}
}
@NotNull
private JsExpression asPrefix() {
JsExpression getExpression = accessTranslator.translateAsGet();
if (isVariableReassignment) {
return variableReassignment(getExpression);
}
return operationExpression(getExpression);
}
//TODO: decide if this expression can be optimised in case of direct access (not property)
@NotNull
private JsExpression asPostfixWithReassignment() {
// code fragment: expr(a++)
// generate: expr( (t1 = a, t2 = t1, a = t1.inc(), t2) )
TemporaryVariable t1 = declareTemporary(accessTranslator.translateAsGet());
TemporaryVariable t2 = declareTemporary(t1.nameReference());
JsExpression variableReassignment = variableReassignment(t1.nameReference());
return AstUtil.newSequence(t1.assignmentExpression(), t2.assignmentExpression(),
variableReassignment, t2.nameReference());
}
@NotNull
private JsExpression asPostfixWithNoReassignment() {
// code fragment: expr(a++)
// generate: expr( (t1 = a, t2 = t1, t2.inc(), t1) )
TemporaryVariable t1 = declareTemporary(accessTranslator.translateAsGet());
TemporaryVariable t2 = declareTemporary(t1.nameReference());
JsExpression methodCall = operationExpression(t2.nameReference());
JsExpression returnedValue = t1.nameReference();
return AstUtil.newSequence(t1.assignmentExpression(), t2.assignmentExpression(), methodCall, returnedValue);
}
@NotNull
private JsExpression variableReassignment(@NotNull JsExpression toCallMethodUpon) {
JsExpression overloadedMethodCallOnPropertyGetter = operationExpression(toCallMethodUpon);
return accessTranslator.translateAsSet(overloadedMethodCallOnPropertyGetter);
}
@NotNull
abstract JsExpression operationExpression(@NotNull JsExpression receiver);
private boolean isPrefix(@NotNull JetUnaryExpression expression) {
return (expression instanceof JetPrefixExpression);
}
//TODO: consider moving into context
protected final class TemporaryVariable {
@NotNull
private final JsExpression assignmentExpression;
@NotNull
private final JsName variableName;
private TemporaryVariable(@NotNull JsExpression initExpression) {
this.variableName = context().enclosingScope().declareTemporary();
this.assignmentExpression = AstUtil.newAssignment(variableName.makeRef(), initExpression);
}
@NotNull
public JsNameRef nameReference() {
return variableName.makeRef();
}
@NotNull
public JsExpression assignmentExpression() {
return assignmentExpression;
}
}
@NotNull
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
return new TemporaryVariable(initExpression);
}
}
@@ -5,22 +5,24 @@ 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;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
/**
* @author Talanov Pavel
*/
public final class IntrinsicBinaryOperationTranslator extends BinaryOperationTranslator {
public final class IntrinsicAssignmentTranslator extends AssignmentTranslator {
@NotNull
public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
return (new IntrinsicBinaryOperationTranslator(expression, context)).translate();
return (new IntrinsicAssignmentTranslator(expression, context)).translate();
}
private IntrinsicBinaryOperationTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
private IntrinsicAssignmentTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
super(expression, context);
}
@@ -33,19 +35,15 @@ public final class IntrinsicBinaryOperationTranslator extends BinaryOperationTra
//TODO: refactor
@NotNull
private JsExpression asBinaryOperation() {
if (isPropertyOnTheLeft && OperatorTable.isAssignment(getOperationToken())) {
return setterCall(right);
if (OperatorTable.isAssignment(getOperationToken(expression))) {
return accessTranslator.translateAsSet(right);
}
JetToken token = getOperationToken();
//TODO: logic broken
JetToken token = getOperationToken(expression);
if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
return new JsBinaryOperation(OperatorTable.getBinaryOperator(token), left, right);
return new JsBinaryOperation(OperatorTable.getBinaryOperator(token),
accessTranslator.translateAsGet(), 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());
}
@@ -5,49 +5,58 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.reference.ReferenceAccessTranslator;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
/**
* @author Talanov Pavel
*/
public final class IntrinsicUnaryOperationTranslator extends UnaryOperationTranslator {
public final class IntrinsicIncrementTranslator extends IncrementTranslator {
@NotNull
public static JsExpression translate(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
return (new IntrinsicUnaryOperationTranslator(expression, context))
return (new IntrinsicIncrementTranslator(expression, context))
.translate();
}
protected IntrinsicUnaryOperationTranslator(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
protected IntrinsicIncrementTranslator(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
super(expression, context);
}
@Override
@NotNull
protected JsExpression translate() {
if (isPropertyAccess) {
return translateAsMethodCall();
if (isPrimitiveExpressionIncrement()) {
return jsUnaryExpression();
}
return jsUnaryExpression();
return translateAsMethodCall();
}
private boolean isPrimitiveExpressionIncrement() {
return accessTranslator instanceof ReferenceAccessTranslator;
}
@NotNull
private JsExpression jsUnaryExpression() {
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken());
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
JsExpression getExpression = accessTranslator.translateAsGet();
if (isPrefix) {
return new JsPrefixOperation(operator, baseExpression);
return new JsPrefixOperation(operator, getExpression);
} else {
return new JsPostfixOperation(operator, baseExpression);
return new JsPostfixOperation(operator, getExpression);
}
}
@Override
@NotNull
protected JsExpression operationExpression(@NotNull JsExpression receiver) {
return unaryAsBinary(getOperationToken(), receiver);
return unaryAsBinary(getOperationToken(expression), receiver);
}
public JsBinaryOperation unaryAsBinary(@NotNull JetToken token, @NotNull JsExpression expression) {
@@ -1,157 +0,0 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
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.JetOperationExpression;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
import org.jetbrains.k2js.translate.reference.CallTranslator;
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
import java.util.Arrays;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
/**
* @author Talanov Pavel
*/
public class OperationTranslator extends AbstractTranslator {
@NotNull
public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
//TODO: move to assignment translator
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
return ArrayAccessTranslator.translateAsArraySetterCall(expression, context);
}
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
(context.bindingContext(), expression.getOperation());
if (descriptorForReferenceExpression == null) {
return IntrinsicBinaryOperationTranslator.translate(expression, context);
}
if (isEqualsCall(expression, context)) {
return translateAsEqualsCall(expression, context);
}
if (isCompareToCall(expression, context)) {
return translateAsCompareToCall(expression, context);
}
return CallTranslator.translate(expression, context);
}
@NotNull
public static JsExpression translate(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
return CallTranslator.translate(expression, context);
}
public static boolean isEqualsCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression, context);
//TODO: add descriptor is equals utils
boolean isEquals = operationDescriptor.getName().equals("equals");
boolean isIntrinsic = context.intrinsics().hasDescriptor(operationDescriptor);
return isEquals && isIntrinsic;
}
@NotNull
public static JsExpression translateAsEqualsCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
Intrinsic intrinsic = context.intrinsics().
getIntrinsic(getOperationDescriptor(expression, context));
//TODO
((EqualsIntrinsic) intrinsic).setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ));
return intrinsic.apply(translateLeftExpression(context, expression),
Arrays.asList(translateRightExpression(context, expression)), context);
}
public static boolean isCompareToCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression, context);
return (operationDescriptor.getName().equals("compareTo")
&& (context.intrinsics().hasDescriptor(operationDescriptor)));
}
@NotNull
public static JsExpression translateAsCompareToCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
Intrinsic intrinsic = context.intrinsics().
getIntrinsic(getOperationDescriptor(expression, context));
((CompareToIntrinsic) intrinsic).setComparisonToken((JetToken) expression.getOperationToken());
return intrinsic.apply(translateLeftExpression(context, expression),
Arrays.asList(translateRightExpression(context, expression)), context);
}
protected OperationTranslator(@NotNull TranslationContext context) {
super(context);
}
//TODO: refactor
@Nullable
protected static JsNameRef getOverloadedOperationReference(@NotNull JetOperationExpression operationExpression,
@NotNull TranslationContext context) {
DeclarationDescriptor operationDescriptor = getOperationDescriptor(operationExpression, context);
if (!context.isDeclared(operationDescriptor)) {
return null;
}
return context.getNameForDescriptor(operationDescriptor).makeRef();
}
@NotNull
private static DeclarationDescriptor getOperationDescriptor(@NotNull JetOperationExpression expression,
@NotNull TranslationContext context) {
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
(context.bindingContext(), expression.getOperation());
assert descriptorForReferenceExpression != null;
return descriptorForReferenceExpression;
}
protected boolean isPropertyAccess(@NotNull JetExpression expression) {
return PropertyAccessTranslator.canBePropertyAccess(expression, context());
}
protected final class TemporaryVariable {
@NotNull
private final JsExpression assignmentExpression;
@NotNull
private final JsName variableName;
private TemporaryVariable(@NotNull JsExpression initExpression) {
this.variableName = context().enclosingScope().declareTemporary();
this.assignmentExpression = AstUtil.newAssignment(variableName.makeRef(), initExpression);
}
@NotNull
public JsNameRef nameReference() {
return variableName.makeRef();
}
@NotNull
public JsExpression assignmentExpression() {
return assignmentExpression;
}
}
@NotNull
public TemporaryVariable declareTemporary(@NotNull JsExpression initExpression) {
return new TemporaryVariable(initExpression);
}
}
@@ -1,10 +1,7 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
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.JsUnaryOperator;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
@@ -19,7 +16,6 @@ public final class OperatorTable {
private static Map<JetToken, JsBinaryOperator> binaryOperatorsMap = new HashMap<JetToken, JsBinaryOperator>();
private static Map<JetToken, JsUnaryOperator> unaryOperatorsMap = new HashMap<JetToken, JsUnaryOperator>();
private static Map<JetToken, JsNameRef> operatorToFunctionNameReference = new HashMap<JetToken, JsNameRef>();
static {
unaryOperatorsMap.put(JetTokens.PLUSPLUS, JsUnaryOperator.INC); //++
@@ -51,26 +47,11 @@ public final class OperatorTable {
binaryOperatorsMap.put(JetTokens.PERCEQ, JsBinaryOperator.ASG_MOD);
}
//TODO: resolve
static {
//operatorToFunctionNameReference.put(JetTokens.IS_KEYWORD, Namer.isOperationReference());
}
public static boolean hasCorrespondingBinaryOperator(@NotNull JetToken token) {
return binaryOperatorsMap.containsKey(token);
}
public static boolean hasCorrespondingFunctionInvocation(@NotNull JetToken token) {
return operatorToFunctionNameReference.containsKey(token);
}
@NotNull
static public JsInvocation getCorrespondingFunctionInvocation(@NotNull JetToken token) {
JsNameRef functionReference = operatorToFunctionNameReference.get(token);
assert functionReference != null : "Token should represent a function call!";
return AstUtil.newInvocation(functionReference);
}
@NotNull
static public JsBinaryOperator getBinaryOperator(@NotNull JetToken token) {
assert JetTokens.OPERATIONS.contains(token) : "Token should represent an operation!";
@@ -3,29 +3,37 @@ 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.descriptors.DeclarationDescriptor;
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;
import org.jetbrains.k2js.translate.context.TranslationContext;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
/**
* @author Talanov Pavel
*/
public final class OverloadedBinaryOperationTranslator extends BinaryOperationTranslator {
public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
@NotNull
public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
return (new OverloadedBinaryOperationTranslator(expression, context)).translate();
return (new OverloadedAssignmentTranslator(expression, context)).translate();
}
@NotNull
private final JsNameRef operationReference;
private OverloadedBinaryOperationTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
private OverloadedAssignmentTranslator(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
super(expression, context);
JsNameRef overloadedOperationReference = getOverloadedOperationReference(expression, context);
//TODO: util
DeclarationDescriptor overloadedOperationDescriptor = getDescriptorForReferenceExpression
(context.bindingContext(), expression.getOperation());
assert overloadedOperationDescriptor != null;
JsNameRef overloadedOperationReference = context().getNameForDescriptor(overloadedOperationDescriptor).makeRef();
assert overloadedOperationReference != null;
this.operationReference = overloadedOperationReference;
}
@@ -41,7 +49,7 @@ public final class OverloadedBinaryOperationTranslator extends BinaryOperationTr
@NotNull
private JsExpression asCompareToOverload() {
JetToken operationToken = getOperationToken();
JetToken operationToken = getOperationToken(expression);
assert (OperatorConventions.COMPARISON_OPERATIONS.contains(operationToken));
JsNumberLiteral zeroLiteral = program().getNumberLiteral(0);
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(operationToken);
@@ -49,36 +57,29 @@ public final class OverloadedBinaryOperationTranslator extends BinaryOperationTr
}
private boolean isCompareTo() {
String nameForOperationSymbol = OperatorConventions.getNameForOperationSymbol(getOperationToken());
//util
JetToken operationToken = getOperationToken(expression);
String nameForOperationSymbol = OperatorConventions.getNameForOperationSymbol(operationToken);
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 reassignment();
}
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());
private JsExpression reassignment() {
return accessTranslator.translateAsSet(overloadedMethodInvocation());
}
@NotNull
private JsExpression overloadedMethodInvocation() {
AstUtil.setQualifier(operationReference, left);
AstUtil.setQualifier(operationReference, accessTranslator.translateAsGet());
return AstUtil.newInvocation(operationReference, right);
}
@@ -0,0 +1,53 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
/**
* @author Talanov Pavel
*/
// TODO: provide better increment translator logic
public final class OverloadedIncrementTranslator extends IncrementTranslator {
@NotNull
public static JsExpression translate(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
return (new OverloadedIncrementTranslator(expression, context))
.translate();
}
@NotNull
private final JsNameRef operationReference;
private OverloadedIncrementTranslator(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
super(expression, context);
//TODO: DUBLICATE CODE
DeclarationDescriptor overloadedOperationDescriptor = BindingUtils.getDescriptorForReferenceExpression
(context.bindingContext(), expression.getOperation());
assert overloadedOperationDescriptor != null;
JsNameRef overloadedOperationReference = context().getNameForDescriptor(overloadedOperationDescriptor).makeRef();
assert overloadedOperationReference != null;
this.operationReference = overloadedOperationReference;
}
@Override
@NotNull
protected JsExpression translate() {
return translateAsMethodCall();
}
@Override
@NotNull
protected JsExpression operationExpression(@NotNull JsExpression receiver) {
AstUtil.setQualifier(operationReference, receiver);
return AstUtil.newInvocation(operationReference);
}
}
@@ -1,44 +0,0 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.k2js.translate.general.TranslationContext;
/**
* @author Talanov Pavel
*/
public final class OverloadedUnaryOperationTranslator extends UnaryOperationTranslator {
@NotNull
public static JsExpression translate(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
return (new OverloadedUnaryOperationTranslator(expression, context))
.translate();
}
@NotNull
private final JsNameRef operationReference;
private OverloadedUnaryOperationTranslator(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
super(expression, context);
this.operationReference = getOverloadedOperationReference(expression, context);
}
@Override
@NotNull
protected JsExpression translate() {
return translateAsMethodCall();
}
@Override
@NotNull
protected JsExpression operationExpression(@NotNull JsExpression receiver) {
AstUtil.setQualifier(operationReference, receiver);
return AstUtil.newInvocation(operationReference);
}
}
@@ -1,134 +1,26 @@
package org.jetbrains.k2js.translate.operation;
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.util.AstUtil;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetPrefixExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getBaseExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateBaseExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.reference.CallTranslator;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
/**
* @author Talanov Pavel
*/
//TODO: reexamine class, see if can be clearer
public abstract class UnaryOperationTranslator extends OperationTranslator {
//TODO: merge with binary operation
public final class UnaryOperationTranslator {
@NotNull
private final JetUnaryExpression expression;
@NotNull
protected final JsExpression baseExpression;
protected final boolean isPrefix;
private final boolean isVariableReassignment;
private final boolean isStatement;
protected final boolean isPropertyAccess;
protected UnaryOperationTranslator(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
this.isPrefix = isPrefix(expression);
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
this.isStatement = BindingUtils.isStatement(context().bindingContext(), expression);
this.baseExpression = translateBaseExpression(context, expression);
this.isPropertyAccess = isPropertyAccess(getBaseExpression(expression));
}
@NotNull
protected abstract JsExpression translate();
@NotNull
protected JsExpression translateAsMethodCall() {
if (isStatement || isPrefix) {
return asPrefix();
}
if (isVariableReassignment) {
return asPostfixWithReassignment();
} else {
return asPostfixWithNoReassignment();
public static JsExpression translate(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) {
if (IncrementTranslator.isIncrement(expression)) {
return IncrementTranslator.translate(expression, context);
}
assert TranslationUtils.isIntrinsicOperation(context, expression);
return CallTranslator.translate(expression, context);
}
@NotNull
private JsExpression asPrefix() {
if (isVariableReassignment) {
return variableReassignment(baseExpression);
}
return operationExpression(baseExpression);
}
//TODO: decide if this expression can be optimised in case of direct access (not property)
@NotNull
private JsExpression asPostfixWithReassignment() {
// code fragment: expr(a++)
// generate: expr( (t1 = a, t2 = t1, a = t1.inc(), t2) )
TemporaryVariable t1 = declareTemporary(baseExpression);
TemporaryVariable t2 = declareTemporary(t1.nameReference());
JsExpression variableReassignment = variableReassignment(t1.nameReference());
return AstUtil.newSequence(t1.assignmentExpression(), t2.assignmentExpression(),
variableReassignment, t2.nameReference());
}
@NotNull
private JsExpression asPostfixWithNoReassignment() {
// code fragment: expr(a++)
// generate: expr( (t1 = a, t2 = t1, t2.inc(), t1) )
TemporaryVariable t1 = declareTemporary(baseExpression);
TemporaryVariable t2 = declareTemporary(t1.nameReference());
JsExpression methodCall = operationExpression(t2.nameReference());
JsExpression returnedValue = t1.nameReference();
return AstUtil.newSequence(t1.assignmentExpression(), t2.assignmentExpression(), methodCall, returnedValue);
}
@NotNull
private JsExpression variableReassignment(@NotNull JsExpression toCallMethodUpon) {
if (isPropertyAccess) {
return propertyReassignment(toCallMethodUpon);
}
return localVariableReassignment(toCallMethodUpon);
}
private JsExpression localVariableReassignment(@NotNull JsExpression toCallMethodUpon) {
assert baseExpression instanceof JsNameRef : "Base expression should be an l-value";
return AstUtil.newAssignment((JsNameRef) baseExpression, operationExpression(toCallMethodUpon));
}
@NotNull
private JsExpression propertyReassignment(@NotNull JsExpression toCallMethodUpon) {
JetExpression jetBaseExpression = getBaseExpression(expression);
JsInvocation setterCall =
PropertyAccessTranslator.translateAsPropertySetterCall(jetBaseExpression, context());
assert PropertyAccessTranslator.canBePropertyGetterCall(jetBaseExpression, context()) : "Should be a getter call";
JsExpression overloadedMethodCallOnPropertyGetter = operationExpression(toCallMethodUpon);
setterCall.setArguments(overloadedMethodCallOnPropertyGetter);
return setterCall;
}
@NotNull
abstract JsExpression operationExpression(@NotNull JsExpression receiver);
@NotNull
protected JetToken getOperationToken() {
JetSimpleNameExpression operationExpression = expression.getOperation();
IElementType elementType = operationExpression.getReferencedNameElementType();
assert elementType instanceof JetToken : "Unary expression should have IElementType of type JetToken";
return (JetToken) elementType;
}
private boolean isPrefix(JetUnaryExpression expression) {
return (expression instanceof JetPrefixExpression);
}
}
@@ -0,0 +1,44 @@
package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
/**
* @author Talanov Pavel
*/
public abstract class AccessTranslator extends AbstractTranslator {
@NotNull
public static AccessTranslator getAccessTranslator(@NotNull JetExpression referenceExpression,
@NotNull TranslationContext context) {
assert ((referenceExpression instanceof JetReferenceExpression) ||
(referenceExpression instanceof JetDotQualifiedExpression));
if (PropertyAccessTranslator.canBePropertyAccess(referenceExpression, context)) {
return PropertyAccessTranslator.newInstance(referenceExpression, context);
}
if (referenceExpression instanceof JetArrayAccessExpression) {
return ArrayAccessTranslator.newInstance((JetArrayAccessExpression) referenceExpression, context);
}
return ReferenceAccessTranslator.newInstance((JetSimpleNameExpression) referenceExpression, context);
}
@NotNull
public static JsExpression translateAsGet(@NotNull JetReferenceExpression expression,
@NotNull TranslationContext context) {
return (getAccessTranslator(expression, context)).translateAsGet();
}
protected AccessTranslator(@Deprecated TranslationContext context) {
super(context);
}
public abstract JsExpression translateAsGet();
public abstract JsExpression translateAsSet(@NotNull JsExpression setTo);
}
@@ -5,16 +5,10 @@ import com.google.dart.compiler.backend.js.ast.JsInvocation;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
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.JetArrayAccessExpression;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -23,41 +17,25 @@ import java.util.List;
/**
* @author Talanov Pavel
*/
public final class ArrayAccessTranslator extends AbstractTranslator {
public final class ArrayAccessTranslator extends AccessTranslator {
public static boolean canBeArraySetterCall(@NotNull JetBinaryExpression expression) {
//TODO: move unsafe call to util
return (OperatorTable.isAssignment((JetToken) expression.getOperationToken())
&& (expression.getLeft() instanceof JetArrayAccessExpression));
public static ArrayAccessTranslator newInstance(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return new ArrayAccessTranslator(expression, context);
}
public static JsInvocation translateAsArrayGetterCall(@NotNull JetArrayAccessExpression expression,
@NotNull TranslationContext context) {
return (new ArrayAccessTranslator(expression, null, context)).translateAsArrayGet();
}
public static JsInvocation translateAsArraySetterCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
JetExpression arrayAccess = expression.getLeft();
assert (arrayAccess instanceof JetArrayAccessExpression) : "Check with canBeArraySetterCall";
JetExpression right = expression.getRight();
assert right != null : "Binary expression should have a right expression";
JsExpression expressionToSetTo = Translation.translateAsExpression(right, context);
return (new ArrayAccessTranslator((JetArrayAccessExpression) arrayAccess, expressionToSetTo, context))
.translateAsArraySet();
}
// public static JsExpression translateAsArrayGet(@NotNull JetArrayAccessExpression expression,
// @NotNull TranslationContext context) {
// return (new ArrayAccessTranslator(expression, context)).translateAsGet();
// }
@NotNull
private final JetArrayAccessExpression expression;
@NotNull
private final DeclarationDescriptor methodDescriptor;
@Nullable
private final JsExpression expressionToSetTo;
private ArrayAccessTranslator(@NotNull JetArrayAccessExpression expression,
@Nullable JsExpression expressionToSetTo,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
@@ -65,28 +43,28 @@ public final class ArrayAccessTranslator extends AbstractTranslator {
BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression);
assert descriptorForReferenceExpression != null : "Array access expression must reference a descriptor";
this.methodDescriptor = descriptorForReferenceExpression;
this.expressionToSetTo = expressionToSetTo;
}
@Override
@NotNull
private JsInvocation translateAsArrayGet() {
public JsInvocation translateAsGet() {
return translateAsArrayAccessWithIndices();
}
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression expression) {
JsInvocation setCall = translateAsArrayAccessWithIndices();
setCall.getArguments().add(expression);
return setCall;
}
private JsInvocation translateAsArrayAccessWithIndices() {
JsNameRef accessMethodReference = getAccessMethodReference();
AstUtil.setQualifier(accessMethodReference, translateArrayExpression());
return AstUtil.newInvocation(accessMethodReference, translateIndexExpressions());
}
@NotNull
private JsInvocation translateAsArraySet() {
assert expressionToSetTo != null;
JsInvocation setCall = translateAsArrayAccessWithIndices();
setCall.getArguments().add(expressionToSetTo);
return setCall;
}
@NotNull
private List<JsExpression> translateIndexExpressions() {
return TranslationUtils.translateExpressionList(context(), expression.getIndexExpressions());
@@ -10,8 +10,8 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -13,68 +13,54 @@ import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.PsiUtils;
/**
* @author Talanov Pavel
*/
public final class PropertyAccessTranslator extends AbstractTranslator {
public final class PropertyAccessTranslator extends AccessTranslator {
private static String MESSAGE = "Cannot be accessor call. Use canBeProperty*Call to ensure this method " +
"can be called safely.";
@NotNull
public static JsInvocation translateAsPropertySetterCall(@NotNull JetQualifiedExpression expression,
public static JsExpression translateAsPropertyGetterCall(@NotNull JetQualifiedExpression expression,
@NotNull TranslationContext context) {
return (new PropertyAccessTranslator(expression, context))
.translateAsPropertySetterCall();
.translateAsGet();
}
@NotNull
public static JsInvocation translateAsPropertySetterCall(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
return (new PropertyAccessTranslator(expression, context))
.translateAsPropertySetterCall();
public static PropertyAccessTranslator newInstance(@NotNull JetQualifiedExpression expression,
@NotNull TranslationContext context) {
return (new PropertyAccessTranslator(expression, context));
}
@NotNull
public static JsInvocation translateAsPropertySetterCall(@NotNull JetExpression expression,
public static PropertyAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
return (new PropertyAccessTranslator(expression, context));
}
@NotNull
public static JsExpression translateAsPropertyGetterCall(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
return (new PropertyAccessTranslator(expression, context))
.translateAsGet();
}
@NotNull
public static PropertyAccessTranslator newInstance(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
if (expression instanceof JetQualifiedExpression) {
return translateAsPropertySetterCall((JetQualifiedExpression) expression, context);
return newInstance((JetQualifiedExpression) expression, context);
}
if (expression instanceof JetSimpleNameExpression) {
return translateAsPropertySetterCall((JetSimpleNameExpression) expression, context);
}
throw new AssertionError(MESSAGE);
}
@NotNull
public static JsInvocation translateAsPropertyGetterCall(@NotNull JetQualifiedExpression expression,
@NotNull TranslationContext context) {
return (new PropertyAccessTranslator(expression, context))
.translateAsPropertyGetterCall();
}
@NotNull
public static JsInvocation translateAsPropertyGetterCall(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
return (new PropertyAccessTranslator(expression, context))
.translateAsPropertyGetterCall();
}
@NotNull
public static JsInvocation translateAsPropertyGetterCall(@NotNull JetExpression expression,
@NotNull TranslationContext context) {
if (expression instanceof JetQualifiedExpression) {
return translateAsPropertyGetterCall((JetQualifiedExpression) expression, context);
}
if (expression instanceof JetSimpleNameExpression) {
return translateAsPropertyGetterCall((JetSimpleNameExpression) expression, context);
return newInstance((JetSimpleNameExpression) expression, context);
}
throw new AssertionError(MESSAGE);
}
@@ -133,12 +119,22 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
this.propertyDescriptor = getNotNullPropertyDescriptor();
}
@Override
@NotNull
public JsInvocation translateAsPropertyGetterCall() {
public JsExpression translateAsGet() {
JsName getterName = getNotNullGetterName();
return qualifiedAccessorInvocation(getterName);
}
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
JsName setterName = getNotNullSetterName();
JsInvocation setterCall = qualifiedAccessorInvocation(setterName);
setterCall.getArguments().add(toSetTo);
return setterCall;
}
@NotNull
private JsInvocation qualifiedAccessorInvocation(@NotNull JsName accessorName) {
JsNameRef accessorReference = accessorName.makeRef();
@@ -146,12 +142,6 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
return AstUtil.newInvocation(accessorReference);
}
@NotNull
public JsInvocation translateAsPropertySetterCall() {
JsName setterName = getNotNullSetterName();
return qualifiedAccessorInvocation(setterName);
}
@NotNull
private JsExpression translateQualifier() {
if (qualifier != null) {
@@ -0,0 +1,45 @@
package org.jetbrains.k2js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
/**
* @author Talanov Pavel
*/
public final class ReferenceAccessTranslator extends AccessTranslator {
@NotNull
public static ReferenceAccessTranslator newInstance(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
return new ReferenceAccessTranslator(expression, context);
}
@NotNull
private final JetSimpleNameExpression expression;
private ReferenceAccessTranslator(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
super(context);
this.expression = expression;
}
@Override
@NotNull
public JsExpression translateAsGet() {
return ReferenceTranslator.translateSimpleName(expression, context());
}
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
JsExpression reference = ReferenceTranslator.translateSimpleName(expression, context());
assert reference instanceof JsNameRef;
return AstUtil.newAssignment((JsNameRef) reference, toSetTo);
}
}
@@ -7,8 +7,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.TranslationContext;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -247,4 +247,18 @@ public final class BindingUtils {
return result;
}
@Nullable
public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context,
@NotNull JetOperationExpression expression) {
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
(context, expression.getOperation());
if (descriptorForReferenceExpression == null) return null;
assert descriptorForReferenceExpression instanceof FunctionDescriptor
: "Operation should resolve to function descriptor.";
return (FunctionDescriptor) descriptorForReferenceExpression;
}
}
@@ -0,0 +1,23 @@
package org.jetbrains.k2js.translate.utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
/**
* @author Talanov Pavel
*/
public final class DescriptorUtils {
private DescriptorUtils() {
}
private static int valueParametersCount(@NotNull FunctionDescriptor functionDescriptor) {
return functionDescriptor.getValueParameters().size();
}
public static boolean hasParameters(@NotNull FunctionDescriptor functionDescriptor) {
return (valueParametersCount(functionDescriptor) > 0);
}
}
@@ -1,10 +1,13 @@
package org.jetbrains.k2js.translate.utils;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetOperationExpression;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lexer.JetToken;
/**
* @author Talanov Pavel
@@ -23,4 +26,12 @@ public final class PsiUtils {
}
return (JetSimpleNameExpression) selectorExpression;
}
@NotNull
public static JetToken getOperationToken(@NotNull JetOperationExpression expression) {
JetSimpleNameExpression operationExpression = expression.getOperation();
IElementType elementType = operationExpression.getReferencedNameElementType();
assert elementType instanceof JetToken : "Unary expression should have operation token of type JetToken";
return (JetToken) elementType;
}
}
@@ -9,8 +9,9 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
import org.jetbrains.k2js.translate.general.TranslationContext;
import java.util.ArrayList;
import java.util.List;
@@ -214,4 +215,15 @@ public final class TranslationUtils {
return Translation.translateAsExpression(rightExpression, context);
}
//TODO: check function with same name
public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
@NotNull JetOperationExpression expression) {
FunctionDescriptor operationDescriptor =
BindingUtils.getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
if (operationDescriptor == null) return true;
if (context.intrinsics().hasDescriptor(operationDescriptor)) return true;
return false;
}
}
@@ -6,12 +6,12 @@ fun box() : Int {
var z = 0
when(c) {
is 5, is 3 => z++;
else => z = -1000;
else => {z = -1000;}
}
when(d) {
is 5, is 3 => z++;
else => z = -1000;
else => {z = -1000;}
}
return z
}
@@ -3,8 +3,8 @@ namespace foo
fun box() : Boolean {
var a = 4
when(a) {
!is 3 => a = 10;
!is 4 => a = 20;
!is 3 => {a = 10;}
!is 4 => {a = 20;}
}
return (a == 10)
}
@@ -3,8 +3,8 @@ namespace foo
fun box() : Boolean {
var a = 4
when(a) {
is 3 => a = 10;
is 4 => a = 20;
is 3 => {a = 10;}
is 4 => {a = 20;}
}
return (a == 20)
}