Make anonymous classes for callable references synthetic

#KT-28453 Fixed
This commit is contained in:
Alexander Udalov
2018-12-13 18:06:46 +01:00
parent ca4521d57d
commit c1ef89df2c
13 changed files with 61 additions and 16 deletions
@@ -435,6 +435,11 @@ public class AsmUtil {
return InlineUtil.isInlineOrContainingInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE; return InlineUtil.isInlineOrContainingInline(descriptor.getContainingDeclaration()) ? ACC_PUBLIC : NO_FLAG_PACKAGE_PRIVATE;
} }
public static int getSyntheticAccessFlagForLambdaClass(@NotNull ClassDescriptor descriptor) {
return descriptor instanceof SyntheticClassDescriptorForLambda &&
((SyntheticClassDescriptorForLambda) descriptor).isCallableReference() ? ACC_SYNTHETIC : 0;
}
public static int calculateInnerClassAccessFlags(@NotNull ClassDescriptor innerClass) { public static int calculateInnerClassAccessFlags(@NotNull ClassDescriptor innerClass) {
int visibility = int visibility =
innerClass instanceof SyntheticClassDescriptorForLambda innerClass instanceof SyntheticClassDescriptorForLambda
@@ -443,6 +448,7 @@ public class AsmUtil {
? ACC_PUBLIC ? ACC_PUBLIC
: getVisibilityAccessFlag(innerClass); : getVisibilityAccessFlag(innerClass);
return visibility | return visibility |
getSyntheticAccessFlagForLambdaClass(innerClass) |
innerAccessFlagsForModalityAndKind(innerClass) | innerAccessFlagsForModalityAndKind(innerClass) |
(innerClass.isInner() ? 0 : ACC_STATIC); (innerClass.isInner() ? 0 : ACC_STATIC);
} }
@@ -142,13 +142,14 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
sw.writeInterfaceEnd(); sw.writeInterfaceEnd();
} }
v.defineClass(element, v.defineClass(
state.getClassFileVersion(), element,
ACC_FINAL | ACC_SUPER | visibilityFlag, state.getClassFileVersion(),
asmType.getInternalName(), ACC_FINAL | ACC_SUPER | visibilityFlag | getSyntheticAccessFlagForLambdaClass(classDescriptor),
sw.makeJavaGenericSignature(), asmType.getInternalName(),
superClassAsmType.getInternalName(), sw.makeJavaGenericSignature(),
superInterfaceAsmTypes superClassAsmType.getInternalName(),
superInterfaceAsmTypes
); );
initDefaultSourceMappingIfNeeded(context, this, state); initDefaultSourceMappingIfNeeded(context, this, state);
@@ -92,7 +92,9 @@ class PropertyReferenceCodegen(
v.defineClass( v.defineClass(
element, element,
state.classFileVersion, state.classFileVersion,
ACC_FINAL or ACC_SUPER or AsmUtil.getVisibilityAccessFlagForClass(classDescriptor), ACC_FINAL or ACC_SUPER or
AsmUtil.getVisibilityAccessFlagForClass(classDescriptor) or
AsmUtil.getSyntheticAccessFlagForLambdaClass(classDescriptor),
asmType.internalName, asmType.internalName,
null, null,
superAsmType.internalName, superAsmType.internalName,
@@ -0,0 +1,20 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND: JVM_IR
// WITH_RUNTIME
class C {
fun f() {}
val r = 0
}
fun check(c: Class<*>) {
if (!c.isSynthetic) throw AssertionError("Fail: $c is not synthetic: ${c.modifiers}")
}
fun box(): String {
check(C::f.javaClass)
check(C::r.javaClass)
check(C()::f.javaClass)
check(C()::r.javaClass)
return "OK"
}
@@ -7,7 +7,7 @@ public final class A {
} }
@kotlin.Metadata @kotlin.Metadata
final class NoReceiverInCallableReferenceClassesKt$A_bar$1 { synthetic final class NoReceiverInCallableReferenceClassesKt$A_bar$1 {
public final static field INSTANCE: kotlin.reflect.KProperty1 public final static field INSTANCE: kotlin.reflect.KProperty1
static method <clinit>(): void static method <clinit>(): void
method <init>(): void method <init>(): void
@@ -18,7 +18,7 @@ final class NoReceiverInCallableReferenceClassesKt$A_bar$1 {
} }
@kotlin.Metadata @kotlin.Metadata
final class NoReceiverInCallableReferenceClassesKt$A_foo$1 { synthetic final class NoReceiverInCallableReferenceClassesKt$A_foo$1 {
public final static field INSTANCE: NoReceiverInCallableReferenceClassesKt$A_foo$1 public final static field INSTANCE: NoReceiverInCallableReferenceClassesKt$A_foo$1
inner class NoReceiverInCallableReferenceClassesKt$A_foo$1 inner class NoReceiverInCallableReferenceClassesKt$A_foo$1
static method <clinit>(): void static method <clinit>(): void
@@ -31,7 +31,7 @@ final class NoReceiverInCallableReferenceClassesKt$A_foo$1 {
} }
@kotlin.Metadata @kotlin.Metadata
final class NoReceiverInCallableReferenceClassesKt$aBar$1 { synthetic final class NoReceiverInCallableReferenceClassesKt$aBar$1 {
method <init>(p0: A): void method <init>(p0: A): void
public @org.jetbrains.annotations.Nullable method get(): java.lang.Object public @org.jetbrains.annotations.Nullable method get(): java.lang.Object
public method getName(): java.lang.String public method getName(): java.lang.String
@@ -40,7 +40,7 @@ final class NoReceiverInCallableReferenceClassesKt$aBar$1 {
} }
@kotlin.Metadata @kotlin.Metadata
final class NoReceiverInCallableReferenceClassesKt$aFoo$1 { synthetic final class NoReceiverInCallableReferenceClassesKt$aFoo$1 {
inner class NoReceiverInCallableReferenceClassesKt$aFoo$1 inner class NoReceiverInCallableReferenceClassesKt$aFoo$1
method <init>(p0: A): void method <init>(p0: A): void
public final method getName(): java.lang.String public final method getName(): java.lang.String
@@ -6,4 +6,4 @@ class A {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: A$bar$1 // TESTED_OBJECTS: A$bar$1
// FLAGS: ACC_FINAL, ACC_SUPER // FLAGS: ACC_FINAL, ACC_SUPER, ACC_SYNTHETIC
@@ -6,4 +6,4 @@ class A {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: A$bar$1 // TESTED_OBJECTS: A$bar$1
// FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER // FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER, ACC_SYNTHETIC
@@ -6,4 +6,4 @@ class A {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: A$bar$1 // TESTED_OBJECTS: A$bar$1
// FLAGS: ACC_FINAL, ACC_SUPER // FLAGS: ACC_FINAL, ACC_SUPER, ACC_SYNTHETIC
@@ -6,4 +6,4 @@ class A {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: A$bar$1 // TESTED_OBJECTS: A$bar$1
// FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER // FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER, ACC_SYNTHETIC
@@ -1744,6 +1744,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
} }
@TestMetadata("classesAreSynthetic.kt")
public void testClassesAreSynthetic() throws Exception {
runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt");
}
@TestMetadata("compiler/testData/codegen/box/callableReference/bound") @TestMetadata("compiler/testData/codegen/box/callableReference/bound")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -1744,6 +1744,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
} }
@TestMetadata("classesAreSynthetic.kt")
public void testClassesAreSynthetic() throws Exception {
runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt");
}
@TestMetadata("compiler/testData/codegen/box/callableReference/bound") @TestMetadata("compiler/testData/codegen/box/callableReference/bound")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -1744,6 +1744,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
} }
@TestMetadata("classesAreSynthetic.kt")
public void testClassesAreSynthetic() throws Exception {
runTest("compiler/testData/codegen/box/callableReference/classesAreSynthetic.kt");
}
@TestMetadata("compiler/testData/codegen/box/callableReference/bound") @TestMetadata("compiler/testData/codegen/box/callableReference/bound")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -33,6 +33,7 @@ class KotlinSyntheticTypeComponentProvider: SyntheticTypeComponentProvider {
val typeName = containingType.name() val typeName = containingType.name()
if (!FqNameUnsafe.isValid(typeName)) return false if (!FqNameUnsafe.isValid(typeName)) return false
// TODO: this is most likely not necessary since KT-28453 is fixed, but still can be useful when debugging old compiled code
if (containingType.isCallableReferenceSyntheticClass()) { if (containingType.isCallableReferenceSyntheticClass()) {
return true return true
} }