generate calls to overloaded binary operators and infix calls

This commit is contained in:
Dmitry Jemerov
2011-07-14 18:35:45 +02:00
parent 0518cba342
commit e316989706
3 changed files with 52 additions and 10 deletions
@@ -815,12 +815,7 @@ public class ExpressionCodegen extends JetVisitor {
invokeMethodWithArguments(callableMethod, expression, haveReceiver);
final Type callReturnType = callableMethod.getSignature().getReturnType();
if (callReturnType != Type.VOID_TYPE) {
final Type retType = typeMapper.mapType(fd.getReturnType());
StackValue.onStack(callReturnType).upcast(retType, v);
return StackValue.onStack(retType);
}
return null;
return returnValueAsStackValue(fd, callReturnType);
}
else {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
@@ -832,6 +827,15 @@ public class ExpressionCodegen extends JetVisitor {
}
}
private StackValue returnValueAsStackValue(FunctionDescriptor fd, Type callReturnType) {
if (callReturnType != Type.VOID_TYPE) {
final Type retType = typeMapper.mapType(fd.getReturnType());
StackValue.onStack(callReturnType).upcast(retType, v);
return StackValue.onStack(retType);
}
return null;
}
private Callable resolveToCallable(FunctionDescriptor fd) {
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(fd);
if (intrinsic != null) {
@@ -1094,14 +1098,23 @@ public class ExpressionCodegen extends JetVisitor {
else {
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
if (op instanceof FunctionDescriptor) {
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(op);
if (intrinsic != null) {
final Callable callable = resolveToCallable((FunctionDescriptor) op);
if (callable instanceof IntrinsicMethod) {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
myStack.push(intrinsic.generate(this, v, expressionType(expression), expression,
Arrays.asList(expression.getLeft(), expression.getRight()), false));
return;
}
else {
CallableMethod callableMethod = (CallableMethod) callable;
genToJVMStack(expression.getLeft());
genToJVMStack(expression.getRight());
callableMethod.invoke(v);
final StackValue value = returnValueAsStackValue((FunctionDescriptor) op, callableMethod.getSignature().getReturnType());
if (value != null) {
myStack.push(value);
}
}
}
throw new UnsupportedOperationException("Don't know how to generate binary op " + expression);
}
}
@@ -0,0 +1,25 @@
import java.util.*
class ArrayWrapper<T>() {
val contents = ArrayList<T>()
fun add(item: T) {
contents.add(item)
}
fun plus(b: ArrayWrapper<T>): ArrayWrapper<T> {
val result = ArrayWrapper<T>()
result.contents.addAll(contents)
result.contents.addAll(b.contents)
return result
}
}
fun box(): String {
val v1 = ArrayWrapper<String>()
val v2 = ArrayWrapper<String>()
v1.add("foo")
v2.add("bar")
val v3 = v1 + v2
return if (v3.contents.size() == 2) "OK" else "fail"
}
@@ -132,6 +132,10 @@ public class ClassGenTest extends CodegenTestCase {
assertInstanceOf(result, Runnable.class);
}
public void testOverloadBinaryOperator() throws Exception {
blackBoxFile("classes/overloadBinaryOperator.jet");
}
public void testEnumClass() throws Exception {
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");