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:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user