[analysis api, test] rework test infrastructure, add multimodule tests
This commit is contained in:
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fe10
|
||||
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.projectModuleProvider
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
|
||||
class KtFe10ModuleRegistrarPreAnalysisHandler(
|
||||
testServices: TestServices,
|
||||
@Suppress("UNUSED_PARAMETER") parentDisposable: Disposable
|
||||
) : PreAnalysisHandler(testServices) {
|
||||
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
|
||||
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
|
||||
// todo rework after all modules will have the same Project instance
|
||||
val ktFilesByModule = moduleStructure.modules.associateWith { testModule ->
|
||||
val project = testServices.compilerConfigurationProvider.getProject(testModule)
|
||||
testServices.sourceFileProvider.getKtFilesForSourceFiles(testModule.files, project)
|
||||
}
|
||||
|
||||
val allKtFiles = ktFilesByModule.values.flatMap { it.values.toList() }
|
||||
|
||||
ktFilesByModule.forEach { (testModule, ktFiles) ->
|
||||
val project = testServices.compilerConfigurationProvider.getProject(testModule)
|
||||
moduleInfoProvider.registerModuleInfo(testModule, TestKtSourceModule(project, testModule, ktFiles, testServices))
|
||||
|
||||
with(project as MockProject) {
|
||||
registerService(KotlinModificationTrackerFactory::class.java, KotlinStaticModificationTrackerFactory::class.java)
|
||||
registerService(KotlinDeclarationProviderFactory::class.java, KotlinStaticDeclarationProviderFactory(allKtFiles))
|
||||
registerService(KotlinPackageProviderFactory::class.java, KotlinStaticPackageProviderFactory(allKtFiles))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.api.fe10.test.configurator
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiBaseTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.toKtSourceModules
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
|
||||
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 org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.io.path.nameWithoutExtension
|
||||
|
||||
object AnalysisApiFe10TestConfigurator : AnalysisApiTestConfigurator() {
|
||||
override val analyseInDependentSession: Boolean get() = false
|
||||
|
||||
override val testPrefix: String
|
||||
get() = "descriptors"
|
||||
|
||||
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
||||
}
|
||||
|
||||
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar> = listOf(
|
||||
AnalysisApiBaseTestServiceRegistrar,
|
||||
AnalysisApiFe10TestServiceRegistrar,
|
||||
)
|
||||
|
||||
override fun createModules(
|
||||
moduleStructure: TestModuleStructure,
|
||||
testServices: TestServices,
|
||||
project: Project,
|
||||
): List<KtModuleWithFiles> {
|
||||
return moduleStructure.toKtSourceModules(testServices, project)
|
||||
}
|
||||
|
||||
override fun prepareFilesInModule(files: List<PsiFile>, module: TestModule, testServices: TestServices) {
|
||||
val compilerConfigurationProvider = testServices.compilerConfigurationProvider
|
||||
val compilerConfiguration = compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||
val project = compilerConfigurationProvider.getProject(module)
|
||||
val packageProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module)
|
||||
JvmResolveUtil.analyze(project, files.filterIsInstance<KtFile>(), compilerConfiguration, packageProviderFactory)
|
||||
}
|
||||
|
||||
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
// TODO not supported yet
|
||||
}
|
||||
|
||||
override fun preprocessTestDataPath(path: Path): Path {
|
||||
val newPath = path.resolveSibling(path.nameWithoutExtension + "." + testPrefix + "." + path.extension)
|
||||
if (newPath.toFile().exists()) return newPath
|
||||
return path
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -3,9 +3,9 @@
|
||||
* 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.fe10
|
||||
package org.jetbrains.kotlin.analysis.api.fe10.test.configurator
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.*
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.*
|
||||
|
||||
object AnalysisApiFe10TestConfiguratorFactory : AnalysisApiTestConfiguratorFactory() {
|
||||
override fun createConfigurator(data: AnalysisApiTestConfiguratorFactoryData): AnalysisApiTestConfigurator {
|
||||
@@ -13,7 +13,7 @@ object AnalysisApiFe10TestConfiguratorFactory : AnalysisApiTestConfiguratorFacto
|
||||
|
||||
return when (data.moduleKind) {
|
||||
TestModuleKind.Source -> when (data.analysisSessionMode) {
|
||||
AnalysisSessionMode.Normal -> AnalysisApiFirTestConfigurator
|
||||
AnalysisSessionMode.Normal -> AnalysisApiFe10TestConfigurator
|
||||
AnalysisSessionMode.Dependent -> error("Unsupported AnalysisSessionMode.Dependent for fe10")
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.api.fe10.test.configurator
|
||||
|
||||
import com.intellij.core.CoreJavaFileManager
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager
|
||||
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.CliFe10AnalysisFacade
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
object AnalysisApiFe10TestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||
override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {
|
||||
AnalysisHandlerExtension.registerExtensionPoint(project)
|
||||
}
|
||||
|
||||
@OptIn(InvalidWayOfUsingAnalysisSession::class)
|
||||
override fun registerProjectServices(project: MockProject, testServices: TestServices) {
|
||||
project.apply {
|
||||
registerService(KtAnalysisSessionProvider::class.java, KtFe10AnalysisSessionProvider())
|
||||
registerService(Fe10AnalysisFacade::class.java, CliFe10AnalysisFacade(project))
|
||||
registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(enabled = true))
|
||||
registerService(CoreJavaFileManager::class.java, project.getService(JavaFileManager::class.java) as CoreJavaFileManager)
|
||||
}
|
||||
AnalysisHandlerExtension.registerExtension(project, KtFe10AnalysisHandlerExtension())
|
||||
KotlinCoreEnvironment.registerKotlinLightClassSupport(project)
|
||||
}
|
||||
|
||||
override fun registerApplicationServices(application: MockApplication, testServices: TestServices) {
|
||||
application.apply {
|
||||
registerService(KotlinReferenceProviderContributor::class.java, KtFe10KotlinReferenceProviderContributor::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-8
@@ -3,11 +3,12 @@
|
||||
* 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
|
||||
package org.jetbrains.kotlin.analysis.api.fir.test.configurators
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.libraries.binary.LibraryAnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.libraries.source.LibrarySourceAnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.*
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.library.AnalysisApiFirLibraryBinaryTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.library.AnalysisApiFirLibrarySourceTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.*
|
||||
|
||||
object AnalysisApiFirTestConfiguratorFactory : AnalysisApiTestConfiguratorFactory() {
|
||||
override fun createConfigurator(data: AnalysisApiTestConfiguratorFactoryData): AnalysisApiTestConfigurator {
|
||||
@@ -15,18 +16,18 @@ object AnalysisApiFirTestConfiguratorFactory : AnalysisApiTestConfiguratorFactor
|
||||
|
||||
return when (data.moduleKind) {
|
||||
TestModuleKind.Source -> when (data.analysisSessionMode) {
|
||||
AnalysisSessionMode.Normal -> AnalysisApiFirTestConfigurator(analyseInDependentSession = false)
|
||||
AnalysisSessionMode.Dependent -> AnalysisApiFirTestConfigurator(analyseInDependentSession = true)
|
||||
AnalysisSessionMode.Normal -> AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false)
|
||||
AnalysisSessionMode.Dependent -> AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = true)
|
||||
}
|
||||
|
||||
TestModuleKind.LibraryBinary -> {
|
||||
require(data.analysisSessionMode == AnalysisSessionMode.Normal)
|
||||
LibraryAnalysisApiTestConfigurator
|
||||
AnalysisApiFirLibraryBinaryTestConfigurator
|
||||
}
|
||||
|
||||
TestModuleKind.LibrarySource -> {
|
||||
require(data.analysisSessionMode == AnalysisSessionMode.Normal)
|
||||
LibrarySourceAnalysisApiTestConfigurator
|
||||
AnalysisApiFirLibrarySourceTestConfigurator
|
||||
}
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.api.fir.test.configurators.library
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiBaseTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiLibraryBaseTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.util.LibraryUtils
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtLibraryModule
|
||||
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
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import java.nio.file.Path
|
||||
|
||||
object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator() {
|
||||
override val analyseInDependentSession: Boolean get() = false
|
||||
|
||||
override fun configureTest(
|
||||
builder: TestConfigurationBuilder,
|
||||
disposable: Disposable
|
||||
) {
|
||||
}
|
||||
|
||||
override fun createModules(
|
||||
moduleStructure: TestModuleStructure,
|
||||
testServices: TestServices,
|
||||
project: Project
|
||||
): List<KtModuleWithFiles> {
|
||||
val testModule = moduleStructure.modules.single()
|
||||
val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).jar
|
||||
val decompiledFiles = LibraryUtils.getAllPsiFilesFromTheJar(library, project)
|
||||
|
||||
return listOf(
|
||||
KtModuleWithFiles(
|
||||
TestKtLibraryModule(project, testModule, decompiledFiles, listOf(library), testServices),
|
||||
decompiledFiles,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar> =
|
||||
listOf(
|
||||
AnalysisApiBaseTestServiceRegistrar,
|
||||
AnalysisApiFirTestServiceRegistrar,
|
||||
AnalysisApiLibraryBaseTestServiceRegistrar,
|
||||
)
|
||||
|
||||
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file)
|
||||
}
|
||||
}
|
||||
+46
-17
@@ -3,55 +3,83 @@
|
||||
* 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.utils.libraries.source
|
||||
package org.jetbrains.kotlin.analysis.api.fir.test.configurators.library
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiBaseTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiLibraryBaseTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.util.LibraryUtils
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtLibrarySourceModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.projectModuleProvider
|
||||
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.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.PreAnalysisHandler
|
||||
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.compilerConfigurationProvider
|
||||
import java.nio.file.Path
|
||||
|
||||
class LibrarySourceModuleRegistrarPreAnalysisHandler(
|
||||
testServices: TestServices
|
||||
) : PreAnalysisHandler(testServices) {
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator() {
|
||||
override val analyseInDependentSession: Boolean get() = false
|
||||
|
||||
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
|
||||
override fun configureTest(
|
||||
builder: TestConfigurationBuilder,
|
||||
disposable: Disposable
|
||||
) {
|
||||
builder.useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider))
|
||||
}
|
||||
|
||||
override fun createModules(
|
||||
moduleStructure: TestModuleStructure,
|
||||
testServices: TestServices,
|
||||
project: Project
|
||||
): List<KtModuleWithFiles> {
|
||||
val testModule = moduleStructure.modules.single()
|
||||
val project = testServices.compilerConfigurationProvider.getProject(testModule)
|
||||
val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.getCompiledLibrary(testModule)
|
||||
val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.compileToLibrary(testModule)
|
||||
|
||||
val libraryKtModule = KtTestLibraryModule(project, testModule, libraryJar)
|
||||
|
||||
val librarySourceKtFiles = LibraryUtils
|
||||
.getAllVirtualFilesFromJar(librarySourcesJar)
|
||||
.mapNotNull { PsiManager.getInstance(project).findFile(it) as? KtFile }
|
||||
val librarySourceFiles = LibraryUtils
|
||||
.getAllPsiFilesFromTheJar(librarySourcesJar, project)
|
||||
|
||||
val sourcesKtModule = TestKtLibrarySourceModule(
|
||||
project,
|
||||
testModule,
|
||||
librarySourceKtFiles.toSet(),
|
||||
librarySourceFiles,
|
||||
testServices,
|
||||
libraryKtModule
|
||||
)
|
||||
libraryKtModule.librarySources = sourcesKtModule
|
||||
|
||||
moduleInfoProvider.registerModuleInfo(testModule, sourcesKtModule)
|
||||
return listOf(
|
||||
KtModuleWithFiles(sourcesKtModule, librarySourceFiles),
|
||||
)
|
||||
}
|
||||
|
||||
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar> =
|
||||
listOf(
|
||||
AnalysisApiBaseTestServiceRegistrar,
|
||||
AnalysisApiFirTestServiceRegistrar,
|
||||
AnalysisApiLibraryBaseTestServiceRegistrar,
|
||||
)
|
||||
|
||||
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,3 +104,4 @@ private class KtTestLibraryModule(
|
||||
override val platform: TargetPlatform get() = testModule.targetPlatform
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices get() = testModule.targetPlatform.getAnalyzerServices()
|
||||
}
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.api.fir.test.configurators.source
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.configureOptionalTestCompilerPlugin
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiBaseTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.FirLowLevelAnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.toKtSourceModules
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
class AnalysisApiFirSourceTestConfigurator(override val analyseInDependentSession: Boolean) : AnalysisApiTestConfigurator() {
|
||||
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
||||
FirLowLevelAnalysisApiTestConfigurator.configureTest(builder, disposable)
|
||||
builder.apply {
|
||||
configureOptionalTestCompilerPlugin()
|
||||
}
|
||||
}
|
||||
|
||||
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar> = listOf(
|
||||
AnalysisApiBaseTestServiceRegistrar,
|
||||
AnalysisApiFirTestServiceRegistrar,
|
||||
)
|
||||
|
||||
override fun createModules(moduleStructure: TestModuleStructure, testServices: TestServices, project: Project): List<KtModuleWithFiles> {
|
||||
return moduleStructure.toKtSourceModules(testServices, project)
|
||||
}
|
||||
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
FirLowLevelAnalysisApiTestConfigurator.doOutOfBlockModification(file)
|
||||
}
|
||||
}
|
||||
-42
@@ -1,42 +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.api.fir.utils.libraries.binary
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.util.LibraryUtils
|
||||
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.projectModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
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 LibraryModuleRegistrarPreAnalysisHandler(
|
||||
testServices: TestServices
|
||||
) : PreAnalysisHandler(testServices) {
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
|
||||
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
|
||||
val testModule = moduleStructure.modules.single()
|
||||
val project = testServices.compilerConfigurationProvider.getProject(testModule)
|
||||
val decompiledKtFiles = getDecompiledVirtualFilesFromLibrary(testModule, project)
|
||||
|
||||
moduleInfoProvider.registerModuleInfo(testModule, TestKtLibraryModule(project, testModule, decompiledKtFiles, testServices))
|
||||
}
|
||||
|
||||
private fun getDecompiledVirtualFilesFromLibrary(module: TestModule, project: Project): List<KtClsFile> {
|
||||
val library = testServices.compiledLibraryProvider.getCompiledLibrary(module).jar
|
||||
|
||||
val virtualFiles = LibraryUtils.getAllVirtualFilesFromJar(library)
|
||||
return virtualFiles.mapNotNull { virtualFile ->
|
||||
PsiManager.getInstance(project).findFile(virtualFile) as? KtClsFile
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,9 @@ dependencies {
|
||||
testApi(projectTests(":compiler:tests-common-new"))
|
||||
testApi(projectTests(":analysis:analysis-api-impl-barebone"))
|
||||
testApi(project(":analysis:symbol-light-classes"))
|
||||
testApi(projectTests(":analysis:decompiled:decompiler-to-file-stubs"))
|
||||
testApi(project(":analysis:decompiled:decompiler-to-file-stubs"))
|
||||
testApi(project(":analysis:decompiled:decompiler-to-psi"))
|
||||
testApi(projectTests(":analysis:analysis-test-framework"))
|
||||
testImplementation(project(":kotlin-reflect"))
|
||||
testImplementation(toolsJar())
|
||||
|
||||
+16
@@ -5,10 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.impl.base.util
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.util.io.URLUtil.JAR_SEPARATOR
|
||||
import java.nio.file.Path
|
||||
|
||||
@@ -32,6 +35,19 @@ object LibraryUtils {
|
||||
?.let { getAllVirtualFilesFromRoot(it, includeRoot) } ?: emptySet()
|
||||
}
|
||||
|
||||
fun getAllPsiFilesFromTheJar(
|
||||
jar: Path,
|
||||
project: Project,
|
||||
jarFileSystem: CoreJarFileSystem = CoreJarFileSystem(),
|
||||
includeRoot: Boolean = true,
|
||||
): List<PsiFile> {
|
||||
val virtualFiles = getAllVirtualFilesFromJar(jar, jarFileSystem, includeRoot)
|
||||
return virtualFiles
|
||||
.mapNotNull { virtualFile ->
|
||||
PsiManager.getInstance(project).findFile(virtualFile)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all [VirtualFile]s inside the given [dir] (of [Path])
|
||||
*
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.api.impl.base.test.components.importOptimizer
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest
|
||||
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.assertions
|
||||
|
||||
abstract class AbstractAnalysisApiImportOptimizerTest : AbstractAnalysisApiBasedSingleModuleTest(){
|
||||
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
|
||||
val mainKtFile = ktFiles.singleOrNull() ?: ktFiles.first { it.name == "main.kt" }
|
||||
val unusedImports = analyseForTest(mainKtFile) { analyseImports(mainKtFile).unusedImports }
|
||||
|
||||
val unusedImportPaths = unusedImports
|
||||
.map { it.importPath ?: error("Import $it should have an import path, instead was ${it.text}") }
|
||||
.sortedBy { it.toString() } // for stable results
|
||||
|
||||
val actualUnusedImports = buildString {
|
||||
unusedImportPaths.forEach(::appendLine)
|
||||
}
|
||||
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actualUnusedImports, extension = ".imports")
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.api.impl.base.test.components.psiTypeProvider
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.analyse
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
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.assertions
|
||||
|
||||
abstract class AbstractAnalysisApiExpressionPsiTypeProviderTest : AbstractAnalysisApiSingleFileTest(){
|
||||
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
|
||||
val declarationAtCaret = testServices.expressionMarkerProvider.getSelectedElement(ktFile) as KtExpression
|
||||
val actual = analyse(ktFile) {
|
||||
val returnType = declarationAtCaret.getKtType()
|
||||
?: error("Not a typable expression ${declarationAtCaret::class} ${declarationAtCaret.text}")
|
||||
val psiType = returnType.asPsiType(declarationAtCaret)
|
||||
buildString {
|
||||
appendLine("KtType: ${returnType.render()}")
|
||||
appendLine("PsiType: $psiType")
|
||||
}
|
||||
}
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.api.impl.base.test.components.psiTypeProvider
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.analysis.api.analyse
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
|
||||
abstract class AbstractAnalysisApiPsiTypeProviderTest : AbstractAnalysisApiSingleFileTest(){
|
||||
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
|
||||
val declaration = testServices.expressionMarkerProvider.getElementOfTypAtCaret<KtDeclaration>(ktFile)
|
||||
val containingClass =
|
||||
getContainingKtLightClass(declaration, ktFile)
|
||||
val psiContext = containingClass.findLightDeclarationContext(declaration)
|
||||
?: error("Can't find psi context for $declaration")
|
||||
val actual = buildString {
|
||||
executeOnPooledThreadInReadAction {
|
||||
analyse(declaration) {
|
||||
val ktType = declaration.getReturnKtType()
|
||||
appendLine("KtType: ${ktType.render()}")
|
||||
appendLine("PsiType: ${ktType.asPsiType(psiContext)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
}
|
||||
|
||||
private fun getContainingKtLightClass(
|
||||
declaration: KtDeclaration,
|
||||
ktFile: KtFile,
|
||||
): KtLightClass {
|
||||
val project = ktFile.project
|
||||
return createLightClassByContainingClass(declaration, project)
|
||||
?: getFacadeLightClass(ktFile, project)
|
||||
?: error("Can't get or create containing KtLightClass for $declaration")
|
||||
|
||||
}
|
||||
|
||||
private fun getFacadeLightClass(
|
||||
ktFile: KtFile,
|
||||
project: Project,
|
||||
): KtLightClass? {
|
||||
val mainKtFileFqName = ktFile.packageFqName.child(Name.identifier(ktFile.name))
|
||||
return project.getService(SymbolLightClassFacadeCache::class.java)
|
||||
.getOrCreateSymbolLightFacade(listOf(ktFile), mainKtFileFqName)
|
||||
}
|
||||
|
||||
private fun createLightClassByContainingClass(
|
||||
declaration: KtDeclaration,
|
||||
project: Project
|
||||
): KtLightClass? {
|
||||
val containingClass = declaration.parents.firstIsInstanceOrNull<KtClassOrObject>() ?: return null
|
||||
return project.getService(KotlinAsJavaSupport::class.java).getLightClass(containingClass)
|
||||
}
|
||||
|
||||
private fun KtLightClass.findLightDeclarationContext(ktDeclaration: KtDeclaration): KtLightElement<*, *>? {
|
||||
val selfOrParents = listOf(ktDeclaration) + ktDeclaration.parents.filterIsInstance<KtDeclaration>()
|
||||
var result: KtLightElement<*, *>? = null
|
||||
val visitor = object : PsiElementVisitor() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
if (element !is KtLightElement<*, *>) return
|
||||
// NB: intentionally visit members first so that `self` can be found first if matched
|
||||
if (element is PsiClass) {
|
||||
element.fields.forEach { it.accept(this) }
|
||||
element.methods.forEach { it.accept(this) }
|
||||
element.innerClasses.forEach { it.accept(this) }
|
||||
}
|
||||
if (result == null && element.kotlinOrigin in selfOrParents) {
|
||||
result = element
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
accept(visitor)
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
+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.api.impl.base.test.components.typeProvider
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.analyse
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtTypeRendererOptions
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
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.assertions
|
||||
|
||||
abstract class AbstractAnalysisApiGetSuperTypesTest : AbstractAnalysisApiSingleFileTest(){
|
||||
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
|
||||
val expression = testServices.expressionMarkerProvider.getSelectedElement(ktFile)
|
||||
|
||||
val actual = executeOnPooledThreadInReadAction {
|
||||
analyse(expression) {
|
||||
val expectedType = expression.getExpectedType() ?: error("expect to get type of expression '${expression.text}'")
|
||||
val directSuperTypes = expectedType.getDirectSuperTypes()
|
||||
val approximatedDirectSuperTypes = expectedType.getDirectSuperTypes(shouldApproximate = true)
|
||||
val allSuperTypes = expectedType.getAllSuperTypes()
|
||||
val approximatedAllSuperTypes = expectedType.getAllSuperTypes(shouldApproximate = true)
|
||||
|
||||
buildString {
|
||||
fun List<KtType>.print(name: String) {
|
||||
appendLine(name)
|
||||
for (type in this) {
|
||||
appendLine(type.render(KtTypeRendererOptions.DEFAULT))
|
||||
}
|
||||
appendLine()
|
||||
}
|
||||
directSuperTypes.print("[direct super types]")
|
||||
approximatedDirectSuperTypes.print("[approximated direct super types]")
|
||||
allSuperTypes.print("[all super types]")
|
||||
approximatedAllSuperTypes.print("[approximated all super types]")
|
||||
}
|
||||
}
|
||||
}
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.api.impl.base.test.configurators
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.references.HLApiReferenceProviderService
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolverFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticAnnotationsResolverFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
object AnalysisApiBaseTestServiceRegistrar: AnalysisApiTestServiceRegistrar() {
|
||||
override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {
|
||||
}
|
||||
|
||||
override fun registerProjectServices(project: MockProject, testServices: TestServices) {
|
||||
val allKtFiles = testServices.ktModuleProvider.getAllModules().flatMap { it.files.filterIsInstance<KtFile>() }
|
||||
|
||||
project.apply {
|
||||
registerService(KotlinModificationTrackerFactory::class.java, KotlinStaticModificationTrackerFactory::class.java)
|
||||
|
||||
registerService(KtModuleScopeProvider::class.java, KtModuleScopeProviderImpl())
|
||||
registerService(KotlinModificationTrackerFactory::class.java, KotlinStaticModificationTrackerFactory::class.java)
|
||||
registerService(KotlinAnnotationsResolverFactory::class.java, KotlinStaticAnnotationsResolverFactory(allKtFiles))
|
||||
registerService(KotlinDeclarationProviderFactory::class.java, KotlinStaticDeclarationProviderFactory(allKtFiles))
|
||||
registerService(KotlinPackageProviderFactory::class.java, KotlinStaticPackageProviderFactory(allKtFiles))
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerApplicationServices(application: MockApplication, testServices: TestServices) {
|
||||
application.apply {
|
||||
registerService(KotlinReferenceProvidersService::class.java, HLApiReferenceProviderService::class.java)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.api.impl.base.test.configurators
|
||||
|
||||
import com.intellij.ide.highlighter.JavaClassFileType
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.extensions.LoadingOrder
|
||||
import com.intellij.psi.ClassFileViewProviderFactory
|
||||
import com.intellij.psi.FileTypeFileViewProviders
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers
|
||||
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInDecompiler
|
||||
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler
|
||||
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService
|
||||
import org.jetbrains.kotlin.analysis.decompiler.stub.files.DummyFileAttributeService
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.disposableProvider
|
||||
|
||||
|
||||
object AnalysisApiLibraryBaseTestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||
override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {
|
||||
}
|
||||
|
||||
override fun registerProjectServices(project: MockProject, testServices: TestServices) {
|
||||
}
|
||||
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
override fun registerApplicationServices(application: MockApplication, testServices: TestServices) {
|
||||
application.apply {
|
||||
registerService(ClsKotlinBinaryClassCache::class.java)
|
||||
registerService(FileAttributeService::class.java, DummyFileAttributeService)
|
||||
}
|
||||
|
||||
FileTypeFileViewProviders.INSTANCE.addExplicitExtension(JavaClassFileType.INSTANCE, ClassFileViewProviderFactory())
|
||||
|
||||
ClassFileDecompilers.getInstance().EP_NAME.point.apply {
|
||||
registerExtension(KotlinClassFileDecompiler(), LoadingOrder.FIRST, testServices.disposableProvider.getApplicationDisposable())
|
||||
registerExtension(KotlinBuiltInDecompiler(), LoadingOrder.FIRST, testServices.disposableProvider.getApplicationDisposable())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(intellijCore())
|
||||
implementation(kotlinStdlib())
|
||||
implementation(project(":compiler:psi"))
|
||||
implementation(project(":compiler:cli"))
|
||||
api(project(":analysis:analysis-api"))
|
||||
api(project(":analysis:analysis-api-providers"))
|
||||
api(project(":analysis:project-structure"))
|
||||
}
|
||||
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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.api.standalone.base.project.structure
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
|
||||
data class KtModuleWithFiles(
|
||||
val ktModule: KtModule,
|
||||
val files: List<PsiFile>
|
||||
)
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.api.standalone.base.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.psiUtil.contains
|
||||
|
||||
class KtStaticModuleProvider(private val modules: List<KtModule>) : ProjectStructureProvider() {
|
||||
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
||||
return modules.first { module ->
|
||||
module.contentScope.contains(element)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKtLibraryModules(): Collection<KtLibraryModule> {
|
||||
return modules.filterIsInstance<KtLibraryModule>()
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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.api.standalone.base.project.structure
|
||||
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.*
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndexImpl
|
||||
import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.JavaModuleGraph
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.popLast
|
||||
import java.nio.file.Path
|
||||
|
||||
object StandaloneProjectFactory {
|
||||
fun createProjectEnvironment(
|
||||
projectDisposable: Disposable,
|
||||
applicationDisposable: Disposable
|
||||
): KotlinCoreProjectEnvironment {
|
||||
val applicationEnvironment =
|
||||
KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForTests(applicationDisposable, CompilerConfiguration())
|
||||
|
||||
return KotlinCoreProjectEnvironment(projectDisposable, applicationEnvironment)
|
||||
}
|
||||
|
||||
|
||||
fun registerServicesForProjectEnvironment(
|
||||
environment: KotlinCoreProjectEnvironment,
|
||||
modules: List<KtModuleWithFiles>,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
jdkHome: Path?,
|
||||
) {
|
||||
val project = environment.project
|
||||
|
||||
KotlinCoreEnvironment.registerProjectExtensionPoints(project.extensionArea)
|
||||
KotlinCoreEnvironment.registerProjectServices(project)
|
||||
|
||||
project.registerService(ProjectStructureProvider::class.java, KtStaticModuleProvider(modules.map { it.ktModule }))
|
||||
initialiseVirtualFinderFinderServices(modules, environment, jdkHome, languageVersionSettings)
|
||||
initialiseAnnotationServices(project)
|
||||
|
||||
project.setupHighestLanguageLevel()
|
||||
}
|
||||
|
||||
private fun initialiseAnnotationServices(project: MockProject) {
|
||||
project.registerService(ExternalAnnotationsManager::class.java, MockExternalAnnotationsManager())
|
||||
project.registerService(InferredAnnotationsManager::class.java, MockInferredAnnotationsManager())
|
||||
}
|
||||
|
||||
private fun initialiseVirtualFinderFinderServices(
|
||||
modules: List<KtModuleWithFiles>,
|
||||
environment: KotlinCoreProjectEnvironment,
|
||||
jdkHome: Path?,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
val project = environment.project
|
||||
|
||||
val allSourceFiles = buildList {
|
||||
val files = modules.flatMap { it.files }
|
||||
addAll(files)
|
||||
addAll(findJvmRootsForJavaFiles(files.filterIsInstance<PsiJavaFile>()))
|
||||
}
|
||||
val allSourceFileRoots = allSourceFiles.map { JavaRoot(it.virtualFile, JavaRoot.RootType.SOURCE) }
|
||||
val libraryRoots = getAllBinaryRoots(modules.map { it.ktModule }, environment)
|
||||
libraryRoots.forEach { environment.addSourcesToClasspath(it.file) }
|
||||
|
||||
val sourceAndLibraryRoots = buildList {
|
||||
addAll(libraryRoots)
|
||||
addAll(allSourceFileRoots)
|
||||
}
|
||||
|
||||
val javaFileManager = project.getService(JavaFileManager::class.java) as KotlinCliJavaFileManagerImpl
|
||||
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.toFile(), null, javaFileManager, project, null)
|
||||
|
||||
javaFileManager.initialize(
|
||||
JvmDependenciesIndexImpl(sourceAndLibraryRoots),
|
||||
listOf(createPackagePartsProvider(languageVersionSettings, project, libraryRoots)),
|
||||
SingleJavaFileRootsIndex(emptyList()),
|
||||
true
|
||||
)
|
||||
|
||||
project.registerService(
|
||||
JavaModuleResolver::class.java,
|
||||
CliJavaModuleResolver(JavaModuleGraph(javaModuleFinder), emptyList(), javaModuleFinder.systemModules.toList(), project)
|
||||
)
|
||||
|
||||
val finderFactory = CliVirtualFileFinderFactory(JvmDependenciesIndexImpl(sourceAndLibraryRoots), false)
|
||||
|
||||
project.registerService(MetadataFinderFactory::class.java, finderFactory)
|
||||
project.registerService(VirtualFileFinderFactory::class.java, finderFactory)
|
||||
}
|
||||
|
||||
private fun findJvmRootsForJavaFiles(files: List<PsiJavaFile>): List<PsiDirectory> {
|
||||
if (files.isEmpty()) return emptyList()
|
||||
val result = mutableSetOf<PsiDirectory>()
|
||||
for (file in files) {
|
||||
val packageParts = file.packageName.takeIf { it.isNotEmpty() }?.split('.') ?: emptyList()
|
||||
val javaDir = packageParts
|
||||
.reversed()
|
||||
.fold(file.parent) { dir, part ->
|
||||
if (dir?.name == part) {
|
||||
dir.parent
|
||||
} else {
|
||||
error("File package ${file.packageName} does not match file path ${file.virtualFile.path}")
|
||||
}
|
||||
}
|
||||
result += javaDir as PsiDirectory
|
||||
}
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
fun getAllBinaryRoots(
|
||||
modules: List<KtModule>,
|
||||
environment: KotlinCoreProjectEnvironment
|
||||
): List<JavaRoot> = withAllTransitiveDependencies(modules)
|
||||
.filterIsInstance<KtLibraryModule>()
|
||||
.flatMap { it.getBinaryRoots() }
|
||||
.map {
|
||||
val jar = environment.environment.jarFileSystem.findFileByPath(it.toAbsolutePath().toString() + "!/")!!
|
||||
JavaRoot(jar, JavaRoot.RootType.BINARY)
|
||||
}
|
||||
|
||||
private fun withAllTransitiveDependencies(ktModules: List<KtModule>): List<KtModule> {
|
||||
val visited = hashSetOf<KtModule>()
|
||||
val stack = ktModules.toMutableList()
|
||||
while (stack.isNotEmpty()) {
|
||||
val module = stack.popLast()
|
||||
if (module in visited) continue
|
||||
visited += module
|
||||
for (dependency in module.allDependencies()) {
|
||||
if (dependency !in visited) {
|
||||
stack += dependency
|
||||
}
|
||||
}
|
||||
}
|
||||
return visited.toList()
|
||||
}
|
||||
|
||||
private fun KtModule.allDependencies(): List<KtModule> = buildList {
|
||||
addAll(allDirectDependencies())
|
||||
when (this) {
|
||||
is KtLibrarySourceModule -> {
|
||||
add(binaryLibrary)
|
||||
}
|
||||
is KtLibraryModule -> {
|
||||
addIfNotNull(librarySources)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun createPackagePartsProvider(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
project: MockProject,
|
||||
libraryRoots: List<JavaRoot>
|
||||
): JvmPackagePartProvider {
|
||||
return JvmPackagePartProvider(languageVersionSettings, ProjectScope.getLibrariesScope(project)).apply {
|
||||
addRoots(libraryRoots, MessageCollector.NONE)
|
||||
(ModuleAnnotationsResolver
|
||||
.getInstance(project) as CliModuleAnnotationsResolver)
|
||||
.addPackagePartProvider(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartP
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
|
||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.impl.ProjectStructureProviderByCompilerConfiguration
|
||||
import org.jetbrains.kotlin.analysis.project.structure.impl.KtModuleProviderByCompilerConfiguration
|
||||
import org.jetbrains.kotlin.analysis.providers.*
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.*
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
@@ -177,7 +177,7 @@ internal fun configureProjectEnvironment(
|
||||
|
||||
project.picoContainer.registerComponentInstance(
|
||||
ProjectStructureProvider::class.qualifiedName,
|
||||
ProjectStructureProviderByCompilerConfiguration(
|
||||
KtModuleProviderByCompilerConfiguration(
|
||||
compilerConfig,
|
||||
project,
|
||||
ktFiles,
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
internal class ProjectStructureProviderByCompilerConfiguration(
|
||||
internal class KtModuleProviderByCompilerConfiguration(
|
||||
compilerConfig: CompilerConfiguration,
|
||||
project: Project,
|
||||
ktFiles: List<KtFile>,
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.standalone
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.*
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.*
|
||||
|
||||
object AnalysisApiFirStandaloneModeTestConfiguratorFactory : AnalysisApiTestConfiguratorFactory() {
|
||||
override fun createConfigurator(data: AnalysisApiTestConfiguratorFactoryData): AnalysisApiTestConfigurator {
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.api.standalone
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
object StandaloneModeConfigurator : AnalysisApiTestConfigurator() {
|
||||
override val analyseInDependentSession: Boolean get() = false
|
||||
|
||||
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
||||
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).configureTest(builder, disposable)
|
||||
}
|
||||
|
||||
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar>
|
||||
get() = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).serviceRegistrars
|
||||
|
||||
override fun createModules(
|
||||
moduleStructure: TestModuleStructure,
|
||||
testServices: TestServices,
|
||||
project: Project
|
||||
): List<KtModuleWithFiles> {
|
||||
return AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).createModules(moduleStructure, testServices, project)
|
||||
}
|
||||
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -36,6 +36,7 @@ dependencies {
|
||||
testApi(projectTests(":compiler:fir:analysis-tests:legacy-fir-tests"))
|
||||
testApi(projectTests(":analysis:analysis-api-impl-barebone"))
|
||||
testApi(projectTests(":analysis:analysis-test-framework"))
|
||||
testApi(projectTests(":analysis:analysis-api-impl-base"))
|
||||
testApi(project(":kotlin-test:kotlin-test-junit"))
|
||||
testApiJUnit5()
|
||||
testApi(project(":kotlin-reflect"))
|
||||
|
||||
+1
@@ -431,6 +431,7 @@ private fun List<KtModule>.extractLibraryPaths(): List<Path> =
|
||||
asSequence()
|
||||
.filterIsInstance<KtBinaryModule>()
|
||||
.flatMap { it.getBinaryRoots() }
|
||||
.map { it.toAbsolutePath() }
|
||||
.toList()
|
||||
|
||||
@Deprecated(
|
||||
|
||||
+2
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDeclarationDesigna
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.ResolveTreeBuilder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformer.Companion.updatePhaseDeep
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.ensurePhase
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
|
||||
|
||||
/**
|
||||
* Transform designation into TYPES phase. Affects only for designation, target declaration and it's children
|
||||
@@ -78,6 +79,7 @@ internal class LLFirDesignatedTypeResolverTransformer(
|
||||
is FirField -> check(declaration.returnTypeRef is FirResolvedTypeRef || declaration.returnTypeRef is FirImplicitTypeRef)
|
||||
is FirClass, is FirTypeAlias, is FirAnonymousInitializer -> Unit
|
||||
is FirEnumEntry -> check(declaration.returnTypeRef is FirResolvedTypeRef)
|
||||
is FirDiagnosticHolder -> {}
|
||||
else -> error("Unexpected type: ${declaration::class.simpleName}")
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,11 +6,11 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
||||
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner
|
||||
|
||||
internal interface LLFirLazyTransformer {
|
||||
fun transformDeclaration(phaseRunner: LLFirPhaseRunner)
|
||||
|
||||
+21
-8
@@ -6,15 +6,18 @@
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based
|
||||
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AbstractCompilerBasedTest
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.createResolveStateForNoCaching
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.FirLowLevelAnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyTransformer
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AbstractCompilerBasedTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.registerAnalysisApiBaseTestServices
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.projectModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.ExecutionListenerBasedDisposableProvider
|
||||
import org.jetbrains.kotlin.test.bind
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
@@ -27,9 +30,13 @@ import org.jetbrains.kotlin.test.model.DependencyKind
|
||||
import org.jetbrains.kotlin.test.model.FrontendFacade
|
||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
import org.jetbrains.kotlin.test.services.isKtFile
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
|
||||
abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() {
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
final override fun TestConfigurationBuilder.configuration() {
|
||||
globalDefaults {
|
||||
frontend = FrontendKinds.FIR
|
||||
@@ -39,11 +46,14 @@ abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() {
|
||||
|
||||
configureTest()
|
||||
defaultConfiguration(this)
|
||||
registerAnalysisApiBaseTestServices(disposable, FirLowLevelAnalysisApiTestConfigurator)
|
||||
|
||||
useAdditionalService<ApplicationDisposableProvider> { ExecutionListenerBasedDisposableProvider() }
|
||||
useAdditionalService<KotlinStandardLibrariesPathProvider> { StandardLibrariesPathProviderForKotlinProject }
|
||||
useAdditionalService(::TestKtModuleProvider)
|
||||
usePreAnalysisHandlers(::ModuleRegistrarPreAnalysisHandler.bind(disposable, true))
|
||||
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
|
||||
|
||||
|
||||
firHandlersStep {
|
||||
useHandlers(::LLDiagnosticParameterChecker)
|
||||
@@ -60,21 +70,24 @@ abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() {
|
||||
get() = listOf(FirDiagnosticsDirectives)
|
||||
|
||||
override fun analyze(module: TestModule): FirOutputArtifact {
|
||||
val moduleInfoProvider = testServices.projectModuleProvider
|
||||
val moduleInfoProvider = testServices.ktModuleProvider
|
||||
val moduleInfo = moduleInfoProvider.getModule(module.name) as TestKtSourceModule
|
||||
|
||||
val project = testServices.compilerConfigurationProvider.getProject(module)
|
||||
val resolveState = createResolveStateForNoCaching(moduleInfo, project)
|
||||
|
||||
val allFirFiles = moduleInfo.testFilesToKtFiles.map { (testFile, psiFile) ->
|
||||
testFile to psiFile.getOrBuildFirFile(resolveState)
|
||||
}.toMap()
|
||||
val allFirFiles =
|
||||
module.files.filter { it.isKtFile }.zip(
|
||||
moduleInfo.psiFiles
|
||||
.filterIsInstance<KtFile>()
|
||||
.map { psiFile -> psiFile.getOrBuildFirFile(resolveState) }
|
||||
)
|
||||
|
||||
val diagnosticCheckerFilter = if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
|
||||
DiagnosticCheckerFilter.EXTENDED_AND_COMMON_CHECKERS
|
||||
} else DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS
|
||||
|
||||
val analyzerFacade = LowLevelFirAnalyzerFacade(resolveState, allFirFiles, diagnosticCheckerFilter)
|
||||
val analyzerFacade = LowLevelFirAnalyzerFacade(resolveState, allFirFiles.toMap(), diagnosticCheckerFilter)
|
||||
return LowLevelFirOutputArtifact(resolveState.rootModuleSession, analyzerFacade)
|
||||
}
|
||||
}
|
||||
|
||||
+7
-34
@@ -5,52 +5,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based
|
||||
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getResolveState
|
||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KotlinProjectStructureProviderTestImpl
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestKtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.getKtFilesFromModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.projectModuleProvider
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.test.services.*
|
||||
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 ModuleRegistrarPreAnalysisHandler(
|
||||
class SealedClassesInheritorsCaclulatorPreAnalysisHandler(
|
||||
testServices: TestServices,
|
||||
private val parentDisposable: Disposable,
|
||||
private val shouldRegisterProjectServices: Boolean,
|
||||
) : PreAnalysisHandler(testServices) {
|
||||
private val moduleInfoProvider = testServices.projectModuleProvider
|
||||
|
||||
override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) {
|
||||
// todo rework after all modules will have the same Project instance
|
||||
val ktFilesByModule = moduleStructure.modules.associateWith { testModule ->
|
||||
val project = testServices.compilerConfigurationProvider.getProject(testModule)
|
||||
testServices.sourceFileProvider.getKtFilesForSourceFiles(testModule.files, project)
|
||||
}
|
||||
|
||||
val allKtFiles = ktFilesByModule.values.flatMap { it.values.toList() }
|
||||
|
||||
ktFilesByModule.forEach { (testModule, ktFiles) ->
|
||||
val project = testServices.compilerConfigurationProvider.getProject(testModule)
|
||||
moduleInfoProvider.registerModuleInfo(testModule, TestKtSourceModule(project, testModule, ktFiles, testServices))
|
||||
|
||||
// Register services for compiler-based tests
|
||||
// On the other hand, frontend API tests will register services via test configurators.
|
||||
if (shouldRegisterProjectServices) {
|
||||
(project as MockProject).registerTestServices(
|
||||
allKtFiles,
|
||||
testServices.compilerConfigurationProvider.getPackagePartProviderFactory(testModule),
|
||||
KotlinProjectStructureProviderTestImpl(testServices)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun prepareSealedClassInheritors(moduleStructure: TestModuleStructure) {
|
||||
@@ -63,10 +36,10 @@ class ModuleRegistrarPreAnalysisHandler(
|
||||
// Manually process all inheritors of sealed classes so that SealedClassInheritorsProviderTestImpl can work correctly for tests.
|
||||
// In the actual IDE, SealedClassInheritorsProviderIdeImpl works by finding inheritors from the index instead of do a
|
||||
// preprocessing of all files. Therefore, the IDE does not rely on such a pre-analysis pass of all files in the module.
|
||||
val projectStructureProvider = project.getService(ProjectStructureProvider::class.java)
|
||||
val ktModuleProvider = project.getService(ProjectStructureProvider::class.java)
|
||||
val allFirFiles = mutableListOf<FirFile>()
|
||||
ktFiles.forEach { ktFile ->
|
||||
val ktModule = projectStructureProvider.getKtModuleForKtElement(ktFile)
|
||||
val ktModule = ktModuleProvider.getKtModuleForKtElement(ktFile)
|
||||
val resolveState = ktModule.getResolveState(project)
|
||||
allFirFiles.add(ktFile.getOrBuildFirFile(resolveState))
|
||||
}
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.low.level.api.fir.compiler.based
|
||||
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveStateService
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
|
||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolverFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticAnnotationsResolverFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl
|
||||
import org.jetbrains.kotlin.light.classes.symbol.KotlinAsJavaFirSupport
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
fun MockProject.registerTestServices(
|
||||
allKtFiles: List<KtFile>,
|
||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
projectStructureProvider: ProjectStructureProvider
|
||||
) {
|
||||
registerService(
|
||||
PackagePartProviderFactory::class.java,
|
||||
PackagePartProviderTestImpl(packagePartProvider)
|
||||
)
|
||||
registerService(
|
||||
FirSealedClassInheritorsProcessorFactory::class.java,
|
||||
FirSealedClassInheritorsProcessorFactoryTestImpl()
|
||||
)
|
||||
registerService(KtModuleScopeProvider::class.java, KtModuleScopeProviderImpl())
|
||||
registerService(LLFirResolveStateService::class.java)
|
||||
registerService(
|
||||
KotlinModificationTrackerFactory::class.java,
|
||||
KotlinStaticModificationTrackerFactory::class.java
|
||||
)
|
||||
registerService(KotlinAnnotationsResolverFactory::class.java, KotlinStaticAnnotationsResolverFactory(allKtFiles))
|
||||
registerService(KotlinDeclarationProviderFactory::class.java, KotlinStaticDeclarationProviderFactory(allKtFiles))
|
||||
registerService(KotlinPackageProviderFactory::class.java, KotlinStaticPackageProviderFactory(allKtFiles))
|
||||
registerService(ProjectStructureProvider::class.java, projectStructureProvider)
|
||||
registerService(SymbolLightClassFacadeCache::class.java)
|
||||
reRegisterJavaElementFinder(this)
|
||||
}
|
||||
|
||||
private class FirSealedClassInheritorsProcessorFactoryTestImpl : FirSealedClassInheritorsProcessorFactory() {
|
||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
return SealedClassInheritorsProviderImpl
|
||||
}
|
||||
}
|
||||
|
||||
private class PackagePartProviderTestImpl(
|
||||
private val packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
) : PackagePartProviderFactory() {
|
||||
override fun createPackagePartProviderForLibrary(scope: GlobalSearchScope): PackagePartProvider {
|
||||
return packagePartProvider(scope)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InvalidWayOfUsingAnalysisSession::class)
|
||||
private fun reRegisterJavaElementFinder(project: Project) {
|
||||
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
|
||||
with(project as MockProject) {
|
||||
picoContainer.registerComponentInstance(
|
||||
KtAnalysisSessionProvider::class.qualifiedName,
|
||||
KtFirAnalysisSessionProvider(this)
|
||||
)
|
||||
picoContainer.unregisterComponent(KotlinAsJavaSupport::class.qualifiedName)
|
||||
picoContainer.registerComponentInstance(
|
||||
KotlinAsJavaSupport::class.qualifiedName,
|
||||
KotlinAsJavaFirSupport(project)
|
||||
)
|
||||
}
|
||||
@Suppress("DEPRECATION")
|
||||
PsiElementFinder.EP.getPoint(project).registerExtension(JavaElementFinder(project))
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.low.level.api.fir.services
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl
|
||||
|
||||
internal class LLFirSealedClassInheritorsProcessorFactoryForTests : FirSealedClassInheritorsProcessorFactory() {
|
||||
override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider {
|
||||
return SealedClassInheritorsProviderImpl
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.low.level.api.fir.services
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartProviderFactory
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassData
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
import org.jetbrains.kotlin.test.services.moduleStructure
|
||||
|
||||
internal class PackagePartProviderTestImpl(
|
||||
private val testServices: TestServices,
|
||||
) : PackagePartProviderFactory() {
|
||||
override fun createPackagePartProviderForLibrary(scope: GlobalSearchScope): PackagePartProvider {
|
||||
val providers = testServices.moduleStructure.modules.map { module ->
|
||||
testServices.compilerConfigurationProvider.getPackagePartProviderFactory(module)(scope)
|
||||
}
|
||||
return object : PackagePartProvider {
|
||||
override fun findPackageParts(packageFqName: String): List<String> {
|
||||
return providers.flatMapTo(mutableSetOf()) { it.findPackageParts(packageFqName) }.toList()
|
||||
}
|
||||
|
||||
override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> {
|
||||
return providers.flatMapTo(mutableSetOf()) { it.getAnnotationsOnBinaryModule(moduleName) }.toList()
|
||||
}
|
||||
|
||||
override fun getAllOptionalAnnotationClasses(): List<ClassData> {
|
||||
return providers.flatMapTo(mutableSetOf()) { it.getAllOptionalAnnotationClasses() }.toList()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -5,13 +5,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.test.base
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AbstractLowLevelApiSingleFileTest : AbstractLowLevelApiSingleModuleTest() {
|
||||
final override fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||
doTestByFileStructure(ktFiles.single(), moduleStructure, testServices)
|
||||
final override fun doTestByFileStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||
val singleModule = moduleStructure.modules.single()
|
||||
val singleFile = testServices.ktModuleProvider.getModuleFiles(singleModule).filterIsInstance<KtFile>().single()
|
||||
doTestByFileStructure(singleFile, moduleStructure, testServices)
|
||||
}
|
||||
|
||||
abstract fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices)
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.test.base
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
|
||||
|
||||
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.low.level.api.fir.test.base
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.impl.PsiElementFinderImpl
|
||||
import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveStateService
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.FirSealedClassInheritorsProcessorFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.PackagePartProviderFactory
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.LLFirSealedClassInheritorsProcessorFactoryForTests
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.services.PackagePartProviderTestImpl
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
|
||||
import org.jetbrains.kotlin.idea.references.KotlinFirReferenceContributor
|
||||
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
|
||||
import org.jetbrains.kotlin.light.classes.symbol.KotlinAsJavaFirSupport
|
||||
import org.jetbrains.kotlin.light.classes.symbol.caches.SymbolLightClassFacadeCache
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.impl.testConfiguration
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
object AnalysisApiFirTestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||
override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {
|
||||
IrGenerationExtension.registerExtensionPoint(project)
|
||||
FirExtensionRegistrarAdapter.registerExtensionPoint(project)
|
||||
}
|
||||
|
||||
@OptIn(InvalidWayOfUsingAnalysisSession::class, TestInfrastructureInternals::class)
|
||||
override fun registerProjectServices(project: MockProject, testServices: TestServices) {
|
||||
project.apply {
|
||||
registerService(KtAnalysisSessionProvider::class.java, KtFirAnalysisSessionProvider(this))
|
||||
registerService(FirSealedClassInheritorsProcessorFactory::class.java, LLFirSealedClassInheritorsProcessorFactoryForTests())
|
||||
registerService(LLFirResolveStateService::class.java)
|
||||
registerService(PackagePartProviderFactory::class.java, PackagePartProviderTestImpl(testServices))
|
||||
|
||||
registerService(SymbolLightClassFacadeCache::class.java)
|
||||
registerService(KotlinAsJavaSupport::class.java, KotlinAsJavaFirSupport(project))
|
||||
}
|
||||
|
||||
with(PsiElementFinder.EP.getPoint(project)) {
|
||||
registerExtension(JavaElementFinder(project), testServices.testConfiguration.rootDisposable)
|
||||
registerExtension(PsiElementFinderImpl(project), testServices.testConfiguration.rootDisposable)
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerApplicationServices(application: MockApplication, testServices: TestServices) {
|
||||
application.apply {
|
||||
registerService(KotlinReferenceProviderContributor::class.java, KotlinFirReferenceContributor::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.low.level.api.fir.test.base
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.SealedClassesInheritorsCaclulatorPreAnalysisHandler
|
||||
import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.toKtSourceModules
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiBaseTestServiceRegistrar
|
||||
|
||||
object FirLowLevelAnalysisApiTestConfigurator : AnalysisApiTestConfigurator() {
|
||||
override val analyseInDependentSession: Boolean get() = false
|
||||
|
||||
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
||||
builder.apply {
|
||||
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
|
||||
}
|
||||
}
|
||||
|
||||
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar> = listOf(
|
||||
AnalysisApiBaseTestServiceRegistrar,
|
||||
AnalysisApiFirTestServiceRegistrar,
|
||||
)
|
||||
|
||||
override fun createModules(
|
||||
moduleStructure: TestModuleStructure,
|
||||
testServices: TestServices,
|
||||
project: Project
|
||||
): List<KtModuleWithFiles> {
|
||||
return moduleStructure.toKtSourceModules(testServices, project)
|
||||
}
|
||||
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
ServiceManager.getService(file.project, KotlinModificationTrackerFactory::class.java)
|
||||
.incrementModificationsCount()
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.base
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.renderClass
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.base
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.SyntaxTraverser
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.renderClass
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.light.classes.symbol.base
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.asJava.LightClassTestCommon
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
+11
-3
@@ -5,12 +5,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.light.classes.symbol.base
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfigurator
|
||||
import com.intellij.util.pico.DefaultPicoContainer
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompilerExecutor
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.light.classes.symbol.base.service.NullabilityAnnotationSourceProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -21,6 +25,7 @@ import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
import org.jetbrains.kotlin.test.services.service
|
||||
import org.jetbrains.kotlin.test.utils.FirIdenticalCheckerHelper
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
@@ -34,6 +39,7 @@ abstract class AbstractSymbolLightClassesTestBase(
|
||||
override fun configureTest(builder: TestConfigurationBuilder) {
|
||||
super.configureTest(builder)
|
||||
with(builder) {
|
||||
useAdditionalServices(service(::CompiledLibraryProvider))
|
||||
useDirectives(Directives, CompilerExecutor.Directives)
|
||||
useAdditionalSourceProviders(::NullabilityAnnotationSourceProvider)
|
||||
}
|
||||
@@ -49,10 +55,12 @@ abstract class AbstractSymbolLightClassesTestBase(
|
||||
return
|
||||
}
|
||||
val testDataFile = module.files.first { it.name.endsWith(".kt") }.originalFile.toPath()
|
||||
val project = ktFiles.first().project
|
||||
|
||||
val ktFile = ktFiles.first()
|
||||
val project = ktFile.project
|
||||
|
||||
ignoreExceptionIfIgnoreFirPresent(module) {
|
||||
val actual = getRenderResult(ktFiles.first(), testDataFile, module, project)
|
||||
val actual = getRenderResult(ktFile, testDataFile, module, project)
|
||||
compareResults(testServices, actual)
|
||||
removeIgnoreFir(module)
|
||||
removeDuplicatedFirJava(testServices)
|
||||
|
||||
+2
-2
@@ -6,11 +6,11 @@
|
||||
package org.jetbrains.kotlin.light.classes.symbol.decompiled
|
||||
|
||||
import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesFacadeTest
|
||||
import org.jetbrains.kotlin.light.classes.symbol.decompiled.service.SymbolLightClassesForLibraryAnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.light.classes.symbol.decompiled.test.configurators.AnalysisApiSymbolLightClassesDecompiledTestConfigurator
|
||||
|
||||
abstract class AbstractSymbolLightClassesFacadeForLibraryTest :
|
||||
AbstractSymbolLightClassesFacadeTest(
|
||||
SymbolLightClassesForLibraryAnalysisApiTestConfigurator,
|
||||
AnalysisApiSymbolLightClassesDecompiledTestConfigurator,
|
||||
EXTENSIONS.LIB_JAVA,
|
||||
stopIfCompilationErrorDirectivePresent = true
|
||||
)
|
||||
+2
-2
@@ -6,11 +6,11 @@
|
||||
package org.jetbrains.kotlin.light.classes.symbol.decompiled
|
||||
|
||||
import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesTest
|
||||
import org.jetbrains.kotlin.light.classes.symbol.decompiled.service.SymbolLightClassesForLibraryAnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.light.classes.symbol.decompiled.test.configurators.AnalysisApiSymbolLightClassesDecompiledTestConfigurator
|
||||
|
||||
abstract class AbstractSymbolLightClassesForLibraryTest :
|
||||
AbstractSymbolLightClassesTest(
|
||||
SymbolLightClassesForLibraryAnalysisApiTestConfigurator,
|
||||
AnalysisApiSymbolLightClassesDecompiledTestConfigurator,
|
||||
EXTENSIONS.LIB_JAVA,
|
||||
stopIfCompilationErrorDirectivePresent = true
|
||||
)
|
||||
+2
-2
@@ -6,11 +6,11 @@
|
||||
package org.jetbrains.kotlin.light.classes.symbol.decompiled
|
||||
|
||||
import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesLoadingTest
|
||||
import org.jetbrains.kotlin.light.classes.symbol.decompiled.service.SymbolLightClassesForLibraryAnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.light.classes.symbol.decompiled.test.configurators.AnalysisApiSymbolLightClassesDecompiledTestConfigurator
|
||||
|
||||
abstract class AbstractSymbolLightClassesLoadingForLibraryTest :
|
||||
AbstractSymbolLightClassesLoadingTest(
|
||||
SymbolLightClassesForLibraryAnalysisApiTestConfigurator,
|
||||
AnalysisApiSymbolLightClassesDecompiledTestConfigurator,
|
||||
EXTENSIONS.LIB_JAVA,
|
||||
stopIfCompilationErrorDirectivePresent = true
|
||||
)
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.light.classes.symbol.decompiled.test.configurators
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.library.AnalysisApiFirLibraryBinaryTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
object AnalysisApiSymbolLightClassesDecompiledTestConfigurator : AnalysisApiTestConfigurator() {
|
||||
override val analyseInDependentSession: Boolean get() = false
|
||||
|
||||
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
||||
AnalysisApiFirLibraryBinaryTestConfigurator.configureTest(builder, disposable)
|
||||
}
|
||||
|
||||
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar>
|
||||
get() = AnalysisApiFirLibraryBinaryTestConfigurator.serviceRegistrars +
|
||||
AnalysisApiSymbolLightClassesDecompiledTestServiceRegistrar
|
||||
|
||||
override fun doOutOfBlockModification(file: KtFile) {
|
||||
AnalysisApiFirLibraryBinaryTestConfigurator.doOutOfBlockModification(file)
|
||||
}
|
||||
|
||||
override fun createModules(
|
||||
moduleStructure: TestModuleStructure,
|
||||
testServices: TestServices,
|
||||
project: Project
|
||||
): List<KtModuleWithFiles> {
|
||||
return AnalysisApiFirLibraryBinaryTestConfigurator.createModules(moduleStructure, testServices, project)
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.light.classes.symbol.decompiled.test.configurators
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.mock.MockProject
|
||||
import org.jetbrains.kotlin.analysis.decompiled.light.classes.ClsJavaStubByVirtualFileCache
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
object AnalysisApiSymbolLightClassesDecompiledTestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||
override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {
|
||||
}
|
||||
|
||||
override fun registerProjectServices(project: MockProject, testServices: TestServices) {
|
||||
project.apply {
|
||||
registerService(ClsJavaStubByVirtualFileCache::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerApplicationServices(application: MockApplication, testServices: TestServices) {
|
||||
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -5,12 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.light.classes.symbol.source
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.AnalysisApiFirTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
|
||||
import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesFacadeTest
|
||||
|
||||
abstract class AbstractSymbolLightClassesFacadeForSourceTest :
|
||||
AbstractSymbolLightClassesFacadeTest(
|
||||
AnalysisApiFirTestConfigurator(analyseInDependentSession = false),
|
||||
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false),
|
||||
EXTENSIONS.FIR_JAVA,
|
||||
stopIfCompilationErrorDirectivePresent = false
|
||||
)
|
||||
+2
-2
@@ -5,12 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.light.classes.symbol.source
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.AnalysisApiFirTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
|
||||
import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesTest
|
||||
|
||||
abstract class AbstractSymbolLightClassesForSourceTest :
|
||||
AbstractSymbolLightClassesTest(
|
||||
AnalysisApiFirTestConfigurator(analyseInDependentSession = false),
|
||||
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false),
|
||||
EXTENSIONS.FIR_JAVA,
|
||||
stopIfCompilationErrorDirectivePresent = false
|
||||
)
|
||||
+2
-2
@@ -5,12 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.light.classes.symbol.source
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.AnalysisApiFirTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
|
||||
import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesLoadingTest
|
||||
|
||||
abstract class AbstractSymbolLightClassesLoadingForSourceTest :
|
||||
AbstractSymbolLightClassesLoadingTest(
|
||||
AnalysisApiFirTestConfigurator(analyseInDependentSession = false),
|
||||
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false),
|
||||
EXTENSIONS.FIR_JAVA,
|
||||
stopIfCompilationErrorDirectivePresent = false
|
||||
)
|
||||
+57
-41
@@ -15,12 +15,14 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreApplicationEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.js.isJs
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
@@ -34,19 +36,25 @@ import org.jetbrains.kotlin.test.model.TestModule
|
||||
import java.io.File
|
||||
|
||||
abstract class CompilerConfigurationProvider(val testServices: TestServices) : TestService {
|
||||
abstract val testServices: TestServices
|
||||
abstract val testRootDisposable: Disposable
|
||||
abstract val configurators: List<AbstractEnvironmentConfigurator>
|
||||
|
||||
protected abstract fun getKotlinCoreEnvironment(module: TestModule): KotlinCoreEnvironment
|
||||
|
||||
fun getProject(module: TestModule): Project {
|
||||
open fun getProject(module: TestModule): Project {
|
||||
return getKotlinCoreEnvironment(module).project
|
||||
}
|
||||
|
||||
fun getPackagePartProviderFactory(module: TestModule): (GlobalSearchScope) -> JvmPackagePartProvider {
|
||||
fun registerCompilerExtensions(project: Project, module: TestModule) {
|
||||
configurators.forEach { it.registerCompilerExtensions(project, module) }
|
||||
}
|
||||
|
||||
open fun getPackagePartProviderFactory(module: TestModule): (GlobalSearchScope) -> JvmPackagePartProvider {
|
||||
return getKotlinCoreEnvironment(module)::createPackagePartProvider
|
||||
}
|
||||
|
||||
fun getCompilerConfiguration(module: TestModule): CompilerConfiguration {
|
||||
open fun getCompilerConfiguration(module: TestModule): CompilerConfiguration {
|
||||
return getKotlinCoreEnvironment(module).configuration
|
||||
}
|
||||
|
||||
@@ -64,9 +72,9 @@ abstract class CompilerConfigurationProvider(val testServices: TestServices) : T
|
||||
val TestServices.compilerConfigurationProvider: CompilerConfigurationProvider by TestServices.testServiceAccessor()
|
||||
|
||||
open class CompilerConfigurationProviderImpl(
|
||||
testServices: TestServices,
|
||||
override val testServices: TestServices,
|
||||
override val testRootDisposable: Disposable,
|
||||
val configurators: List<AbstractEnvironmentConfigurator>
|
||||
override val configurators: List<AbstractEnvironmentConfigurator>
|
||||
) : CompilerConfigurationProvider(testServices) {
|
||||
private val cache: MutableMap<TestModule, KotlinCoreEnvironment> = mutableMapOf()
|
||||
|
||||
@@ -79,62 +87,70 @@ open class CompilerConfigurationProviderImpl(
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
protected open fun createKotlinCoreEnvironment(module: TestModule): KotlinCoreEnvironment {
|
||||
val platform = module.targetPlatform
|
||||
val configFiles = when {
|
||||
platform.isJvm() -> EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
platform.isJs() -> EnvironmentConfigFiles.JS_CONFIG_FILES
|
||||
platform.isNative() -> EnvironmentConfigFiles.NATIVE_CONFIG_FILES
|
||||
// TODO: is it correct?
|
||||
platform.isCommon() -> EnvironmentConfigFiles.METADATA_CONFIG_FILES
|
||||
else -> error("Unknown platform: $platform")
|
||||
}
|
||||
val configFiles = platform.platformToEnvironmentConfigFiles()
|
||||
val applicationEnvironment = KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForTests(
|
||||
testServices.applicationDisposableProvider.getApplicationRootDisposable(),
|
||||
CompilerConfiguration()
|
||||
)
|
||||
val configuration = createCompilerConfiguration(module)
|
||||
val configuration = createCompilerConfiguration(module, configurators)
|
||||
val projectEnv = KotlinCoreEnvironment.ProjectEnvironment(testRootDisposable, applicationEnvironment, configuration)
|
||||
val project = projectEnv.project
|
||||
return KotlinCoreEnvironment.createForTests(
|
||||
projectEnv,
|
||||
configuration,
|
||||
configFiles
|
||||
).also { configurators.forEach { it.registerCompilerExtensions(project, module, configuration) } }
|
||||
).also { registerCompilerExtensions(projectEnv.project, module, configuration) }
|
||||
}
|
||||
|
||||
@TestInfrastructureInternals
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
fun createCompilerConfiguration(module: TestModule): CompilerConfiguration {
|
||||
val configuration = CompilerConfiguration()
|
||||
configuration[CommonConfigurationKeys.MODULE_NAME] = module.name
|
||||
if (JsEnvironmentConfigurationDirectives.PROPERTY_LAZY_INITIALIZATION in module.directives) {
|
||||
configuration.put(JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION, true)
|
||||
}
|
||||
return createCompilerConfiguration(module, configurators)
|
||||
}
|
||||
}
|
||||
|
||||
if (module.frontendKind == FrontendKinds.FIR) {
|
||||
configuration[CommonConfigurationKeys.USE_FIR] = true
|
||||
}
|
||||
|
||||
configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY] = object : MessageCollector {
|
||||
override fun clear() {}
|
||||
@TestInfrastructureInternals
|
||||
fun TargetPlatform.platformToEnvironmentConfigFiles() = when {
|
||||
isJvm() -> EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
isJs() -> EnvironmentConfigFiles.JS_CONFIG_FILES
|
||||
isNative() -> EnvironmentConfigFiles.NATIVE_CONFIG_FILES
|
||||
// TODO: is it correct?
|
||||
isCommon() -> EnvironmentConfigFiles.METADATA_CONFIG_FILES
|
||||
else -> error("Unknown platform: ${this}")
|
||||
}
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
|
||||
if (severity == CompilerMessageSeverity.ERROR) {
|
||||
val prefix = if (location == null) "" else "(" + location.path + ":" + location.line + ":" + location.column + ") "
|
||||
throw AssertionError(prefix + message)
|
||||
}
|
||||
@TestInfrastructureInternals
|
||||
fun createCompilerConfiguration(module: TestModule, configurators: List<AbstractEnvironmentConfigurator>): CompilerConfiguration {
|
||||
val configuration = CompilerConfiguration()
|
||||
configuration[CommonConfigurationKeys.MODULE_NAME] = module.name
|
||||
if (JsEnvironmentConfigurationDirectives.PROPERTY_LAZY_INITIALIZATION in module.directives) {
|
||||
configuration.put(JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION, true)
|
||||
}
|
||||
|
||||
if (module.frontendKind == FrontendKinds.FIR) {
|
||||
configuration[CommonConfigurationKeys.USE_FIR] = true
|
||||
}
|
||||
|
||||
configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY] = object : MessageCollector {
|
||||
override fun clear() {}
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
|
||||
if (severity == CompilerMessageSeverity.ERROR) {
|
||||
val prefix = if (location == null) "" else "(" + location.path + ":" + location.line + ":" + location.column + ") "
|
||||
throw AssertionError(prefix + message)
|
||||
}
|
||||
|
||||
override fun hasErrors(): Boolean = false
|
||||
}
|
||||
configuration.languageVersionSettings = module.languageVersionSettings
|
||||
|
||||
configurators.forEach { it.configureCompileConfigurationWithAdditionalConfigurationKeys(configuration, module) }
|
||||
|
||||
return configuration
|
||||
override fun hasErrors(): Boolean = false
|
||||
}
|
||||
configuration.languageVersionSettings = module.languageVersionSettings
|
||||
|
||||
private operator fun <T : Any> CompilerConfiguration.set(key: CompilerConfigurationKey<T>, value: T) {
|
||||
put(key, value)
|
||||
}
|
||||
configurators.forEach { it.configureCompileConfigurationWithAdditionalConfigurationKeys(configuration, module) }
|
||||
|
||||
return configuration
|
||||
}
|
||||
|
||||
private operator fun <T : Any> CompilerConfiguration.set(key: CompilerConfigurationKey<T>, value: T) {
|
||||
put(key, value)
|
||||
}
|
||||
|
||||
val TestModule.javaFiles: List<TestFile>
|
||||
|
||||
+7
-4
@@ -37,9 +37,10 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.scopes.AbstractSubstitut
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.symbols.AbstractSymbolByFqNameTest
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.symbols.AbstractSymbolByPsiTest
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.symbols.AbstractSymbolByReferenceTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisSessionMode
|
||||
import org.jetbrains.kotlin.analysis.test.framework.FrontendKind
|
||||
import org.jetbrains.kotlin.analysis.test.framework.TestModuleKind
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind
|
||||
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.*
|
||||
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.AnalysisApiTestGroup
|
||||
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.component
|
||||
@@ -48,7 +49,9 @@ import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
||||
internal fun AnalysisApiTestGroup.generateAnalysisApiTests() {
|
||||
test(
|
||||
AbstractReferenceResolveTest::class,
|
||||
filter = frontendIs(FrontendKind.Fir) and testModuleKindIs(TestModuleKind.Source, TestModuleKind.LibrarySource),
|
||||
filter = frontendIs(FrontendKind.Fir) and
|
||||
testModuleKindIs(TestModuleKind.Source, TestModuleKind.LibrarySource) and
|
||||
analysisApiModeIs(AnalysisApiMode.Ide, AnalysisApiMode.Standalone),
|
||||
) { data ->
|
||||
when (data.moduleKind) {
|
||||
TestModuleKind.LibrarySource -> {
|
||||
|
||||
+3
-4
@@ -5,10 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.generators.tests.analysis.api.dsl
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fe10.AnalysisApiFe10TestConfiguratorFactory
|
||||
import org.jetbrains.kotlin.analysis.api.fir.AnalysisApiFirTestConfiguratorFactory
|
||||
import org.jetbrains.kotlin.analysis.api.standalone.AnalysisApiFirStandaloneModeTestConfiguratorFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.*
|
||||
import org.jetbrains.kotlin.analysis.api.fe10.test.configurator.AnalysisApiFe10TestConfiguratorFactory
|
||||
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.*
|
||||
|
||||
object AnalysisApiConfiguratorFactoryProvider {
|
||||
private val allFactories = listOf(
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.generators.tests.analysis.api.dsl
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfiguratorFactoryData
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData
|
||||
import org.jetbrains.kotlin.generators.TestGroup
|
||||
import org.jetbrains.kotlin.generators.TestGroupSuite
|
||||
import org.jetbrains.kotlin.generators.getDefaultSuiteTestClassName
|
||||
|
||||
+3
-4
@@ -6,10 +6,9 @@
|
||||
package org.jetbrains.kotlin.generators.tests.analysis.api.dsl
|
||||
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfiguratorFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfiguratorFactoryData
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.analysis.test.framework.FrontendKind
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactory
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
|
||||
import org.jetbrains.kotlin.generators.MethodGenerator
|
||||
import org.jetbrains.kotlin.generators.model.MethodModel
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.generators.tests.analysis.api.dsl
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.*
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.*
|
||||
|
||||
typealias TestFilter = (AnalysisApiTestConfiguratorFactoryData) -> Boolean
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.generators.tests.analysis.api.dsl
|
||||
|
||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestConfiguratorFactoryData
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData
|
||||
|
||||
internal fun AnalysisApiTestGroup.component(
|
||||
directory: String,
|
||||
|
||||
@@ -546,6 +546,7 @@ include ":generators:analysis-api-generator",
|
||||
":analysis:symbol-light-classes",
|
||||
":analysis:project-structure",
|
||||
":analysis:analysis-api-standalone",
|
||||
":analysis:analysis-api-standalone:analysis-api-standalone-base",
|
||||
":analysis:analysis-api-fe10",
|
||||
":analysis:decompiled:decompiler-to-psi",
|
||||
":analysis:decompiled:decompiler-to-stubs",
|
||||
|
||||
Reference in New Issue
Block a user