KT-3523: VerifyError for invoke function in inner class

KT-4106: VerifyError: Can't access outer this in a lambda in inner class' constructor
KT-3152: VerifyError when accessing from a function of object to a field of outer outer class

  #KT-3523 Fixed
  #KT-4106 Fixed
  #KT-3152 Fixed
This commit is contained in:
Mikhael Bogdanov
2013-10-30 16:00:17 +04:00
parent 10396b853a
commit c325dfffd9
5 changed files with 89 additions and 17 deletions
@@ -2218,9 +2218,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private void generateScript(@NotNull ScriptReceiver receiver) {
CodegenContext cur = context;
StackValue result = StackValue.local(0, OBJECT_TYPE);
boolean inStartConstructorContext = cur instanceof ConstructorContext;
while (cur != null) {
if (cur instanceof MethodContext && !(cur instanceof ConstructorContext)) {
cur = cur.getParentContext();
if (!inStartConstructorContext) {
cur = getNotNullParentContextForMethod(cur);
}
if (cur instanceof ScriptContext) {
@@ -2239,13 +2240,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return;
}
assert cur != null;
result = cur.getOuterExpression(result, false);
if (cur instanceof ConstructorContext) {
cur = cur.getParentContext();
if (inStartConstructorContext) {
cur = getNotNullParentContextForMethod(cur);
inStartConstructorContext = false;
}
assert cur != null;
cur = cur.getParentContext();
}
@@ -2268,6 +2269,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
CodegenContext cur = context;
Type type = asmType(calleeContainingClass.getDefaultType());
StackValue result = StackValue.local(0, type);
boolean inStartConstructorContext = cur instanceof ConstructorContext;
while (cur != null) {
ClassDescriptor thisDescriptor = cur.getThisDescriptor();
if (!isSuper && thisDescriptor.equals(calleeContainingClass)
@@ -2275,25 +2277,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return castToRequiredTypeOfInterfaceIfNeeded(result, thisDescriptor, calleeContainingClass);
}
if (cur instanceof MethodContext && !(cur instanceof ConstructorContext)) {
cur = cur.getParentContext();
//for constructor super call we should access to outer instance through parameter in locals, in other cases through field for captured outer
if (inStartConstructorContext) {
result = cur.getOuterExpression(result, false);
cur = getNotNullParentContextForMethod(cur);
inStartConstructorContext = false;
}
else {
cur = getNotNullParentContextForMethod(cur);
result = cur.getOuterExpression(result, false);
}
assert cur != null;
result = cur.getOuterExpression(result, false);
if (cur instanceof ConstructorContext) {
cur = cur.getParentContext();
}
assert cur != null;
cur = cur.getParentContext();
}
throw new UnsupportedOperationException();
}
@NotNull
private CodegenContext getNotNullParentContextForMethod(@NotNull CodegenContext cur) {
if (cur instanceof MethodContext) {
cur = cur.getParentContext();
}
assert cur != null;
return cur;
}
private static boolean isReceiver(PsiElement expression) {
PsiElement parent = expression.getParent();
if (parent instanceof JetQualifiedExpression) {
@@ -0,0 +1,14 @@
public class Test {
val content = 1
inner class A {
val v = object {
fun f() = content
}
}
}
fun box(): String {
Test().A()
return "OK"
}
@@ -0,0 +1,18 @@
open class Base {
fun doSomething() {
}
}
class X(val action: () -> Unit) { }
class Foo : Base() {
inner class Bar() {
val x = X({ doSomething() })
}
}
fun box() : String {
Foo().Bar()
return "OK"
}
@@ -0,0 +1,15 @@
class Foo(private val s: String) {
private inner class Inner {
private val x = {
this@Foo.s
}()
}
val f = Inner()
}
fun box(): String {
Foo("!")
return "OK"
}
@@ -1257,11 +1257,26 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/closures/kt2151.kt");
}
@TestMetadata("kt3152.kt")
public void testKt3152() throws Exception {
doTest("compiler/testData/codegen/box/closures/kt3152.kt");
}
@TestMetadata("kt3523.kt")
public void testKt3523() throws Exception {
doTest("compiler/testData/codegen/box/closures/kt3523.kt");
}
@TestMetadata("kt3905.kt")
public void testKt3905() throws Exception {
doTest("compiler/testData/codegen/box/closures/kt3905.kt");
}
@TestMetadata("kt4106.kt")
public void testKt4106() throws Exception {
doTest("compiler/testData/codegen/box/closures/kt4106.kt");
}
@TestMetadata("kt4137.kt")
public void testKt4137() throws Exception {
doTest("compiler/testData/codegen/box/closures/kt4137.kt");