diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index 5a81729f429..f6252bab57c 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -744,7 +744,7 @@ class FirElementSerializer private constructor( for (attribute in type.attributes) { when { attribute is CustomAnnotationTypeAttribute -> - for (annotation in attribute.annotations) { + for (annotation in attribute.annotations.nonSourceAnnotations(session)) { extension.serializeTypeAnnotation(annotation, builder) } attribute.key in CompilerConeAttributes.classIdByCompilerAttributeKey -> diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt index d32b3af1e00..3f0bad329c5 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt @@ -55,8 +55,8 @@ private val FirExpression.callableNameOfMetaAnnotationArgument: Name? private val sourceName = Name.identifier("SOURCE") -fun FirAnnotationContainer.nonSourceAnnotations(session: FirSession): List = - annotations.filter { annotation -> +fun List.nonSourceAnnotations(session: FirSession): List = + this.filter { annotation -> val firAnnotationClass = annotation.toAnnotationClass(session) firAnnotationClass != null && firAnnotationClass.annotations.none { meta -> meta.toAnnotationClassId(session) == StandardClassIds.Annotations.Retention && @@ -64,6 +64,8 @@ fun FirAnnotationContainer.nonSourceAnnotations(session: FirSession): List = + annotations.nonSourceAnnotations(session) @Suppress("NOTHING_TO_INLINE") inline fun FirProperty.hasJvmFieldAnnotation(session: FirSession): Boolean = annotations.any { it.isJvmFieldAnnotation(session) } diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/coroutinesBinary.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/coroutinesBinary.kt index cf27f7d1c48..f6b0c98748f 100644 --- a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/coroutinesBinary.kt +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/coroutinesBinary.kt @@ -1,5 +1,3 @@ -// KT-55464 -// IGNORE_BACKEND_K2: NATIVE // MODULE: lib // WITH_STDLIB // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt b/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt index 1fcbd55ddbe..a5dd8bb3375 100644 --- a/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt +++ b/compiler/testData/codegen/box/coroutines/multiModule/inlineMultiModuleWithController.kt @@ -1,6 +1,4 @@ // IGNORE_BACKEND: JS_IR, JS_IR_ES6 -// KT-55464 -// IGNORE_BACKEND_K2: NATIVE // WITH_COROUTINES // WITH_STDLIB // MODULE: lib(support) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt index 6e200cf5937..e307f743c53 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/FirSerializer.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation @@ -135,10 +136,10 @@ class FirNativeKLibSerializerExtension( ) { // inspired by KlibMetadataSerializerExtension.serializeFunction declarationFileId(function)?.let { proto.setExtension(KlibMetadataProtoBuf.functionFile, it) } - function.annotations.forEach { + function.nonSourceAnnotations(session).forEach { proto.addExtension(KlibMetadataProtoBuf.functionAnnotation, annotationSerializer.serializeAnnotation(it)) } - function.receiverParameter?.annotations?.forEach { + function.receiverParameter?.nonSourceAnnotations(session)?.forEach { proto.addExtension(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation, annotationSerializer.serializeAnnotation(it)) } // TODO KT-56090 Serialize KDocString @@ -146,7 +147,7 @@ class FirNativeKLibSerializerExtension( } override fun serializeValueParameter(parameter: FirValueParameter, proto: ProtoBuf.ValueParameter.Builder) { - parameter.annotations.forEach { + parameter.nonSourceAnnotations(session).forEach { proto.addExtension(KlibMetadataProtoBuf.parameterAnnotation, annotationSerializer.serializeAnnotation(it)) } super.serializeValueParameter(parameter, proto) @@ -160,8 +161,19 @@ class FirNativeKLibSerializerExtension( ) { // inspired by KlibMetadataSerializerExtension.serializeProperty declarationFileId(property)?.let { proto.setExtension(KlibMetadataProtoBuf.propertyFile, it) } - property.annotations.forEach { - proto.addExtension(KlibMetadataProtoBuf.propertyAnnotation, annotationSerializer.serializeAnnotation(it)) + property.nonSourceAnnotations(session).forEach { + val extension = when (it.useSiteTarget) { // Revise this code after KT-54385 + AnnotationUseSiteTarget.FIELD -> KlibMetadataProtoBuf.propertyBackingFieldAnnotation + AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD -> KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation + else -> KlibMetadataProtoBuf.propertyAnnotation + } + proto.addExtension(extension, annotationSerializer.serializeAnnotation(it)) + } + property.getter?.nonSourceAnnotations(session)?.forEach { + proto.addExtension(KlibMetadataProtoBuf.propertyGetterAnnotation, annotationSerializer.serializeAnnotation(it)) + } + property.setter?.nonSourceAnnotations(session)?.forEach { + proto.addExtension(KlibMetadataProtoBuf.propertySetterAnnotation, annotationSerializer.serializeAnnotation(it)) } // TODO KT-56090 Serialize KDocString super.serializeProperty(property, proto, versionRequirementTable, childSerializer) @@ -173,7 +185,8 @@ class FirNativeKLibSerializerExtension( versionRequirementTable: MutableVersionRequirementTable, childSerializer: FirElementSerializer ) { - klass.annotations.forEach { + declarationFileId(klass)?.let { proto.setExtension(KlibMetadataProtoBuf.classFile, it) } + klass.nonSourceAnnotations(session).forEach { proto.addExtension(KlibMetadataProtoBuf.classAnnotation, annotationSerializer.serializeAnnotation(it)) } // TODO KT-56090 Serialize KDocString @@ -185,7 +198,7 @@ class FirNativeKLibSerializerExtension( proto: ProtoBuf.Constructor.Builder, childSerializer: FirElementSerializer ) { - constructor.annotations.forEach { + constructor.nonSourceAnnotations(session).forEach { proto.addExtension(KlibMetadataProtoBuf.constructorAnnotation, annotationSerializer.serializeAnnotation(it)) } // TODO KT-56090 Serialize KDocString @@ -193,21 +206,19 @@ class FirNativeKLibSerializerExtension( } override fun serializeEnumEntry(enumEntry: FirEnumEntry, proto: ProtoBuf.EnumEntry.Builder) { - enumEntry.annotations.forEach { + enumEntry.nonSourceAnnotations(session).forEach { proto.addExtension(KlibMetadataProtoBuf.enumEntryAnnotation, annotationSerializer.serializeAnnotation(it)) } super.serializeEnumEntry(enumEntry, proto) } override fun serializeTypeAnnotation(annotation: FirAnnotation, proto: ProtoBuf.Type.Builder) { - annotation.annotations.forEach { - proto.addExtension(KlibMetadataProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(it)) - } + proto.addExtension(KlibMetadataProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation)) super.serializeTypeAnnotation(annotation, proto) } override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) { - typeParameter.annotations.forEach { + typeParameter.nonSourceAnnotations(session).forEach { proto.addExtension(KlibMetadataProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(it)) } super.serializeTypeParameter(typeParameter, proto) diff --git a/native/native.tests/testData/klibContents/annotations.kt b/native/native.tests/testData/klibContents/annotations.kt new file mode 100644 index 00000000000..e126ff727c4 --- /dev/null +++ b/native/native.tests/testData/klibContents/annotations.kt @@ -0,0 +1,38 @@ +package test +annotation class AnnoClass +annotation class AnnoConstructor +annotation class AnnoConstructorParameter +annotation class AnnoProperty +annotation class AnnoSetParam +annotation class AnnoSetParam2 +annotation class AnnoBackingField +annotation class AnnoGetter +annotation class AnnoSetter +annotation class AnnoSetter2 +annotation class AnnoDelegatedField +annotation class AnnoFunction +annotation class AnnoFunctionParam +annotation class AnnoFunctionExtensionReceiver +annotation class AnnoPropertyExtensionReceiver +@AnnoClass +class Foo @AnnoConstructor constructor(@AnnoConstructorParameter i: Int) { + @AnnoProperty + @setparam:AnnoSetParam + @field:AnnoBackingField + var prop: Int = i + @AnnoGetter + get() = field + 1 + @AnnoSetter + set(x: Int) { field = x*2 } + + @set:AnnoSetter2 + var mutableProp = 0 + set(@AnnoSetParam2 x: Int) { field = x*2 } + + @delegate:AnnoDelegatedField + val immutableProp by lazy { prop } +} +@AnnoFunction +fun @receiver:AnnoFunctionExtensionReceiver Foo.extfun(@AnnoFunctionParam x: Int) {} +@AnnoPropertyExtensionReceiver +val Foo.extProp get() = this.prop diff --git a/native/native.tests/testData/klibContents/annotations.txt b/native/native.tests/testData/klibContents/annotations.txt new file mode 100644 index 00000000000..75d33179c06 --- /dev/null +++ b/native/native.tests/testData/klibContents/annotations.txt @@ -0,0 +1,25 @@ + annotation class AnnoBackingField constructor() : Annotation + annotation class AnnoClass constructor() : Annotation + annotation class AnnoConstructor constructor() : Annotation + annotation class AnnoConstructorParameter constructor() : Annotation + annotation class AnnoDelegatedField constructor() : Annotation + annotation class AnnoFunction constructor() : Annotation + annotation class AnnoFunctionExtensionReceiver constructor() : Annotation + annotation class AnnoFunctionParam constructor() : Annotation + annotation class AnnoGetter constructor() : Annotation + annotation class AnnoProperty constructor() : Annotation + annotation class AnnoPropertyExtensionReceiver constructor() : Annotation + annotation class AnnoSetParam constructor() : Annotation + annotation class AnnoSetParam2 constructor() : Annotation + annotation class AnnoSetter constructor() : Annotation + annotation class AnnoSetter2 constructor() : Annotation + @AnnoClass class Foo @AnnoConstructor constructor(@AnnoConstructorParameter i: Int) { + @delegate:AnnoDelegatedField val immutableProp: Int + var mutableProp: Int + @AnnoSetter2 set + @AnnoProperty @field:AnnoBackingField var prop: Int + @AnnoGetter get + @AnnoSetter set + } + @AnnoPropertyExtensionReceiver val Foo.extProp: Int + @AnnoFunction fun @receiver:AnnoFunctionExtensionReceiver Foo.extfun(@AnnoFunctionParam x: Int) \ No newline at end of file diff --git a/native/native.tests/testData/klibContents/annotations_source_retention.kt b/native/native.tests/testData/klibContents/annotations_source_retention.kt new file mode 100644 index 00000000000..60e69de8e91 --- /dev/null +++ b/native/native.tests/testData/klibContents/annotations_source_retention.kt @@ -0,0 +1,53 @@ +package test +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoClass +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoConstructor +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoConstructorParameter +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoProperty +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoSetParam +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoSetParam2 +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoBackingField +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoGetter +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoSetter +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoSetter2 +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoDelegatedField +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoFunction +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoFunctionParam +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoFunctionExtensionReceiver +@Retention(AnnotationRetention.SOURCE) +annotation class AnnoPropertyExtensionReceiver +@AnnoClass +class Foo @AnnoConstructor constructor(@AnnoConstructorParameter i: Int) { + @AnnoProperty + @setparam:AnnoSetParam + @field:AnnoBackingField + var prop: Int = i + @AnnoGetter + get() = field + 1 + @AnnoSetter + set(x: Int) { field = x*2 } + + @set:AnnoSetter2 + var mutableProp = 0 + set(@AnnoSetParam2 x: Int) { field = x*2 } + + @delegate:AnnoDelegatedField + val immutableProp by lazy { prop } +} +@AnnoFunction +fun @receiver:AnnoFunctionExtensionReceiver Foo.extfun(@AnnoFunctionParam x: Int) {} +@AnnoPropertyExtensionReceiver +val Foo.extProp get() = this.prop diff --git a/native/native.tests/testData/klibContents/annotations_source_retention.txt b/native/native.tests/testData/klibContents/annotations_source_retention.txt new file mode 100644 index 00000000000..c95d4302837 --- /dev/null +++ b/native/native.tests/testData/klibContents/annotations_source_retention.txt @@ -0,0 +1,22 @@ + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoBackingField constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoClass constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoConstructor constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoConstructorParameter constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoDelegatedField constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoFunction constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoFunctionExtensionReceiver constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoFunctionParam constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoGetter constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoProperty constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoPropertyExtensionReceiver constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoSetParam constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoSetParam2 constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoSetter constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) annotation class AnnoSetter2 constructor() : Annotation + class Foo constructor(i: Int) { + val immutableProp: Int + var mutableProp: Int + var prop: Int + } + val Foo.extProp: Int + fun Foo.extfun(x: Int) \ No newline at end of file diff --git a/native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.kt b/native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.kt new file mode 100644 index 00000000000..fefbfcd15db --- /dev/null +++ b/native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.kt @@ -0,0 +1,5 @@ +package test +class C + +// If serializeTypeAnnotation() is wrong, the following callback would have wrong type: (C) -> Unit +fun C.builder(c: C.() -> Unit) {} diff --git a/native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.txt b/native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.txt new file mode 100644 index 00000000000..2375c92ed3b --- /dev/null +++ b/native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.txt @@ -0,0 +1,2 @@ + class C constructor() + fun C.builder(c: C.() -> Unit) \ No newline at end of file diff --git a/native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.kt b/native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.kt new file mode 100644 index 00000000000..952b5d5498c --- /dev/null +++ b/native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.kt @@ -0,0 +1,7 @@ +package test +annotation class Annotation + +fun foo(@Annotation arg: Int) {} + +// KT-56177 TODO uncomment the line after KT-56177 is fixed +//data class Clazz(@Annotation val param: Int) diff --git a/native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.txt b/native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.txt new file mode 100644 index 00000000000..a7241a770b3 --- /dev/null +++ b/native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.txt @@ -0,0 +1,2 @@ + annotation class Annotation constructor() : Annotation + fun foo(@Annotation arg: Int) \ No newline at end of file diff --git a/native/native.tests/testData/klibContents/type_annotations.kt b/native/native.tests/testData/klibContents/type_annotations.kt new file mode 100644 index 00000000000..c8806612b18 --- /dev/null +++ b/native/native.tests/testData/klibContents/type_annotations.kt @@ -0,0 +1,14 @@ +package test +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.TYPE) +annotation class AnnoRuntime +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.TYPE) +annotation class AnnoBinary +@Retention(AnnotationRetention.SOURCE) +@Target(AnnotationTarget.TYPE) +annotation class AnnoSource + +fun withRuntimeAnnotation(id: @AnnoRuntime Int) {} +fun withBinaryAnnotation(id: @AnnoBinary Int) {} +fun withSourceAnnotation(id: @AnnoSource Int) {} diff --git a/native/native.tests/testData/klibContents/type_annotations.txt b/native/native.tests/testData/klibContents/type_annotations.txt new file mode 100644 index 00000000000..4fe67309b5f --- /dev/null +++ b/native/native.tests/testData/klibContents/type_annotations.txt @@ -0,0 +1,6 @@ + @Retention(value = AnnotationRetention.BINARY) @Target(allowedTargets = {AnnotationTarget.TYPE}) annotation class AnnoBinary constructor() : Annotation + @Retention(value = AnnotationRetention.RUNTIME) @Target(allowedTargets = {AnnotationTarget.TYPE}) annotation class AnnoRuntime constructor() : Annotation + @Retention(value = AnnotationRetention.SOURCE) @Target(allowedTargets = {AnnotationTarget.TYPE}) annotation class AnnoSource constructor() : Annotation + fun withBinaryAnnotation(id: @AnnoBinary Int) + fun withRuntimeAnnotation(id: @AnnoRuntime Int) + fun withSourceAnnotation(id: Int) \ No newline at end of file diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeK1LibContentsTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeK1LibContentsTestGenerated.java new file mode 100644 index 00000000000..eea8e2d94c1 --- /dev/null +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeK1LibContentsTestGenerated.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.blackboxtest; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("native/native.tests/testData/klibContents") +@TestDataPath("$PROJECT_ROOT") +public class NativeK1LibContentsTestGenerated extends AbstractNativeKlibContentsTest { + @Test + public void testAllFilesPresentInKlibContents() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klibContents"), Pattern.compile("^([^_](.+)).kt$"), null, false); + } + + @Test + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + runTest("native/native.tests/testData/klibContents/annotations.kt"); + } + + @Test + @TestMetadata("annotations_source_retention.kt") + public void testAnnotations_source_retention() throws Exception { + runTest("native/native.tests/testData/klibContents/annotations_source_retention.kt"); + } + + @Test + @TestMetadata("kt55464_serializeTypeAnnotation.kt") + public void testKt55464_serializeTypeAnnotation() throws Exception { + runTest("native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.kt"); + } + + @Test + @TestMetadata("kt56018_value_parameters_annotations.kt") + public void testKt56018_value_parameters_annotations() throws Exception { + runTest("native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.kt"); + } + + @Test + @TestMetadata("type_annotations.kt") + public void testType_annotations() throws Exception { + runTest("native/native.tests/testData/klibContents/type_annotations.kt"); + } +} diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeK2LibContentsTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeK2LibContentsTestGenerated.java new file mode 100644 index 00000000000..4ce0c70cfa0 --- /dev/null +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeK2LibContentsTestGenerated.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.blackboxtest; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.konan.blackboxtest.support.group.K2Pipeline; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.GenerateNativeTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("native/native.tests/testData/klibContents") +@TestDataPath("$PROJECT_ROOT") +@K2Pipeline() +public class NativeK2LibContentsTestGenerated extends AbstractNativeKlibContentsTest { + @Test + public void testAllFilesPresentInKlibContents() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("native/native.tests/testData/klibContents"), Pattern.compile("^([^_](.+)).kt$"), null, false); + } + + @Test + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + runTest("native/native.tests/testData/klibContents/annotations.kt"); + } + + @Test + @TestMetadata("annotations_source_retention.kt") + public void testAnnotations_source_retention() throws Exception { + runTest("native/native.tests/testData/klibContents/annotations_source_retention.kt"); + } + + @Test + @TestMetadata("kt55464_serializeTypeAnnotation.kt") + public void testKt55464_serializeTypeAnnotation() throws Exception { + runTest("native/native.tests/testData/klibContents/kt55464_serializeTypeAnnotation.kt"); + } + + @Test + @TestMetadata("kt56018_value_parameters_annotations.kt") + public void testKt56018_value_parameters_annotations() throws Exception { + runTest("native/native.tests/testData/klibContents/kt56018_value_parameters_annotations.kt"); + } + + @Test + @TestMetadata("type_annotations.kt") + public void testType_annotations() throws Exception { + runTest("native/native.tests/testData/klibContents/type_annotations.kt"); + } +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt b/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt index 33557e2e896..d2750fded7d 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/generators/tests/GenerateNativeTests.kt @@ -100,6 +100,23 @@ fun main() { } } + // Klib contents tests + testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { + testClass( + suiteTestClassName = "NativeK1LibContentsTestGenerated" + ) { + model("klibContents", pattern = "^([^_](.+)).kt$", recursive = false) + } + } + testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { + testClass( + suiteTestClassName = "NativeK2LibContentsTestGenerated", + annotations = listOf(provider()) + ) { + model("klibContents", pattern = "^([^_](.+)).kt$", recursive = false) + } + } + // LLDB integration tests. testGroup("native/native.tests/tests-gen", "native/native.tests/testData") { testClass( diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibContentsTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibContentsTest.kt new file mode 100644 index 00000000000..033b59fb3c9 --- /dev/null +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeKlibContentsTest.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.konan.blackboxtest + +import com.intellij.openapi.util.text.StringUtilRt +import com.intellij.testFramework.TestDataFile +import org.jetbrains.kotlin.konan.blackboxtest.support.* +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.* +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationArtifact.* +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.TestCompilationResult.Companion.assertSuccess +import org.jetbrains.kotlin.konan.blackboxtest.support.runner.* +import org.jetbrains.kotlin.konan.blackboxtest.support.settings.* +import org.jetbrains.kotlin.konan.blackboxtest.support.util.* +import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEquals +import org.junit.jupiter.api.Tag +import java.io.File + +@Tag("klib-contents") +abstract class AbstractNativeKlibContentsTest : AbstractNativeSimpleTest() { + + protected fun runTest(@TestDataFile testPath: String) { + val testPathFull = getAbsoluteFile(testPath) + + val testCase: TestCase = generateTestCaseWithSingleSource(testPathFull, listOf()) + val testCompilationResult: TestCompilationResult.Success = compileToLibrary(testCase) + + val kotlinNativeClassLoader = testRunSettings.get() + val klibContents = testCompilationResult.assertSuccess().resultingArtifact.getContents(kotlinNativeClassLoader.classLoader) + val klibContentsFiltered = filterContentsOutput(klibContents, linestoExclude = listOf("package test {", "}", "")) + val expectedContents = File("${testPathFull.canonicalPath.substringBeforeLast(".")}.txt").readText() + assertEquals(StringUtilRt.convertLineSeparators(expectedContents), StringUtilRt.convertLineSeparators(klibContentsFiltered)) { + "Test failed. Compilation result was: $testCompilationResult" + } + } + + private fun generateTestCaseWithSingleSource(source: File, extraArgs: List): TestCase { + val moduleName: String = source.name + val module = TestModule.Exclusive(moduleName, emptySet(), emptySet()) + module.files += TestFile.createCommitted(source, module) + + return TestCase( + id = TestCaseId.Named(moduleName), + kind = TestKind.STANDALONE, + modules = setOf(module), + freeCompilerArgs = TestCompilerArgs(extraArgs), + nominalPackageName = PackageName.EMPTY, + checks = TestRunChecks.Default(testRunSettings.get().executionTimeout), + extras = TestCase.WithTestRunnerExtras(TestRunnerType.DEFAULT) + ).apply { + initialize(null, null) + } + } + + private fun filterContentsOutput(contents: String, linestoExclude: List) = + contents.split("\n").filterNot { line -> + linestoExclude.any { exclude -> exclude == line } + }.joinToString(separator = "\n") +}