diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 55a6fbcb1f7..a2b9194b3dd 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -7,17 +7,16 @@
-
-
-
-
+
+
+
+
-
-
+
@@ -102,94 +101,94 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -199,46 +198,91 @@
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -265,22 +309,22 @@
@@ -323,21 +367,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -384,11 +413,7 @@
-
-
-
-
-
+
@@ -406,7 +431,7 @@
-
+
@@ -414,24 +439,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -456,19 +463,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -478,19 +473,63 @@
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -538,6 +577,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -555,9 +609,9 @@
-
-
+
+
@@ -813,17 +867,6 @@
-
-
-
-
-
-
-
-
-
-
-
@@ -850,6 +893,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -891,7 +945,7 @@
-
+
@@ -908,8 +962,8 @@
-
-
+
+
@@ -953,7 +1007,7 @@
-
+
@@ -966,7 +1020,6 @@
-
@@ -991,6 +1044,7 @@
+
@@ -1000,86 +1054,58 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
-
-
-
-
-
-
-
+
@@ -1098,16 +1124,44 @@
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/translator/src/org/jetbrains/k2js/translate/BinaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/BinaryOperationTranslator.java
new file mode 100644
index 00000000000..27a11cc4568
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/BinaryOperationTranslator.java
@@ -0,0 +1,105 @@
+package org.jetbrains.k2js.translate;
+
+import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
+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 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.lexer.JetToken;
+
+import java.util.Arrays;
+
+/**
+ * @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();
+ }
+
+ @NotNull
+ private final JetBinaryExpression expression;
+
+ private BinaryOperationTranslator(@NotNull JetBinaryExpression expression,
+ @NotNull TranslationContext context) {
+ super(context);
+ this.expression = expression;
+ }
+
+ @NotNull
+ JsExpression translate() {
+ JsInvocation setterCall = translateAsSetterCall();
+ if (setterCall != null) {
+ return setterCall;
+ }
+ return translateAsBinaryOperation();
+ }
+
+ //TODO: think about the ways to improve logic here
+ @Nullable
+ public JsInvocation translateAsSetterCall() {
+ JetToken jetOperationToken = getOperationToken();
+ if (!OperatorTable.isAssignment(jetOperationToken)) {
+ return null;
+ }
+ JetExpression leftExpression = expression.getLeft();
+ JsInvocation setterCall = Translation.propertyAccessTranslator(translationContext()).
+ translateAsPropertySetterCall(leftExpression);
+ if (setterCall == null) {
+ return null;
+ }
+ JsExpression right = translateRightExpression();
+ setterCall.setArguments(Arrays.asList(right));
+ return setterCall;
+ }
+
+ @NotNull
+ private JsExpression translateAsBinaryOperation() {
+
+ JsExpression left = Translation.translateAsExpression(expression.getLeft(), translationContext());
+ JsExpression right = translateRightExpression();
+
+ JsNameRef operationReference = getOverloadedOperationReference(expression);
+ if (operationReference != null) {
+ return overloadedMethodInvocation(left, right, operationReference);
+ }
+ 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(Arrays.asList(left, right));
+ return functionInvocation;
+ }
+ throw new AssertionError("Unsupported token encountered: " + token.toString());
+ }
+
+ @NotNull
+ private JsExpression overloadedMethodInvocation(@NotNull JsExpression left, @NotNull JsExpression right,
+ @NotNull JsNameRef operationReference) {
+ AstUtil.setQualifier(operationReference, left);
+ return AstUtil.newInvocation(operationReference, right);
+ }
+
+ @NotNull
+ private JsExpression translateRightExpression() {
+ JetExpression rightExpression = expression.getRight();
+ assert rightExpression != null : "Binary expression should have a right expression";
+ return Translation.translateAsExpression(rightExpression, translationContext());
+ }
+
+ @NotNull
+ private JetToken getOperationToken() {
+ return (JetToken) expression.getOperationToken();
+ }
+
+
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java
index cea0f6f2076..3a97c3b2184 100644
--- a/translator/src/org/jetbrains/k2js/translate/BindingUtils.java
+++ b/translator/src/org/jetbrains/k2js/translate/BindingUtils.java
@@ -172,4 +172,10 @@ public final class BindingUtils {
@NotNull JetExpression expression) {
return (context.get(BindingContext.RESOLVED_CALL, expression));
}
+
+ static public boolean isVariableReassignment(@NotNull BindingContext context, @NotNull JetExpression expression) {
+ Boolean result = context.get(BindingContext.VARIABLE_REASSIGNMENT, expression);
+ assert result != null;
+ return result;
+ }
}
diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
index 22dfd364f83..c5872ebd326 100644
--- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
+++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java
@@ -81,7 +81,7 @@ public final class ExpressionVisitor extends TranslatorVisitor {
@NotNull
public JsNode visitBinaryExpression(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
- return Translation.operationTranslator(context).translate(expression);
+ return BinaryOperationTranslator.translate(expression, context);
}
@Override
@@ -320,7 +320,7 @@ public final class ExpressionVisitor extends TranslatorVisitor {
@NotNull
public JsNode visitPrefixExpression(@NotNull JetPrefixExpression expression,
@NotNull TranslationContext context) {
- return Translation.operationTranslator(context).translatePrefixOperation(expression);
+ return UnaryOperationTranslator.translate(expression, context);
}
@@ -328,7 +328,7 @@ public final class ExpressionVisitor extends TranslatorVisitor {
@NotNull
public JsNode visitPostfixExpression(@NotNull JetPostfixExpression expression,
@NotNull TranslationContext context) {
- return Translation.operationTranslator(context).translatePostfixOperation(expression);
+ return UnaryOperationTranslator.translate(expression, context);
}
@Override
diff --git a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java
index f4a6efdb004..f8998f6fc18 100644
--- a/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/OperationTranslator.java
@@ -1,129 +1,25 @@
package org.jetbrains.k2js.translate;
-import com.google.dart.compiler.backend.js.ast.*;
-import com.google.dart.compiler.util.AstUtil;
-import com.intellij.psi.tree.IElementType;
+import com.google.dart.compiler.backend.js.ast.JsNameRef;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.psi.*;
-import org.jetbrains.jet.lexer.JetToken;
-
-import java.util.Arrays;
+import org.jetbrains.jet.lang.psi.JetBinaryExpression;
+import org.jetbrains.jet.lang.psi.JetExpression;
+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
+import org.jetbrains.jet.lang.psi.JetUnaryExpression;
/**
* @author Talanov Pavel
*/
-public final class OperationTranslator extends AbstractTranslator {
+public class OperationTranslator extends AbstractTranslator {
- @NotNull
- static public OperationTranslator newInstance(@NotNull TranslationContext context) {
- return new OperationTranslator(context);
- }
-
- private OperationTranslator(@NotNull TranslationContext context) {
+ protected OperationTranslator(@NotNull TranslationContext context) {
super(context);
}
- @NotNull
- JsExpression translatePostfixOperation(@NotNull JetPostfixExpression expression) {
- JsExpression baseExpression = translateBaseExpression(expression);
- JsNameRef operationReference = getOverloadedOperationReference(expression);
- if (operationReference != null) {
- return overloadedMethodInvocation(baseExpression, operationReference);
- }
- JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
- return new JsPostfixOperation(operator, baseExpression);
- }
-
- @NotNull
- JsExpression translatePrefixOperation(@NotNull JetPrefixExpression expression) {
- JsExpression baseExpression = translateBaseExpression(expression);
- JsNameRef operationReference = getOverloadedOperationReference(expression);
- if (operationReference != null) {
- return overloadedMethodInvocation(baseExpression, operationReference);
- }
- JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
- return new JsPrefixOperation(operator, baseExpression);
- }
-
- @NotNull
- private JsExpression translateBaseExpression(@NotNull JetUnaryExpression expression) {
- JetExpression baseExpression = expression.getBaseExpression();
- assert baseExpression != null : "Unary operation should have a base expression";
- return Translation.translateAsExpression(baseExpression, translationContext());
- }
-
- @NotNull
- private JsExpression overloadedMethodInvocation(@NotNull JsExpression base, @NotNull JsNameRef operationReference) {
- AstUtil.setQualifier(operationReference, base);
- return AstUtil.newInvocation(operationReference);
- }
-
- @NotNull
- private JetToken getOperationToken(@NotNull JetUnaryExpression expression) {
- JetSimpleNameExpression operationExpression = expression.getOperationSign();
- IElementType elementType = operationExpression.getReferencedNameElementType();
- assert elementType instanceof JetToken : "Unary operation should have IElementType of type JetToken";
- return (JetToken) elementType;
- }
-
- @NotNull
- JsExpression translate(@NotNull JetBinaryExpression expression) {
- JsInvocation setterCall = translateAsSetterCall(expression);
- if (setterCall != null) {
- return setterCall;
- }
- return translateAsBinaryOperation(expression);
- }
-
- //TODO: think about the ways to improve logic here
@Nullable
- public JsInvocation translateAsSetterCall(@NotNull JetBinaryExpression expression) {
- JetToken jetOperationToken = getOperationToken(expression);
- if (!OperatorTable.isAssignment(jetOperationToken)) {
- return null;
- }
- JetExpression leftExpression = expression.getLeft();
- JsInvocation setterCall = Translation.propertyAccessTranslator(translationContext()).
- translateAsPropertySetterCall(leftExpression);
- if (setterCall == null) {
- return null;
- }
- JsExpression right = translateRightExpression(expression);
- setterCall.setArguments(Arrays.asList(right));
- return setterCall;
- }
-
- @NotNull
- private JsExpression translateAsBinaryOperation(@NotNull JetBinaryExpression expression) {
-
- JsExpression left = Translation.translateAsExpression(expression.getLeft(), translationContext());
- JsExpression right = translateRightExpression(expression);
-
- JsNameRef operationReference = getOverloadedOperationReference(expression);
- if (operationReference != null) {
- return overloadedMethodInvocation(left, right, operationReference);
- }
- JetToken token = getOperationToken(expression);
- if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
- return new JsBinaryOperation(OperatorTable.getBinaryOperator(token), left, right);
- }
- if (OperatorTable.hasCorrespondingFunctionInvocation(token)) {
- JsInvocation functionInvocation = OperatorTable.getCorrespondingFunctionInvocation(token);
- functionInvocation.setArguments(Arrays.asList(left, right));
- return functionInvocation;
- }
- throw new AssertionError("Unsupported token encountered: " + token.toString());
- }
-
- private JsExpression overloadedMethodInvocation(JsExpression left, JsExpression right, JsNameRef operationReference) {
- AstUtil.setQualifier(operationReference, left);
- return AstUtil.newInvocation(operationReference, right);
- }
-
- @Nullable
- private JsNameRef getOverloadedOperationReference(@NotNull JetExpression expression) {
+ protected JsNameRef getOverloadedOperationReference(@NotNull JetExpression expression) {
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression);
if (operationDescriptor == null) {
return null;
@@ -143,22 +39,8 @@ public final class OperationTranslator extends AbstractTranslator {
if (expression instanceof JetUnaryExpression) {
operationReference = ((JetUnaryExpression) expression).getOperationSign();
}
- assert operationReference != null : "should be applied only to unary or binary operations";
+ assert operationReference != null : "Should be applied only to unary or binary operations";
return BindingUtils.getDescriptorForReferenceExpression
(translationContext().bindingContext(), operationReference);
}
-
- @NotNull
- private JsExpression translateRightExpression(@NotNull JetBinaryExpression expression) {
- JetExpression rightExpression = expression.getRight();
- assert rightExpression != null : "Binary expression should have a right expression";
- return Translation.translateAsExpression(rightExpression, translationContext());
- }
-
- @NotNull
- private JetToken getOperationToken(@NotNull JetBinaryExpression expression) {
- return (JetToken) expression.getOperationToken();
- }
-
-
}
diff --git a/translator/src/org/jetbrains/k2js/translate/Translation.java b/translator/src/org/jetbrains/k2js/translate/Translation.java
index 0ce9bc0f75b..1b870236386 100644
--- a/translator/src/org/jetbrains/k2js/translate/Translation.java
+++ b/translator/src/org/jetbrains/k2js/translate/Translation.java
@@ -44,11 +44,6 @@ public final class Translation {
return ClassTranslator.newInstance(context);
}
- @NotNull
- static public OperationTranslator operationTranslator(@NotNull TranslationContext context) {
- return OperationTranslator.newInstance(context);
- }
-
@NotNull
static public PatternTranslator patternTranslator(@NotNull TranslationContext context) {
return PatternTranslator.newInstance(context);
diff --git a/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java
new file mode 100644
index 00000000000..493061298cd
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java
@@ -0,0 +1,87 @@
+package org.jetbrains.k2js.translate;
+
+import com.google.dart.compiler.backend.js.ast.*;
+import com.google.dart.compiler.util.AstUtil;
+import com.intellij.psi.tree.IElementType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.psi.*;
+import org.jetbrains.jet.lexer.JetToken;
+
+/**
+ * @author Talanov Pavel
+ */
+public final class UnaryOperationTranslator extends OperationTranslator {
+
+
+ @NotNull
+ static public JsExpression translate(@NotNull JetPrefixExpression expression,
+ @NotNull TranslationContext context) {
+ return (new UnaryOperationTranslator(context, expression, true)).translate();
+ }
+
+ @NotNull
+ static public JsExpression translate(@NotNull JetPostfixExpression expression,
+ @NotNull TranslationContext context) {
+ return (new UnaryOperationTranslator(context, expression, false)).translate();
+ }
+
+ @NotNull
+ private final JetUnaryExpression expression;
+ private final boolean isPrefix;
+ private final boolean isVariableReassignment;
+
+ private UnaryOperationTranslator(@NotNull TranslationContext context, @NotNull JetUnaryExpression expression,
+ boolean isPrefix) {
+ super(context);
+ this.expression = expression;
+ this.isPrefix = isPrefix;
+ this.isVariableReassignment = BindingUtils.isVariableReassignment
+ (translationContext().bindingContext(), expression);
+ }
+
+ @NotNull
+ JsExpression translate() {
+ JsExpression baseExpression = translateBaseExpression();
+ JsNameRef operationReference = getOverloadedOperationReference(expression);
+ if (operationReference != null) {
+ if (isPrefix && !isVariableReassignment) {
+ return overloadedMethodInvocation(baseExpression, operationReference);
+ } else if (isPrefix) {
+
+ }
+ }
+ return jsUnaryExpression(baseExpression);
+ }
+
+ @NotNull
+ private JsExpression jsUnaryExpression(@NotNull JsExpression baseExpression) {
+ JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken());
+ if (isPrefix) {
+ return new JsPrefixOperation(operator, baseExpression);
+ } else {
+ return new JsPostfixOperation(operator, baseExpression);
+ }
+ }
+
+ @NotNull
+ private JsExpression translateBaseExpression() {
+ JetExpression baseExpression = expression.getBaseExpression();
+ assert baseExpression != null : "Unary expression should have a base expression";
+ return Translation.translateAsExpression(baseExpression, translationContext());
+ }
+
+ @NotNull
+ private JsExpression overloadedMethodInvocation(@NotNull JsExpression receiver,
+ @NotNull JsNameRef operationReference) {
+ AstUtil.setQualifier(operationReference, receiver);
+ return AstUtil.newInvocation(operationReference);
+ }
+
+ @NotNull
+ private JetToken getOperationToken() {
+ JetSimpleNameExpression operationExpression = expression.getOperationSign();
+ IElementType elementType = operationExpression.getReferencedNameElementType();
+ assert elementType instanceof JetToken : "Unary expression should have IElementType of type JetToken";
+ return (JetToken) elementType;
+ }
+}
diff --git a/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java b/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java
index 3c393a51d4f..4f67514c292 100644
--- a/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java
+++ b/translator/test/org/jetbrains/k2js/test/KotlinLibTest.java
@@ -107,5 +107,11 @@ public class KotlinLibTest extends TranslationTest {
new RhinoFunctionResultChecker("test", true));
}
+ @Test
+ public void commaExpression() throws Exception {
+ runRhinoTest(Arrays.asList(kotlinLibraryPath(), cases("commaExpression.js")),
+ new RhinoFunctionResultChecker("test", true));
+ }
+
}
diff --git a/translator/testFiles/kotlinLib/cases/commaExpression.js b/translator/testFiles/kotlinLib/cases/commaExpression.js
new file mode 100644
index 00000000000..f145440e08c
--- /dev/null
+++ b/translator/testFiles/kotlinLib/cases/commaExpression.js
@@ -0,0 +1,6 @@
+a = 0
+f = (t = a, t1 = t, a = ++t1, t)
+
+test = function () {
+ return (f == 0) && (a == 1)
+}
\ No newline at end of file