From 748eb2f9ee78400166b3d028934423b91f36115e Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Fri, 28 Jul 2023 16:48:37 +0200 Subject: [PATCH] [KLIB] ABI reader: Tests for classes inherited from classes produced by Native interop tool ^KT-54402 --- .../cinterop/interop_class_inheritor.def | 9 +++++ .../cinterop/interop_class_inheritor.kt | 17 +++++++++ .../cinterop/interop_class_inheritor.v1.txt | 25 +++++++++++++ .../cinterop/interop_class_inheritor.v2.txt | 25 +++++++++++++ ...FirNativeCInteropLibraryAbiReaderTest.java | 36 +++++++++++++++++++ .../NativeCInteropLibraryAbiReaderTest.java | 32 +++++++++++++++++ .../generators/tests/GenerateNativeTests.kt | 19 +++++++++- .../AbstractNativeLibraryAbiReaderTest.kt | 34 +++++++++++++++++- 8 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.def create mode 100644 compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.kt create mode 100644 compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v1.txt create mode 100644 compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v2.txt create mode 100644 native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCInteropLibraryAbiReaderTest.java create mode 100644 native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCInteropLibraryAbiReaderTest.java diff --git a/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.def b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.def new file mode 100644 index 00000000000..db23204e0fd --- /dev/null +++ b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.def @@ -0,0 +1,9 @@ +language = Objective-C +--- +@interface Base +-(instancetype) init; +-(void) overriddenFunction; +-(void) nonOverriddenFunction; +@property int overriddenProperty; +@property int nonOverriddenProperty; +@end diff --git a/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.kt b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.kt new file mode 100644 index 00000000000..df53d51ec66 --- /dev/null +++ b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.kt @@ -0,0 +1,17 @@ +// MODULE: interop_class_inheritor_library + +@file:Suppress("RedundantModalityModifier") + +package interop_class_inheritor.test + +@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class) +class Derived : interop_class_inheritor.Base() { + override fun overriddenFunction() = Unit + //override fun nonOverriddenFunction() = Unit + + override fun overriddenProperty(): Int = 42 + //override fun nonOverriddenProperty(): Int = 42 + + override fun setOverriddenProperty(overriddenProperty: Int) = Unit + //override fun setNonOverriddenProperty(nonOverriddenProperty: Int) = Unit +} diff --git a/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v1.txt b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v1.txt new file mode 100644 index 00000000000..f26536fecb2 --- /dev/null +++ b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v1.txt @@ -0,0 +1,25 @@ +// Rendering settings: +// - Signature version: 1 +// - Show manifest properties: false +// - Show declarations: true + +// Library unique name: +final class interop_class_inheritor.test/Derived : interop_class_inheritor/Base { // interop_class_inheritor.test/Derived|null[0] + final var nonOverriddenProperty // interop_class_inheritor.test/Derived.nonOverriddenProperty|-9006076905898583858[0] + final fun (): kotlin/Int // interop_class_inheritor.test/Derived.nonOverriddenProperty.|2758692278606108838[0] + final fun (kotlin/Int) // interop_class_inheritor.test/Derived.nonOverriddenProperty.|-2229258798912660779[0] + final var overriddenProperty // interop_class_inheritor.test/Derived.overriddenProperty|-1390063372067425061[0] + final fun (): kotlin/Int // interop_class_inheritor.test/Derived.overriddenProperty.|7022302077100732862[0] + final fun (kotlin/Int) // interop_class_inheritor.test/Derived.overriddenProperty.|-4304223391766217362[0] + constructor () // interop_class_inheritor.test/Derived.|-5645683436151566731[0] + final fun equals(kotlin/Any?): kotlin/Boolean // interop_class_inheritor.test/Derived.equals|-2081205089284609834[0] + final fun hashCode(): kotlin/Int // interop_class_inheritor.test/Derived.hashCode|3409210261493131192[0] + final fun init(): interop_class_inheritor/Base? // interop_class_inheritor.test/Derived.init|-3274032692079634155[0] + final fun nonOverriddenFunction() // interop_class_inheritor.test/Derived.nonOverriddenFunction|3505898422087519936[0] + final fun nonOverriddenProperty(): kotlin/Int // interop_class_inheritor.test/Derived.nonOverriddenProperty|-355772021403371063[0] + final fun overriddenFunction() // interop_class_inheritor.test/Derived.overriddenFunction|-6472102329825707726[0] + final fun overriddenProperty(): kotlin/Int // interop_class_inheritor.test/Derived.overriddenProperty|-7224960608403565684[0] + final fun setNonOverriddenProperty(kotlin/Int) // interop_class_inheritor.test/Derived.setNonOverriddenProperty|-5242067576658008142[0] + final fun setOverriddenProperty(kotlin/Int) // interop_class_inheritor.test/Derived.setOverriddenProperty|-8479216322956180924[0] + final fun toString(): kotlin/String // interop_class_inheritor.test/Derived.toString|-1522858123163872138[0] +} diff --git a/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v2.txt b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v2.txt new file mode 100644 index 00000000000..faf5b504e52 --- /dev/null +++ b/compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.v2.txt @@ -0,0 +1,25 @@ +// Rendering settings: +// - Signature version: 2 +// - Show manifest properties: false +// - Show declarations: true + +// Library unique name: +final class interop_class_inheritor.test/Derived : interop_class_inheritor/Base { // interop_class_inheritor.test/Derived|null[0] + final var nonOverriddenProperty // interop_class_inheritor.test/Derived.nonOverriddenProperty|{}nonOverriddenProperty[0] + final fun (): kotlin/Int // interop_class_inheritor.test/Derived.nonOverriddenProperty.|objc:nonOverriddenProperty#Accessor[0] + final fun (kotlin/Int) // interop_class_inheritor.test/Derived.nonOverriddenProperty.|objc:setNonOverriddenProperty:#Accessor[0] + final var overriddenProperty // interop_class_inheritor.test/Derived.overriddenProperty|{}overriddenProperty[0] + final fun (): kotlin/Int // interop_class_inheritor.test/Derived.overriddenProperty.|objc:overriddenProperty#Accessor[0] + final fun (kotlin/Int) // interop_class_inheritor.test/Derived.overriddenProperty.|objc:setOverriddenProperty:#Accessor[0] + constructor () // interop_class_inheritor.test/Derived.|(){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // interop_class_inheritor.test/Derived.equals|equals(other:kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // interop_class_inheritor.test/Derived.hashCode|hashCode(){}[0] + final fun init(): interop_class_inheritor/Base? // interop_class_inheritor.test/Derived.init|objc:init[0] + final fun nonOverriddenFunction() // interop_class_inheritor.test/Derived.nonOverriddenFunction|objc:nonOverriddenFunction[0] + final fun nonOverriddenProperty(): kotlin/Int // interop_class_inheritor.test/Derived.nonOverriddenProperty|objc:nonOverriddenProperty[0] + final fun overriddenFunction() // interop_class_inheritor.test/Derived.overriddenFunction|objc:overriddenFunction[0] + final fun overriddenProperty(): kotlin/Int // interop_class_inheritor.test/Derived.overriddenProperty|objc:overriddenProperty[0] + final fun setNonOverriddenProperty(kotlin/Int) // interop_class_inheritor.test/Derived.setNonOverriddenProperty|objc:setNonOverriddenProperty:[0] + final fun setOverriddenProperty(kotlin/Int) // interop_class_inheritor.test/Derived.setOverriddenProperty|objc:setOverriddenProperty:[0] + final fun toString(): kotlin/String // interop_class_inheritor.test/Derived.toString|toString(){}[0] +} diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCInteropLibraryAbiReaderTest.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCInteropLibraryAbiReaderTest.java new file mode 100644 index 00000000000..4101506bba0 --- /dev/null +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/FirNativeCInteropLibraryAbiReaderTest.java @@ -0,0 +1,36 @@ +/* + * 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.junit.jupiter.api.Tag; +import org.jetbrains.kotlin.konan.blackboxtest.support.group.FirPipeline; +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("compiler/util-klib-abi/testData/cinterop") +@TestDataPath("$PROJECT_ROOT") +@Tag("frontend-fir") +@FirPipeline() +public class FirNativeCInteropLibraryAbiReaderTest extends AbstractNativeCInteropLibraryAbiReaderTest { + @Test + public void testAllFilesPresentInCinterop() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/util-klib-abi/testData/cinterop"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("interop_class_inheritor.kt") + public void testInterop_class_inheritor() throws Exception { + runTest("compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.kt"); + } +} diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCInteropLibraryAbiReaderTest.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCInteropLibraryAbiReaderTest.java new file mode 100644 index 00000000000..c91c3b06a37 --- /dev/null +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCInteropLibraryAbiReaderTest.java @@ -0,0 +1,32 @@ +/* + * 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("compiler/util-klib-abi/testData/cinterop") +@TestDataPath("$PROJECT_ROOT") +public class NativeCInteropLibraryAbiReaderTest extends AbstractNativeCInteropLibraryAbiReaderTest { + @Test + public void testAllFilesPresentInCinterop() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/util-klib-abi/testData/cinterop"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("interop_class_inheritor.kt") + public void testInterop_class_inheritor() throws Exception { + runTest("compiler/util-klib-abi/testData/cinterop/interop_class_inheritor.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 01380dfbffb..d1f27e93d7a 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 @@ -275,7 +275,6 @@ fun main() { model("content", targetBackend = TargetBackend.NATIVE) } } - testGroup("native/native.tests/tests-gen", "compiler/util-klib-abi/testData") { testClass( suiteTestClassName = "FirNativeLibraryAbiReaderTest", @@ -286,6 +285,24 @@ fun main() { model("content", targetBackend = TargetBackend.NATIVE) } } + + testGroup("native/native.tests/tests-gen", "compiler/util-klib-abi/testData") { + testClass( + suiteTestClassName = "NativeCInteropLibraryAbiReaderTest" + ) { + model("cinterop") + } + } + testGroup("native/native.tests/tests-gen", "compiler/util-klib-abi/testData") { + testClass( + suiteTestClassName = "FirNativeCInteropLibraryAbiReaderTest", + annotations = listOf( + *frontendFir() + ) + ) { + model("cinterop") + } + } } } } diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeLibraryAbiReaderTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeLibraryAbiReaderTest.kt index 4ebed9ad52e..37640338464 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeLibraryAbiReaderTest.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativeLibraryAbiReaderTest.kt @@ -10,6 +10,10 @@ import org.jetbrains.kotlin.konan.blackboxtest.support.TestCompilerArgs import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives import org.jetbrains.kotlin.konan.blackboxtest.support.TestDirectives.MODULE import org.jetbrains.kotlin.konan.blackboxtest.support.parseModule +import org.jetbrains.kotlin.konan.blackboxtest.support.compilation.ExistingDependency +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.settings.KotlinNativeTargets import org.jetbrains.kotlin.konan.blackboxtest.support.util.getAbsoluteFile import org.jetbrains.kotlin.library.abi.* import org.jetbrains.kotlin.library.abi.directives.LibraryAbiDumpDirectives @@ -21,9 +25,11 @@ import org.jetbrains.kotlin.test.services.JUnit5Assertions import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEqualsToFile import org.jetbrains.kotlin.test.services.impl.RegisteredDirectivesParser import org.jetbrains.kotlin.test.services.impl.RegisteredDirectivesParser.ParsedDirective +import org.jetbrains.kotlin.test.utils.withExtension import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Assumptions.assumeTrue import org.junit.jupiter.api.Tag import java.io.File @@ -34,12 +40,16 @@ abstract class AbstractNativeLibraryAbiReaderTest : AbstractNativeSimpleTest() { val (sourceFile, dumpFiles) = computeTestFiles(localPath) val (moduleName, filters) = parseDirectives(sourceFile) + val customDependencies: List> = + produceCustomDependencies(sourceFile).map(TestCompilationArtifact.KLIB::asLibraryDependency) + val library = compileToLibrary( testCase = generateTestCaseWithSingleFile( sourceFile = sourceFile, moduleName = moduleName, freeCompilerArgs = TestCompilerArgs("-Xcontext-receivers") - ) + ), + dependencies = customDependencies.toTypedArray() ).resultingArtifact.klibFile val libraryAbi = LibraryAbiReader.readAbiInfo(library, filters) @@ -54,6 +64,8 @@ abstract class AbstractNativeLibraryAbiReaderTest : AbstractNativeSimpleTest() { } } + internal open fun produceCustomDependencies(sourceFile: File): List = emptyList() + companion object { private fun computeTestFiles(localPath: String): Pair> { val sourceFile = getAbsoluteFile(localPath) @@ -98,3 +110,23 @@ abstract class AbstractNativeLibraryAbiReaderTest : AbstractNativeSimpleTest() { } } } + +abstract class AbstractNativeCInteropLibraryAbiReaderTest : AbstractNativeLibraryAbiReaderTest() { + override fun produceCustomDependencies(sourceFile: File): List { + val targets: KotlinNativeTargets = testRunSettings.get() + + assumeTrue(targets.hostTarget.family.isAppleFamily) // ObjC tests can run only on Apple targets. + + val defFile = sourceFile.withExtension(".def") + assertTrue(defFile.isFile) { "Def file does not exist: $defFile" } + + return listOf( + cinteropToLibrary( + targets = targets, + defFile = defFile, + outputDir = buildDir, + freeCompilerArgs = TestCompilerArgs.EMPTY + ).assertSuccess().resultingArtifact + ) + } +}