From 4bd7fed1ead0feb3697b16619ec5307083892fdd Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 24 Mar 2022 22:34:31 +0100 Subject: [PATCH] [analysis api, test] rework test infrastructure, add multimodule tests --- ...KtFe10ModuleRegistrarPreAnalysisHandler.kt | 47 ----- .../AnalysisApiFe10TestConfigurator.kt | 67 +++++++ .../AnalysisApiFe10TestConfiguratorFactory.kt | 6 +- .../AnalysisApiFe10TestServiceRegistrar.kt | 49 +++++ .../AnalysisApiFirTestConfiguratorFactory.kt | 17 +- ...ysisApiFirLibraryBinaryTestConfigurator.kt | 66 +++++++ ...sisApiFirLibrarySourceTestConfigurator.kt} | 63 ++++-- .../AnalysisApiFirSourceTestConfigurator.kt | 43 ++++ ...ibraryModuleRegistrarPreAnalysisHandler.kt | 42 ---- .../analysis-api-impl-base/build.gradle.kts | 3 + .../api/impl/base/util/LibraryUtils.kt | 16 ++ .../AbstractAnalysisApiImportOptimizerTest.kt | 29 +++ ...nalysisApiExpressionPsiTypeProviderTest.kt | 31 +++ .../AbstractAnalysisApiPsiTypeProviderTest.kt | 98 ++++++++++ .../AbstractAnalysisApiGetSuperTypesTest.kt | 47 +++++ .../AnalysisApiBaseTestServiceRegistrar.kt | 51 +++++ ...lysisApiLibraryBaseTestServiceRegistrar.kt | 48 +++++ .../build.gradle.kts | 20 ++ .../project/structure/KtModuleWithFiles.kt | 14 ++ .../structure/KtStaticModuleProvider.kt | 24 +++ .../structure/StandaloneProjectFactory.kt | 184 ++++++++++++++++++ .../api/standalone/StandaloneModeUtils.kt | 4 +- ...tModuleProviderByCompilerConfiguration.kt} | 2 +- ...irStandaloneModeTestConfiguratorFactory.kt | 2 +- .../standalone/StandaloneModeConfigurator.kt | 40 ++++ .../analysis-test-framework/build.gradle.kts | 2 + ...bstractAnalysisApiBasedSingleModuleTest.kt | 6 +- .../base/AbstractAnalysisApiBasedTest.kt | 88 +++------ .../base/AbstractAnalysisApiSingleFileTest.kt | 2 +- .../base/registerBaseTestServices.kt | 28 +++ .../AnalysisApiKtModuleProviderImpl.kt | 60 ++++++ .../KotlinKtModuleProviderTestImpl.kt | 7 + .../KotlinProjectStructureProviderTestImpl.kt | 25 --- .../project/structure/TestKtModuleProvider.kt | 35 ---- .../project/structure/TestKtSourceModule.kt | 33 ++-- .../structure/projectStructureUtils.kt | 46 ++++- .../services/AnalysisApiEnvironmentManager.kt | 80 ++++++++ ...ysisApiTestCompilerConfiguratorProvider.kt | 68 +++++++ ...ructureInitialisationPreAnalysisHandler.kt | 47 +++++ .../services/TestDisposableProvder.kt | 37 ++++ .../libraries/CompiledLibraryProvider.kt | 3 - .../LibraryEnvironmentConfigurator.kt | 19 -- .../services/libraries/TestModuleCompiler.kt | 2 +- .../AnalysisApiTestConfigurator.kt | 87 +++++++++ ...alysisApiTestConfiguratorServiceFactory.kt | 2 +- .../AnalysisApiTestServiceRegistrar.kt | 18 ++ analysis/low-level-api-fir/build.gradle.kts | 1 + .../api/fir/sessions/LLFirSessionFactory.kt | 1 + .../LLFirDesignatedTypeResolverTransformer.kt | 2 + .../fir/transformers/LLFirLazyTransformer.kt | 2 +- .../based/AbstractCompilerBasedTestForFir.kt | 29 ++- ...InheritorsCaclulatorPreAnalysisHandler.kt} | 41 +--- .../api/fir/compiler/based/testServices.kt | 95 --------- ...ClassInheritorsProcessorFactoryForTests.kt | 16 ++ .../services/PackagePartProviderTestImpl.kt | 39 ++++ .../base/AbstractLowLevelApiSingleFileTest.kt | 7 +- .../AbstractLowLevelApiSingleModuleTest.kt | 2 +- .../AnalysisApiFirTestServiceRegistrar.kt | 62 ++++++ .../FirLowLevelAnalysisApiTestConfigurator.kt | 49 +++++ .../AbstractSymbolLightClassesFacadeTest.kt | 2 +- .../AbstractSymbolLightClassesLoadingTest.kt | 2 +- .../base/AbstractSymbolLightClassesTest.kt | 2 +- .../AbstractSymbolLightClassesTestBase.kt | 14 +- ...tSymbolLightClassesFacadeForLibraryTest.kt | 4 +- ...bstractSymbolLightClassesForLibraryTest.kt | 4 +- ...SymbolLightClassesLoadingForLibraryTest.kt | 4 +- ...lLightClassesDecompiledTestConfigurator.kt | 41 ++++ ...htClassesDecompiledTestServiceRegistrar.kt | 27 +++ ...ctSymbolLightClassesFacadeForSourceTest.kt | 4 +- ...AbstractSymbolLightClassesForSourceTest.kt | 4 +- ...tSymbolLightClassesLoadingForSourceTest.kt | 4 +- .../services/CompilerConfigurationProvider.kt | 98 ++++++---- .../tests/analysis/api/analysisApi.kt | 11 +- .../AnalysisApiConfiguratorFactoryProvider.kt | 7 +- .../analysis/api/dsl/AnalysisApiTestGroup.kt | 2 +- .../dsl/FrontendConfiguratorTestGenerator.kt | 7 +- .../tests/analysis/api/dsl/TestFilter.kt | 2 +- .../generators/tests/analysis/api/dsl/dsl.kt | 2 +- settings.gradle | 1 + 79 files changed, 1786 insertions(+), 510 deletions(-) delete mode 100644 analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/KtFe10ModuleRegistrarPreAnalysisHandler.kt create mode 100644 analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestConfigurator.kt rename analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/{ => test/configurator}/AnalysisApiFe10TestConfiguratorFactory.kt (86%) create mode 100644 analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt rename analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/{ => test/configurators}/AnalysisApiFirTestConfiguratorFactory.kt (62%) create mode 100644 analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibraryBinaryTestConfigurator.kt rename analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/{utils/libraries/source/LibrarySourceModuleRegistrarPreAnalysisHandler.kt => test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt} (52%) create mode 100644 analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/source/AnalysisApiFirSourceTestConfigurator.kt delete mode 100644 analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/utils/libraries/binary/LibraryModuleRegistrarPreAnalysisHandler.kt create mode 100644 analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/importOptimizer/AbstractAnalysisApiImportOptimizerTest.kt create mode 100644 analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt create mode 100644 analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt create mode 100644 analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt create mode 100644 analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt create mode 100644 analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt create mode 100644 analysis/analysis-api-standalone/analysis-api-standalone-base/build.gradle.kts create mode 100644 analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtModuleWithFiles.kt create mode 100644 analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtStaticModuleProvider.kt create mode 100644 analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/StandaloneProjectFactory.kt rename analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/{ProjectStructureProviderByCompilerConfiguration.kt => KtModuleProviderByCompilerConfiguration.kt} (96%) create mode 100644 analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeConfigurator.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/registerBaseTestServices.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/AnalysisApiKtModuleProviderImpl.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinKtModuleProviderTestImpl.kt delete mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinProjectStructureProviderTestImpl.kt delete mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtModuleProvider.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiEnvironmentManager.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiTestCompilerConfiguratorProvider.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ProjectStructureInitialisationPreAnalysisHandler.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/TestDisposableProvder.kt delete mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/LibraryEnvironmentConfigurator.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestConfigurator.kt rename analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/{ => test/configurators}/AnalysisApiTestConfiguratorServiceFactory.kt (95%) create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestServiceRegistrar.kt rename analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/{ModuleRegistrarPreAnalysisHandler.kt => SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt} (55%) delete mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelAnalysisApiTestConfigurator.kt create mode 100644 analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestConfigurator.kt create mode 100644 analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestServiceRegistrar.kt diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/KtFe10ModuleRegistrarPreAnalysisHandler.kt b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/KtFe10ModuleRegistrarPreAnalysisHandler.kt deleted file mode 100644 index 597c22175cf..00000000000 --- a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/KtFe10ModuleRegistrarPreAnalysisHandler.kt +++ /dev/null @@ -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)) - } - } - } -} \ No newline at end of file diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestConfigurator.kt b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestConfigurator.kt new file mode 100644 index 00000000000..316bf077a8f --- /dev/null +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestConfigurator.kt @@ -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 = listOf( + AnalysisApiBaseTestServiceRegistrar, + AnalysisApiFe10TestServiceRegistrar, + ) + + override fun createModules( + moduleStructure: TestModuleStructure, + testServices: TestServices, + project: Project, + ): List { + return moduleStructure.toKtSourceModules(testServices, project) + } + + override fun prepareFilesInModule(files: List, 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(), 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 + } +} diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/AnalysisApiFe10TestConfiguratorFactory.kt b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestConfiguratorFactory.kt similarity index 86% rename from analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/AnalysisApiFe10TestConfiguratorFactory.kt rename to analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestConfiguratorFactory.kt index cd5c3f781f9..58b48417eea 100644 --- a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/AnalysisApiFe10TestConfiguratorFactory.kt +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestConfiguratorFactory.kt @@ -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") } diff --git a/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt new file mode 100644 index 00000000000..5390877d8a3 --- /dev/null +++ b/analysis/analysis-api-fe10/tests/org/jetbrains/kotlin/analysis/api/fe10/test/configurator/AnalysisApiFe10TestServiceRegistrar.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/AnalysisApiFirTestConfiguratorFactory.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/AnalysisApiFirTestConfiguratorFactory.kt similarity index 62% rename from analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/AnalysisApiFirTestConfiguratorFactory.kt rename to analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/AnalysisApiFirTestConfiguratorFactory.kt index ec5a009ace3..4f851945b15 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/AnalysisApiFirTestConfiguratorFactory.kt +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/AnalysisApiFirTestConfiguratorFactory.kt @@ -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 } } } diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibraryBinaryTestConfigurator.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibraryBinaryTestConfigurator.kt new file mode 100644 index 00000000000..1c89d208139 --- /dev/null +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibraryBinaryTestConfigurator.kt @@ -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 { + 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 = + listOf( + AnalysisApiBaseTestServiceRegistrar, + AnalysisApiFirTestServiceRegistrar, + AnalysisApiLibraryBaseTestServiceRegistrar, + ) + + + override fun doOutOfBlockModification(file: KtFile) { + AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file) + } +} diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/utils/libraries/source/LibrarySourceModuleRegistrarPreAnalysisHandler.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt similarity index 52% rename from analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/utils/libraries/source/LibrarySourceModuleRegistrarPreAnalysisHandler.kt rename to analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt index 5a4c60fb494..3fd5b7c61da 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/utils/libraries/source/LibrarySourceModuleRegistrarPreAnalysisHandler.kt +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt @@ -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 { 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 = + 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() } + diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/source/AnalysisApiFirSourceTestConfigurator.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/source/AnalysisApiFirSourceTestConfigurator.kt new file mode 100644 index 00000000000..cc576b5ab16 --- /dev/null +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/source/AnalysisApiFirSourceTestConfigurator.kt @@ -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 = listOf( + AnalysisApiBaseTestServiceRegistrar, + AnalysisApiFirTestServiceRegistrar, + ) + + override fun createModules(moduleStructure: TestModuleStructure, testServices: TestServices, project: Project): List { + return moduleStructure.toKtSourceModules(testServices, project) + } + + override fun doOutOfBlockModification(file: KtFile) { + FirLowLevelAnalysisApiTestConfigurator.doOutOfBlockModification(file) + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/utils/libraries/binary/LibraryModuleRegistrarPreAnalysisHandler.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/utils/libraries/binary/LibraryModuleRegistrarPreAnalysisHandler.kt deleted file mode 100644 index d6bb41e78d0..00000000000 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/utils/libraries/binary/LibraryModuleRegistrarPreAnalysisHandler.kt +++ /dev/null @@ -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 { - val library = testServices.compiledLibraryProvider.getCompiledLibrary(module).jar - - val virtualFiles = LibraryUtils.getAllVirtualFilesFromJar(library) - return virtualFiles.mapNotNull { virtualFile -> - PsiManager.getInstance(project).findFile(virtualFile) as? KtClsFile - } - } -} diff --git a/analysis/analysis-api-impl-base/build.gradle.kts b/analysis/analysis-api-impl-base/build.gradle.kts index 9dcf37bacaa..1385d9d2574 100644 --- a/analysis/analysis-api-impl-base/build.gradle.kts +++ b/analysis/analysis-api-impl-base/build.gradle.kts @@ -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()) diff --git a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/util/LibraryUtils.kt b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/util/LibraryUtils.kt index 41581c7f5c2..8bf068fdfb1 100644 --- a/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/util/LibraryUtils.kt +++ b/analysis/analysis-api-impl-base/src/org/jetbrains/kotlin/analysis/api/impl/base/util/LibraryUtils.kt @@ -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 { + 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]) * diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/importOptimizer/AbstractAnalysisApiImportOptimizerTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/importOptimizer/AbstractAnalysisApiImportOptimizerTest.kt new file mode 100644 index 00000000000..302b1788f50 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/importOptimizer/AbstractAnalysisApiImportOptimizerTest.kt @@ -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, 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") + } +} \ No newline at end of file diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt new file mode 100644 index 00000000000..2cd3d2e8415 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiExpressionPsiTypeProviderTest.kt @@ -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) + } +} diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt new file mode 100644 index 00000000000..10860307e07 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/psiTypeProvider/AbstractAnalysisApiPsiTypeProviderTest.kt @@ -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(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() ?: return null + return project.getService(KotlinAsJavaSupport::class.java).getLightClass(containingClass) + } + + private fun KtLightClass.findLightDeclarationContext(ktDeclaration: KtDeclaration): KtLightElement<*, *>? { + val selfOrParents = listOf(ktDeclaration) + ktDeclaration.parents.filterIsInstance() + 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 + } + +} diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt new file mode 100644 index 00000000000..8afc73d22e9 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/components/typeProvider/AbstractAnalysisApiGetSuperTypesTest.kt @@ -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.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) + } +} \ No newline at end of file diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt new file mode 100644 index 00000000000..9f3a542a2a9 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt @@ -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() } + + 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) + } + + } +} \ No newline at end of file diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt new file mode 100644 index 00000000000..895306ad511 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt @@ -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()) + } + + } +} \ No newline at end of file diff --git a/analysis/analysis-api-standalone/analysis-api-standalone-base/build.gradle.kts b/analysis/analysis-api-standalone/analysis-api-standalone-base/build.gradle.kts new file mode 100644 index 00000000000..0b32e7765c5 --- /dev/null +++ b/analysis/analysis-api-standalone/analysis-api-standalone-base/build.gradle.kts @@ -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() } +} diff --git a/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtModuleWithFiles.kt b/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtModuleWithFiles.kt new file mode 100644 index 00000000000..ef5ec3d9a78 --- /dev/null +++ b/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtModuleWithFiles.kt @@ -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 +) \ No newline at end of file diff --git a/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtStaticModuleProvider.kt b/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtStaticModuleProvider.kt new file mode 100644 index 00000000000..b58de3e16bb --- /dev/null +++ b/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/KtStaticModuleProvider.kt @@ -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) : ProjectStructureProvider() { + override fun getKtModuleForKtElement(element: PsiElement): KtModule { + return modules.first { module -> + module.contentScope.contains(element) + } + } + + override fun getKtLibraryModules(): Collection { + return modules.filterIsInstance() + } +} diff --git a/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/StandaloneProjectFactory.kt b/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/StandaloneProjectFactory.kt new file mode 100644 index 00000000000..75673f3f3be --- /dev/null +++ b/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/StandaloneProjectFactory.kt @@ -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, + 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, + 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())) + } + 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): List { + if (files.isEmpty()) return emptyList() + val result = mutableSetOf() + 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, + environment: KotlinCoreProjectEnvironment + ): List = withAllTransitiveDependencies(modules) + .filterIsInstance() + .flatMap { it.getBinaryRoots() } + .map { + val jar = environment.environment.jarFileSystem.findFileByPath(it.toAbsolutePath().toString() + "!/")!! + JavaRoot(jar, JavaRoot.RootType.BINARY) + } + + private fun withAllTransitiveDependencies(ktModules: List): List { + val visited = hashSetOf() + 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 = buildList { + addAll(allDirectDependencies()) + when (this) { + is KtLibrarySourceModule -> { + add(binaryLibrary) + } + is KtLibraryModule -> { + addIfNotNull(librarySources) + } + } + } + + + fun createPackagePartsProvider( + languageVersionSettings: LanguageVersionSettings, + project: MockProject, + libraryRoots: List + ): JvmPackagePartProvider { + return JvmPackagePartProvider(languageVersionSettings, ProjectScope.getLibrariesScope(project)).apply { + addRoots(libraryRoots, MessageCollector.NONE) + (ModuleAnnotationsResolver + .getInstance(project) as CliModuleAnnotationsResolver) + .addPackagePartProvider(this) + } + } +} \ No newline at end of file diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeUtils.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeUtils.kt index 1991ca2b817..9deed8bad77 100644 --- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeUtils.kt +++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeUtils.kt @@ -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, diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/ProjectStructureProviderByCompilerConfiguration.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderByCompilerConfiguration.kt similarity index 96% rename from analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/ProjectStructureProviderByCompilerConfiguration.kt rename to analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderByCompilerConfiguration.kt index 0189ed4fa0b..c670a592568 100644 --- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/ProjectStructureProviderByCompilerConfiguration.kt +++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderByCompilerConfiguration.kt @@ -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, diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/AnalysisApiFirStandaloneModeTestConfiguratorFactory.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/AnalysisApiFirStandaloneModeTestConfiguratorFactory.kt index d02fc6f5bc5..ce87320f4ba 100644 --- a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/AnalysisApiFirStandaloneModeTestConfiguratorFactory.kt +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/AnalysisApiFirStandaloneModeTestConfiguratorFactory.kt @@ -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 { diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeConfigurator.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeConfigurator.kt new file mode 100644 index 00000000000..9c4680c514d --- /dev/null +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/StandaloneModeConfigurator.kt @@ -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 + get() = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).serviceRegistrars + + override fun createModules( + moduleStructure: TestModuleStructure, + testServices: TestServices, + project: Project + ): List { + return AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).createModules(moduleStructure, testServices, project) + } + + override fun doOutOfBlockModification(file: KtFile) { + AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file) + } +} diff --git a/analysis/analysis-test-framework/build.gradle.kts b/analysis/analysis-test-framework/build.gradle.kts index 3626dd20439..6ad673959d9 100644 --- a/analysis/analysis-test-framework/build.gradle.kts +++ b/analysis/analysis-test-framework/build.gradle.kts @@ -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() } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt index ac15beffad3..01d7083012a 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt @@ -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, moduleStructure: TestModuleStructure, testServices: TestServices) { + final override fun doTestByFileStructure(moduleStructure: TestModuleStructure, testServices: TestServices) { val singleModule = moduleStructure.modules.single() + val ktFiles = testServices.ktModuleProvider.getModuleFiles(singleModule).filterIsInstance() doTestByFileStructure(ktFiles, singleModule, testServices) } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt index c3531b5e5ed..317c90c3ea6 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt @@ -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, 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 { ExecutionListenerBasedDisposableProvider() } useAdditionalService { 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 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( diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiSingleFileTest.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiSingleFileTest.kt index e62aaf738a7..642e1b6354b 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiSingleFileTest.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiSingleFileTest.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.test.services.TestServices abstract class AbstractAnalysisApiSingleFileTest : AbstractAnalysisApiBasedSingleModuleTest() { final override fun doTestByFileStructure(ktFiles: List, module: TestModule, testServices: TestServices) { - val singleFile = ktFiles.singleOrNull() ?: ktFiles.first { it.name == "main.kt" } + val singleFile = ktFiles.first() doTestByFileStructure(singleFile, module, testServices) } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/registerBaseTestServices.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/registerBaseTestServices.kt new file mode 100644 index 00000000000..77a7c710ff6 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/registerBaseTestServices.kt @@ -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(::TestDisposableProviderImpl) + useAdditionalService(::AnalysisApiKtModuleProviderImpl) + useAdditionalService(::AnalysisApiEnvironmentManagerImpl.bind(testDisposable)) + + useCustomCompilerConfigurationProvider(::AnalysisApiTestCompilerConfiguratorProvider) + usePreAnalysisHandlers(::ProjectStructureInitialisationPreAnalysisHandler.bind(configurator)) +} \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/AnalysisApiKtModuleProviderImpl.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/AnalysisApiKtModuleProviderImpl.kt new file mode 100644 index 00000000000..37454c78390 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/AnalysisApiKtModuleProviderImpl.kt @@ -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 + + abstract fun registerProjectStructure(modules: List) + + protected abstract fun getModuleName(ktModule: KtModule): String + + abstract fun getAllModules(): List +} + +class AnalysisApiKtModuleProviderImpl( + override val testServices: TestServices, +) : AnalysisApiKtModuleProvider() { + private lateinit var modules: List + private lateinit var modulesByName: Map + + override fun getModule(moduleName: String): KtModule { + return modulesByName.getValue(moduleName).ktModule + } + + override fun getModuleFiles(module: TestModule): List = modulesByName.getValue(module.name).files + + override fun registerProjectStructure(modules: List) { + 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 = modules +} + +val TestServices.ktModuleProvider: AnalysisApiKtModuleProvider by TestServices.testServiceAccessor() diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinKtModuleProviderTestImpl.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinKtModuleProviderTestImpl.kt new file mode 100644 index 00000000000..eee84b48e21 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinKtModuleProviderTestImpl.kt @@ -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 + diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinProjectStructureProviderTestImpl.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinProjectStructureProviderTestImpl.kt deleted file mode 100644 index 0a9697ac48e..00000000000 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KotlinProjectStructureProviderTestImpl.kt +++ /dev/null @@ -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 { - return moduleInfoProvider.getLibraryModules() - } -} diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtModuleProvider.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtModuleProvider.kt deleted file mode 100644 index 29d621aaac4..00000000000 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtModuleProvider.kt +++ /dev/null @@ -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() - - 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 { - return cache.values.filterIsInstance() - } -} - -val TestServices.projectModuleProvider: TestKtModuleProvider by TestServices.testServiceAccessor() diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtSourceModule.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtSourceModule.kt index 8dbc8188a3e..101b59e743f 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtSourceModule.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtSourceModule.kt @@ -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, + val psiFiles: List, 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 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 by lazy(LazyThreadSafetyMode.PUBLICATION) { testModule.dependsOnDependencies - .map { moduleProvider.getModule(it.moduleName) as KtModule } + .map { moduleProvider.getModule(it.moduleName) } } val directFriendDependencies: List 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, + psiFiles: List, 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()) } class TestKtLibraryModule( project: Project, testModule: TestModule, - ktFiles: Collection, + psiFiles: List, + private val binaryRoots: List, 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 = ktFiles.map { it.virtualFile.toNioPath() } + override fun getBinaryRoots(): Collection = 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, + psiFiles: List, 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 } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/projectStructureUtils.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/projectStructureUtils.kt index 9652e111be9..52444c7f0ca 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/projectStructureUtils.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/projectStructureUtils.kt @@ -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 { - 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() + is TestKtLibraryModule -> moduleInfo.psiFiles.filterIsInstance() + is TestKtLibrarySourceModule -> moduleInfo.psiFiles.filterIsInstance() 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 + ) +} \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiEnvironmentManager.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiEnvironmentManager.kt new file mode 100644 index 00000000000..b22839e1362 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiEnvironmentManager.kt @@ -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() diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiTestCompilerConfiguratorProvider.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiTestCompilerConfiguratorProvider.kt new file mode 100644 index 00000000000..ecbbe0a27e3 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/AnalysisApiTestCompilerConfiguratorProvider.kt @@ -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 +) : CompilerConfigurationProvider() { + private val configurationCache: MutableMap = 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) + } +} \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ProjectStructureInitialisationPreAnalysisHandler.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ProjectStructureInitialisationPreAnalysisHandler.kt new file mode 100644 index 00000000000..69a22f48d83 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ProjectStructureInitialisationPreAnalysisHandler.kt @@ -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 }) + } +} \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/TestDisposableProvder.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/TestDisposableProvder.kt new file mode 100644 index 00000000000..3751e021179 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/TestDisposableProvder.kt @@ -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() \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt index c7b2b0e7e2a..774550ce300 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompiledLibraryProvider.kt @@ -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() diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/LibraryEnvironmentConfigurator.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/LibraryEnvironmentConfigurator.kt deleted file mode 100644 index 788939a5451..00000000000 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/LibraryEnvironmentConfigurator.kt +++ /dev/null @@ -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()) - } -} \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt index 6da54ee8756..5bcdeaf4da9 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt @@ -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 diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestConfigurator.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestConfigurator.kt new file mode 100644 index 00000000000..6c60a61d5ef --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestConfigurator.kt @@ -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 + + open fun prepareFilesInModule(files: List, 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 + + 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, 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( + Key("TestApplicationServicesRegistrarLock"), + ReentrantReadWriteLock(), + ) + + private var Application.serviceRegistered + by NotNullableUserDataProperty, Boolean>>( + Key("TestApplicationServicesRegistered"), + mutableMapOf(), + ) +} diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/AnalysisApiTestConfiguratorServiceFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestConfiguratorServiceFactory.kt similarity index 95% rename from analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/AnalysisApiTestConfiguratorServiceFactory.kt rename to analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestConfiguratorServiceFactory.kt index 854c9fea1c0..b86e6475140 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/AnalysisApiTestConfiguratorServiceFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestConfiguratorServiceFactory.kt @@ -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 diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestServiceRegistrar.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestServiceRegistrar.kt new file mode 100644 index 00000000000..f2e71f77fef --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/test/configurators/AnalysisApiTestServiceRegistrar.kt @@ -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) +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/build.gradle.kts b/analysis/low-level-api-fir/build.gradle.kts index 73591e381a1..eb81e3f0e51 100644 --- a/analysis/low-level-api-fir/build.gradle.kts +++ b/analysis/low-level-api-fir/build.gradle.kts @@ -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")) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt index 03f776622de..a953a045ae9 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt @@ -431,6 +431,7 @@ private fun List.extractLibraryPaths(): List = asSequence() .filterIsInstance() .flatMap { it.getBinaryRoots() } + .map { it.toAbsolutePath() } .toList() @Deprecated( diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedTypeResolverTransformer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedTypeResolverTransformer.kt index ea060717ea8..00ee89a26e4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedTypeResolverTransformer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirDesignatedTypeResolverTransformer.kt @@ -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}") } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformer.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformer.kt index c20dd22eac3..2bbb85d8ab2 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformer.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirLazyTransformer.kt @@ -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) diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTestForFir.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTestForFir.kt index 4d6be88372e..96f33538055 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTestForFir.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTestForFir.kt @@ -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 { ExecutionListenerBasedDisposableProvider() } useAdditionalService { 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() + .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) } } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt similarity index 55% rename from analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt rename to analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt index de0f116ec5f..e52e2d548f0 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt @@ -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() ktFiles.forEach { ktFile -> - val ktModule = projectStructureProvider.getKtModuleForKtElement(ktFile) + val ktModule = ktModuleProvider.getKtModuleForKtElement(ktFile) val resolveState = ktModule.getResolveState(project) allFirFiles.add(ktFile.getOrBuildFirFile(resolveState)) } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt deleted file mode 100644 index 9a3916ea733..00000000000 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt +++ /dev/null @@ -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, - 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)) -} diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt new file mode 100644 index 00000000000..3860f7ca12f --- /dev/null +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/LLFirSealedClassInheritorsProcessorFactoryForTests.kt @@ -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 + } +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt new file mode 100644 index 00000000000..0536bc08ec3 --- /dev/null +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/services/PackagePartProviderTestImpl.kt @@ -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 { + return providers.flatMapTo(mutableSetOf()) { it.findPackageParts(packageFqName) }.toList() + } + + override fun getAnnotationsOnBinaryModule(moduleName: String): List { + return providers.flatMapTo(mutableSetOf()) { it.getAnnotationsOnBinaryModule(moduleName) }.toList() + } + + override fun getAllOptionalAnnotationClasses(): List { + return providers.flatMapTo(mutableSetOf()) { it.getAllOptionalAnnotationClasses() }.toList() + } + + } + } +} diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleFileTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleFileTest.kt index ed5bb2f0747..0b302b74b2f 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleFileTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleFileTest.kt @@ -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, 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().single() + doTestByFileStructure(singleFile, moduleStructure, testServices) } abstract fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleModuleTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleModuleTest.kt index 6d5086d2f79..162495f58f3 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleModuleTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiSingleModuleTest.kt @@ -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 diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt new file mode 100644 index 00000000000..1305f88f4ef --- /dev/null +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AnalysisApiFirTestServiceRegistrar.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelAnalysisApiTestConfigurator.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelAnalysisApiTestConfigurator.kt new file mode 100644 index 00000000000..c7798b4bedb --- /dev/null +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelAnalysisApiTestConfigurator.kt @@ -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 = listOf( + AnalysisApiBaseTestServiceRegistrar, + AnalysisApiFirTestServiceRegistrar, + ) + + override fun createModules( + moduleStructure: TestModuleStructure, + testServices: TestServices, + project: Project + ): List { + return moduleStructure.toKtSourceModules(testServices, project) + } + + override fun doOutOfBlockModification(file: KtFile) { + ServiceManager.getService(file.project, KotlinModificationTrackerFactory::class.java) + .incrementModificationsCount() + } +} diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesFacadeTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesFacadeTest.kt index 7f2d034b775..67259724e8f 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesFacadeTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesFacadeTest.kt @@ -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 diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesLoadingTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesLoadingTest.kt index 4896c452421..cfd5106f768 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesLoadingTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesLoadingTest.kt @@ -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 diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTest.kt index fd0071c4ad0..7116a1051da 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTest.kt @@ -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 diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt index 22fe9a40a4b..91735330676 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt @@ -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) diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesFacadeForLibraryTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesFacadeForLibraryTest.kt index 935134772b8..76cfdca8865 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesFacadeForLibraryTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesFacadeForLibraryTest.kt @@ -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 ) \ No newline at end of file diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesForLibraryTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesForLibraryTest.kt index 13e98dbcd92..ef79355258a 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesForLibraryTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesForLibraryTest.kt @@ -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 ) \ No newline at end of file diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesLoadingForLibraryTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesLoadingForLibraryTest.kt index 8b6899e2057..e2b10ce0a25 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesLoadingForLibraryTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/AbstractSymbolLightClassesLoadingForLibraryTest.kt @@ -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 ) diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestConfigurator.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestConfigurator.kt new file mode 100644 index 00000000000..e2320fe1415 --- /dev/null +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestConfigurator.kt @@ -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 + get() = AnalysisApiFirLibraryBinaryTestConfigurator.serviceRegistrars + + AnalysisApiSymbolLightClassesDecompiledTestServiceRegistrar + + override fun doOutOfBlockModification(file: KtFile) { + AnalysisApiFirLibraryBinaryTestConfigurator.doOutOfBlockModification(file) + } + + override fun createModules( + moduleStructure: TestModuleStructure, + testServices: TestServices, + project: Project + ): List { + return AnalysisApiFirLibraryBinaryTestConfigurator.createModules(moduleStructure, testServices, project) + } +} \ No newline at end of file diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestServiceRegistrar.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestServiceRegistrar.kt new file mode 100644 index 00000000000..937ad796e5e --- /dev/null +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/decompiled/test/configurators/AnalysisApiSymbolLightClassesDecompiledTestServiceRegistrar.kt @@ -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) { + + } +} \ No newline at end of file diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesFacadeForSourceTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesFacadeForSourceTest.kt index e0f3e83a346..ec340619fb4 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesFacadeForSourceTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesFacadeForSourceTest.kt @@ -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 ) \ No newline at end of file diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesForSourceTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesForSourceTest.kt index e5f186bce93..74d65e6952b 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesForSourceTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesForSourceTest.kt @@ -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 ) \ No newline at end of file diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesLoadingForSourceTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesLoadingForSourceTest.kt index 3d47f23f579..f95b9ae4e85 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesLoadingForSourceTest.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesLoadingForSourceTest.kt @@ -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 ) \ No newline at end of file diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt index 60101a42701..ac366d9ec90 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt @@ -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 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 + override val configurators: List ) : CompilerConfigurationProvider(testServices) { private val cache: MutableMap = 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): 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 CompilerConfiguration.set(key: CompilerConfigurationKey, value: T) { - put(key, value) - } + configurators.forEach { it.configureCompileConfigurationWithAdditionalConfigurationKeys(configuration, module) } + + return configuration +} + +private operator fun CompilerConfiguration.set(key: CompilerConfigurationKey, value: T) { + put(key, value) } val TestModule.javaFiles: List diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt index b345e83c697..abc28822d54 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt @@ -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 -> { diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiConfiguratorFactoryProvider.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiConfiguratorFactoryProvider.kt index 47a02a02825..42bd4bba1e9 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiConfiguratorFactoryProvider.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiConfiguratorFactoryProvider.kt @@ -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( diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt index 99f775130d8..945f0b5c6e1 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt @@ -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 diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/FrontendConfiguratorTestGenerator.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/FrontendConfiguratorTestGenerator.kt index 22d0d9b5bc0..91366c501cf 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/FrontendConfiguratorTestGenerator.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/FrontendConfiguratorTestGenerator.kt @@ -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 diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/TestFilter.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/TestFilter.kt index 1412b6b8f03..4b64926ab5a 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/TestFilter.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/TestFilter.kt @@ -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 diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/dsl.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/dsl.kt index 63be02fc03f..15941658b65 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/dsl.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/dsl.kt @@ -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, diff --git a/settings.gradle b/settings.gradle index 354fda5d29d..9b89815f5f0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -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",