diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt index f60ab547f14..01b2bfd9f21 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt @@ -18,6 +18,8 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.create import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider +import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleCompiler +import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleCompilerJar import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar @@ -28,6 +30,8 @@ import org.jetbrains.kotlin.test.services.ServiceRegistrationData import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator +import kotlin.contracts.contract +import kotlin.test.assertNotNull object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator() { override val analyseInDependentSession: Boolean get() = false @@ -40,6 +44,7 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator builder.apply { useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider)) useAdditionalService { KtLibrarySourceModuleFactory() } + useAdditionalService { TestModuleCompilerJar() } useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives) usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler) useConfigurators(::JvmEnvironmentConfigurator) @@ -66,6 +71,9 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator private class KtLibrarySourceModuleFactory : KtModuleFactory { override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles { val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.compileToLibrary(testModule) + + require(librarySourcesJar != null) + return createKtLibrarySourceModule( libraryJar = libraryJar, librarySourcesJar = librarySourcesJar, 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 774550ce300..7c468240cbd 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 @@ -17,15 +17,17 @@ class CompiledLibraryProvider(private val testServices: TestServices) : TestServ if (module.name in libraries) { error("Library for module ${module.name} is already compiled") } - val libraryJar = TestModuleCompiler.compileTestModuleToLibrary(module, testServices) - val librarySourcesJar = TestModuleCompiler.compileTestModuleToLibrarySources(module, testServices) + val libraryJar = testServices.testModuleCompiler.compileTestModuleToLibrary(module, testServices) + val librarySourcesJar = testServices.testModuleCompiler.compileTestModuleToLibrarySources(module, testServices) + return CompiledLibrary(libraryJar, librarySourcesJar).also { libraries[module.name] = it } } } val TestServices.compiledLibraryProvider: CompiledLibraryProvider by TestServices.testServiceAccessor() +val TestServices.testModuleCompiler: TestModuleCompiler by TestServices.testServiceAccessor() data class CompiledLibrary( - val jar: Path, - val sourcesJar: Path, -) \ No newline at end of file + val artifact: Path, + val sources: Path?, +) 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 5bcdeaf4da9..e9a4e8cdb26 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.test.framework.services.libraries import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.TestService import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.sourceFileProvider import org.jetbrains.kotlin.test.util.KtTestUtil @@ -20,8 +21,7 @@ import kotlin.io.path.div import kotlin.io.path.outputStream import kotlin.io.path.writeText - -internal object TestModuleCompiler { +abstract class TestModuleCompiler : TestService { fun compileTestModuleToLibrary(module: TestModule, testServices: TestServices): Path { val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath() for (testFile in module.files) { @@ -29,14 +29,28 @@ internal object TestModuleCompiler { val tmpSourceFile = (tmpDir / testFile.name).createFile() tmpSourceFile.writeText(text) } - return CompilerExecutor.compileLibrary( - tmpDir, - CompilerExecutor.parseCompilerOptionsFromTestdata(module), - compilationErrorExpected = CompilerExecutor.Directives.COMPILATION_ERRORS in module.directives - ) + return compile(tmpDir, module) } - fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path { + abstract fun compile(tmpDir: Path, module: TestModule): Path + + abstract fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path? +} + +class TestModuleCompilerJar : TestModuleCompiler() { + override fun compile(tmpDir: Path, module: TestModule): Path = CompilerExecutor.compileLibrary( + tmpDir, + CompilerExecutor.parseCompilerOptionsFromTestdata(module), + compilationErrorExpected = CompilerExecutor.Directives.COMPILATION_ERRORS in module.directives + ) + + override fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path { + fun addFileToJar(path: String, text: String, jarOutputStream: JarOutputStream) { + jarOutputStream.putNextEntry(JarEntry(path)) + ByteArrayInputStream(text.toByteArray()).copyTo(jarOutputStream) + jarOutputStream.closeEntry() + } + val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath() val librarySourcesPath = tmpDir / "library-sources.jar" val manifest = Manifest().apply { mainAttributes[Attributes.Name.MANIFEST_VERSION] = "1.0" } @@ -48,10 +62,4 @@ internal object TestModuleCompiler { } return librarySourcesPath } - - private fun addFileToJar(path: String, text: String, jarOutputStream: JarOutputStream) { - jarOutputStream.putNextEntry(JarEntry(path)) - ByteArrayInputStream(text.toByteArray()).copyTo(jarOutputStream) - jarOutputStream.closeEntry() - } -} \ No newline at end of file +} diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleDecompiler.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleDecompiler.kt new file mode 100644 index 00000000000..c6ee47984d0 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleDecompiler.kt @@ -0,0 +1,24 @@ +/* + * 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.analysis.test.framework.services.libraries + +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.analysis.api.impl.base.util.LibraryUtils +import org.jetbrains.kotlin.test.services.TestService +import org.jetbrains.kotlin.test.services.TestServices +import java.nio.file.Path + +interface TestModuleDecompiler : TestService { + fun getAllPsiFilesFromLibrary(artifact: Path, project: Project): List +} + +val TestServices.testModuleDecompiler: TestModuleDecompiler by TestServices.testServiceAccessor() + +class TestModuleDecompilerJar : TestModuleDecompiler { + override fun getAllPsiFilesFromLibrary(artifact: Path, project: Project): List = + LibraryUtils.getAllPsiFilesFromJar(artifact, project) +} diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt index 54e43084d7a..a2319540bca 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirT import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtLibraryModuleImpl import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory -import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider +import org.jetbrains.kotlin.analysis.test.framework.services.libraries.* import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind @@ -34,6 +34,8 @@ object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) { builder.apply { useAdditionalService { KtLibraryBinaryModuleFactory() } + useAdditionalService { TestModuleCompilerJar() } + useAdditionalService { TestModuleDecompilerJar() } } } @@ -56,8 +58,8 @@ object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator private class KtLibraryBinaryModuleFactory : KtModuleFactory { override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles { - val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).jar - val decompiledFiles = LibraryUtils.getAllPsiFilesFromJar(library, project) + val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).artifact + val decompiledFiles = testServices.testModuleDecompiler.getAllPsiFilesFromLibrary(library, project) return KtModuleWithFiles( KtLibraryModuleImpl( @@ -71,4 +73,4 @@ private class KtLibraryBinaryModuleFactory : KtModuleFactory { decompiledFiles ) } -} \ No newline at end of file +}