From 512efb96491b41c7cbf506b84e3f13e9ad8b2b66 Mon Sep 17 00:00:00 2001 From: Jaebaek Seo Date: Thu, 8 Feb 2024 15:28:42 -0800 Subject: [PATCH] K2: Support binary library dependencies between test modules The test infrastructure for analysis supports binary module tests, but the binary build does not use another binary module as a dependency when it passes the class path. As a result, each binary module build does not work when they have dependency on each other. This commit fixes the issue by 1. Topological sort in the order of dependency graph for test modules. 2. Pass module paths as extra class paths when they have dependency on each other. ^KT-64994 --- ...tiModuleCompilerFacilityTestGenerated.java | 54 +++++++++++++++++++ .../dependencyBetweenBinaryLibraries.ir.txt | 6 +++ .../dependencyBetweenBinaryLibraries.kt | 16 ++++++ .../dependencyBetweenBinaryLibraries.txt | 4 ++ .../structure/KtCodeFragmentModuleFactory.kt | 2 + .../structure/KtLibraryBinaryModuleFactory.kt | 4 +- .../structure/KtLibrarySourceModuleFactory.kt | 1 + .../project/structure/KtModuleFactory.kt | 2 + .../structure/KtScriptModuleFactory.kt | 2 + .../structure/KtSourceModuleFactory.kt | 2 + .../structure/TestModuleStructureFactory.kt | 46 ++++++++++++++-- .../libraries/CliTestModuleCompilers.kt | 14 +++-- .../libraries/CompiledLibraryProvider.kt | 4 +- .../services/libraries/TestModuleCompiler.kt | 11 ++-- ...sApiFirOutOfContentRootTestConfigurator.kt | 2 + ...lysisApiFirStdlibSourceTestConfigurator.kt | 2 + .../tests/analysis/api/analysisApi.kt | 8 ++- 17 files changed, 164 insertions(+), 16 deletions(-) create mode 100644 analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibraryBinaryModuleMultiModuleCompilerFacilityTestGenerated.java create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.ir.txt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.kt create mode 100644 analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.txt diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibraryBinaryModuleMultiModuleCompilerFacilityTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibraryBinaryModuleMultiModuleCompilerFacilityTestGenerated.java new file mode 100644 index 00000000000..b7085cf9350 --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/compilerFacility/FirIdeNormalAnalysisLibraryBinaryModuleMultiModuleCompilerFacilityTestGenerated.java @@ -0,0 +1,54 @@ +/* + * Copyright 2010-2024 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.analysis.api.fir.test.cases.generated.cases.components.compilerFacility; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.compilerFacility.AbstractMultiModuleCompilerFacilityTest; +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.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule") +@TestDataPath("$PROJECT_ROOT") +public class FirIdeNormalAnalysisLibraryBinaryModuleMultiModuleCompilerFacilityTestGenerated extends AbstractMultiModuleCompilerFacilityTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.LibraryBinary, + AnalysisSessionMode.Normal, + AnalysisApiMode.Ide + ) + ); + } + + @Test + public void testAllFilesPresentInCompilationMultiBinaryModule() { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule"), Pattern.compile("^(.+)\\.(kt)$"), null, true); + } + + @Test + @TestMetadata("dependencyBetweenBinaryLibraries.kt") + public void testDependencyBetweenBinaryLibraries() { + runTest("analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.kt"); + } +} diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.ir.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.ir.txt new file mode 100644 index 00000000000..c52da890c4f --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.ir.txt @@ -0,0 +1,6 @@ +MODULE_FRAGMENT + FILE fqName: fileName:main.kt + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Int + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun test (): kotlin.Int declared in ' + CALL 'public final fun bar (): kotlin.Int declared in p2' type=kotlin.Int origin=null diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.kt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.kt new file mode 100644 index 00000000000..35d283c4e25 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.kt @@ -0,0 +1,16 @@ +// MODULE: lib +// FILE: p3/foo.kt +package p3; + +fun foo() = 3 +// MODULE: lib2(lib) +// FILE: p2/bar.kt +package p2; + +fun bar() = 4 + p3.foo() +// MODULE: main(lib, lib2) +// MODULE_KIND: Source +// FILE: main.kt +import p2.bar + +fun test() = bar() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.txt b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.txt new file mode 100644 index 00000000000..1d118951724 --- /dev/null +++ b/analysis/analysis-api/testData/components/compilerFacility/compilationMultiBinaryModule/dependencyBetweenBinaryLibraries.txt @@ -0,0 +1,4 @@ +public final class MainKt { + // source: 'main.kt' + public final static method test(): int +} diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtCodeFragmentModuleFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtCodeFragmentModuleFactory.kt index 2c410be125f..12ffb8dfc38 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtCodeFragmentModuleFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtCodeFragmentModuleFactory.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.sourceFileProvider +import java.nio.file.Path object KtCodeFragmentModuleFactory : KtModuleFactory { override fun createModule( @@ -30,6 +31,7 @@ object KtCodeFragmentModuleFactory : KtModuleFactory { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection ): KtModuleWithFiles { requireNotNull(contextModule) { "Code fragment requires a context module" } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibraryBinaryModuleFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibraryBinaryModuleFactory.kt index 58d4218c4a2..2a30088911c 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibraryBinaryModuleFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibraryBinaryModuleFactory.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledL import org.jetbrains.kotlin.analysis.test.framework.services.libraries.testModuleDecompiler import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices +import java.nio.file.Path /** * @see org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind.LibraryBinary @@ -23,8 +24,9 @@ object KtLibraryBinaryModuleFactory : KtModuleFactory { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection, ): KtModuleWithFiles { - val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).artifact + val library = testServices.compiledLibraryProvider.compileToLibrary(testModule, dependencyPaths).artifact val decompiledFiles = testServices.testModuleDecompiler.getAllPsiFilesFromLibrary(library, project) return KtModuleWithFiles( diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibrarySourceModuleFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibrarySourceModuleFactory.kt index 6c2fd106c4e..db2a1864e2c 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibrarySourceModuleFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtLibrarySourceModuleFactory.kt @@ -27,6 +27,7 @@ object KtLibrarySourceModuleFactory : KtModuleFactory { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection, ): KtModuleWithFiles { Assume.assumeFalse("Compilation of multi-platform libraries is not supported", testModule.targetPlatform.isMultiPlatform()) diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtModuleFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtModuleFactory.kt index 1291142b8a9..78af0b2aaa7 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtModuleFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtModuleFactory.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.analysis.test.framework.test.configurators.moduleKin import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestService import org.jetbrains.kotlin.test.services.TestServices +import java.nio.file.Path fun interface KtModuleFactory : TestService { /** @@ -26,6 +27,7 @@ fun interface KtModuleFactory : TestService { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection, ): KtModuleWithFiles } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtScriptModuleFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtScriptModuleFactory.kt index 005fd6651f2..0c840e1dee5 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtScriptModuleFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtScriptModuleFactory.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtMod import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices +import java.nio.file.Path /** * @see org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind.ScriptSource @@ -20,6 +21,7 @@ object KtScriptModuleFactory : KtModuleFactory { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection, ): KtModuleWithFiles { val ktFile = TestModuleStructureFactory.createSourcePsiFiles(testModule, testServices, project).single() as KtFile val module = KtScriptModuleImpl( diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleFactory.kt index 5c18505cc00..bd77a714e99 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleFactory.kt @@ -10,6 +10,7 @@ import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices +import java.nio.file.Path /** * @see org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind.Source @@ -20,6 +21,7 @@ object KtSourceModuleFactory : KtModuleFactory { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection, ): KtModuleWithFiles { val psiFiles = TestModuleStructureFactory.createSourcePsiFiles(testModule, testServices, project) diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt index e9334e842d1..d4822804b69 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt @@ -42,6 +42,31 @@ private typealias LibraryCache = MutableMap, KtBinaryModule> private typealias ModulesByName = Map +/** + * A function to run the topological sort (or post-order sort) for [TestModule]s based on the dependency graph. + * This function guarantees: + * - For [TestModule] A and B, where A has dependency on B, A will never appears earlier than B in the result list. + */ +private fun sortInDependencyPostOrder(testModules: List): List { + val namesToModules = buildMap { testModules.forEach { put(it.name, it) } } + val notVisited = testModules.toMutableSet() + val sortedModules = mutableListOf() + + fun dfsWalk(module: TestModule) { + notVisited.remove(module) + for (dependency in module.regularDependencies) { + val dependencyAsModule = namesToModules[dependency.moduleName] ?: error("Module ${dependency.moduleName} is missing") + if (dependencyAsModule in notVisited) dfsWalk(dependencyAsModule) + } + sortedModules.add(module) + } + + while (notVisited.isNotEmpty()) { + dfsWalk(notVisited.first()) + } + return sortedModules +} + object TestModuleStructureFactory { fun createProjectStructureByTestStructure( moduleStructure: TestModuleStructure, @@ -64,25 +89,38 @@ object TestModuleStructureFactory { return KtModuleProjectStructure(modules, libraryCache.values) } + /** + * A function to create [KtModuleWithFiles] for the given [moduleStructure]. This function guarantees: + * - For [TestModule] A and B, where A has dependency on B, + * - B will always be created earlier than A. + * - The class path of B will be given to the creation of A's module. + * + * In particular, it handles unresolved symbol issues caused by building binary libraries. + */ private fun createModules( moduleStructure: TestModuleStructure, testServices: TestServices, - project: Project + project: Project, ): List { - val moduleCount = moduleStructure.modules.size + val modulesSortedByDependencies = sortInDependencyPostOrder(moduleStructure.modules) + val moduleCount = modulesSortedByDependencies.size + val moduleNamesToPaths = mutableMapOf>() val existingModules = HashMap(moduleCount) val result = ArrayList(moduleCount) - for (testModule in moduleStructure.modules) { + for (testModule in modulesSortedByDependencies) { val contextModuleName = testModule.directives.singleOrZeroValue(AnalysisApiTestDirectives.CONTEXT_MODULE) val contextModule = contextModuleName?.let(existingModules::getValue) + val dependencies = testModule.regularDependencies.mapNotNull { moduleNamesToPaths[it.moduleName] }.flatten() val moduleWithFiles = testServices .getKtModuleFactoryForTestModule(testModule) - .createModule(testModule, contextModule, testServices, project) + .createModule(testModule, contextModule, testServices, project, dependencies) existingModules[testModule.name] = moduleWithFiles result.add(moduleWithFiles) + val libraryModule = moduleWithFiles.ktModule as? KtLibraryModuleImpl ?: continue + moduleNamesToPaths[testModule.name] = libraryModule.getBinaryRoots() } return result diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CliTestModuleCompilers.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CliTestModuleCompilers.kt index b7c2705d6b7..e5d9df499c7 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CliTestModuleCompilers.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CliTestModuleCompilers.kt @@ -30,19 +30,25 @@ import java.util.jar.JarOutputStream import java.util.jar.Manifest import kotlin.io.path.div import kotlin.io.path.outputStream +import kotlin.io.path.pathString abstract class CliTestModuleCompiler : TestModuleCompiler() { internal abstract val compilerKind: CompilerExecutor.CompilerKind protected abstract fun buildPlatformCompilerOptions(module: TestModule, testServices: TestServices): List - override fun compile(tmpDir: Path, module: TestModule, testServices: TestServices): Path = CompilerExecutor.compileLibrary( + override fun compile( + tmpDir: Path, + module: TestModule, + testServices: TestServices, + dependencyPaths: Collection, + ): Path = CompilerExecutor.compileLibrary( compilerKind, tmpDir, buildCompilerOptions(module, testServices), compilationErrorExpected = Directives.COMPILATION_ERRORS in module.directives, libraryName = module.name, - extraClasspath = buildExtraClasspath(module, testServices), + extraClasspath = buildExtraClasspath(module, testServices) + dependencyPaths.map { it.pathString }, ) override fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path { @@ -145,8 +151,8 @@ class DispatchingTestModuleCompiler : TestModuleCompiler() { CompilerExecutor.CompilerKind.JS to JsKlibTestModuleCompiler(), ) - override fun compile(tmpDir: Path, module: TestModule, testServices: TestServices): Path { - return getCompiler(module).compileTestModuleToLibrary(module, testServices) + override fun compile(tmpDir: Path, module: TestModule, testServices: TestServices, dependencyPaths: Collection): Path { + return getCompiler(module).compileTestModuleToLibrary(module, testServices, dependencyPaths) } override fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path { diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt index 1eb9ea7aad2..dcfe776612d 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt @@ -13,11 +13,11 @@ import java.nio.file.Path class CompiledLibraryProvider(private val testServices: TestServices) : TestService { private val libraries = mutableMapOf() - fun compileToLibrary(module: TestModule): CompiledLibrary { + fun compileToLibrary(module: TestModule, dependencyPaths: Collection = emptyList()): CompiledLibrary { if (module.name in libraries) { error("Library for module ${module.name} is already compiled") } - val libraryJar = testServices.testModuleCompiler.compileTestModuleToLibrary(module, testServices) + val libraryJar = testServices.testModuleCompiler.compileTestModuleToLibrary(module, testServices, dependencyPaths) val librarySourcesJar = testServices.testModuleCompiler.compileTestModuleToLibrarySources(module, testServices) return CompiledLibrary(libraryJar, librarySourcesJar).also { libraries[module.name] = it } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt index b848dc16050..65505d6a9d3 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt @@ -18,7 +18,7 @@ import kotlin.io.path.div import kotlin.io.path.writeText abstract class TestModuleCompiler : TestService { - fun compileTestModuleToLibrary(module: TestModule, testServices: TestServices): Path { + fun compileTestModuleToLibrary(module: TestModule, testServices: TestServices, dependencyPaths: Collection = emptyList()): Path { val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath() for (testFile in module.files) { val text = testServices.sourceFileProvider.getContentOfSourceFile(testFile) @@ -28,10 +28,15 @@ abstract class TestModuleCompiler : TestService { val tmpSourceFile = filePath.createFile() tmpSourceFile.writeText(text) } - return compile(tmpDir, module, testServices) + return compile(tmpDir, module, testServices, dependencyPaths) } - abstract fun compile(tmpDir: Path, module: TestModule, testServices: TestServices): Path + abstract fun compile( + tmpDir: Path, + module: TestModule, + testServices: TestServices, + dependencyPaths: Collection = emptyList(), + ): Path abstract fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path? diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirOutOfContentRootTestConfigurator.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirOutOfContentRootTestConfigurator.kt index 108ae62a09e..65cc0d3f8e7 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirOutOfContentRootTestConfigurator.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirOutOfContentRootTestConfigurator.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.test.getAnalyzerServices import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestServices +import java.nio.file.Path object AnalysisApiFirOutOfContentRootTestConfigurator : AnalysisApiFirSourceLikeTestConfigurator(false) { override val testPrefix: String @@ -68,6 +69,7 @@ private object KtOutOfContentRootModuleFactory : KtModuleFactory { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection, ): KtModuleWithFiles { val psiFiles = TestModuleStructureFactory.createSourcePsiFiles(testModule, testServices, project) val platform = testModule.targetPlatform diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirStdlibSourceTestConfigurator.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirStdlibSourceTestConfigurator.kt index b84202219c7..b4d24b8d2a1 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirStdlibSourceTestConfigurator.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirStdlibSourceTestConfigurator.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestServices +import java.nio.file.Path object AnalysisApiFirStdlibSourceTestConfigurator : AnalysisApiFirSourceLikeTestConfigurator(false) { override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) { @@ -30,6 +31,7 @@ private object KtStdlibSourceModuleFactory : KtModuleFactory { contextModule: KtModuleWithFiles?, testServices: TestServices, project: Project, + dependencyPaths: Collection, ): KtModuleWithFiles { val libraryJar = ForTestCompileRuntime.runtimeJarForTests().toPath() val librarySourcesJar = ForTestCompileRuntime.runtimeSourcesJarForTests().toPath() diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt index c71084c2da4..d827fc511fa 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt @@ -100,18 +100,22 @@ internal fun AnalysisApiTestGroup.generateAnalysisApiTests() { component( "compilerFacility", - filter = testModuleKindIs(TestModuleKind.Source, TestModuleKind.LibrarySource) + filter = testModuleKindIs(TestModuleKind.Source, TestModuleKind.LibrarySource, TestModuleKind.LibraryBinary) and frontendIs(FrontendKind.Fir) and analysisSessionModeIs(AnalysisSessionMode.Normal) and analysisApiModeIs(AnalysisApiMode.Ide) ) { - test(AbstractCompilerFacilityTest::class) { + test(AbstractCompilerFacilityTest::class, filter = testModuleKindIs(TestModuleKind.Source, TestModuleKind.LibrarySource)) { model("compilation", pattern = TestGeneratorUtil.KT) } test(AbstractMultiModuleCompilerFacilityTest::class, filter = testModuleKindIs(TestModuleKind.Source)) { model("compilationMultiModule", pattern = TestGeneratorUtil.KT) } + + test(AbstractMultiModuleCompilerFacilityTest::class, filter = testModuleKindIs(TestModuleKind.LibraryBinary)) { + model("compilationMultiBinaryModule", pattern = TestGeneratorUtil.KT) + } } group(filter = testModuleKindIs(TestModuleKind.Source, TestModuleKind.ScriptSource)) {