diff --git a/compiler/testData/klibABI/changeClassVisibility/main/m.kt b/compiler/testData/klibABI/changeClassVisibility/main/m.kt index 0738b269220..ceae1f7169c 100644 --- a/compiler/testData/klibABI/changeClassVisibility/main/m.kt +++ b/compiler/testData/klibABI/changeClassVisibility/main/m.kt @@ -74,33 +74,33 @@ fun box() = abiTest { } // Shortcuts: -private inline fun TestBuilder.success(expectedOutcome: String, noinline block: () -> Any) = +private fun TestBuilder.success(expectedOutcome: String, block: () -> Any) = expectSuccess(expectedOutcome) { block().toString() } -private inline fun TestBuilder.successViaException(testExceptionId: String, noinline block: () -> Unit) = +private fun TestBuilder.successViaException(testExceptionId: String, block: () -> Unit) = expectFailure(custom { (it as? TestException)?.id == testExceptionId }, block) -private inline fun TestBuilder.inaccessible(className: String, noinline block: () -> Unit) = expectFailure( +private fun TestBuilder.inaccessible(className: String, block: () -> Unit) = expectFailure( linkage("Constructor '$className.' can not be called: Private constructor declared in module can not be accessed in module "), block ) -private inline fun TestBuilder.unlinkedSymbolInValueParameter(signature: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedSymbolInValueParameter(signature: String, block: () -> Unit) { val functionName = signature.removePrefix("/").replace('.', '_') + "_valueParameter" unlinkedSymbol(signature, functionName, block) } -private inline fun TestBuilder.unlinkedSymbolInReturnType(signature: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedSymbolInReturnType(signature: String, block: () -> Unit) { val functionName = signature.removePrefix("/").replace('.', '_') + "_returnType" unlinkedSymbol(signature, functionName, block) } -private inline fun TestBuilder.unlinkedConstructorSymbol(signature: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedConstructorSymbol(signature: String, block: () -> Unit) { val constructorName = signature.removePrefix("/").split('.').takeLast(2).joinToString(".") expectFailure(linkage("Constructor '$constructorName' can not be called: No constructor found for symbol '$signature'"), block) } -private inline fun TestBuilder.unlinkedSymbol(signature: String, functionName: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedSymbol(signature: String, functionName: String, block: () -> Unit) { // Need to slightly adjust the expected IR linkage error message. Reason: When Lazy IR is used the type of the // symbol is determined more accurately. val symbolKind = if ("InnerClass" in functionName && testMode.lazyIr.usedEverywhere) diff --git a/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt b/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt index c726a4d86b6..b129ce1b969 100644 --- a/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt +++ b/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt @@ -51,15 +51,15 @@ fun box() = abiTest { } // Shortcuts: -private inline fun TestBuilder.success(expectedOutcome: String, noinline block: () -> String) = +private fun TestBuilder.success(expectedOutcome: String, block: () -> String) = expectSuccess(expectedOutcome, block) -private inline fun TestBuilder.unlinkedSymbol(signature: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedSymbol(signature: String, block: () -> Unit) { val functionName = signature.removePrefix("/").substringAfterLast(".") expectFailure(linkage("Function '$functionName' can not be called: No function found for symbol '$signature'"), block) } -private inline fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, block: () -> Unit) { if (testMode.lazyIr.usedEverywhere) { val functionName = signature.removePrefix("/").substringAfterLast(".") expectFailure(linkage("Function '$functionName' can not be called: Private function declared in module can not be accessed in module
"), block) @@ -67,7 +67,7 @@ private inline fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, unlinkedSymbol(signature, block) } -private inline fun TestBuilder.inaccessible(functionName: String, noinline block: () -> Unit) = expectFailure( +private fun TestBuilder.inaccessible(functionName: String, block: () -> Unit) = expectFailure( linkage("Function '$functionName' can not be called: Private function declared in module can not be accessed in module
"), block ) diff --git a/compiler/testData/klibABI/changePropertyVisibility/main/m.kt b/compiler/testData/klibABI/changePropertyVisibility/main/m.kt index 66a27e14d13..ee1b89f3e41 100644 --- a/compiler/testData/klibABI/changePropertyVisibility/main/m.kt +++ b/compiler/testData/klibABI/changePropertyVisibility/main/m.kt @@ -114,15 +114,15 @@ fun box() = abiTest { } // Shortcuts: -private inline fun TestBuilder.success(expectedOutcome: String, noinline block: () -> String) = +private fun TestBuilder.success(expectedOutcome: String, block: () -> String) = expectSuccess(expectedOutcome, block) -private inline fun TestBuilder.unlinkedSymbol(signature: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedSymbol(signature: String, block: () -> Unit) { val accessorName = signature.removePrefix("/").split('.').takeLast(2).joinToString(".") expectFailure(linkage("Property accessor '$accessorName' can not be called: No property accessor found for symbol '$signature'"), block) } -private inline fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, noinline block: () -> Unit) { +private fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, block: () -> Unit) { if (testMode.lazyIr.usedEverywhere) { val accessorName = signature.removePrefix("/").split('.').takeLast(2).joinToString(".") expectFailure(linkage("Property accessor '$accessorName' can not be called: Private property accessor declared in module can not be accessed in module
"), block) @@ -130,7 +130,7 @@ private inline fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, unlinkedSymbol(signature, block) } -private inline fun TestBuilder.inaccessible(accessorName: String, noinline block: () -> Unit) = expectFailure( +private fun TestBuilder.inaccessible(accessorName: String, block: () -> Unit) = expectFailure( linkage("Property accessor '$accessorName' can not be called: Private property accessor declared in module can not be accessed in module
"), block ) diff --git a/compiler/testData/klibABI/classTransformations/lib2/l2.kt b/compiler/testData/klibABI/classTransformations/lib2/l2.kt index da8ed49c6ef..954379c1ed1 100644 --- a/compiler/testData/klibABI/classTransformations/lib2/l2.kt +++ b/compiler/testData/klibABI/classTransformations/lib2/l2.kt @@ -1,3 +1,4 @@ +@file:Suppress("NOTHING_TO_INLINE") fun getClassToEnumFoo(): ClassToEnum.Foo = ClassToEnum.Foo() inline fun getClassToEnumFooInline(): ClassToEnum.Foo = ClassToEnum.Foo() diff --git a/compiler/testData/klibABI/externalDeclarations/main/m.kt b/compiler/testData/klibABI/externalDeclarations/main/m.kt index e5955cbd697..a9c0a4784a5 100644 --- a/compiler/testData/klibABI/externalDeclarations/main/m.kt +++ b/compiler/testData/klibABI/externalDeclarations/main/m.kt @@ -27,5 +27,5 @@ fun box() = abiTest { expectSuccess("RegularClassInheritedFromExternalInterfaceInheritedFromOpenExternalClass.abstractFunction") { rcifeiifoec.abstractFunction() } } -private inline fun TestBuilder.expectRuntimeFailure(errorMessage: String, noinline block: () -> Any) = +private fun TestBuilder.expectRuntimeFailure(errorMessage: String, block: () -> Any) = expectFailure(custom { throwable -> throwable !is Exception && throwable.message == errorMessage }) { block() } diff --git a/compiler/testData/klibABI/functionTransformations/lib2/l2.kt b/compiler/testData/klibABI/functionTransformations/lib2/l2.kt index 6a93ec0f8d0..b4646daf9c8 100644 --- a/compiler/testData/klibABI/functionTransformations/lib2/l2.kt +++ b/compiler/testData/klibABI/functionTransformations/lib2/l2.kt @@ -129,8 +129,8 @@ class OpenClassImpl : OpenClass() { override fun openNonInlineToInlineFunction(x: Int): String = "OpenClassImpl.openNonInlineToInlineFunction($x)" override fun openNonInlineToInlineFunctionWithDelegation(x: Int): String = super.openNonInlineToInlineFunctionWithDelegation(x) + " called from OpenClassImpl.openNonInlineToInlineFunctionWithDelegation($x)" fun newInlineFunction1(x: Int): String = "OpenClassImpl.newInlineFunction1($x)" // overrides accidentally appeared inline function - inline fun newInlineFunction2(x: Int): String = "OpenClassImpl.newInlineFunction2($x)" // overrides accidentally appeared inline function - inline fun newNonInlineFunction(x: Int): String = "OpenClassImpl.newNonInlineFunction($x)" // overrides accidentally appeared non-inline function + @Suppress("NOTHING_TO_INLINE") inline fun newInlineFunction2(x: Int): String = "OpenClassImpl.newInlineFunction2($x)" // overrides accidentally appeared inline function + @Suppress("NOTHING_TO_INLINE") inline fun newNonInlineFunction(x: Int): String = "OpenClassImpl.newNonInlineFunction($x)" // overrides accidentally appeared non-inline function } fun suspendToNonSuspendFunctionInInterface(i: Interface, x: Int): String = runCoroutine { i.suspendToNonSuspendFunction(x) } diff --git a/compiler/testData/klibABI/inheritanceIssues/lib2/l2.kt b/compiler/testData/klibABI/inheritanceIssues/lib2/l2.kt index 8f45b1219f5..ef58284827e 100644 --- a/compiler/testData/klibABI/inheritanceIssues/lib2/l2.kt +++ b/compiler/testData/klibABI/inheritanceIssues/lib2/l2.kt @@ -1,3 +1,5 @@ +@file:Suppress("NOTHING_TO_INLINE") + fun getInterfaceToAbstractClass() = object : InterfaceToAbstractClass {} inline fun getInterfaceToAbstractClassInline() = object : InterfaceToAbstractClass {} fun getInterfaceToAbstractClassAsAny(): Any = object : InterfaceToAbstractClass {} diff --git a/compiler/testData/klibABI/removeCallable/lib2/l2.kt b/compiler/testData/klibABI/removeCallable/lib2/l2.kt index 3290e49b474..8b8429c5c0f 100644 --- a/compiler/testData/klibABI/removeCallable/lib2/l2.kt +++ b/compiler/testData/klibABI/removeCallable/lib2/l2.kt @@ -5,8 +5,8 @@ fun readRemovedOrNormalProperty(removed: Boolean): String = if (removed) removed fun readRemovedOrNormalPropertyOnObject1(removed: Boolean): String = if (removed) A().removedProperty1 else A().property1 fun readRemovedOrNormalPropertyOnObject2(removed: Boolean): String = if (removed) A().removedProperty2 else A().property2 -inline fun callInlinedRemovedFunction() = removedFunction() -inline fun readInlinedRemovedProperty() = removedProperty +@Suppress("NOTHING_TO_INLINE") inline fun callInlinedRemovedFunction() = removedFunction() +@Suppress("NOTHING_TO_INLINE") inline fun readInlinedRemovedProperty() = removedProperty class C2 : C() { override fun removedOpenFunction(): String = "O" // does not call super diff --git a/compiler/testData/klibABI/removeClass/lib2/l2.kt b/compiler/testData/klibABI/removeClass/lib2/l2.kt index 52ff1047e5a..461ba9c5d9e 100644 --- a/compiler/testData/klibABI/removeClass/lib2/l2.kt +++ b/compiler/testData/klibABI/removeClass/lib2/l2.kt @@ -1,3 +1,5 @@ +@file:Suppress("NOTHING_TO_INLINE") + fun createRemovedClass() { check(RemovedClass().toString() != "Yellow Submarine") } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/PartialLinkageTestUtils.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/PartialLinkageTestUtils.kt index 1c13df628fe..cfca0247da9 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/klib/PartialLinkageTestUtils.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/klib/PartialLinkageTestUtils.kt @@ -26,8 +26,8 @@ object PartialLinkageTestUtils { // Build a KLIB from a module. fun buildKlib(moduleName: String, buildDirs: ModuleBuildDirs, dependencies: Dependencies, klibFile: File) - // Build a binary (executable) file given the main KLIB and dependencies. - fun buildBinaryAndRun(mainModuleKlibFile: File, dependencies: Dependencies) + // Build a binary (executable) file given the main KLIB and the rest of dependencies. + fun buildBinaryAndRun(mainModule: Dependency, otherDependencies: Dependencies) // Take measures if the build directory is non-empty before the compilation // (ex: backup the previously generated artifacts stored in the build directory). @@ -163,9 +163,8 @@ object PartialLinkageTestUtils { val mainModuleKlibFile = modulesMap[MAIN_MODULE_NAME]?.klibFile ?: fail { "No main module $MAIN_MODULE_NAME found" } val mainModuleDependency = Dependency(MAIN_MODULE_NAME, mainModuleKlibFile) - binaryDependencies = binaryDependencies.mergeWith(Dependencies(setOf(mainModuleDependency), emptySet())) - buildBinaryAndRun(mainModuleKlibFile, binaryDependencies) + buildBinaryAndRun(mainModuleDependency, binaryDependencies) } private fun copySources(from: File, to: File, patchSourceFile: ((String) -> String)? = null) { diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsPartialLinkageTestCase.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsPartialLinkageTestCase.kt index 76f45f33453..d01a17a13d9 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsPartialLinkageTestCase.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/AbstractJsPartialLinkageTestCase.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.backend.js.* import org.jetbrains.kotlin.js.testOld.V8IrJsTestChecker import org.jetbrains.kotlin.klib.PartialLinkageTestUtils import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.Dependencies +import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.Dependency import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.MAIN_MODULE_NAME import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.ModuleBuildDirs import org.junit.jupiter.api.AfterEach @@ -60,8 +61,8 @@ abstract class AbstractJsPartialLinkageTestCase(private val compilerType: Compil klibFile: File, ) = this@AbstractJsPartialLinkageTestCase.buildKlib(moduleName, buildDirs, dependencies, klibFile) - override fun buildBinaryAndRun(mainModuleKlibFile: File, dependencies: Dependencies) = - this@AbstractJsPartialLinkageTestCase.buildBinaryAndRun(mainModuleKlibFile, dependencies) + override fun buildBinaryAndRun(mainModule: Dependency, otherDependencies: Dependencies) = + this@AbstractJsPartialLinkageTestCase.buildBinaryAndRun(mainModule, otherDependencies) override fun onNonEmptyBuildDirectory(directory: File) { directory.listFiles()?.forEach(File::deleteRecursively) @@ -110,19 +111,24 @@ abstract class AbstractJsPartialLinkageTestCase(private val compilerType: Compil listOf( "-Xir-produce-klib-file", "-ir-output-dir", klibFile.parentFile.absolutePath, - "-ir-output-name", moduleName + "-ir-output-name", moduleName, + "-Werror" // Halt on any unexpected warning. ), dependencies.toCompilerArgs(), - listOf("-language-version", "2.0").takeIf { compilerType.useFir }, + listOf( + "-language-version", "2.0", + "-Xsuppress-version-warnings" // Don't fail on language version warnings. + ).takeIf { compilerType.useFir }, kotlinSourceFilePaths ) } - private fun buildBinaryAndRun(mainModuleKlibFile: File, allDependencies: Dependencies) { + private fun buildBinaryAndRun(mainModule: Dependency, otherDependencies: Dependencies) { // The modules in `Dependencies.regularDependencies` are already in topological order. // It is important to pass the provided and the produced JS files to Node in exactly the same order. - val knownModulesInTopologicalOrder: List = allDependencies.regularDependencies.map { dependency -> - ModuleDetails(name = dependency.moduleName, outputDir = dependency.libraryFile.parentFile) + val knownModulesInTopologicalOrder: List = buildList { + otherDependencies.regularDependencies.mapTo(this, ::ModuleDetails) + this += ModuleDetails(mainModule) } val knownModuleNames: Set = knownModulesInTopologicalOrder.mapTo(hashSetOf(), ModuleDetails::name) @@ -133,20 +139,19 @@ abstract class AbstractJsPartialLinkageTestCase(private val compilerType: Compil "-Xir-produce-js", "-Xir-per-module", "-module-kind", "plain", - "-Xinclude=${mainModuleKlibFile.absolutePath}", + "-Xinclude=${mainModule.libraryFile.absolutePath}", "-ir-output-dir", binariesDir.absolutePath, - "-ir-output-name", MAIN_MODULE_NAME + "-ir-output-name", MAIN_MODULE_NAME, + // IMPORTANT: Omitting PL arguments here. The default PL mode should be in effect. + // "-Xpartial-linkage=enable", "-Xpartial-linkage-loglevel=INFO", + "-Werror" ), listOf( "-Xcache-directory", buildDir.resolve("libs-cache").absolutePath ).takeIf { compilerType.useIc }, - allDependencies.toCompilerArgs(), - listOf("-Xes-classes").takeIf { compilerType.es6Mode }, - listOf( - "-Xpartial-linkage=enable", - "-Xpartial-linkage-loglevel=WARNING" - ) + otherDependencies.toCompilerArgs(), + listOf("-Xes-classes").takeIf { compilerType.es6Mode } ) // All JS files produced during the compiler call. @@ -225,4 +230,6 @@ abstract class AbstractJsPartialLinkageTestCase(private val compilerType: Compil } private typealias ModuleName = String -private class ModuleDetails(val name: ModuleName, val outputDir: File) +private class ModuleDetails(val name: ModuleName, val outputDir: File) { + constructor(dependency: Dependency) : this(dependency.moduleName, dependency.libraryFile.parentFile) +} diff --git a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativePartialLinkageTest.kt b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativePartialLinkageTest.kt index d250112b9c2..acf97dbebe1 100644 --- a/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativePartialLinkageTest.kt +++ b/native/native.tests/tests/org/jetbrains/kotlin/konan/blackboxtest/AbstractNativePartialLinkageTest.kt @@ -9,6 +9,7 @@ import com.intellij.testFramework.TestDataFile import org.jetbrains.kotlin.codegen.ProjectInfo import org.jetbrains.kotlin.klib.PartialLinkageTestUtils import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.Dependencies +import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.Dependency import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.MAIN_MODULE_NAME import org.jetbrains.kotlin.klib.PartialLinkageTestUtils.ModuleBuildDirs import org.jetbrains.kotlin.konan.blackboxtest.support.* @@ -62,8 +63,8 @@ abstract class AbstractNativePartialLinkageTest : AbstractNativeSimpleTest() { klibFile: File ) = this@AbstractNativePartialLinkageTest.buildKlib(moduleName, buildDirs.sourceDir, dependencies, klibFile) - override fun buildBinaryAndRun(mainModuleKlibFile: File, dependencies: Dependencies) = - this@AbstractNativePartialLinkageTest.buildBinaryAndRun(dependencies) + override fun buildBinaryAndRun(mainModule: Dependency, otherDependencies: Dependencies) = + this@AbstractNativePartialLinkageTest.buildBinaryAndRun(mainModule, otherDependencies) override fun onNonEmptyBuildDirectory(directory: File) = backupDirectoryContents(directory) @@ -103,7 +104,7 @@ abstract class AbstractNativePartialLinkageTest : AbstractNativeSimpleTest() { settings = testRunSettings, freeCompilerArgs = testCase.freeCompilerArgs, sourceModules = testCase.modules, - dependencies = createLibraryDependencies(dependencies, forExecutable = false), + dependencies = createLibraryDependencies(dependencies), expectedArtifact = klibArtifact ) @@ -112,7 +113,7 @@ abstract class AbstractNativePartialLinkageTest : AbstractNativeSimpleTest() { producedKlibs += ProducedKlib(moduleName, klibArtifact, dependencies) // Remember the artifact with its dependencies. } - private fun buildBinaryAndRun(allDependencies: Dependencies) { + private fun buildBinaryAndRun(mainModule: Dependency, otherDependencies: Dependencies) { val cacheDependencies = if (useStaticCacheForUserLibraries) { producedKlibs.map { producedKlib -> buildCacheForKlib(producedKlib) @@ -132,7 +133,11 @@ abstract class AbstractNativePartialLinkageTest : AbstractNativeSimpleTest() { freeCompilerArgs = testCase.freeCompilerArgs, sourceModules = testCase.modules, extras = testCase.extras, - dependencies = createLibraryDependencies(allDependencies, forExecutable = true) + cacheDependencies, + dependencies = buildList { + this += createIncludedDependency(mainModule) + this += createLibraryDependencies(otherDependencies) + this += cacheDependencies + }, expectedArtifact = executableArtifact ) @@ -187,20 +192,17 @@ abstract class AbstractNativePartialLinkageTest : AbstractNativeSimpleTest() { } } - private fun createLibraryDependencies( - dependencies: Dependencies, - forExecutable: Boolean - ): Iterable> = - dependencies.regularDependencies.map { dependency -> - val klib = KLIB(dependency.libraryFile) - if (forExecutable && dependency.moduleName == MAIN_MODULE_NAME) klib.toIncludedDependency() else klib.toDependency() - } + dependencies.friendDependencies.map { KLIB(it.libraryFile).toFriendDependency() } + private fun createIncludedDependency(dependency: Dependency): TestCompilationDependency = + KLIB(dependency.libraryFile).toIncludedDependency() - private fun createLibraryCacheDependencies( - dependencies: Dependencies - ): Iterable> = dependencies.regularDependencies.mapNotNull { dependency -> - if (dependency.libraryFile != stdlibFile) KLIB(dependency.libraryFile).toStaticCacheArtifact().toDependency() else null - } + private fun createLibraryDependencies(dependencies: Dependencies): Iterable> = + dependencies.regularDependencies.map { dependency -> KLIB(dependency.libraryFile).toDependency() } + + dependencies.friendDependencies.map { KLIB(it.libraryFile).toFriendDependency() } + + private fun createLibraryCacheDependencies(dependencies: Dependencies): Iterable> = + dependencies.regularDependencies.mapNotNull { dependency -> + if (dependency.libraryFile != stdlibFile) KLIB(dependency.libraryFile).toStaticCacheArtifact().toDependency() else null + } private fun KLIB.toDependency() = ExistingDependency(this, Library) private fun KLIB.toIncludedDependency() = ExistingDependency(this, IncludedLibrary)