JVM: Allow the JvmSynthetic annotation on file classes (KT-41884)

This commit is contained in:
Steven Schäfer
2020-10-09 14:04:35 +02:00
committed by Alexander Udalov
parent 66bc142f92
commit 4e03b1e05f
6 changed files with 40 additions and 13 deletions
@@ -42,9 +42,11 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.writeAnnotationData;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.METADATA_PACKAGE_NAME_FIELD_NAME;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.JVM_SYNTHETIC_ANNOTATION_FQ_NAME;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class PackagePartCodegen extends MemberCodegen<KtFile> {
@@ -63,8 +65,20 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
@Override
protected void generateDeclaration() {
boolean isSynthetic = false;
List<AnnotationDescriptor> fileAnnotationDescriptors = new ArrayList<>();
for (KtAnnotationEntry annotationEntry : element.getAnnotationEntries()) {
AnnotationDescriptor annotationDescriptor = state.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
if (annotationDescriptor != null) {
fileAnnotationDescriptors.add(annotationDescriptor);
if (Objects.equals(annotationDescriptor.getFqName(), JVM_SYNTHETIC_ANNOTATION_FQ_NAME)) {
isSynthetic = true;
}
}
}
v.defineClass(element, state.getClassFileVersion(),
ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
ACC_PUBLIC | ACC_FINAL | ACC_SUPER | (isSynthetic ? ACC_SYNTHETIC : 0),
packagePartType.getInternalName(),
null,
"java/lang/Object",
@@ -74,17 +88,6 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
generatePropertyMetadataArrayFieldIfNeeded(packagePartType);
generateAnnotationsForPartClass();
}
private void generateAnnotationsForPartClass() {
List<AnnotationDescriptor> fileAnnotationDescriptors = new ArrayList<>();
for (KtAnnotationEntry annotationEntry : element.getAnnotationEntries()) {
AnnotationDescriptor annotationDescriptor = state.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
if (annotationDescriptor != null) {
fileAnnotationDescriptors.add(annotationDescriptor);
}
}
Annotated annotatedFile = new AnnotatedImpl(Annotations.Companion.create(fileAnnotationDescriptors));
AnnotationCodegen.forClass(v.getVisitor(), this, state).genAnnotations(annotatedFile, null, null);
}
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.util.findImplementationFromInterface
val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault")
val JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME = FqName("kotlin.jvm.JvmDefaultWithoutCompatibility")
val JVM_OVERLOADS_FQ_NAME = FqName("kotlin.jvm.JvmOverloads")
@JvmField
val JVM_SYNTHETIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSynthetic")
@JvmField
@@ -10,8 +10,9 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.backend.jvm.lower.buildAssertionsDisabledField
import org.jetbrains.kotlin.backend.jvm.lower.hasAssertionsDisabledField
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.writeKotlinMetadata
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
@@ -446,6 +447,7 @@ class ClassCodegen private constructor(
private val IrClass.flags: Int
get() = origin.flags or getVisibilityAccessFlagForClass() or
(if (isAnnotatedWithDeprecated) Opcodes.ACC_DEPRECATED else 0) or
(if (hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)) Opcodes.ACC_SYNTHETIC else 0) or
when {
isAnnotationClass -> Opcodes.ACC_ANNOTATION or Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT
isInterface -> Opcodes.ACC_INTERFACE or Opcodes.ACC_ABSTRACT
@@ -0,0 +1,10 @@
// WITH_RUNTIME
// FILE: test.kt
@file:Suppress("WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET")
@file:JvmSynthetic
private val keepme = 1
// TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: TestKt
// FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER, ACC_SYNTHETIC
@@ -153,6 +153,11 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest {
public void testSimpleFilePackageFacade() throws Exception {
runTest("compiler/testData/writeFlags/class/accessFlags/simpleFilePackageFacade.kt");
}
@TestMetadata("syntheticFile.kt")
public void testSyntheticFile() throws Exception {
runTest("compiler/testData/writeFlags/class/accessFlags/syntheticFile.kt");
}
}
@TestMetadata("compiler/testData/writeFlags/class/deprecatedFlag")
@@ -153,6 +153,11 @@ public class IrWriteFlagsTestGenerated extends AbstractIrWriteFlagsTest {
public void testSimpleFilePackageFacade() throws Exception {
runTest("compiler/testData/writeFlags/class/accessFlags/simpleFilePackageFacade.kt");
}
@TestMetadata("syntheticFile.kt")
public void testSyntheticFile() throws Exception {
runTest("compiler/testData/writeFlags/class/accessFlags/syntheticFile.kt");
}
}
@TestMetadata("compiler/testData/writeFlags/class/deprecatedFlag")