Private outer functions are now accessed via bridge methods. Added tests.
This commit is contained in:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user