[analysis api, test] rework test infrastructure, add multimodule tests

This commit is contained in:
Ilya Kirillov
2022-03-24 22:34:31 +01:00
parent 1e5cf80278
commit 4bd7fed1ea
79 changed files with 1786 additions and 510 deletions
@@ -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))
}
}
}
}
@@ -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,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")
}
@@ -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)
}
}
}
@@ -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
}
}
}
@@ -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)
}
}
@@ -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()
}
@@ -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)
}
}
@@ -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())
@@ -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])
*
@@ -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")
}
}
@@ -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)
}
}
@@ -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
}
}
@@ -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)
}
}
@@ -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)
}
}
}
@@ -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() }
}
@@ -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>
)
@@ -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>()
}
}
@@ -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)
}
}
}
@@ -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,
@@ -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>,
@@ -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 {
@@ -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()
}
@@ -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)
}
@@ -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(
@@ -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)
}
@@ -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))
}
@@ -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()
@@ -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
@@ -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()
}
}
@@ -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()
@@ -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
}
@@ -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
)
}
@@ -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()
@@ -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)
}
}
@@ -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 })
}
}
@@ -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()
@@ -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()
@@ -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())
}
}
@@ -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
@@ -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(),
)
}
@@ -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
@@ -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"))
@@ -431,6 +431,7 @@ private fun List<KtModule>.extractLibraryPaths(): List<Path> =
asSequence()
.filterIsInstance<KtBinaryModule>()
.flatMap { it.getBinaryRoots() }
.map { it.toAbsolutePath() }
.toList()
@Deprecated(
@@ -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}")
}
}
@@ -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)
@@ -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)
}
}
@@ -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))
}
@@ -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))
}
@@ -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
}
}
@@ -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,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)
@@ -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
@@ -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)
}
}
}
@@ -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()
}
}
@@ -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
@@ -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
@@ -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
@@ -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)
@@ -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
)
@@ -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
)
@@ -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
)
@@ -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)
}
}
@@ -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) {
}
}
@@ -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
)
@@ -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
)
@@ -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
)
@@ -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>
@@ -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 -> {
@@ -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(
@@ -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
@@ -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
@@ -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
@@ -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,
+1
View File
@@ -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",