Private outer functions are now accessed via bridge methods. Added tests.

This commit is contained in:
Evgeny Gerashchenko
2012-06-19 22:34:22 +04:00
parent 993aecbc94
commit 5ecfd71611
4 changed files with 86 additions and 4 deletions
@@ -1339,7 +1339,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private StackValue invokeFunction(JetCallExpression expression,
DeclarationDescriptor fd,
FunctionDescriptor fd,
StackValue receiver,
ResolvedCall<? extends CallableDescriptor> resolvedCall) {
boolean superCall = false;
@@ -1357,7 +1357,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
while(c.getContextDescriptor() != enclosed) {
c = c.getParentContext();
}
fd = c.getAccessor(fd);
fd = (FunctionDescriptor) c.getAccessor(fd);
superCall = false;
receiver = StackValue.thisOrOuter(this, enclosed);
}
@@ -1365,13 +1365,27 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
Callable callable = resolveToCallable((FunctionDescriptor) fd, superCall);
if (fd.getVisibility() == Visibilities.PRIVATE
&& !DescriptorUtils.isClassObject(fd.getContainingDeclaration())) {
if (context.getClassOrNamespaceDescriptor() != fd.getContainingDeclaration()) {
DeclarationDescriptor enclosed = fd.getContainingDeclaration();
if (enclosed != context.getThisDescriptor()) {
CodegenContext c = context;
while(c.getContextDescriptor() != enclosed) {
c = c.getParentContext();
}
fd = (FunctionDescriptor) c.getAccessor(fd);
}
}
}
Callable callable = resolveToCallable(fd, superCall);
if (callable instanceof CallableMethod) {
final CallableMethod callableMethod = (CallableMethod) callable;
invokeMethodWithArguments(callableMethod, expression, receiver);
final Type callReturnType = callableMethod.getSignature().getAsmMethod().getReturnType();
return returnValueAsStackValue((FunctionDescriptor) fd, callReturnType);
return returnValueAsStackValue(fd, callReturnType);
}
else {
receiver = StackValue.receiver(resolvedCall, receiver, this, null, state);
@@ -0,0 +1,31 @@
class C {
private fun String.ext() : String = ""
private fun f() {}
public fun foo() : String {
{
"".ext()
f()
}.invoke()
object : Runnable {
public override fun run() {
"".ext()
f()
}
}.run()
Inner().innerFun()
return "OK"
}
private class Inner() {
fun innerFun() {
"".ext()
f()
}
}
}
fun box() = C().foo()
@@ -0,0 +1,27 @@
class C{
private var v : Int = 0
public fun foo() : Int {
{
v = v + 1
}.invoke()
object : Runnable {
public override fun run() {
v = v + 1
}
}.run()
Inner().innerFun()
return v
}
private class Inner() {
fun innerFun() {
v = v + 1
}
}
}
fun box() = if (C().foo() == 3) "OK" else "NOT OK"
@@ -231,6 +231,16 @@ public class ClassGenTest extends CodegenTestCase {
blackBox();
}
public void testPrivateOuterProperty() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.JDK_HEADERS);
blackBoxFile("classes/privateOuterProperty.kt");
}
public void testPrivateOuterFunctions() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.JDK_HEADERS);
blackBoxFile("classes/privateOuterFunctions.kt");
}
public void testKt249() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.JDK_HEADERS);
blackBoxFile("regressions/kt249.jet");