Fix determining enclosing class for closure
Enclosing class for closure is a class whose instance is captured by
closure as an outer 'this', and stored in a field 'this$0'.
Usually enclosing class for closure is an immediate outer class,
including classes for nested closures. For example:
class C {
fun foo() {}
val example1 = L1@ { foo() }
// Enclosing class for lambda 'L1' is 'C'
val example2 = L2a@ { L2b@ { foo() } }
// Enclosing class for nested lambda 'L2b'
// is a closure class for outer lambda 'L2a'
}
However, if the closure is created in a super type constructor call for
the outer class, corresponding instance is considered "uninitialized",
and can't be used as a proper class instance, and can't be referenced:
corresponding code is rejected by front-end.
class Outer {
fun foo() {}
inner class Inner : Base(L3@ { foo() })
// Enclosing class for lambda 'L3' is 'Outer',
// because 'Inner' is uninitialized in super type constructor call.
}
In CodegenAnnotatingVisitor, we maintain a stack of currently
uninitialized classes, and chose enclosing class for closure
as an inner-most surrounding class with initialized instance.
When generating code for this or outer class instance, we skip
contexts corresponding to classes with uninitialized instances.
This fixes a number of bytecode verification errors caused by incorrect
enclosing class for closure.
#KT-4174 Fixed Target versions 1.2.20
#KT-13454 Fixed Target versions 1.2.20
#KT-14148 Fixed Target versions 1.2.20
This commit is contained in:
@@ -2664,7 +2664,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
result = cur.getOuterExpression(result, false);
|
||||
}
|
||||
|
||||
cur = cur.getParentContext();
|
||||
cur = cur.getEnclosingClassContext();
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
+46
-2
@@ -81,6 +81,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
private final Stack<ClassDescriptor> classStack = new Stack<>();
|
||||
private final Stack<String> nameStack = new Stack<>();
|
||||
private final Set<ClassDescriptor> uninitializedClasses = new HashSet<>();
|
||||
|
||||
private final BindingTrace bindingTrace;
|
||||
private final BindingContext bindingContext;
|
||||
@@ -394,7 +395,18 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
@NotNull
|
||||
private MutableClosure recordClosure(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
|
||||
return CodegenBinding.recordClosure(bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name));
|
||||
return CodegenBinding.recordClosure(bindingTrace, classDescriptor, getProperEnclosingClass(), Type.getObjectType(name));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassDescriptor getProperEnclosingClass() {
|
||||
for (int i = classStack.size() - 1; i >= 0; i--) {
|
||||
ClassDescriptor fromStack = classStack.get(i);
|
||||
if (!uninitializedClasses.contains(fromStack)) {
|
||||
return fromStack;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void recordLocalVariablePropertyMetadata(LocalVariableDescriptor variableDescriptor) {
|
||||
@@ -627,10 +639,42 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
|
||||
@Override
|
||||
public void visitSuperTypeCallEntry(@NotNull KtSuperTypeCallEntry call) {
|
||||
super.visitSuperTypeCallEntry(call);
|
||||
// Closures in super type constructor calls for anonymous objects are created in outer context
|
||||
if (!isSuperTypeCallForAnonymousObject(call)) {
|
||||
withinUninitializedClass(call, () -> super.visitSuperTypeCallEntry(call));
|
||||
}
|
||||
else {
|
||||
super.visitSuperTypeCallEntry(call);
|
||||
}
|
||||
|
||||
checkSamCall(call);
|
||||
}
|
||||
|
||||
private static boolean isSuperTypeCallForAnonymousObject(@NotNull KtSuperTypeCallEntry call) {
|
||||
PsiElement parent = call.getParent();
|
||||
if (!(parent instanceof KtSuperTypeList)) return false;
|
||||
parent = parent.getParent();
|
||||
if (!(parent instanceof KtObjectDeclaration)) return false;
|
||||
parent = parent.getParent();
|
||||
if (!(parent instanceof KtObjectLiteralExpression)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitConstructorDelegationCall(@NotNull KtConstructorDelegationCall call) {
|
||||
withinUninitializedClass(call, () -> super.visitConstructorDelegationCall(call));
|
||||
}
|
||||
|
||||
private void withinUninitializedClass(@NotNull KtElement element, @NotNull Runnable operation) {
|
||||
ClassDescriptor currentClass = peekFromStack(classStack);
|
||||
assert currentClass != null : element.getClass().getSimpleName() + " should be inside a class: " + element.getText();
|
||||
assert !uninitializedClasses.contains(currentClass) : "Class entered twice: " + currentClass;
|
||||
uninitializedClasses.add(currentClass);
|
||||
operation.run();
|
||||
boolean removed = uninitializedClasses.remove(currentClass);
|
||||
assert removed : "Inconsistent uninitialized class stack: " + currentClass;
|
||||
}
|
||||
|
||||
private void recordSamConstructorIfNeeded(@NotNull KtCallElement expression, @NotNull ResolvedCall<?> call) {
|
||||
CallableDescriptor callableDescriptor = call.getResultingDescriptor();
|
||||
if (!(callableDescriptor.getOriginal() instanceof SamConstructorDescriptor)) return;
|
||||
|
||||
@@ -215,13 +215,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
private StackValue getOuterExpression(@Nullable StackValue prefix, boolean ignoreNoOuter, boolean captureThis) {
|
||||
if (outerExpression.invoke() == null) {
|
||||
if (!ignoreNoOuter) {
|
||||
throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor());
|
||||
throw new UnsupportedOperationException("Don't know how to generate outer expression: " + this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (captureThis) {
|
||||
if (closure == null) {
|
||||
throw new IllegalStateException("Can't capture this for context without closure: " + getContextDescriptor());
|
||||
throw new IllegalStateException("Can't capture this for context without closure: " + this);
|
||||
}
|
||||
closure.setCaptureThis();
|
||||
}
|
||||
@@ -348,13 +348,34 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return parentContext;
|
||||
}
|
||||
|
||||
public ClassDescriptor getEnclosingClass() {
|
||||
@Nullable
|
||||
public CodegenContext getEnclosingClassContext() {
|
||||
CodegenContext cur = getParentContext();
|
||||
while (cur != null && !(cur.getContextDescriptor() instanceof ClassDescriptor)) {
|
||||
while (cur != null) {
|
||||
if (cur instanceof ConstructorContext && !(((ConstructorContext) cur).isThisInitialized())) {
|
||||
// If the current context is a constructor with uninitialized 'this',
|
||||
// skip it and the corresponding class context
|
||||
CodegenContext parent = cur.getParentContext();
|
||||
assert parent != null : "Context " + cur + " should have a parent";
|
||||
cur = parent;
|
||||
}
|
||||
else {
|
||||
DeclarationDescriptor curDescriptor = cur.getContextDescriptor();
|
||||
if (curDescriptor instanceof ClassDescriptor) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
cur = cur.getParentContext();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return cur == null ? null : (ClassDescriptor) cur.getContextDescriptor();
|
||||
@Nullable
|
||||
public ClassDescriptor getEnclosingClass() {
|
||||
// TODO store enclosing context class in the context itself
|
||||
CodegenContext enclosingClassContext = getEnclosingClassContext();
|
||||
if (enclosingClassContext == null) return null;
|
||||
return (ClassDescriptor) enclosingClassContext.getContextDescriptor();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -474,7 +495,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor);
|
||||
throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor +
|
||||
" in context " + this);
|
||||
}
|
||||
|
||||
accessors.put(key, accessor);
|
||||
|
||||
@@ -61,6 +61,6 @@ public class ConstructorContext extends MethodContext {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Constructor: " + getContextDescriptor();
|
||||
return "Constructor: " + (isThisInitialized() ? "" : "UNINITIALIZED ") + getContextDescriptor();
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
open class Foo(val x: () -> String)
|
||||
|
||||
class Outer {
|
||||
val s = "OK"
|
||||
|
||||
inner class Inner : Foo({ s })
|
||||
}
|
||||
|
||||
fun box() = Outer().Inner().x()
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
interface Test {
|
||||
fun test(): String
|
||||
}
|
||||
|
||||
open class Base(val test: Test)
|
||||
|
||||
open class Outer(val x: String) {
|
||||
open inner class Inner
|
||||
|
||||
inner class JavacBug : Base(
|
||||
object : Outer.Inner(), Test {
|
||||
override fun test() = x
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun box() = Outer("OK").JavacBug().test.test()
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
open class C(val f: () -> String)
|
||||
|
||||
class B(val x: String) {
|
||||
fun foo(): C {
|
||||
class A : C({x}) {}
|
||||
return A()
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = B("OK").foo().f()
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
open class C(val s: String) {
|
||||
fun test(): String {
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
fun foo(): String {
|
||||
var s = "OK"
|
||||
class Z : C(s) {}
|
||||
return Z().test()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun box() : String {
|
||||
val b = B()
|
||||
val result = b.foo()
|
||||
return result
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
abstract class Base(val fn: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base(::ok)
|
||||
}
|
||||
|
||||
fun box() = Outer().Inner().fn()
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base(
|
||||
fun(): String {
|
||||
return ok
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner().callback()
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base(
|
||||
run {
|
||||
val x = ok
|
||||
{ x }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner().callback()
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base({ ok })
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner().callback()
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner1 {
|
||||
inner class Inner2 : Base({ ok })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner1().Inner2().callback()
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
// ^ see KT-21041
|
||||
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base {
|
||||
constructor() : super({ ok })
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner().callback()
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
abstract class Base(val fn: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
fun foo(): String {
|
||||
class Local : Base({ ok })
|
||||
|
||||
return Local().fn()
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = Outer().foo()
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
open class Base(val callback: () -> String)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base({ { ok }() })
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner().callback()
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
interface Callback {
|
||||
fun invoke(): String
|
||||
}
|
||||
|
||||
open class Base(val callback: Callback)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base(
|
||||
object : Callback {
|
||||
override fun invoke() =
|
||||
(object : Callback {
|
||||
override fun invoke() = ok
|
||||
}).invoke()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner().callback.invoke()
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
interface Callback {
|
||||
fun invoke(): String
|
||||
}
|
||||
|
||||
open class Base(val callback: Callback)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner : Base(
|
||||
object : Callback {
|
||||
override fun invoke() = ok
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner().callback.invoke()
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
interface Callback {
|
||||
fun invoke(): String
|
||||
}
|
||||
|
||||
open class Base(val callback: Callback)
|
||||
|
||||
class Outer {
|
||||
val ok = "OK"
|
||||
|
||||
inner class Inner1 {
|
||||
inner class Inner2 : Base(
|
||||
object : Callback {
|
||||
override fun invoke() = ok
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String =
|
||||
Outer().Inner1().Inner2().callback.invoke()
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
abstract class Base(val fn: () -> Test)
|
||||
|
||||
enum class Test(val ok: String) {
|
||||
TEST("OK") {
|
||||
inner class Inner : Base({ TEST })
|
||||
|
||||
override val base: Base
|
||||
get() = Inner()
|
||||
};
|
||||
|
||||
abstract val base: Base
|
||||
}
|
||||
|
||||
fun box() = Test.TEST.base.fn().ok
|
||||
+105
@@ -4019,6 +4019,111 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CapturingOuterClassInstanceInSuperCall extends AbstractIrBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInCapturingOuterClassInstanceInSuperCall() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13454.kt")
|
||||
public void testKt13454() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt13454.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14148.kt")
|
||||
public void testKt14148() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt14148.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174.kt")
|
||||
public void testKt4174() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174a.kt")
|
||||
public void testKt4174a() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174a.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedAsImplicitThisInBoundReference.kt")
|
||||
public void testOuterCapturedAsImplicitThisInBoundReference() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedAsImplicitThisInBoundReference.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInFunctionLiteral.kt")
|
||||
public void testOuterCapturedInFunctionLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInFunctionLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInInlineLambda.kt")
|
||||
public void testOuterCapturedInInlineLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInInlineLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda.kt")
|
||||
public void testOuterCapturedInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda2.kt")
|
||||
public void testOuterCapturedInLambda2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambdaInSecondaryConstructor.kt")
|
||||
public void testOuterCapturedInLambdaInSecondaryConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambdaInSecondaryConstructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLocalClass.kt")
|
||||
public void testOuterCapturedInLocalClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLocalClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedLambda.kt")
|
||||
public void testOuterCapturedInNestedLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedObject.kt")
|
||||
public void testOuterCapturedInNestedObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject.kt")
|
||||
public void testOuterCapturedInObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject2.kt")
|
||||
public void testOuterCapturedInObject2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
|
||||
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/closureInsideClosure")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -4019,6 +4019,111 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CapturingOuterClassInstanceInSuperCall extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInCapturingOuterClassInstanceInSuperCall() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13454.kt")
|
||||
public void testKt13454() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt13454.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14148.kt")
|
||||
public void testKt14148() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt14148.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174.kt")
|
||||
public void testKt4174() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174a.kt")
|
||||
public void testKt4174a() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174a.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedAsImplicitThisInBoundReference.kt")
|
||||
public void testOuterCapturedAsImplicitThisInBoundReference() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedAsImplicitThisInBoundReference.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInFunctionLiteral.kt")
|
||||
public void testOuterCapturedInFunctionLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInFunctionLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInInlineLambda.kt")
|
||||
public void testOuterCapturedInInlineLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInInlineLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda.kt")
|
||||
public void testOuterCapturedInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda2.kt")
|
||||
public void testOuterCapturedInLambda2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambdaInSecondaryConstructor.kt")
|
||||
public void testOuterCapturedInLambdaInSecondaryConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambdaInSecondaryConstructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLocalClass.kt")
|
||||
public void testOuterCapturedInLocalClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLocalClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedLambda.kt")
|
||||
public void testOuterCapturedInNestedLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedObject.kt")
|
||||
public void testOuterCapturedInNestedObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject.kt")
|
||||
public void testOuterCapturedInObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject2.kt")
|
||||
public void testOuterCapturedInObject2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
|
||||
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/closureInsideClosure")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -4019,6 +4019,111 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CapturingOuterClassInstanceInSuperCall extends AbstractLightAnalysisModeTest {
|
||||
public void testAllFilesPresentInCapturingOuterClassInstanceInSuperCall() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13454.kt")
|
||||
public void testKt13454() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt13454.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14148.kt")
|
||||
public void testKt14148() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt14148.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174.kt")
|
||||
public void testKt4174() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174a.kt")
|
||||
public void testKt4174a() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174a.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedAsImplicitThisInBoundReference.kt")
|
||||
public void testOuterCapturedAsImplicitThisInBoundReference() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedAsImplicitThisInBoundReference.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInFunctionLiteral.kt")
|
||||
public void testOuterCapturedInFunctionLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInFunctionLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInInlineLambda.kt")
|
||||
public void testOuterCapturedInInlineLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInInlineLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda.kt")
|
||||
public void testOuterCapturedInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda2.kt")
|
||||
public void testOuterCapturedInLambda2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambdaInSecondaryConstructor.kt")
|
||||
public void testOuterCapturedInLambdaInSecondaryConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambdaInSecondaryConstructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLocalClass.kt")
|
||||
public void testOuterCapturedInLocalClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLocalClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedLambda.kt")
|
||||
public void testOuterCapturedInNestedLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedObject.kt")
|
||||
public void testOuterCapturedInNestedObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject.kt")
|
||||
public void testOuterCapturedInObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject2.kt")
|
||||
public void testOuterCapturedInObject2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
|
||||
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/closureInsideClosure")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+111
@@ -4649,6 +4649,117 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CapturingOuterClassInstanceInSuperCall extends AbstractJsCodegenBoxTest {
|
||||
public void testAllFilesPresentInCapturingOuterClassInstanceInSuperCall() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt13454.kt")
|
||||
public void testKt13454() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt13454.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt14148.kt")
|
||||
public void testKt14148() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt14148.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174.kt")
|
||||
public void testKt4174() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4174a.kt")
|
||||
public void testKt4174a() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/kt4174a.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedAsImplicitThisInBoundReference.kt")
|
||||
public void testOuterCapturedAsImplicitThisInBoundReference() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedAsImplicitThisInBoundReference.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInFunctionLiteral.kt")
|
||||
public void testOuterCapturedInFunctionLiteral() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInFunctionLiteral.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInInlineLambda.kt")
|
||||
public void testOuterCapturedInInlineLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInInlineLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda.kt")
|
||||
public void testOuterCapturedInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambda2.kt")
|
||||
public void testOuterCapturedInLambda2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambda2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLambdaInSecondaryConstructor.kt")
|
||||
public void testOuterCapturedInLambdaInSecondaryConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLambdaInSecondaryConstructor.kt");
|
||||
try {
|
||||
doTest(fileName);
|
||||
}
|
||||
catch (Throwable ignore) {
|
||||
return;
|
||||
}
|
||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInLocalClass.kt")
|
||||
public void testOuterCapturedInLocalClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInLocalClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedLambda.kt")
|
||||
public void testOuterCapturedInNestedLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedLambda.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInNestedObject.kt")
|
||||
public void testOuterCapturedInNestedObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInNestedObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject.kt")
|
||||
public void testOuterCapturedInObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerCapturedInObject2.kt")
|
||||
public void testOuterCapturedInObject2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerCapturedInObject2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("outerEnumEntryCapturedInLambdaInInnerClass.kt")
|
||||
public void testOuterEnumEntryCapturedInLambdaInInnerClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/capturingOuterClassInstanceInSuperCall/outerEnumEntryCapturedInLambdaInInnerClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/closures/closureInsideClosure")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user