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 4c79c6a9a6e..a540f80d405 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 @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.jvm.codegen +import org.jetbrains.kotlin.backend.common.lower.ANNOTATION_IMPLEMENTATION import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin @@ -450,7 +451,7 @@ class ClassCodegen private constructor( for (klass in innerClasses) { val innerClass = typeMapper.classInternalName(klass) val outerClass = - if (klass.isSamWrapper || klass.attributeOwnerId in context.isEnclosedInConstructor) + if (klass.isSamWrapper || klass.isAnnotationImplementation || klass.attributeOwnerId in context.isEnclosedInConstructor) null else { when (val parent = klass.parent) { @@ -465,7 +466,7 @@ class ClassCodegen private constructor( } private val IrClass.isAnonymousInnerClass: Boolean - get() = isSamWrapper || name.isSpecial // NB '' is treated as anonymous inner class here + get() = isSamWrapper || name.isSpecial || isAnnotationImplementation // NB '' is treated as anonymous inner class here private val IrClass.isInlineSamWrapper: Boolean get() = isSamWrapper && visibility == DescriptorVisibilities.PUBLIC @@ -473,6 +474,9 @@ class ClassCodegen private constructor( private val IrClass.isSamWrapper: Boolean get() = origin == IrDeclarationOrigin.GENERATED_SAM_IMPLEMENTATION + private val IrClass.isAnnotationImplementation: Boolean + get() = origin == ANNOTATION_IMPLEMENTATION + override fun addInnerClassInfoFromAnnotation(innerClass: IrClass) { // It's necessary for proper recovering of classId by plain string JVM descriptor when loading annotations // See FileBasedKotlinClass.convertAnnotationVisitor diff --git a/compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallGenerateSynthetic.txt b/compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallGenerateSynthetic.txt index e3b5c4822ae..bb6e69031ca 100644 --- a/compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallGenerateSynthetic.txt +++ b/compiler/testData/codegen/bytecodeListing/annotations/annotationCtorCallGenerateSynthetic.txt @@ -1,21 +1,22 @@ @kotlin.Metadata public synthetic final class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0 { // source: 'annotationCtorCallGenerateSynthetic.kt' + enclosing class AnnotationCtorCallGenerateSyntheticKt private synthetic final field int: int + inner (anonymous) class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0 public method (p0: int): void public synthetic final method annotationType(): java.lang.Class public final method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public final method hashCode(): int public synthetic final method int(): int public final @org.jetbrains.annotations.NotNull method toString(): java.lang.String - public synthetic inner class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0 } @kotlin.Metadata public final class AnnotationCtorCallGenerateSyntheticKt { // source: 'annotationCtorCallGenerateSynthetic.kt' + inner (anonymous) class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0 public final static method box(): void - public synthetic inner class AnnotationCtorCallGenerateSyntheticKt$annotationImpl$Foo$0 } @java.lang.annotation.Retention(value=RUNTIME) diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt index e24b28ec674..1cfe31af884 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.codegen.CodegenTestUtil import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File import kotlin.io.path.ExperimentalPathApi @@ -52,6 +53,9 @@ abstract class BaseJvmAbiTest : TestCase() { val javaDestinationDir: File get() = if (name == null) workingDir.resolve("javaOut") else workingDir.resolve("$name/javaOut") + val directives: File + get() = workingDir.resolve("directives.txt") + override fun toString(): String = "compilation '$name'" } @@ -77,6 +81,9 @@ abstract class BaseJvmAbiTest : TestCase() { ).toTypedArray() destination = compilation.destinationDir.canonicalPath useOldBackend = !useIrBackend + languageVersion = if (!compilation.directives.exists()) null else { + InTextDirectivesUtils.findStringWithPrefixes(compilation.directives.readText(), "// LANGUAGE_VERSION:") + } } val exitCode = compiler.exec(messageCollector, Services.EMPTY, args) if (exitCode != ExitCode.OK || messageCollector.errors.isNotEmpty()) { diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java index 766693321ec..768ce22a846 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/CompileAgainstJvmAbiTestGenerated.java @@ -45,6 +45,11 @@ public class CompileAgainstJvmAbiTestGenerated extends AbstractCompileAgainstJvm runTest("plugins/jvm-abi-gen/testData/compile/clinit/"); } + @TestMetadata("inlineAnnotationInstantiation") + public void testInlineAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/"); + } + @TestMetadata("inlineAnonymousObject") public void testInlineAnonymousObject() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/inlineAnonymousObject/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java index 137f0319624..10018498a0d 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrCompileAgainstJvmAbiTestGenerated.java @@ -45,6 +45,11 @@ public class IrCompileAgainstJvmAbiTestGenerated extends AbstractIrCompileAgains runTest("plugins/jvm-abi-gen/testData/compile/clinit/"); } + @TestMetadata("inlineAnnotationInstantiation") + public void testInlineAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/"); + } + @TestMetadata("inlineAnonymousObject") public void testInlineAnonymousObject() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/inlineAnonymousObject/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java index 78d2edd683f..b26bb65a8e3 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/IrJvmAbiContentTestGenerated.java @@ -35,6 +35,16 @@ public class IrJvmAbiContentTestGenerated extends AbstractIrJvmAbiContentTest { runTest("plugins/jvm-abi-gen/testData/content/annotation/"); } + @TestMetadata("annotationInstantiation") + public void testAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/annotationInstantiation/"); + } + + @TestMetadata("anonymousAnnotationInstantiation") + public void testAnonymousAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/"); + } + @TestMetadata("anonymousWhenMapping") public void testAnonymousWhenMapping() throws Exception { runTest("plugins/jvm-abi-gen/testData/content/anonymousWhenMapping/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java index c5c19bc8791..f675c05170c 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/JvmAbiContentTestGenerated.java @@ -35,6 +35,16 @@ public class JvmAbiContentTestGenerated extends AbstractJvmAbiContentTest { runTest("plugins/jvm-abi-gen/testData/content/annotation/"); } + @TestMetadata("annotationInstantiation") + public void testAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/annotationInstantiation/"); + } + + @TestMetadata("anonymousAnnotationInstantiation") + public void testAnonymousAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/"); + } + @TestMetadata("anonymousWhenMapping") public void testAnonymousWhenMapping() throws Exception { runTest("plugins/jvm-abi-gen/testData/content/anonymousWhenMapping/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java index afc3ccce6ee..8a75e923de8 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyCompileAgainstJvmAbiTestGenerated.java @@ -45,6 +45,11 @@ public class LegacyCompileAgainstJvmAbiTestGenerated extends AbstractLegacyCompi runTest("plugins/jvm-abi-gen/testData/compile/clinit/"); } + @TestMetadata("inlineAnnotationInstantiation") + public void testInlineAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/"); + } + @TestMetadata("inlineAnonymousObject") public void testInlineAnonymousObject() throws Exception { runTest("plugins/jvm-abi-gen/testData/compile/inlineAnonymousObject/"); diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java index 401a3f514ac..968146c0de9 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/LegacyJvmAbiContentTestGenerated.java @@ -35,6 +35,16 @@ public class LegacyJvmAbiContentTestGenerated extends AbstractLegacyJvmAbiConten runTest("plugins/jvm-abi-gen/testData/content/annotation/"); } + @TestMetadata("annotationInstantiation") + public void testAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/annotationInstantiation/"); + } + + @TestMetadata("anonymousAnnotationInstantiation") + public void testAnonymousAnnotationInstantiation() throws Exception { + runTest("plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/"); + } + @TestMetadata("anonymousWhenMapping") public void testAnonymousWhenMapping() throws Exception { runTest("plugins/jvm-abi-gen/testData/content/anonymousWhenMapping/"); diff --git a/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/app/app.kt b/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/app/app.kt new file mode 100644 index 00000000000..b4ce58037db --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/app/app.kt @@ -0,0 +1,7 @@ +package app + +import lib.* + +fun runAppAndReturnOk(): String { + return a().value +} diff --git a/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/directives.txt b/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/directives.txt new file mode 100644 index 00000000000..993013a0dbc --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/directives.txt @@ -0,0 +1,3 @@ +// LANGUAGE_VERSION: 1.6 +// IGNORE_BACKEND_LEGACY: JVM +// IGNORE_BACKEND: JVM \ No newline at end of file diff --git a/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/lib/lib.kt b/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/lib/lib.kt new file mode 100644 index 00000000000..320eb9db33e --- /dev/null +++ b/plugins/jvm-abi-gen/testData/compile/inlineAnnotationInstantiation/lib/lib.kt @@ -0,0 +1,5 @@ +package lib + +annotation class A(val value: String) + +inline fun a() = A("OK") diff --git a/plugins/jvm-abi-gen/testData/content/annotationInstantiation/directives.txt b/plugins/jvm-abi-gen/testData/content/annotationInstantiation/directives.txt new file mode 100644 index 00000000000..993013a0dbc --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/annotationInstantiation/directives.txt @@ -0,0 +1,3 @@ +// LANGUAGE_VERSION: 1.6 +// IGNORE_BACKEND_LEGACY: JVM +// IGNORE_BACKEND: JVM \ No newline at end of file diff --git a/plugins/jvm-abi-gen/testData/content/annotationInstantiation/signatures.txt b/plugins/jvm-abi-gen/testData/content/annotationInstantiation/signatures.txt new file mode 100644 index 00000000000..cd02c52777a --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/annotationInstantiation/signatures.txt @@ -0,0 +1,23 @@ +@java.lang.annotation.Retention(value=RUNTIME) +@kotlin.Metadata +public annotation class test/A { + // source: 'test.kt' +} +@kotlin.Metadata +public synthetic final class test/Test$annotationImpl$test_A$0 { + // source: 'test.kt' + enclosing class test/Test + inner (anonymous) class test/Test$annotationImpl$test_A$0 + public method (): void + public synthetic final method annotationType(): java.lang.Class + public final method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public final method hashCode(): int + public final @org.jetbrains.annotations.NotNull method toString(): java.lang.String +} +@kotlin.Metadata +public final class test/Test { + // source: 'test.kt' + inner (anonymous) class test/Test$annotationImpl$test_A$0 + public method (): void + public final @org.jetbrains.annotations.NotNull method annotationInstantiation(): test.A +} \ No newline at end of file diff --git a/plugins/jvm-abi-gen/testData/content/annotationInstantiation/test.kt b/plugins/jvm-abi-gen/testData/content/annotationInstantiation/test.kt new file mode 100644 index 00000000000..ff602d978b3 --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/annotationInstantiation/test.kt @@ -0,0 +1,7 @@ +package test + +annotation class A + +class Test { + inline fun annotationInstantiation() = A() +} diff --git a/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/directives.txt b/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/directives.txt new file mode 100644 index 00000000000..e89ced03c66 --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/directives.txt @@ -0,0 +1 @@ +// LANGUAGE_VERSION: 1.6 \ No newline at end of file diff --git a/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/signatures.txt b/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/signatures.txt new file mode 100644 index 00000000000..133842f54f2 --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/signatures.txt @@ -0,0 +1,11 @@ +@java.lang.annotation.Retention(value=RUNTIME) +@kotlin.Metadata +public annotation class test/A { + // source: 'test.kt' +} +@kotlin.Metadata +public final class test/Test { + // source: 'test.kt' + public method (): void + public final @org.jetbrains.annotations.NotNull method anonymousAnnotationInstantiation(): test.A +} \ No newline at end of file diff --git a/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/test.kt b/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/test.kt new file mode 100644 index 00000000000..5eca5c3d375 --- /dev/null +++ b/plugins/jvm-abi-gen/testData/content/anonymousAnnotationInstantiation/test.kt @@ -0,0 +1,7 @@ +package test + +annotation class A + +class Test { + fun anonymousAnnotationInstantiation() = A() +}