support operator overloading for unary methods

This commit is contained in:
Dmitry Jemerov
2011-07-14 19:19:27 +02:00
parent 385f8267fa
commit 8a6ccdfbf4
3 changed files with 53 additions and 10 deletions
@@ -1323,7 +1323,8 @@ public class ExpressionCodegen extends JetVisitor {
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationSign());
if (op instanceof FunctionDescriptor) {
final Type asmType = expressionType(expression);
if (generateUnaryOp(op, asmType, expression)) return;
generateUnaryOp(op, asmType, expression);
return;
}
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
}
@@ -1351,18 +1352,28 @@ public class ExpressionCodegen extends JetVisitor {
throw new UnsupportedOperationException("Don't know how to generate this prefix expression");
}
private boolean generateUnaryOp(DeclarationDescriptor op, Type asmType, final JetUnaryExpression unaryExpression) {
final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(op);
private void generateUnaryOp(DeclarationDescriptor op, Type asmType, final JetUnaryExpression unaryExpression) {
final JetExpression operand = unaryExpression.getBaseExpression();
if (intrinsic != null) {
myStack.push(intrinsic.generate(this, v, asmType, unaryExpression, Collections.singletonList(operand), false));
return true;
}
else if (isNumberPrimitive(asmType) && (op.getName().equals("inc") || op.getName().equals("dec"))) {
if (isNumberPrimitive(asmType) && (op.getName().equals("inc") || op.getName().equals("dec"))) {
myStack.push(generateIncrement(op, asmType, operand));
return true;
return;
}
final Callable callable = resolveToCallable((FunctionDescriptor) op);
if (callable instanceof IntrinsicMethod) {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
myStack.push(intrinsic.generate(this, v, expressionType(unaryExpression), unaryExpression,
Arrays.asList(unaryExpression.getBaseExpression()), false));
}
else {
CallableMethod callableMethod = (CallableMethod) callable;
genToJVMStack(unaryExpression.getBaseExpression());
callableMethod.invoke(v);
final StackValue value = returnValueAsStackValue((FunctionDescriptor) op, callableMethod.getSignature().getReturnType());
if (value != null) {
myStack.push(value);
}
}
return false;
}
private StackValue generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand) {
@@ -0,0 +1,28 @@
import java.util.*
class ArrayWrapper<T>() {
val contents = ArrayList<T>()
fun add(item: T) {
contents.add(item)
}
fun minus(): ArrayWrapper<T> {
val result = ArrayWrapper<T>()
result.contents.addAll(contents)
Collections.reverse(result.contents)
return result
}
fun get(index: Int): T {
return contents.get(index)
}
}
fun box(): String {
val v1 = ArrayWrapper<String>()
v1.add("foo")
v1.add("bar")
val v2 = -v1
return if (v2[0] == "bar" && v2[1] == "foo") "OK" else "fail"
}
@@ -136,6 +136,10 @@ public class ClassGenTest extends CodegenTestCase {
blackBoxFile("classes/overloadBinaryOperator.jet");
}
public void testOverloadUnaryOperator() throws Exception {
blackBoxFile("classes/overloadUnaryOperator.jet");
}
public void testEnumClass() throws Exception {
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
final Class direction = loadAllClasses(generateClassesInFile()).get("Direction");