[analysis api, test] rework test infrastructure, add multimodule tests
This commit is contained in:
@@ -14,6 +14,7 @@ dependencies {
|
||||
testApi(projectTests(":compiler:tests-common-new"))
|
||||
testApi(project(":analysis:analysis-api-providers"))
|
||||
testApi(project(":analysis:analysis-api"))
|
||||
testApi(project(":analysis:analysis-api-standalone:analysis-api-standalone-base"))
|
||||
testApi(project(":analysis:analysis-api-impl-barebone"))
|
||||
}
|
||||
|
||||
@@ -24,6 +25,7 @@ sourceSets {
|
||||
|
||||
projectTest(jUnitMode = JUnitMode.JUnit5) {
|
||||
dependsOn(":dist")
|
||||
dependsOn(":plugins:fir-plugin-prototype:plugin-annotations:jar")
|
||||
workingDir = rootDir
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
+3
-3
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.analysis.test.framework.base
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Computable
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyse
|
||||
import org.jetbrains.kotlin.analysis.api.analyseInDependedAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
@@ -17,8 +16,9 @@ import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AbstractAnalysisApiBasedSingleModuleTest : AbstractAnalysisApiBasedTest() {
|
||||
final override fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||
final override fun doTestByFileStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||
val singleModule = moduleStructure.modules.single()
|
||||
val ktFiles = testServices.ktModuleProvider.getModuleFiles(singleModule).filterIsInstance<KtFile>()
|
||||
doTestByFileStructure(ktFiles, singleModule, testServices)
|
||||
}
|
||||
|
||||
|
||||
+23
-65
@@ -5,9 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.test.framework.base
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.TestDataFile
|
||||
@@ -15,17 +12,13 @@ import junit.framework.ComparisonFailure
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyse
|
||||
import org.jetbrains.kotlin.analysis.api.analyseInDependedAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestDirectives
|
||||
import org.jetbrains.kotlin.analysis.test.framework.TestWithDisposable
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KotlinProjectStructureProviderTestImpl
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.ExpressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.ExpressionMarkersSourceFilePreprocessor
|
||||
import org.jetbrains.kotlin.analysis.test.framework.utils.SkipTestException
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.getKtFilesFromModule
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoots
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.LibraryWasNotCompiledDueToExpectedCompilationError
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -45,7 +38,6 @@ import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurat
|
||||
import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.TestInfo
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import kotlin.io.path.exists
|
||||
@@ -55,7 +47,6 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() {
|
||||
abstract val configurator: AnalysisApiTestConfigurator
|
||||
|
||||
private lateinit var testInfo: KotlinTestInfo
|
||||
private set
|
||||
|
||||
protected lateinit var testDataPath: Path
|
||||
private set
|
||||
@@ -63,12 +54,10 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() {
|
||||
private lateinit var moduleStructure: TestModuleStructure
|
||||
|
||||
protected open fun configureTest(builder: TestConfigurationBuilder) {
|
||||
with(configurator) {
|
||||
builder.configureTest(disposable)
|
||||
}
|
||||
configurator.configureTest(builder, disposable)
|
||||
}
|
||||
|
||||
protected abstract fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices)
|
||||
protected abstract fun doTestByFileStructure(moduleStructure: TestModuleStructure, testServices: TestServices)
|
||||
|
||||
protected fun AssertionsService.assertEqualsToTestDataFileSibling(actual: String, extension: String = ".txt") {
|
||||
val testPrefix = configurator.testPrefix
|
||||
@@ -123,10 +112,14 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() {
|
||||
|
||||
useSourcePreprocessor(::ExpressionMarkersSourceFilePreprocessor)
|
||||
useAdditionalService { ExpressionMarkerProvider() }
|
||||
|
||||
registerAnalysisApiBaseTestServices(disposable, configurator)
|
||||
|
||||
useAdditionalService(::TestKtModuleProvider)
|
||||
useAdditionalService<ApplicationDisposableProvider> { ExecutionListenerBasedDisposableProvider() }
|
||||
useAdditionalService<KotlinStandardLibrariesPathProvider> { StandardLibrariesPathProviderForKotlinProject }
|
||||
useDirectives(AnalysisApiTestDirectives)
|
||||
|
||||
configureTest(this)
|
||||
|
||||
startingArtifactFactory = { ResultingArtifact.Source() }
|
||||
@@ -145,59 +138,31 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() {
|
||||
val testConfiguration = testConfiguration(path, configure)
|
||||
Disposer.register(disposable, testConfiguration.rootDisposable)
|
||||
val testServices = testConfiguration.testServices
|
||||
val moduleStructure = testConfiguration.moduleStructureExtractor.splitTestDataByModules(
|
||||
path,
|
||||
testConfiguration.directives,
|
||||
)
|
||||
val moduleStructure =
|
||||
testConfiguration.moduleStructureExtractor.splitTestDataByModules(path, testConfiguration.directives)
|
||||
testServices.register(TestModuleStructure::class, moduleStructure)
|
||||
this.moduleStructure = moduleStructure
|
||||
val singleModule = moduleStructure.modules.single()
|
||||
val project = try {
|
||||
testServices.compilerConfigurationProvider.getProject(singleModule)
|
||||
} catch (_: SkipTestException) {
|
||||
testConfiguration.testServices.register(TestModuleStructure::class, moduleStructure)
|
||||
|
||||
try {
|
||||
testConfiguration.preAnalysisHandlers.forEach { preprocessor -> preprocessor.preprocessModuleStructure(moduleStructure) }
|
||||
} catch(ignored: LibraryWasNotCompiledDueToExpectedCompilationError) {
|
||||
return
|
||||
}
|
||||
|
||||
registerApplicationServices()
|
||||
testConfiguration.testServices.register(TestModuleStructure::class, moduleStructure)
|
||||
testConfiguration.preAnalysisHandlers.forEach { preprocessor ->
|
||||
try {
|
||||
preprocessor.preprocessModuleStructure(moduleStructure)
|
||||
} catch (exception: Throwable) {
|
||||
when (handleInitializationError(exception, moduleStructure)) {
|
||||
InitializationErrorAction.IGNORE -> {}
|
||||
InitializationErrorAction.THROW -> throw exception
|
||||
}
|
||||
}
|
||||
preprocessor.prepareSealedClassInheritors(moduleStructure)
|
||||
}
|
||||
|
||||
val ktFiles = getKtFilesFromModule(testServices, singleModule)
|
||||
with(project as MockProject) {
|
||||
val compilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(singleModule)
|
||||
compilerConfiguration.addJavaSourceRoots(ktFiles.map { File(it.virtualFilePath) })
|
||||
configurator.registerProjectServices(
|
||||
this,
|
||||
compilerConfiguration,
|
||||
ktFiles,
|
||||
testServices.compilerConfigurationProvider.getPackagePartProviderFactory(singleModule),
|
||||
KotlinProjectStructureProviderTestImpl(testServices)
|
||||
)
|
||||
moduleStructure.modules.forEach { module ->
|
||||
val files = testServices.ktModuleProvider.getModuleFiles(module)
|
||||
configurator.prepareFilesInModule(files, module, testServices)
|
||||
}
|
||||
|
||||
testConfiguration.preAnalysisHandlers.forEach { preprocessor ->
|
||||
try {
|
||||
preprocessor.prepareSealedClassInheritors(moduleStructure)
|
||||
} catch (exception: Throwable) {
|
||||
when (handleInitializationError(exception, moduleStructure)) {
|
||||
InitializationErrorAction.IGNORE -> {}
|
||||
InitializationErrorAction.THROW -> throw exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurator.prepareTestFiles(ktFiles, singleModule, testServices)
|
||||
doTestByFileStructure(ktFiles, moduleStructure, testServices)
|
||||
doTestByFileStructure(moduleStructure, testServices)
|
||||
}
|
||||
|
||||
|
||||
protected fun <R> analyseForTest(contextElement: KtElement, action: KtAnalysisSession.() -> R): R {
|
||||
return if (configurator.analyseInDependentSession
|
||||
&& AnalysisApiTestDirectives.DISABLE_DEPENDED_MODE !in this.moduleStructure.allDirectives
|
||||
@@ -210,13 +175,6 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerApplicationServices() {
|
||||
val application = ApplicationManager.getApplication() as MockApplication
|
||||
KotlinCoreEnvironment.underApplicationLock {
|
||||
configurator.registerApplicationServices(application)
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
fun initTestInfo(testInfo: TestInfo) {
|
||||
this.testInfo = KotlinTestInfo(
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AbstractAnalysisApiSingleFileTest : AbstractAnalysisApiBasedSingleModuleTest() {
|
||||
final override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
|
||||
val singleFile = ktFiles.singleOrNull() ?: ktFiles.first { it.name == "main.kt" }
|
||||
val singleFile = ktFiles.first()
|
||||
doTestByFileStructure(singleFile, module, testServices)
|
||||
}
|
||||
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.base
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.AnalysisApiKtModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.AnalysisApiKtModuleProviderImpl
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.*
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.bind
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
fun TestConfigurationBuilder.registerAnalysisApiBaseTestServices(
|
||||
testDisposable: Disposable,
|
||||
configurator: AnalysisApiTestConfigurator,
|
||||
) {
|
||||
useAdditionalService<TestDisposableProvider>(::TestDisposableProviderImpl)
|
||||
useAdditionalService<AnalysisApiKtModuleProvider>(::AnalysisApiKtModuleProviderImpl)
|
||||
useAdditionalService<AnalysisApiEnvironmentManager>(::AnalysisApiEnvironmentManagerImpl.bind(testDisposable))
|
||||
|
||||
useCustomCompilerConfigurationProvider(::AnalysisApiTestCompilerConfiguratorProvider)
|
||||
usePreAnalysisHandlers(::ProjectStructureInitialisationPreAnalysisHandler.bind(configurator))
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.project.structure
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestService
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AnalysisApiKtModuleProvider : TestService {
|
||||
protected abstract val testServices: TestServices
|
||||
abstract fun getModule(moduleName: String): KtModule
|
||||
|
||||
abstract fun getModuleFiles(module: TestModule): List<PsiFile>
|
||||
|
||||
abstract fun registerProjectStructure(modules: List<KtModuleWithFiles>)
|
||||
|
||||
protected abstract fun getModuleName(ktModule: KtModule): String
|
||||
|
||||
abstract fun getAllModules(): List<KtModuleWithFiles>
|
||||
}
|
||||
|
||||
class AnalysisApiKtModuleProviderImpl(
|
||||
override val testServices: TestServices,
|
||||
) : AnalysisApiKtModuleProvider() {
|
||||
private lateinit var modules: List<KtModuleWithFiles>
|
||||
private lateinit var modulesByName: Map<String, KtModuleWithFiles>
|
||||
|
||||
override fun getModule(moduleName: String): KtModule {
|
||||
return modulesByName.getValue(moduleName).ktModule
|
||||
}
|
||||
|
||||
override fun getModuleFiles(module: TestModule): List<PsiFile> = modulesByName.getValue(module.name).files
|
||||
|
||||
override fun registerProjectStructure(modules: List<KtModuleWithFiles>) {
|
||||
require(!this::modules.isInitialized)
|
||||
require(!this::modulesByName.isInitialized)
|
||||
|
||||
this.modules = modules
|
||||
this.modulesByName = modules.associateBy { getModuleName(it.ktModule) }
|
||||
}
|
||||
|
||||
override fun getModuleName(ktModule: KtModule): String = when (ktModule) {
|
||||
is KtLibraryModule -> ktModule.libraryName
|
||||
is KtSdkModule -> ktModule.sdkName
|
||||
is KtLibrarySourceModule -> ktModule.libraryName
|
||||
is KtSourceModule -> ktModule.moduleName
|
||||
is KtNotUnderContentRootModule -> TODO()
|
||||
}
|
||||
|
||||
|
||||
override fun getAllModules(): List<KtModuleWithFiles> = modules
|
||||
}
|
||||
|
||||
val TestServices.ktModuleProvider: AnalysisApiKtModuleProvider by TestServices.testServiceAccessor()
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.project.structure
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.project.structure
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
class KotlinProjectStructureProviderTestImpl(private val testServices: TestServices) : ProjectStructureProvider() {
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
||||
val containingFile = element.containingFile as KtFile
|
||||
return moduleInfoProvider.getModuleInfoByKtFile(containingFile) as KtModule
|
||||
}
|
||||
|
||||
override fun getKtLibraryModules(): Collection<TestKtLibraryModule> {
|
||||
return moduleInfoProvider.getLibraryModules()
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.project.structure
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestService
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
class TestKtModuleProvider(
|
||||
private val testServices: TestServices
|
||||
) : TestService {
|
||||
private val cache = mutableMapOf<String, TestKtModule>()
|
||||
|
||||
fun registerModuleInfo(testModule: TestModule, ktModule: TestKtModule) {
|
||||
cache[testModule.name] = ktModule
|
||||
}
|
||||
|
||||
fun getModuleInfoByKtFile(ktFile: KtFile): TestKtModule =
|
||||
cache.values.first { moduleSourceInfo ->
|
||||
(if (ktFile.isPhysical) ktFile else ktFile.originalFile) in moduleSourceInfo.ktFiles
|
||||
}
|
||||
|
||||
fun getModule(moduleName: String): TestKtModule =
|
||||
cache.getValue(moduleName)
|
||||
|
||||
fun getLibraryModules(): Collection<TestKtLibraryModule> {
|
||||
return cache.values.filterIsInstance<TestKtLibraryModule>()
|
||||
}
|
||||
}
|
||||
|
||||
val TestServices.projectModuleProvider: TestKtModuleProvider by TestServices.testServiceAccessor()
|
||||
+17
-16
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.analysis.test.framework.project.structure
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
@@ -21,7 +22,6 @@ import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
@@ -34,10 +34,10 @@ import java.nio.file.Paths
|
||||
abstract class TestKtModule(
|
||||
val project: Project,
|
||||
val testModule: TestModule,
|
||||
val ktFiles: Set<KtFile>,
|
||||
val psiFiles: List<PsiFile>,
|
||||
testServices: TestServices,
|
||||
) {
|
||||
private val moduleProvider = testServices.projectModuleProvider
|
||||
private val moduleProvider = testServices.ktModuleProvider
|
||||
private val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||
private val configuration = compilerConfigurationProvider.getCompilerConfiguration(testModule)
|
||||
|
||||
@@ -47,7 +47,7 @@ abstract class TestKtModule(
|
||||
|
||||
val directRegularDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
buildList {
|
||||
testModule.allDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) as KtModule }
|
||||
testModule.allDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
|
||||
addIfNotNull(
|
||||
libraryByRoots(
|
||||
(configuration.jvmModularRoots + configuration.jvmClasspathRoots).map(File::toPath)
|
||||
@@ -58,12 +58,12 @@ abstract class TestKtModule(
|
||||
|
||||
val directRefinementDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
testModule.dependsOnDependencies
|
||||
.map { moduleProvider.getModule(it.moduleName) as KtModule }
|
||||
.map { moduleProvider.getModule(it.moduleName) }
|
||||
}
|
||||
|
||||
val directFriendDependencies: List<KtModule> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
buildList {
|
||||
testModule.friendDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) as KtModule }
|
||||
testModule.friendDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) }
|
||||
addIfNotNull(
|
||||
libraryByRoots(configuration[JVMConfigurationKeys.FRIEND_PATHS].orEmpty().map(Paths::get))
|
||||
)
|
||||
@@ -94,40 +94,41 @@ abstract class TestKtModule(
|
||||
class TestKtSourceModule(
|
||||
project: Project,
|
||||
testModule: TestModule,
|
||||
val testFilesToKtFiles: Map<TestFile, KtFile>,
|
||||
psiFiles: List<PsiFile>,
|
||||
testServices: TestServices
|
||||
) : TestKtModule(project, testModule, testFilesToKtFiles.values.toSet(), testServices), KtSourceModule {
|
||||
) : TestKtModule(project, testModule, psiFiles, testServices), KtSourceModule {
|
||||
override val ktModule: KtModule get() = this
|
||||
|
||||
override val contentScope: GlobalSearchScope =
|
||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, testFilesToKtFiles.values)
|
||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, psiFiles.filterIsInstance<KtFile>())
|
||||
}
|
||||
|
||||
class TestKtLibraryModule(
|
||||
project: Project,
|
||||
testModule: TestModule,
|
||||
ktFiles: Collection<KtFile>,
|
||||
psiFiles: List<PsiFile>,
|
||||
private val binaryRoots: List<Path>,
|
||||
testServices: TestServices
|
||||
) : TestKtModule(project, testModule, ktFiles.toSet(), testServices), KtLibraryModule {
|
||||
) : TestKtModule(project, testModule, psiFiles, testServices), KtLibraryModule {
|
||||
override val ktModule: KtModule get() = this
|
||||
override val libraryName: String get() = testModule.name
|
||||
override val librarySources: KtLibrarySourceModule? get() = null
|
||||
|
||||
override fun getBinaryRoots(): Collection<Path> = ktFiles.map { it.virtualFile.toNioPath() }
|
||||
override fun getBinaryRoots(): Collection<Path> = binaryRoots
|
||||
|
||||
override val contentScope: GlobalSearchScope =
|
||||
GlobalSearchScope.filesScope(project, ktFiles.map { it.virtualFile })
|
||||
GlobalSearchScope.filesScope(project, psiFiles.map { it.virtualFile })
|
||||
}
|
||||
|
||||
class TestKtLibrarySourceModule(
|
||||
project: Project,
|
||||
testModule: TestModule,
|
||||
ktFilesFromSourceJar: Set<KtFile>,
|
||||
psiFiles: List<PsiFile>,
|
||||
testServices: TestServices,
|
||||
override val binaryLibrary: KtLibraryModule,
|
||||
) : TestKtModule(project, testModule, ktFilesFromSourceJar, testServices), KtLibrarySourceModule {
|
||||
) : TestKtModule(project, testModule, psiFiles, testServices), KtLibrarySourceModule {
|
||||
override val ktModule: KtModule get() = this
|
||||
override val contentScope: GlobalSearchScope get() = GlobalSearchScope.filesScope(project, ktFiles.map { it.virtualFile })
|
||||
override val contentScope: GlobalSearchScope get() = GlobalSearchScope.filesScope(project, psiFiles.map { it.virtualFile })
|
||||
|
||||
override val libraryName: String get() = testModule.name
|
||||
}
|
||||
|
||||
+41
-5
@@ -5,16 +5,52 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.test.framework.project.structure
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
|
||||
fun getKtFilesFromModule(testServices: TestServices, testModule: TestModule): List<KtFile> {
|
||||
val moduleInfoProvider = testServices.projectModuleProvider
|
||||
val moduleInfoProvider = testServices.ktModuleProvider
|
||||
return when (val moduleInfo = moduleInfoProvider.getModule(testModule.name)) {
|
||||
is TestKtSourceModule -> moduleInfo.testFilesToKtFiles.filterKeys { testFile -> !testFile.isAdditional }.values.toList()
|
||||
is TestKtLibraryModule -> moduleInfo.ktFiles.toList()
|
||||
is TestKtLibrarySourceModule -> moduleInfo.ktFiles.toList()
|
||||
is TestKtSourceModule -> moduleInfo.psiFiles.filterIsInstance<KtFile>()
|
||||
is TestKtLibraryModule -> moduleInfo.psiFiles.filterIsInstance<KtFile>()
|
||||
is TestKtLibrarySourceModule -> moduleInfo.psiFiles.filterIsInstance<KtFile>()
|
||||
else -> error("Unexpected $moduleInfo")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun TestModuleStructure.toKtSourceModules(testServices: TestServices, project: Project) =
|
||||
modules.map { testModule -> testModule.toKtSourceModule(testServices, project) }
|
||||
|
||||
fun TestModule.toKtSourceModule(testServices: TestServices, project: Project): KtModuleWithFiles {
|
||||
val files = files.map { testFile ->
|
||||
when {
|
||||
testFile.isKtFile -> {
|
||||
val fileText = testServices.sourceFileProvider.getContentOfSourceFile(testFile)
|
||||
KtTestUtil.createFile(testFile.name, fileText, project)
|
||||
}
|
||||
|
||||
testFile.isJavaFile -> {
|
||||
val filePath = testServices.sourceFileProvider.getRealFileForSourceFile(testFile)
|
||||
val virtualFile =
|
||||
testServices.environmentManager.getApplicationEnvironment().localFileSystem.findFileByIoFile(filePath)
|
||||
?: error("Virtual file not found for $filePath")
|
||||
PsiManager.getInstance(project).findFile(virtualFile)
|
||||
?: error("PsiFile file not found for $filePath")
|
||||
}
|
||||
|
||||
else -> error("Unexpected file ${testFile.name}")
|
||||
}
|
||||
}
|
||||
return KtModuleWithFiles(
|
||||
TestKtSourceModule(project, this, files, testServices),
|
||||
files
|
||||
)
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.Application
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreApplicationEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.test.ApplicationEnvironmentDisposer
|
||||
import org.jetbrains.kotlin.test.services.TestService
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
import org.jetbrains.kotlin.test.services.moduleStructure
|
||||
|
||||
abstract class AnalysisApiEnvironmentManager : TestService {
|
||||
abstract val testServices: TestServices
|
||||
abstract val testRootDisposable: Disposable
|
||||
abstract fun initializeEnvironment()
|
||||
|
||||
fun getProject(): Project =
|
||||
getProjectEnvironment().project
|
||||
|
||||
fun getApplication(): Application =
|
||||
getApplicationEnvironment().application
|
||||
|
||||
abstract fun initializeProjectStructure()
|
||||
abstract fun getProjectEnvironment(): KotlinCoreProjectEnvironment
|
||||
abstract fun getApplicationEnvironment(): KotlinCoreApplicationEnvironment
|
||||
}
|
||||
|
||||
class AnalysisApiEnvironmentManagerImpl(
|
||||
override val testServices: TestServices,
|
||||
override val testRootDisposable: Disposable,
|
||||
) : AnalysisApiEnvironmentManager() {
|
||||
private val _projectEnvironment: KotlinCoreProjectEnvironment by lazy {
|
||||
StandaloneProjectFactory.createProjectEnvironment(
|
||||
testRootDisposable,
|
||||
ApplicationEnvironmentDisposer.ROOT_DISPOSABLE
|
||||
)
|
||||
}
|
||||
|
||||
override fun initializeEnvironment() {
|
||||
testServices.disposableProvider.registerDisposables(
|
||||
projectDisposable = _projectEnvironment.parentDisposable,
|
||||
applicationDisposable = _projectEnvironment.environment.parentDisposable,
|
||||
)
|
||||
}
|
||||
|
||||
override fun initializeProjectStructure() {
|
||||
val ktModules = testServices.ktModuleProvider.getAllModules()
|
||||
val useSiteModule = testServices.moduleStructure.modules.first()
|
||||
val useSiteCompilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(useSiteModule)
|
||||
|
||||
StandaloneProjectFactory.registerServicesForProjectEnvironment(
|
||||
_projectEnvironment,
|
||||
ktModules,
|
||||
useSiteCompilerConfiguration.languageVersionSettings,
|
||||
useSiteCompilerConfiguration.get(JVMConfigurationKeys.JDK_HOME)?.toPath(),
|
||||
)
|
||||
|
||||
testServices.compilerConfigurationProvider.registerCompilerExtensions(getProject(), useSiteModule)
|
||||
}
|
||||
|
||||
override fun getProjectEnvironment(): KotlinCoreProjectEnvironment =
|
||||
_projectEnvironment
|
||||
|
||||
override fun getApplicationEnvironment(): KotlinCoreApplicationEnvironment =
|
||||
_projectEnvironment.environment as KotlinCoreApplicationEnvironment
|
||||
|
||||
}
|
||||
|
||||
val TestServices.environmentManager: AnalysisApiEnvironmentManager by TestServices.testServiceAccessor()
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.*
|
||||
import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
|
||||
class AnalysisApiTestCompilerConfiguratorProvider(
|
||||
override val testServices: TestServices,
|
||||
override val testRootDisposable: Disposable,
|
||||
override val configurators: List<AbstractEnvironmentConfigurator>
|
||||
) : CompilerConfigurationProvider() {
|
||||
private val configurationCache: MutableMap<TestModule, CompilerConfiguration> = mutableMapOf()
|
||||
|
||||
private val allProjectBinaryRoots by lazy {
|
||||
StandaloneProjectFactory.getAllBinaryRoots(
|
||||
testServices.ktModuleProvider.getAllModules().map { it.ktModule },
|
||||
testServices.environmentManager.getProjectEnvironment()
|
||||
)
|
||||
}
|
||||
|
||||
override fun getProject(module: TestModule): Project {
|
||||
return testServices.environmentManager.getProject()
|
||||
}
|
||||
|
||||
override fun getCompilerConfiguration(module: TestModule): CompilerConfiguration {
|
||||
return configurationCache.getOrPut(module) {
|
||||
createKotlinCompilerConfiguration(module)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPackagePartProviderFactory(module: TestModule): (GlobalSearchScope) -> JvmPackagePartProvider {
|
||||
val configuration = getCompilerConfiguration(module)
|
||||
|
||||
return { scope ->
|
||||
JvmPackagePartProvider(configuration.languageVersionSettings, scope).apply {
|
||||
addRoots(allProjectBinaryRoots, configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY))
|
||||
(ModuleAnnotationsResolver
|
||||
.getInstance(testServices.environmentManager.getProject()) as CliModuleAnnotationsResolver)
|
||||
.addPackagePartProvider(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKotlinCoreEnvironment(module: TestModule): KotlinCoreEnvironment {
|
||||
error("Should not be called")
|
||||
}
|
||||
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
private fun createKotlinCompilerConfiguration(module: TestModule): CompilerConfiguration {
|
||||
return createCompilerConfiguration(module, configurators)
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
|
||||
class ProjectStructureInitialisationPreAnalysisHandler(
|
||||
testServices: TestServices,
|
||||
private val configurator: AnalysisApiTestConfigurator,
|
||||
) : PreAnalysisHandler(testServices) {
|
||||
|
||||
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
|
||||
checkAllModulesHaveTheSameProject(moduleStructure)
|
||||
|
||||
testServices.environmentManager.initializeEnvironment()
|
||||
|
||||
val project = testServices.environmentManager.getProject() as MockProject
|
||||
val application = testServices.environmentManager.getApplication() as MockApplication
|
||||
|
||||
configurator.registerApplicationServices(application, testServices)
|
||||
createAndRegisterKtModules(moduleStructure, project)
|
||||
configurator.registerProjectExtensionPoints(project, testServices)
|
||||
testServices.environmentManager.initializeProjectStructure()
|
||||
configurator.registerProjectServices(project, testServices)
|
||||
}
|
||||
|
||||
private fun createAndRegisterKtModules(moduleStructure: TestModuleStructure, project: MockProject) {
|
||||
val ktModules = configurator.createModules(moduleStructure, testServices, project)
|
||||
testServices.ktModuleProvider.registerProjectStructure(ktModules)
|
||||
}
|
||||
|
||||
private fun checkAllModulesHaveTheSameProject(moduleStructure: TestModuleStructure) {
|
||||
val modules = moduleStructure.modules
|
||||
val project = testServices.compilerConfigurationProvider.getProject(moduleStructure.modules.first()) as MockProject
|
||||
check(modules.all { testServices.compilerConfigurationProvider.getProject(it) == project })
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.test.services.TestService
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class TestDisposableProvider : TestService {
|
||||
abstract val testServices: TestServices
|
||||
abstract fun registerDisposables(projectDisposable: Disposable, applicationDisposable: Disposable)
|
||||
|
||||
abstract fun getProjectDisposable(): Disposable
|
||||
|
||||
abstract fun getApplicationDisposable(): Disposable
|
||||
}
|
||||
|
||||
class TestDisposableProviderImpl(override val testServices: TestServices) : TestDisposableProvider() {
|
||||
private lateinit var _projectDisposable: Disposable
|
||||
private lateinit var _applicationDisposable: Disposable
|
||||
|
||||
override fun registerDisposables(projectDisposable: Disposable, applicationDisposable: Disposable) {
|
||||
require(!this::_projectDisposable.isInitialized)
|
||||
require(!this::_applicationDisposable.isInitialized)
|
||||
|
||||
this._projectDisposable = projectDisposable
|
||||
this._applicationDisposable = applicationDisposable
|
||||
}
|
||||
|
||||
override fun getProjectDisposable(): Disposable = _projectDisposable
|
||||
override fun getApplicationDisposable(): Disposable = _applicationDisposable
|
||||
}
|
||||
|
||||
val TestServices.disposableProvider: TestDisposableProvider by TestServices.testServiceAccessor()
|
||||
-3
@@ -21,9 +21,6 @@ class CompiledLibraryProvider(private val testServices: TestServices) : TestServ
|
||||
val librarySourcesJar = TestModuleCompiler.compileTestModuleToLibrarySources(module, testServices)
|
||||
return CompiledLibrary(libraryJar, librarySourcesJar).also { libraries[module.name] = it }
|
||||
}
|
||||
|
||||
fun getCompiledLibrary(module: TestModule): CompiledLibrary =
|
||||
libraries.getValue(module.name)
|
||||
}
|
||||
|
||||
val TestServices.compiledLibraryProvider: CompiledLibraryProvider by TestServices.testServiceAccessor()
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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 org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
class LibraryEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
|
||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
|
||||
val library = testServices.compiledLibraryProvider.compileToLibrary(module).jar
|
||||
configuration.addJvmClasspathRoot(library.toFile())
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -43,7 +43,7 @@ internal object TestModuleCompiler {
|
||||
JarOutputStream(librarySourcesPath.outputStream(), manifest).use { jarOutputStream ->
|
||||
for (testFile in module.files) {
|
||||
val text = testServices.sourceFileProvider.getContentOfSourceFile(testFile)
|
||||
addFileToJar(testFile.name, text, jarOutputStream)
|
||||
addFileToJar(testFile.relativePath, text, jarOutputStream)
|
||||
}
|
||||
}
|
||||
return librarySourcesPath
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.test.configurators
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.Application
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.NotNullableUserDataProperty
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
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
|
||||
import java.util.concurrent.locks.ReadWriteLock
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.withLock
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class AnalysisApiTestConfigurator {
|
||||
open val testPrefix: String? get() = null
|
||||
|
||||
abstract val analyseInDependentSession: Boolean
|
||||
|
||||
abstract fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable)
|
||||
|
||||
abstract val serviceRegistrars: List<AnalysisApiTestServiceRegistrar>
|
||||
|
||||
open fun prepareFilesInModule(files: List<PsiFile>, module: TestModule, testServices: TestServices) {}
|
||||
|
||||
abstract fun doOutOfBlockModification(file: KtFile)
|
||||
|
||||
open fun preprocessTestDataPath(path: Path): Path = path
|
||||
|
||||
abstract fun createModules(moduleStructure: TestModuleStructure, testServices: TestServices, project: Project): List<KtModuleWithFiles>
|
||||
|
||||
fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {
|
||||
serviceRegistrars.forEach { it.registerProjectExtensionPoints(project, testServices) }
|
||||
}
|
||||
|
||||
fun registerProjectServices(project: MockProject, testServices: TestServices) {
|
||||
serviceRegistrars.forEach { it.registerProjectServices(project, testServices) }
|
||||
}
|
||||
|
||||
fun registerApplicationServices(application: MockApplication, testServices: TestServices) {
|
||||
ApplicationServiceRegistrar.register(application, serviceRegistrars, testServices)
|
||||
}
|
||||
}
|
||||
|
||||
private object ApplicationServiceRegistrar {
|
||||
fun register(application: MockApplication, registrars: List<AnalysisApiTestServiceRegistrar>, testServices: TestServices) {
|
||||
for (registrar in registrars) {
|
||||
val registered = application.lock.readLock().withLock {
|
||||
application.serviceRegistered[registrar::class] == true
|
||||
}
|
||||
|
||||
if (registered) {
|
||||
continue
|
||||
}
|
||||
|
||||
application.lock.writeLock().withLock {
|
||||
registrar.registerApplicationServices(application, testServices)
|
||||
application.serviceRegistered[registrar::class] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val Application.lock
|
||||
by NotNullableUserDataProperty<Application, ReadWriteLock>(
|
||||
Key("TestApplicationServicesRegistrarLock"),
|
||||
ReentrantReadWriteLock(),
|
||||
)
|
||||
|
||||
private var Application.serviceRegistered
|
||||
by NotNullableUserDataProperty<Application, MutableMap<KClass<out AnalysisApiTestServiceRegistrar>, Boolean>>(
|
||||
Key("TestApplicationServicesRegistered"),
|
||||
mutableMapOf(),
|
||||
)
|
||||
}
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
* 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
|
||||
package org.jetbrains.kotlin.analysis.test.framework.test.configurators
|
||||
|
||||
abstract class AnalysisApiTestConfiguratorFactory {
|
||||
abstract fun createConfigurator(data: AnalysisApiTestConfiguratorFactoryData): AnalysisApiTestConfigurator
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2022 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.test.configurators
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AnalysisApiTestServiceRegistrar {
|
||||
abstract fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices)
|
||||
|
||||
abstract fun registerProjectServices(project: MockProject, testServices: TestServices)
|
||||
|
||||
abstract fun registerApplicationServices(application: MockApplication, testServices: TestServices)
|
||||
}
|
||||
Reference in New Issue
Block a user