From 5890813fc3225cf097bfccf5826ab0a406f2dca0 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 23 Jun 2011 21:24:49 +0400 Subject: [PATCH] Extension closures test fixed --- .../org/jetbrains/jet/codegen/ClosureCodegen.java | 11 +++++++++-- .../org/jetbrains/jet/codegen/ExpressionCodegen.java | 2 +- .../org/jetbrains/jet/codegen/FunctionCodegen.java | 11 +++++++++-- idea/testData/codegen/classes/extensionClosure.jet | 12 +++++++----- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java index e304a74b519..1fd2018aebc 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -93,7 +93,7 @@ public class ClosureCodegen { private void generateBody(String className, FunctionDescriptor funDescriptor, ClassVisitor cv, Project project, List body) { FunctionCodegen fc = new FunctionCodegen(null, cv, state); - fc.generatedMethod(body, OwnerKind.IMPLEMENTATION, invokeSignature(funDescriptor), null, funDescriptor.getUnsubstitutedValueParameters(), null); + fc.generatedMethod(body, OwnerKind.IMPLEMENTATION, invokeSignature(funDescriptor), funDescriptor.getReceiverType(), funDescriptor.getUnsubstitutedValueParameters(), null); } private void generateBridge(String className, FunctionDescriptor funDescriptor, ClassVisitor cv) { @@ -107,8 +107,15 @@ public class ClosureCodegen { iv.load(0, Type.getObjectType(className)); - final List params = funDescriptor.getUnsubstitutedValueParameters(); + final JetType receiverType = funDescriptor.getReceiverType(); int count = 1; + if (receiverType != null) { + StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); + StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(receiverType), iv); + count++; + } + + final List params = funDescriptor.getUnsubstitutedValueParameters(); for (ValueParameterDescriptor param : params) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(param.getOutType()), iv); diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 30c0dd42b60..9e4a967a99e 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -851,7 +851,7 @@ public class ExpressionCodegen extends JetVisitor { // TODO handle more levels of class nestng } else { - return StackValue.local(0, JetTypeMapper.TYPE_OBJECT); + return thisExpression != null ? thisExpression : StackValue.local(0, JetTypeMapper.TYPE_OBJECT); } } } diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 45a66dafeea..98517b007b2 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -74,8 +74,15 @@ public class FunctionCodegen { mv.visitCode(); FrameMap frameMap = new FrameMap(); - if (kind != OwnerKind.NAMESPACE || receiverType != null) { + int thisIdx = -1; + if (kind != OwnerKind.NAMESPACE) { frameMap.enterTemp(); // 0 slot for this + thisIdx++; + } + + if (receiverType != null) { + thisIdx++; + frameMap.enterTemp(); // Next slot for fake this } Type[] argTypes = jvmSignature.getArgumentTypes(); @@ -84,7 +91,7 @@ public class FunctionCodegen { frameMap.enter(parameter, argTypes[i].getSize()); } - StackValue thisExpression = receiverType == null ? null : StackValue.local(0, state.getTypeMapper().mapType(receiverType)); + StackValue thisExpression = receiverType == null ? null : StackValue.local(thisIdx, state.getTypeMapper().mapType(receiverType)); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), contextDesc, kind, thisExpression, state); if (kind instanceof OwnerKind.DelegateKind) { OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind; diff --git a/idea/testData/codegen/classes/extensionClosure.jet b/idea/testData/codegen/classes/extensionClosure.jet index c296b5fc242..8f95a8615d8 100644 --- a/idea/testData/codegen/classes/extensionClosure.jet +++ b/idea/testData/codegen/classes/extensionClosure.jet @@ -1,11 +1,13 @@ +class Point(val x : Int, val y : Int) + fun box() : String { - val answer = apply("OK", { String.() : Int => - length + val answer = apply(Point(3, 5), { Point.(scalar : Int) : Point => + Point(x * scalar, y * scalar) }) - return if (answer == 2) "OK" else "FAIL" + return if (answer.x == 6 && answer.y == 10) "OK" else "FAIL" } -fun apply(arg:String, f : {String.() : Int}) : Int { - return arg.f() +fun apply(arg:Point, f : {Point.(scalar : Int) : Point}) : Point { + return arg.f(2) }