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) {
|
private void generateScript(@NotNull ScriptReceiver receiver) {
|
||||||
CodegenContext cur = context;
|
CodegenContext cur = context;
|
||||||
StackValue result = StackValue.local(0, OBJECT_TYPE);
|
StackValue result = StackValue.local(0, OBJECT_TYPE);
|
||||||
|
boolean inStartConstructorContext = cur instanceof ConstructorContext;
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
if (cur instanceof MethodContext && !(cur instanceof ConstructorContext)) {
|
if (!inStartConstructorContext) {
|
||||||
cur = cur.getParentContext();
|
cur = getNotNullParentContextForMethod(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur instanceof ScriptContext) {
|
if (cur instanceof ScriptContext) {
|
||||||
@@ -2239,13 +2240,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert cur != null;
|
|
||||||
result = cur.getOuterExpression(result, false);
|
result = cur.getOuterExpression(result, false);
|
||||||
|
|
||||||
if (cur instanceof ConstructorContext) {
|
if (inStartConstructorContext) {
|
||||||
cur = cur.getParentContext();
|
cur = getNotNullParentContextForMethod(cur);
|
||||||
|
inStartConstructorContext = false;
|
||||||
}
|
}
|
||||||
assert cur != null;
|
|
||||||
cur = cur.getParentContext();
|
cur = cur.getParentContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2268,6 +2269,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
CodegenContext cur = context;
|
CodegenContext cur = context;
|
||||||
Type type = asmType(calleeContainingClass.getDefaultType());
|
Type type = asmType(calleeContainingClass.getDefaultType());
|
||||||
StackValue result = StackValue.local(0, type);
|
StackValue result = StackValue.local(0, type);
|
||||||
|
boolean inStartConstructorContext = cur instanceof ConstructorContext;
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
ClassDescriptor thisDescriptor = cur.getThisDescriptor();
|
ClassDescriptor thisDescriptor = cur.getThisDescriptor();
|
||||||
if (!isSuper && thisDescriptor.equals(calleeContainingClass)
|
if (!isSuper && thisDescriptor.equals(calleeContainingClass)
|
||||||
@@ -2275,25 +2277,33 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
return castToRequiredTypeOfInterfaceIfNeeded(result, thisDescriptor, calleeContainingClass);
|
return castToRequiredTypeOfInterfaceIfNeeded(result, thisDescriptor, calleeContainingClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur instanceof MethodContext && !(cur instanceof ConstructorContext)) {
|
//for constructor super call we should access to outer instance through parameter in locals, in other cases through field for captured outer
|
||||||
cur = cur.getParentContext();
|
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();
|
cur = cur.getParentContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedOperationException();
|
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) {
|
private static boolean isReceiver(PsiElement expression) {
|
||||||
PsiElement parent = expression.getParent();
|
PsiElement parent = expression.getParent();
|
||||||
if (parent instanceof JetQualifiedExpression) {
|
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");
|
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")
|
@TestMetadata("kt3905.kt")
|
||||||
public void testKt3905() throws Exception {
|
public void testKt3905() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/closures/kt3905.kt");
|
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")
|
@TestMetadata("kt4137.kt")
|
||||||
public void testKt4137() throws Exception {
|
public void testKt4137() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/closures/kt4137.kt");
|
doTest("compiler/testData/codegen/box/closures/kt4137.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user