diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e70430f1aa0..958e027e8f2 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1288,9 +1288,20 @@ public class ExpressionCodegen extends JetVisitor { intrinsic.generate(this, v, Type.VOID_TYPE, expression, Arrays.asList(lhs, expression.getRight()), false); } else { - throw new UnsupportedOperationException("TODO"); + CallableMethod method = (CallableMethod) callable; + FunctionDescriptor fd = (FunctionDescriptor) op; + StackValue value = generateIntermediateValue(lhs); + final boolean keepReturnValue = !fd.getReturnType().equals(JetStandardClasses.getUnitType()); + if (keepReturnValue) { + value.dupReceiver(v, 0); + } + value.put(lhsType, v); + genToJVMStack(expression.getRight()); + method.invoke(v); + if (keepReturnValue) { + value.store(v); + } } - } } diff --git a/idea/testData/codegen/classes/overloadPlusAssign.jet b/idea/testData/codegen/classes/overloadPlusAssign.jet new file mode 100644 index 00000000000..21459ecff1e --- /dev/null +++ b/idea/testData/codegen/classes/overloadPlusAssign.jet @@ -0,0 +1,26 @@ +import java.util.* + +class ArrayWrapper() { + val contents = ArrayList() + + fun add(item: T) { + contents.add(item) + } + + fun plusAssign(rhs: ArrayWrapper) { + contents.addAll(rhs.contents) + } + + fun get(index: Int): T { + return contents.get(index) + } +} + +fun box(): String { + val v1 = ArrayWrapper() + val v2 = ArrayWrapper() + v1.add("foo") + v2.add("bar") + v1 += v2 + return if (v1.contents.size() == 2) "OK" else "fail" +} diff --git a/idea/testData/codegen/classes/overloadPlusAssignReturn.jet b/idea/testData/codegen/classes/overloadPlusAssignReturn.jet new file mode 100644 index 00000000000..28fb9af2652 --- /dev/null +++ b/idea/testData/codegen/classes/overloadPlusAssignReturn.jet @@ -0,0 +1,30 @@ +import java.util.* + +class ArrayWrapper() { + val contents = ArrayList() + + fun add(item: T) { + contents.add(item) + } + + fun plusAssign(rhs: ArrayWrapper): ArrayWrapper { + val result = ArrayWrapper() + result.contents.addAll(contents) + result.contents.addAll(rhs.contents) + return result + } + + fun get(index: Int): T { + return contents.get(index) + } +} + +fun box(): String { + val v1 = ArrayWrapper() + val v2 = ArrayWrapper() + v1.add("foo") + val v3 = v1 + v2.add("bar") + v1 += v2 + return if (v1.contents.size() == 2 && v3.contents.size() == 1) "OK" else "fail" +} diff --git a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java index aefcec68fab..aac3d2ceb7a 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -140,6 +140,14 @@ public class ClassGenTest extends CodegenTestCase { blackBoxFile("classes/overloadUnaryOperator.jet"); } + public void testOverloadPlusAssign() throws Exception { + blackBoxFile("classes/overloadPlusAssign.jet"); + } + + public void testOverloadPlusAssignReturn() throws Exception { + blackBoxFile("classes/overloadPlusAssignReturn.jet"); + } + public void testEnumClass() throws Exception { loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }"); final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");