JVM: Allow the JvmSynthetic annotation on file classes (KT-41884)
This commit is contained in:
committed by
Alexander Udalov
parent
66bc142f92
commit
4e03b1e05f
@@ -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);
|
||||
}
|
||||
|
||||
+2
@@ -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
|
||||
|
||||
+3
-1
@@ -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
|
||||
+5
@@ -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")
|
||||
|
||||
+5
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user