diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 381b9217ce2..5991d28f1f1 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -7,19 +7,14 @@
-
-
-
-
+
+
+
-
-
-
-
-
-
+
+
@@ -90,78 +85,31 @@
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -170,16 +118,63 @@
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -246,7 +241,7 @@
-
+
@@ -300,22 +295,22 @@
@@ -390,6 +385,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -452,28 +487,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -532,6 +545,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -578,54 +609,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -719,116 +702,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -900,6 +773,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -996,11 +938,11 @@
-
-
-
-
-
+
+
+
+
+
localhost
@@ -1040,21 +982,21 @@
-
+
-
+
-
+
-
-
+
+
@@ -1098,7 +1040,7 @@
-
+
@@ -1111,7 +1053,6 @@
-
@@ -1136,6 +1077,7 @@
+
@@ -1145,116 +1087,116 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
+
diff --git a/js/src/com/google/dart/compiler/util/AstUtil.java b/js/src/com/google/dart/compiler/util/AstUtil.java
index 09d37bbd348..1b583c11257 100644
--- a/js/src/com/google/dart/compiler/util/AstUtil.java
+++ b/js/src/com/google/dart/compiler/util/AstUtil.java
@@ -8,7 +8,6 @@ import com.google.dart.compiler.InternalCompilerException;
import com.google.dart.compiler.backend.js.ast.*;
import com.google.dart.compiler.common.SourceInfo;
-import java.util.Arrays;
import java.util.List;
/**
@@ -321,17 +320,4 @@ public class AstUtil {
public static JsExpression equalsTrue(JsExpression expression, JsProgram program) {
return equals(expression, program.getTrueLiteral());
}
-
- public static JsBinaryOperation comma(JsExpression... expressions) {
- return comma(Arrays.asList(expressions));
- }
-
- public static JsBinaryOperation comma(List expressions) {
- assert expressions.size() >= 2 : "Comma operator applicable to two or more expressions";
- JsBinaryOperation result = new JsBinaryOperation(JsBinaryOperator.COMMA, expressions.get(0), expressions.get(1));
- for (int i = 2; i < expressions.size(); ++i) {
- result = new JsBinaryOperation(JsBinaryOperator.COMMA, result, expressions.get(i));
- }
- return result;
- }
}
diff --git a/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java b/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java
index 2126333201f..c6a4140c269 100644
--- a/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java
+++ b/translator/src/org/jetbrains/k2js/translate/InitializerGenerator.java
@@ -36,6 +36,8 @@ public class InitializerGenerator {
return initializer;
}
+ //TODO: track context change points, make them consistent, make sure that inside class declaration block
+ // classes reference their ancestor by aliases
@NotNull
private JsFunction generateInitializeFunction() {
AbstractInitializerVisitor visitor;
diff --git a/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java b/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java
index 249b50ee6a0..ccfa13639c0 100644
--- a/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/UnaryOperationTranslator.java
@@ -63,7 +63,7 @@ public final class UnaryOperationTranslator extends OperationTranslator {
@NotNull
JsExpression translate() {
- if (operationReference != null) {
+ if ((operationReference != null) || isPropertyAccess) {
return translateOverload();
}
return jsUnaryExpression();
@@ -84,18 +84,21 @@ public final class UnaryOperationTranslator extends OperationTranslator {
@NotNull
private JsExpression asPrefix() {
if (isVariableReassignment) {
- return variableReassignment();
+ return variableReassignment(baseExpression);
}
- return overloadedMethodInvocation(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( (t = a, a = a.inc(), t) )
- TemporaryVariable t = declareTemporary(baseExpression);
- JsExpression variableReassignment = variableReassignment();
- return AstUtil.comma(t.assignmentExpression(), variableReassignment, t.nameReference());
+ // 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
@@ -105,41 +108,44 @@ public final class UnaryOperationTranslator extends OperationTranslator {
assert operationReference != null;
TemporaryVariable t1 = declareTemporary(baseExpression);
TemporaryVariable t2 = declareTemporary(t1.nameReference());
- JsExpression methodCall = overloadedMethodInvocation(t2.nameReference());
+ JsExpression methodCall = operationExpression(t2.nameReference());
JsExpression returnedValue = t1.nameReference();
- return AstUtil.comma(t1.assignmentExpression(), t2.assignmentExpression(), methodCall, returnedValue);
+ return AstUtil.newSequence(t1.assignmentExpression(), t2.assignmentExpression(), methodCall, returnedValue);
}
//TODO: should modify this for properties
@NotNull
- private JsExpression variableReassignment() {
+ private JsExpression variableReassignment(@NotNull JsExpression toCallMethodUpon) {
if (isPropertyAccess) {
- return propertyReassignment();
+ return propertyReassignment(toCallMethodUpon);
}
- return localVariableReassignment();
+ return localVariableReassignment(toCallMethodUpon);
}
- private JsExpression localVariableReassignment() {
+ private JsExpression localVariableReassignment(@NotNull JsExpression toCallMethodUpon) {
assert baseExpression instanceof JsNameRef : "Base expression should be an l-value";
- return AstUtil.newAssignment((JsNameRef) baseExpression, overloadedMethodInvocation(baseExpression));
+ return AstUtil.newAssignment((JsNameRef) baseExpression, operationExpression(toCallMethodUpon));
}
@NotNull
- private JsExpression propertyReassignment() {
+ private JsExpression propertyReassignment(@NotNull JsExpression toCallMethodUpon) {
JetExpression jetBaseExpression = getBaseExpression();
PropertyAccessTranslator propertyAccessTranslator = Translation.propertyAccessTranslator(translationContext());
JsInvocation setterCall = propertyAccessTranslator.translateAsPropertySetterCall(jetBaseExpression);
assert propertyAccessTranslator.canBePropertyGetterCall(jetBaseExpression) : "Should be a getter call";
- JsExpression overloadedMethodCallOnPropertyGetter = overloadedMethodInvocation(baseExpression);
+ JsExpression overloadedMethodCallOnPropertyGetter = operationExpression(toCallMethodUpon);
setterCall.setArguments(Arrays.asList(overloadedMethodCallOnPropertyGetter));
return setterCall;
}
@NotNull
- private JsExpression overloadedMethodInvocation(@NotNull JsExpression receiver) {
- AstUtil.setQualifier(operationReference, receiver);
- return AstUtil.newInvocation(operationReference);
+ private JsExpression operationExpression(@NotNull JsExpression receiver) {
+ if (operationReference != null) {
+ AstUtil.setQualifier(operationReference, receiver);
+ return AstUtil.newInvocation(operationReference);
+ }
+ return new JsPrefixOperation(OperatorTable.getUnaryOperator(getOperationToken()), receiver);
}
@NotNull
diff --git a/translator/test/org/jetbrains/k2js/test/FunctionTest.java b/translator/test/org/jetbrains/k2js/test/FunctionTest.java
index 3b41d6d0a41..b5155e10af0 100644
--- a/translator/test/org/jetbrains/k2js/test/FunctionTest.java
+++ b/translator/test/org/jetbrains/k2js/test/FunctionTest.java
@@ -54,4 +54,5 @@ public class FunctionTest extends AbstractExpressionTest {
testFooBoxIsOk("closureWithParameterAndBoxing.jet");
}
+
}
diff --git a/translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java b/translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java
index 60c4a939d53..217c25e0bbd 100644
--- a/translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java
+++ b/translator/test/org/jetbrains/k2js/test/OperatorOverloadingTest.java
@@ -43,4 +43,14 @@ public class OperatorOverloadingTest extends TranslationTest {
public void postfixOnProperty() throws Exception {
testFooBoxIsTrue("postfixOnProperty.kt");
}
+
+ @Test
+ public void operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce() throws Exception {
+ testFooBoxIsTrue("operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce.kt");
+ }
+
+ @Test
+ public void unaryOnIntProperty() throws Exception {
+ testFooBoxIsTrue("unaryOnIntProperty.kt");
+ }
}
diff --git a/translator/testFiles/operatorOverloading/cases/operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce.kt b/translator/testFiles/operatorOverloading/cases/operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce.kt
new file mode 100644
index 00000000000..0a4f4fc0045
--- /dev/null
+++ b/translator/testFiles/operatorOverloading/cases/operatorOverloadOnPropertyCallGetterAndSetterOnlyOnce.kt
@@ -0,0 +1,32 @@
+namespace foo
+
+class MyInt(i : Int) {
+ var b = i
+ fun inc() : MyInt {
+ b = b + 1;
+ return this;
+ }
+}
+
+class A() {
+
+ var gc = 0
+ var sc = 0
+
+
+ var b = MyInt(0)
+ get() {
+ gc = gc + 1;
+ return $b;
+ }
+ set(a : MyInt) {
+ sc = sc + 1;
+ }
+}
+
+
+fun box() : Boolean {
+ val t = A()
+ val d = t.b++;
+ return (t.sc == 1) && (t.gc == 1);
+}
\ No newline at end of file
diff --git a/translator/testFiles/operatorOverloading/cases/unaryOnIntProperty.kt b/translator/testFiles/operatorOverloading/cases/unaryOnIntProperty.kt
new file mode 100644
index 00000000000..1deb16a8d6d
--- /dev/null
+++ b/translator/testFiles/operatorOverloading/cases/unaryOnIntProperty.kt
@@ -0,0 +1,15 @@
+namespace foo
+
+class MyInt(i : Int) {
+ var b = i
+ fun inc() : MyInt {
+ b = b++;
+ return this;
+ }
+}
+
+fun box() : Boolean {
+ var t = MyInt(0)
+ t++;
+ return (t.b == 0)
+}
\ No newline at end of file