[Analysis API] [Test Infra] move (de)compilation services
move (de)compilation services from static dependencies into DI This is done for allowing different (de)compile strategies in the future Merge-request: KT-MR-13213 Merged-by: Artem Olkov <artem.olkov@jetbrains.com>
This commit is contained in:
+8
@@ -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.KtModuleFactory
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory
|
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.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.services.libraries.compiledLibraryProvider
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
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.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.TestModuleStructure
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
|
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
|
||||||
|
import kotlin.contracts.contract
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator() {
|
object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator() {
|
||||||
override val analyseInDependentSession: Boolean get() = false
|
override val analyseInDependentSession: Boolean get() = false
|
||||||
@@ -40,6 +44,7 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator
|
|||||||
builder.apply {
|
builder.apply {
|
||||||
useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider))
|
useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider))
|
||||||
useAdditionalService<KtModuleFactory> { KtLibrarySourceModuleFactory() }
|
useAdditionalService<KtModuleFactory> { KtLibrarySourceModuleFactory() }
|
||||||
|
useAdditionalService<TestModuleCompiler> { TestModuleCompilerJar() }
|
||||||
useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives)
|
useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives)
|
||||||
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
|
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
|
||||||
useConfigurators(::JvmEnvironmentConfigurator)
|
useConfigurators(::JvmEnvironmentConfigurator)
|
||||||
@@ -66,6 +71,9 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator
|
|||||||
private class KtLibrarySourceModuleFactory : KtModuleFactory {
|
private class KtLibrarySourceModuleFactory : KtModuleFactory {
|
||||||
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
|
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
|
||||||
val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.compileToLibrary(testModule)
|
val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.compileToLibrary(testModule)
|
||||||
|
|
||||||
|
require(librarySourcesJar != null)
|
||||||
|
|
||||||
return createKtLibrarySourceModule(
|
return createKtLibrarySourceModule(
|
||||||
libraryJar = libraryJar,
|
libraryJar = libraryJar,
|
||||||
librarySourcesJar = librarySourcesJar,
|
librarySourcesJar = librarySourcesJar,
|
||||||
|
|||||||
+7
-5
@@ -17,15 +17,17 @@ class CompiledLibraryProvider(private val testServices: TestServices) : TestServ
|
|||||||
if (module.name in libraries) {
|
if (module.name in libraries) {
|
||||||
error("Library for module ${module.name} is already compiled")
|
error("Library for module ${module.name} is already compiled")
|
||||||
}
|
}
|
||||||
val libraryJar = TestModuleCompiler.compileTestModuleToLibrary(module, testServices)
|
val libraryJar = testServices.testModuleCompiler.compileTestModuleToLibrary(module, testServices)
|
||||||
val librarySourcesJar = TestModuleCompiler.compileTestModuleToLibrarySources(module, testServices)
|
val librarySourcesJar = testServices.testModuleCompiler.compileTestModuleToLibrarySources(module, testServices)
|
||||||
|
|
||||||
return CompiledLibrary(libraryJar, librarySourcesJar).also { libraries[module.name] = it }
|
return CompiledLibrary(libraryJar, librarySourcesJar).also { libraries[module.name] = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val TestServices.compiledLibraryProvider: CompiledLibraryProvider by TestServices.testServiceAccessor()
|
val TestServices.compiledLibraryProvider: CompiledLibraryProvider by TestServices.testServiceAccessor()
|
||||||
|
val TestServices.testModuleCompiler: TestModuleCompiler by TestServices.testServiceAccessor()
|
||||||
|
|
||||||
data class CompiledLibrary(
|
data class CompiledLibrary(
|
||||||
val jar: Path,
|
val artifact: Path,
|
||||||
val sourcesJar: Path,
|
val sources: Path?,
|
||||||
)
|
)
|
||||||
|
|||||||
+23
-15
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.analysis.test.framework.services.libraries
|
package org.jetbrains.kotlin.analysis.test.framework.services.libraries
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
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.TestServices
|
||||||
import org.jetbrains.kotlin.test.services.sourceFileProvider
|
import org.jetbrains.kotlin.test.services.sourceFileProvider
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
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.outputStream
|
||||||
import kotlin.io.path.writeText
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
|
abstract class TestModuleCompiler : TestService {
|
||||||
internal object TestModuleCompiler {
|
|
||||||
fun compileTestModuleToLibrary(module: TestModule, testServices: TestServices): Path {
|
fun compileTestModuleToLibrary(module: TestModule, testServices: TestServices): Path {
|
||||||
val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath()
|
val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath()
|
||||||
for (testFile in module.files) {
|
for (testFile in module.files) {
|
||||||
@@ -29,14 +29,28 @@ internal object TestModuleCompiler {
|
|||||||
val tmpSourceFile = (tmpDir / testFile.name).createFile()
|
val tmpSourceFile = (tmpDir / testFile.name).createFile()
|
||||||
tmpSourceFile.writeText(text)
|
tmpSourceFile.writeText(text)
|
||||||
}
|
}
|
||||||
return CompilerExecutor.compileLibrary(
|
return compile(tmpDir, module)
|
||||||
tmpDir,
|
|
||||||
CompilerExecutor.parseCompilerOptionsFromTestdata(module),
|
|
||||||
compilationErrorExpected = CompilerExecutor.Directives.COMPILATION_ERRORS in module.directives
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath()
|
||||||
val librarySourcesPath = tmpDir / "library-sources.jar"
|
val librarySourcesPath = tmpDir / "library-sources.jar"
|
||||||
val manifest = Manifest().apply { mainAttributes[Attributes.Name.MANIFEST_VERSION] = "1.0" }
|
val manifest = Manifest().apply { mainAttributes[Attributes.Name.MANIFEST_VERSION] = "1.0" }
|
||||||
@@ -48,10 +62,4 @@ internal object TestModuleCompiler {
|
|||||||
}
|
}
|
||||||
return librarySourcesPath
|
return librarySourcesPath
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun addFileToJar(path: String, text: String, jarOutputStream: JarOutputStream) {
|
|
||||||
jarOutputStream.putNextEntry(JarEntry(path))
|
|
||||||
ByteArrayInputStream(text.toByteArray()).copyTo(jarOutputStream)
|
|
||||||
jarOutputStream.closeEntry()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+24
@@ -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<PsiFile>
|
||||||
|
}
|
||||||
|
|
||||||
|
val TestServices.testModuleDecompiler: TestModuleDecompiler by TestServices.testServiceAccessor()
|
||||||
|
|
||||||
|
class TestModuleDecompilerJar : TestModuleDecompiler {
|
||||||
|
override fun getAllPsiFilesFromLibrary(artifact: Path, project: Project): List<PsiFile> =
|
||||||
|
LibraryUtils.getAllPsiFilesFromJar(artifact, project)
|
||||||
|
}
|
||||||
+6
-4
@@ -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.KtLibraryModuleImpl
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory
|
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.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.AnalysisApiTestConfigurator
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
|
||||||
@@ -34,6 +34,8 @@ object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator
|
|||||||
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
||||||
builder.apply {
|
builder.apply {
|
||||||
useAdditionalService<KtModuleFactory> { KtLibraryBinaryModuleFactory() }
|
useAdditionalService<KtModuleFactory> { KtLibraryBinaryModuleFactory() }
|
||||||
|
useAdditionalService<TestModuleCompiler> { TestModuleCompilerJar() }
|
||||||
|
useAdditionalService<TestModuleDecompiler> { TestModuleDecompilerJar() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,8 +58,8 @@ object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator
|
|||||||
|
|
||||||
private class KtLibraryBinaryModuleFactory : KtModuleFactory {
|
private class KtLibraryBinaryModuleFactory : KtModuleFactory {
|
||||||
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
|
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
|
||||||
val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).jar
|
val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).artifact
|
||||||
val decompiledFiles = LibraryUtils.getAllPsiFilesFromJar(library, project)
|
val decompiledFiles = testServices.testModuleDecompiler.getAllPsiFilesFromLibrary(library, project)
|
||||||
|
|
||||||
return KtModuleWithFiles(
|
return KtModuleWithFiles(
|
||||||
KtLibraryModuleImpl(
|
KtLibraryModuleImpl(
|
||||||
@@ -71,4 +73,4 @@ private class KtLibraryBinaryModuleFactory : KtModuleFactory {
|
|||||||
decompiledFiles
|
decompiledFiles
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user