diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index e2aa36113af..bcca78b36dd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -348,6 +348,8 @@ class GenerationState private constructor( val abiStability = configuration.get(JVMConfigurationKeys.ABI_STABILITY) + val noNewJavaAnnotationTargets = configuration.getBoolean(JVMConfigurationKeys.NO_NEW_JAVA_ANNOTATION_TARGETS) + val globalSerializationBindings = JvmSerializationBindings() var mapInlineClass: (ClassDescriptor) -> Type = { descriptor -> typeMapper.mapType(descriptor.defaultType) } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 7d3d8de31a8..dc215c63ba5 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -524,6 +524,12 @@ Also sets `-jvm-target` value equal to the selected JDK version""" ) var ignoreConstOptimizationErrors: Boolean by FreezableVar(false) + @Argument( + value = "-Xno-new-java-annotation-targets", + description = "Do not generate Java 1.8+ targets for Kotlin annotation classes" + ) + var noNewJavaAnnotationTargets: Boolean by FreezableVar(false) + override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap, Any> { val result = super.configureAnalysisFlags(collector, languageVersion) result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index a3ee97bb85a..16dd1bccf60 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -312,6 +312,7 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr put(JVMConfigurationKeys.ENABLE_DEBUG_MODE, arguments.enableDebugMode) put(JVMConfigurationKeys.IGNORE_CONST_OPTIMIZATION_ERRORS, arguments.ignoreConstOptimizationErrors) + put(JVMConfigurationKeys.NO_NEW_JAVA_ANNOTATION_TARGETS, arguments.noNewJavaAnnotationTargets) val assertionsMode = JVMAssertionsMode.fromStringOrNull(arguments.assertionsMode) diff --git a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java index 6c33d4c8dd8..64a736ca0cd 100644 --- a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java +++ b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java @@ -162,4 +162,7 @@ public class JVMConfigurationKeys { public static final CompilerConfigurationKey IGNORE_CONST_OPTIMIZATION_ERRORS = CompilerConfigurationKey.create("Ignore errors from IrConstTransformer"); + + public static final CompilerConfigurationKey NO_NEW_JAVA_ANNOTATION_TARGETS = + CompilerConfigurationKey.create("Do not generate Java 1.8+ targets for Kotlin annotation classes"); } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 5096b024008..a55b02735f2 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -287,6 +287,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/annotations/noTypeUseIfDependOnJvm6.kt"); } + @Test + @TestMetadata("noTypeUseIfFlagIsSpecified.kt") + public void testNoTypeUseIfFlagIsSpecified() throws Exception { + runTest("compiler/testData/codegen/box/annotations/noTypeUseIfFlagIsSpecified.kt"); + } + @Test @TestMetadata("objectConstValInAnnotationArgument.kt") public void testObjectConstValInAnnotationArgument() throws Exception { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AdditionalClassAnnotationLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AdditionalClassAnnotationLowering.kt index 7396c12fc24..5e2118cd6d9 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AdditionalClassAnnotationLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/AdditionalClassAnnotationLowering.kt @@ -43,6 +43,8 @@ private class AdditionalClassAnnotationLowering(private val context: JvmBackendC context.state.jvmBackendClassResolver.resolveToClassDescriptors( Type.getObjectType("java/lang/invoke/LambdaMetafactory") ).isNotEmpty() + private val noNewJavaAnnotationTargets = + context.state.noNewJavaAnnotationTargets || !isCompilingAgainstJdk8OrLater override fun lower(irClass: IrClass) { if (!irClass.isAnnotationClass) return @@ -113,8 +115,8 @@ private class AdditionalClassAnnotationLowering(private val context: JvmBackendC private fun mapTarget(target: KotlinTarget): IrEnumEntry? = when (target) { - KotlinTarget.TYPE_PARAMETER -> symbols.typeParameterTarget.takeUnless { isCompilingAgainstJdk8OrLater } - KotlinTarget.TYPE -> symbols.typeUseTarget.takeUnless { isCompilingAgainstJdk8OrLater } + KotlinTarget.TYPE_PARAMETER -> symbols.typeParameterTarget.takeUnless { noNewJavaAnnotationTargets } + KotlinTarget.TYPE -> symbols.typeUseTarget.takeUnless { noNewJavaAnnotationTargets } else -> symbols.jvmTargetMap[target] } diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt index 28afa134f18..b9236d38a46 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt @@ -74,6 +74,7 @@ object LanguageSettingsDirectives : SimpleDirectivesContainer() { val NO_UNIFIED_NULL_CHECKS by directive("No unified null checks") val PARAMETERS_METADATA by directive("Add parameters metadata for 1.8 reflection") val USE_TYPE_TABLE by directive("Use type table in metadata serialization") + val NO_NEW_JAVA_ANNOTATION_TARGETS by directive("Do not generate Java annotation targets TYPE_USE/TYPE_PARAMETER for Kotlin annotation classes with Kotlin targets TYPE/TYPE_PARAMETER") // --------------------- Utils --------------------- diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index cacacdfc2c7..c21bd4383d9 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -93,6 +93,8 @@ where advanced options include: -Xno-call-assertions Don't generate not-null assertions for arguments of platform types -Xno-kotlin-nothing-value-exception Do not use KotlinNothingValueException available since 1.4 + -Xno-new-java-annotation-targets + Do not generate Java 1.8+ targets for Kotlin annotation classes -Xno-optimize Disable optimizations -Xno-optimized-callable-references Do not use optimized callable reference superclasses available from 1.4 diff --git a/compiler/testData/codegen/box/annotations/noTypeUseIfFlagIsSpecified.kt b/compiler/testData/codegen/box/annotations/noTypeUseIfFlagIsSpecified.kt new file mode 100644 index 00000000000..4e69b6e470b --- /dev/null +++ b/compiler/testData/codegen/box/annotations/noTypeUseIfFlagIsSpecified.kt @@ -0,0 +1,39 @@ +// This test checks that we don't generate target TYPE_USE if `-Xno-new-java-annotation-targets` is used. +// It's important that this test depends on _full JDK_, which has ElementType.TYPE_USE, to check that filtering based on +// the compiler argument is taking place. + +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// NO_NEW_JAVA_ANNOTATION_TARGETS +// FULL_JDK +// WITH_STDLIB + +import kotlin.annotation.AnnotationTarget.* + +@Target( + CLASS, + ANNOTATION_CLASS, + TYPE_PARAMETER, + PROPERTY, + FIELD, + LOCAL_VARIABLE, + VALUE_PARAMETER, + CONSTRUCTOR, + FUNCTION, + PROPERTY_GETTER, + PROPERTY_SETTER, + TYPE, + EXPRESSION, + FILE, + TYPEALIAS, +) +@Retention(AnnotationRetention.SOURCE) +annotation class A + +fun box(): String { + val targets = A::class.java.getAnnotation(java.lang.annotation.Target::class.java).value + if (targets.toList().toString() != "[TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE]") + return "Fail: Java annotation target list should not contain TYPE_USE/TYPE_PARAMETER: ${targets.toList()}" + + return "OK" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index d78f4d1233d..19e931efe4d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -275,6 +275,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/annotations/noTypeUseIfDependOnJvm6.kt"); } + @Test + @TestMetadata("noTypeUseIfFlagIsSpecified.kt") + public void testNoTypeUseIfFlagIsSpecified() throws Exception { + runTest("compiler/testData/codegen/box/annotations/noTypeUseIfFlagIsSpecified.kt"); + } + @Test @TestMetadata("parameterAnnotationInDefaultImpls.kt") public void testParameterAnnotationInDefaultImpls() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 841727a374b..5f640b2f136 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -287,6 +287,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/annotations/noTypeUseIfDependOnJvm6.kt"); } + @Test + @TestMetadata("noTypeUseIfFlagIsSpecified.kt") + public void testNoTypeUseIfFlagIsSpecified() throws Exception { + runTest("compiler/testData/codegen/box/annotations/noTypeUseIfFlagIsSpecified.kt"); + } + @Test @TestMetadata("objectConstValInAnnotationArgument.kt") public void testObjectConstValInAnnotationArgument() throws Exception { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt index 541e880978d..639fae91e09 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt @@ -48,6 +48,7 @@ import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.NO_OPTIMI import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.NO_UNIFIED_NULL_CHECKS import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.PARAMETERS_METADATA import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.JDK_RELEASE +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.NO_NEW_JAVA_ANNOTATION_TARGETS import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.USE_TYPE_TABLE import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives @@ -173,6 +174,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig register(JDK_RELEASE, JVMConfigurationKeys.JDK_RELEASE) register(USE_TYPE_TABLE, JVMConfigurationKeys.USE_TYPE_TABLE) register(ENABLE_DEBUG_MODE, JVMConfigurationKeys.ENABLE_DEBUG_MODE) + register(NO_NEW_JAVA_ANNOTATION_TARGETS, JVMConfigurationKeys.NO_NEW_JAVA_ANNOTATION_TARGETS) } override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 31fba2cea88..2d6b5dcef9e 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -35,6 +35,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class Annotations extends AbstractLightAnalysisModeTest { + @TestMetadata("noTypeUseIfDependOnJvm6.kt") + public void ignoreNoTypeUseIfDependOnJvm6() throws Exception { + runTest("compiler/testData/codegen/box/annotations/noTypeUseIfDependOnJvm6.kt"); + } + + @TestMetadata("noTypeUseIfFlagIsSpecified.kt") + public void ignoreNoTypeUseIfFlagIsSpecified() throws Exception { + runTest("compiler/testData/codegen/box/annotations/noTypeUseIfFlagIsSpecified.kt"); + } + private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); } @@ -238,11 +248,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/annotations/nestedClassesInAnnotations.kt"); } - @TestMetadata("noTypeUseIfDependOnJvm6.kt") - public void testNoTypeUseIfDependOnJvm6() throws Exception { - runTest("compiler/testData/codegen/box/annotations/noTypeUseIfDependOnJvm6.kt"); - } - @TestMetadata("parameterAnnotationInDefaultImpls.kt") public void testParameterAnnotationInDefaultImpls() throws Exception { runTest("compiler/testData/codegen/box/annotations/parameterAnnotationInDefaultImpls.kt");