From 4e03b1e05f3a8a29a5d9175bc347dafad73b0762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Fri, 9 Oct 2020 14:04:35 +0200 Subject: [PATCH] JVM: Allow the JvmSynthetic annotation on file classes (KT-41884) --- .../kotlin/codegen/PackagePartCodegen.java | 27 ++++++++++--------- .../jvm/annotations/jvmAnnotationUtil.kt | 2 ++ .../backend/jvm/codegen/ClassCodegen.kt | 4 ++- .../class/accessFlags/syntheticFile.kt | 10 +++++++ .../flags/WriteFlagsTestGenerated.java | 5 ++++ .../codegen/ir/IrWriteFlagsTestGenerated.java | 5 ++++ 6 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/writeFlags/class/accessFlags/syntheticFile.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java index 874c29396ec..0cd60d0c0fb 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackagePartCodegen.java @@ -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 { @@ -63,8 +65,20 @@ public class PackagePartCodegen extends MemberCodegen { @Override protected void generateDeclaration() { + boolean isSynthetic = false; + List 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 { generatePropertyMetadataArrayFieldIfNeeded(packagePartType); - generateAnnotationsForPartClass(); - } - - private void generateAnnotationsForPartClass() { - List 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); } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt index 91eca15f61d..8ed167fb0ae 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotations/jvmAnnotationUtil.kt @@ -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 diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 54d24e6cb2f..94096187b51 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -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 diff --git a/compiler/testData/writeFlags/class/accessFlags/syntheticFile.kt b/compiler/testData/writeFlags/class/accessFlags/syntheticFile.kt new file mode 100644 index 00000000000..c364b9c4be3 --- /dev/null +++ b/compiler/testData/writeFlags/class/accessFlags/syntheticFile.kt @@ -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 diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java index 184bb0e2a2d..45c5350c65b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java @@ -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") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java index 9bed820bd69..12f8f98ce30 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java @@ -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")