From 2649788b87fb0ecdd76c590c643d91285491aec1 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 7 Apr 2022 08:09:00 +0200 Subject: [PATCH] [analysis api fir] put every library into a separate KtModule in tests --- .../AnalysisApiFe10TestConfigurator.kt | 5 +- analysis/analysis-api-fir/build.gradle.kts | 3 - .../AnalysisApiFirTestConfiguratorFactory.kt | 2 +- ...ysisApiFirLibraryBinaryTestConfigurator.kt | 38 ++- ...ysisApiFirLibrarySourceTestConfigurator.kt | 95 +++---- ...nalysisApiLibrarySourceTestConfigurator.kt | 108 -------- .../AnalysisApiFirSourceTestConfigurator.kt | 43 --- .../AnalysisApiBaseTestServiceRegistrar.kt | 2 +- .../project/structure/KtModuleWithFiles.kt | 14 + .../structure/KtStaticModuleProvider.kt | 18 +- .../structure/StandaloneProjectFactory.kt | 12 +- ...KtModuleProviderByCompilerConfiguration.kt | 4 + .../fir/test/StandaloneModeConfigurator.kt | 4 +- .../kotlin/analysis/utils/errors/checks.kt | 25 ++ .../analysis-test-framework/build.gradle.kts | 1 + .../base/AbstractAnalysisApiBasedTest.kt | 5 +- .../AnalysisApiKtModuleProviderImpl.kt | 17 +- ... KtSourceModuleByCompilerConfiguration.kt} | 14 +- .../project/structure/KtSourceModuleImpl.kt | 83 ++++++ .../structure/TestModuleStructureFactory.kt | 249 ++++++++++++++++++ .../structure/projectStructureUtils.kt | 56 ---- .../services/AnalysisApiEnvironmentManager.kt | 2 +- ...ysisApiTestCompilerConfiguratorProvider.kt | 2 +- .../AnalysisApiTestConfigurator.kt | 4 +- analysis/low-level-api-fir/build.gradle.kts | 5 + .../api/fir/sessions/LLFirSessionFactory.kt | 9 +- .../sessions/LLFirSessionProviderStorage.kt | 9 +- .../based/AbstractCompilerBasedTestForFir.kt | 11 +- ...sInheritorsCaclulatorPreAnalysisHandler.kt | 5 +- .../AbstractLowLevelApiSingleModuleTest.kt | 3 +- ...irLowLevelCompilerBasedTestConfigurator.kt | 83 ++++++ .../test/base/compilerPluginConfiguration.kt | 66 +++++ .../AnalysisApiFirSourceTestConfigurator.kt} | 29 +- .../structure/ProjectStructureProvider.kt | 2 +- .../project/structure/ktModuleUtils.kt | 20 +- ...lLightClassesDecompiledTestConfigurator.kt | 4 +- ...ctSymbolLightClassesFacadeForSourceTest.kt | 2 +- ...AbstractSymbolLightClassesForSourceTest.kt | 2 +- ...tSymbolLightClassesLoadingForSourceTest.kt | 2 +- .../fir/deserialization/ModuleDataProvider.kt | 9 + .../AbstractEnvironmentConfigurator.kt | 6 + .../kotlin/test/impl/TestConfigurationImpl.kt | 1 + .../JvmEnvironmentConfigurator.kt | 103 ++++---- 43 files changed, 778 insertions(+), 399 deletions(-) delete mode 100644 analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiLibrarySourceTestConfigurator.kt delete mode 100644 analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/source/AnalysisApiFirSourceTestConfigurator.kt create mode 100644 analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/checks.kt rename analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/{TestKtSourceModule.kt => KtSourceModuleByCompilerConfiguration.kt} (92%) create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleImpl.kt create mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt delete mode 100644 analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/projectStructureUtils.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelCompilerBasedTestConfigurator.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/compilerPluginConfiguration.kt rename analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/{base/FirLowLevelAnalysisApiTestConfigurator.kt => configurators/AnalysisApiFirSourceTestConfigurator.kt} (66%) 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 index 316bf077a8f..ae343dfc784 100644 --- 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 @@ -9,8 +9,7 @@ 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.api.standalone.base.project.structure.KtModuleProjectStructure 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 @@ -42,7 +41,7 @@ object AnalysisApiFe10TestConfigurator : AnalysisApiTestConfigurator() { moduleStructure: TestModuleStructure, testServices: TestServices, project: Project, - ): List { + ): KtModuleProjectStructure { return moduleStructure.toKtSourceModules(testServices, project) } diff --git a/analysis/analysis-api-fir/build.gradle.kts b/analysis/analysis-api-fir/build.gradle.kts index 1a9e6f7c000..bdd5229d3a8 100644 --- a/analysis/analysis-api-fir/build.gradle.kts +++ b/analysis/analysis-api-fir/build.gradle.kts @@ -39,9 +39,6 @@ dependencies { testApiJUnit5() testApi(project(":analysis:symbol-light-classes")) - // We use 'api' instead of 'implementation' because other modules might be using these jars indirectly - testApi(project(":plugins:fir-plugin-prototype")) - testApi(projectTests(":plugins:fir-plugin-prototype")) } sourceSets { diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/AnalysisApiFirTestConfiguratorFactory.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/AnalysisApiFirTestConfiguratorFactory.kt index 4f851945b15..346f575c26d 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/AnalysisApiFirTestConfiguratorFactory.kt +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/AnalysisApiFirTestConfiguratorFactory.kt @@ -6,8 +6,8 @@ package org.jetbrains.kotlin.analysis.api.fir.test.configurators 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.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator import org.jetbrains.kotlin.analysis.test.framework.test.configurators.* object AnalysisApiFirTestConfiguratorFactory : AnalysisApiTestConfiguratorFactory() { 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 index 1c89d208139..fa4dc6b4cbb 100644 --- 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 @@ -7,23 +7,24 @@ 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 com.intellij.psi.search.GlobalSearchScope 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.KtModuleProjectStructure 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.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator +import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtLibraryModuleImpl +import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider import org.jetbrains.kotlin.analysis.test.framework.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.model.TestModule 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 @@ -38,17 +39,28 @@ object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator 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) + ): KtModuleProjectStructure { + return TestModuleStructureFactory.createProjectStructureByTestStructure( + moduleStructure, + testServices, + project + ) { testModule: TestModule, _, _ -> + val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).jar + val decompiledFiles = LibraryUtils.getAllPsiFilesFromTheJar(library, project) - return listOf( KtModuleWithFiles( - TestKtLibraryModule(project, testModule, decompiledFiles, listOf(library), testServices), - decompiledFiles, + KtLibraryModuleImpl( + testModule.name, + testModule.targetPlatform, + GlobalSearchScope.filesScope(project, decompiledFiles.mapTo(mutableSetOf()) { it.virtualFile }), + project, + binaryRoots = listOf(library), + librarySources = null, + isBuitinsContainingStdlib = false, + ), + decompiledFiles ) - ) + } } diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt index 3fd5b7c61da..d52f7d44e38 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt @@ -8,30 +8,27 @@ 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.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.KtModuleProjectStructure 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.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.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator +import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtLibraryModuleImpl +import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtLibrarySourceModuleImpl +import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider import org.jetbrains.kotlin.analysis.test.framework.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.ServiceRegistrationData import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestServices -import java.nio.file.Path object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator() { override val analyseInDependentSession: Boolean get() = false @@ -40,34 +37,49 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator builder: TestConfigurationBuilder, disposable: Disposable ) { - builder.useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider)) + builder.apply { + useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider)) + usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler) + } } override fun createModules( moduleStructure: TestModuleStructure, testServices: TestServices, project: Project - ): List { - val testModule = moduleStructure.modules.single() - val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.compileToLibrary(testModule) - - val libraryKtModule = KtTestLibraryModule(project, testModule, libraryJar) - - val librarySourceFiles = LibraryUtils - .getAllPsiFilesFromTheJar(librarySourcesJar, project) - - val sourcesKtModule = TestKtLibrarySourceModule( - project, - testModule, - librarySourceFiles, + ): KtModuleProjectStructure { + return TestModuleStructureFactory.createProjectStructureByTestStructure( + moduleStructure, testServices, - libraryKtModule - ) - libraryKtModule.librarySources = sourcesKtModule + project + ) { testModule: TestModule, _, _ -> + val (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.compileToLibrary(testModule) - return listOf( - KtModuleWithFiles(sourcesKtModule, librarySourceFiles), - ) + val libraryKtModule = KtLibraryModuleImpl( + testModule.name, + testModule.targetPlatform, + GlobalSearchScope.filesScope(project, LibraryUtils.getAllVirtualFilesFromJar(libraryJar)), + project, + binaryRoots = listOf(libraryJar), + librarySources = null, + isBuitinsContainingStdlib = false, + ) + + val decompiledPsiFilesFromSourceJar = LibraryUtils.getAllPsiFilesFromTheJar(librarySourcesJar, project) + val librarySourceKtModule = KtLibrarySourceModuleImpl( + testModule.name, + testModule.targetPlatform, + GlobalSearchScope.filesScope(project, decompiledPsiFilesFromSourceJar.map { it.virtualFile }), + project, + binaryLibrary = libraryKtModule, + ) + libraryKtModule.librarySources = librarySourceKtModule + + KtModuleWithFiles( + librarySourceKtModule, + decompiledPsiFilesFromSourceJar + ) + } } override val serviceRegistrars: List = @@ -81,27 +93,4 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator override fun doOutOfBlockModification(file: KtFile) { AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file) } -} - -private class KtTestLibraryModule( - override val project: Project, - private val testModule: TestModule, - private val jar: Path -) : KtLibraryModule { - override val directRegularDependencies: List get() = emptyList() - override val directRefinementDependencies: List get() = emptyList() - override val directFriendDependencies: List get() = emptyList() - - override val contentScope: GlobalSearchScope by lazy { - GlobalSearchScope.filesScope(project, LibraryUtils.getAllVirtualFilesFromJar(jar)) - } - - override fun getBinaryRoots(): Collection = listOf(jar) - override val libraryName: String get() = testModule.name - - override lateinit var librarySources: KtLibrarySourceModule - - override val platform: TargetPlatform get() = testModule.targetPlatform - override val analyzerServices: PlatformDependentAnalyzerServices get() = testModule.targetPlatform.getAnalyzerServices() -} - +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiLibrarySourceTestConfigurator.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiLibrarySourceTestConfigurator.kt deleted file mode 100644 index 71a2368da2a..00000000000 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiLibrarySourceTestConfigurator.kt +++ /dev/null @@ -1,108 +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.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.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.ServiceRegistrationData -import org.jetbrains.kotlin.test.services.TestModuleStructure -import org.jetbrains.kotlin.test.services.TestServices -import java.nio.file.Path - -object AnalysisApiLibrarySourceTestConfigurator : AnalysisApiTestConfigurator() { - override val analyseInDependentSession: Boolean get() = false - - 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 (libraryJar, librarySourcesJar) = testServices.compiledLibraryProvider.compileToLibrary(testModule) - - val libraryKtModule = KtTestLibraryModule(project, testModule, libraryJar) - - val librarySourceFiles = LibraryUtils - .getAllPsiFilesFromTheJar(librarySourcesJar, project) - - val sourcesKtModule = TestKtLibrarySourceModule( - project, - testModule, - librarySourceFiles, - testServices, - libraryKtModule - ) - libraryKtModule.librarySources = sourcesKtModule - - return listOf( - KtModuleWithFiles(sourcesKtModule, librarySourceFiles), - ) - } - - override val serviceRegistrars: List = - listOf( - AnalysisApiBaseTestServiceRegistrar, - AnalysisApiFirTestServiceRegistrar, - AnalysisApiLibraryBaseTestServiceRegistrar, - ) - - - override fun doOutOfBlockModification(file: KtFile) { - AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file) - } -} - -private class KtTestLibraryModule( - override val project: Project, - private val testModule: TestModule, - private val jar: Path -) : KtLibraryModule { - override val directRegularDependencies: List get() = emptyList() - override val directRefinementDependencies: List get() = emptyList() - override val directFriendDependencies: List get() = emptyList() - - override val contentScope: GlobalSearchScope by lazy { - GlobalSearchScope.filesScope(project, LibraryUtils.getAllVirtualFilesFromJar(jar)) - } - - override fun getBinaryRoots(): Collection = listOf(jar) - override val libraryName: String get() = testModule.name - - override lateinit var librarySources: KtLibrarySourceModule - - 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 deleted file mode 100644 index cc576b5ab16..00000000000 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/source/AnalysisApiFirSourceTestConfigurator.kt +++ /dev/null @@ -1,43 +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.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-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 index 9f3a542a2a9..4f52546d82c 100644 --- 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 @@ -29,7 +29,7 @@ object AnalysisApiBaseTestServiceRegistrar: AnalysisApiTestServiceRegistrar() { } override fun registerProjectServices(project: MockProject, testServices: TestServices) { - val allKtFiles = testServices.ktModuleProvider.getAllModules().flatMap { it.files.filterIsInstance() } + val allKtFiles = testServices.ktModuleProvider.getModuleStructure().mainModules.flatMap { it.files.filterIsInstance() } project.apply { registerService(KotlinModificationTrackerFactory::class.java, KotlinStaticModificationTrackerFactory::class.java) 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 index ef5ec3d9a78..d56e522043a 100644 --- 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 @@ -6,8 +6,22 @@ package org.jetbrains.kotlin.analysis.api.standalone.base.project.structure import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule +import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule import org.jetbrains.kotlin.analysis.project.structure.KtModule + +data class KtModuleProjectStructure( + val mainModules: List, + val binaryModules: Iterable, + val stdlibFor: (KtModule) -> KtLibraryModule, +) { + fun allKtModules(): List = buildList { + mainModules.mapTo(this) { it.ktModule } + addAll(binaryModules) + } +} + data class KtModuleWithFiles( val ktModule: KtModule, val files: List 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 index 084ed974ce8..aeb834d025f 100644 --- 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 @@ -10,20 +10,20 @@ import org.jetbrains.kotlin.analysis.project.structure.* import org.jetbrains.kotlin.psi.psiUtil.contains class KtStaticModuleProvider( - private val modules: List, - private val stdlibs: Set + private val testProjectStructure: KtModuleProjectStructure, ) : ProjectStructureProvider() { override fun getKtModuleForKtElement(element: PsiElement): KtModule { - return modules.first { module -> - module.contentScope.contains(element) - } + return testProjectStructure.mainModules + .first { module -> + module.ktModule.contentScope.contains(element) + }.ktModule } override fun getKtLibraryModules(): Collection { - return modules.filterIsInstance() + return testProjectStructure.allKtModules().filterIsInstance() } - override fun getStdlibModule(module: KtModule): KtLibraryModule? { - return module.allDirectDependenciesOfType().firstOrNull { it in stdlibs } + override fun getStdlibWithBuiltinsModule(module: KtModule): KtLibraryModule { + return testProjectStructure.stdlibFor(module) } -} +} \ 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/StandaloneProjectFactory.kt b/analysis/analysis-api-standalone/analysis-api-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/StandaloneProjectFactory.kt index b4b3d2d4fee..c4021bb7b1c 100644 --- 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 @@ -46,7 +46,7 @@ object StandaloneProjectFactory { fun registerServicesForProjectEnvironment( environment: KotlinCoreProjectEnvironment, - modules: List, + modules: KtModuleProjectStructure, languageVersionSettings: LanguageVersionSettings, jdkHome: Path?, ) { @@ -55,7 +55,7 @@ object StandaloneProjectFactory { KotlinCoreEnvironment.registerProjectExtensionPoints(project.extensionArea) KotlinCoreEnvironment.registerProjectServices(project) - project.registerService(ProjectStructureProvider::class.java, KtStaticModuleProvider(modules.map { it.ktModule }, emptySet())) + project.registerService(ProjectStructureProvider::class.java, KtStaticModuleProvider(modules)) initialiseVirtualFinderFinderServices(modules, environment, jdkHome, languageVersionSettings) initialiseAnnotationServices(project) @@ -68,7 +68,7 @@ object StandaloneProjectFactory { } private fun initialiseVirtualFinderFinderServices( - modules: List, + modules: KtModuleProjectStructure, environment: KotlinCoreProjectEnvironment, jdkHome: Path?, languageVersionSettings: LanguageVersionSettings @@ -76,12 +76,12 @@ object StandaloneProjectFactory { val project = environment.project val allSourceFiles = buildList { - val files = modules.flatMap { it.files } + val files = modules.mainModules.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) + val libraryRoots = getAllBinaryRoots(modules.allKtModules(), environment) libraryRoots.forEach { environment.addSourcesToClasspath(it.file) } val sourceAndLibraryRoots = buildList { @@ -133,7 +133,7 @@ object StandaloneProjectFactory { modules: List, environment: KotlinCoreProjectEnvironment ): List = withAllTransitiveDependencies(modules) - .filterIsInstance() + .filterIsInstance() .flatMap { it.getBinaryRoots() } .map { val jar = environment.environment.jarFileSystem.findFileByPath(it.toAbsolutePath().toString() + "!/")!! diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderByCompilerConfiguration.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderByCompilerConfiguration.kt index c670a592568..00a34bc85ad 100644 --- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderByCompilerConfiguration.kt +++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleProviderByCompilerConfiguration.kt @@ -39,4 +39,8 @@ internal class KtModuleProviderByCompilerConfiguration( override fun getKtLibraryModules(): Collection { return libraryModules } + + override fun getStdlibWithBuiltinsModule(module: KtModule): KtLibraryModule? { + TODO("Not yet implemented") + } } diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt index 06155bec5fe..bbeed343407 100644 --- a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt @@ -7,8 +7,8 @@ package org.jetbrains.kotlin.analysis.api.standalone.fir.test 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.api.standalone.base.project.structure.KtModuleProjectStructure +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator 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 diff --git a/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/checks.kt b/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/checks.kt new file mode 100644 index 00000000000..c1c404e8413 --- /dev/null +++ b/analysis/analysis-internal-utils/src/org/jetbrains/kotlin/analysis/utils/errors/checks.kt @@ -0,0 +1,25 @@ +/* + * 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.utils.errors + +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract + +@OptIn(ExperimentalContracts::class) +public inline fun requireIsInstance(obj: Any) { + contract { + returns() implies (obj is T) + } + require(obj is T) { "Expected ${T::class} instead of ${obj::class} for $obj" } +} + +@OptIn(ExperimentalContracts::class) +public inline fun checkIsInstance(obj: Any) { + contract { + returns() implies (obj is T) + } + check(obj is T) { "Expected ${T::class} instead of ${obj::class} for $obj" } +} \ No newline at end of file diff --git a/analysis/analysis-test-framework/build.gradle.kts b/analysis/analysis-test-framework/build.gradle.kts index 6ad673959d9..45dd3b408ec 100644 --- a/analysis/analysis-test-framework/build.gradle.kts +++ b/analysis/analysis-test-framework/build.gradle.kts @@ -9,6 +9,7 @@ dependencies { testApiJUnit5() testApi(project(":kotlin-test:kotlin-test-junit")) + testImplementation(project(":analysis:analysis-internal-utils")) testApi(project(":compiler:psi")) testApi(project(":analysis:kt-references")) testApi(projectTests(":compiler:tests-common-new")) 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 dd14194dcf8..45bfbcf2548 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 @@ -104,10 +104,7 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() { targetPlatform = JvmPlatforms.defaultJvmPlatform dependencyKind = DependencyKind.Source } - useConfigurators( - ::CommonEnvironmentConfigurator, - ::JvmEnvironmentConfigurator, - ) + assertions = JUnit5Assertions useAdditionalService(::TemporaryDirectoryManagerImpl) 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 index 37454c78390..e1f4373d92c 100644 --- 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 @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.analysis.test.framework.project.structure import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure 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 @@ -18,17 +19,17 @@ abstract class AnalysisApiKtModuleProvider : TestService { abstract fun getModuleFiles(module: TestModule): List - abstract fun registerProjectStructure(modules: List) + abstract fun registerProjectStructure(modules: KtModuleProjectStructure) protected abstract fun getModuleName(ktModule: KtModule): String - abstract fun getAllModules(): List + abstract fun getModuleStructure(): KtModuleProjectStructure } class AnalysisApiKtModuleProviderImpl( override val testServices: TestServices, ) : AnalysisApiKtModuleProvider() { - private lateinit var modules: List + private lateinit var modulesStructure: KtModuleProjectStructure private lateinit var modulesByName: Map override fun getModule(moduleName: String): KtModule { @@ -37,12 +38,12 @@ class AnalysisApiKtModuleProviderImpl( override fun getModuleFiles(module: TestModule): List = modulesByName.getValue(module.name).files - override fun registerProjectStructure(modules: List) { - require(!this::modules.isInitialized) + override fun registerProjectStructure(modules: KtModuleProjectStructure) { + require(!this::modulesStructure.isInitialized) require(!this::modulesByName.isInitialized) - this.modules = modules - this.modulesByName = modules.associateBy { getModuleName(it.ktModule) } + this.modulesStructure = modules + this.modulesByName = modulesStructure.mainModules.associateBy { getModuleName(it.ktModule) } } override fun getModuleName(ktModule: KtModule): String = when (ktModule) { @@ -54,7 +55,7 @@ class AnalysisApiKtModuleProviderImpl( } - override fun getAllModules(): List = modules + override fun getModuleStructure(): KtModuleProjectStructure = modulesStructure } val TestServices.ktModuleProvider: AnalysisApiKtModuleProvider 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/KtSourceModuleByCompilerConfiguration.kt similarity index 92% rename from analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestKtSourceModule.kt rename to analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleByCompilerConfiguration.kt index 101b59e743f..08f8cf247c2 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/KtSourceModuleByCompilerConfiguration.kt @@ -31,7 +31,7 @@ import java.nio.file.Path import java.nio.file.Paths @OptIn(ExperimentalStdlibApi::class) -abstract class TestKtModule( +abstract class KtModuleByCompilerConfiguration( val project: Project, val testModule: TestModule, val psiFiles: List, @@ -91,25 +91,25 @@ abstract class TestKtModule( get() = testModule.targetPlatform.getAnalyzerServices() } -class TestKtSourceModule( +class KtSourceModuleByCompilerConfiguration( project: Project, testModule: TestModule, psiFiles: List, testServices: TestServices -) : TestKtModule(project, testModule, psiFiles, testServices), KtSourceModule { +) : KtModuleByCompilerConfiguration(project, testModule, psiFiles, testServices), KtSourceModule { override val ktModule: KtModule get() = this override val contentScope: GlobalSearchScope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, psiFiles.filterIsInstance()) } -class TestKtLibraryModule( +class KtLibraryModuleByCompilerConfiguration( project: Project, testModule: TestModule, psiFiles: List, private val binaryRoots: List, testServices: TestServices -) : TestKtModule(project, testModule, psiFiles, testServices), KtLibraryModule { +) : KtModuleByCompilerConfiguration(project, testModule, psiFiles, testServices), KtLibraryModule { override val ktModule: KtModule get() = this override val libraryName: String get() = testModule.name override val librarySources: KtLibrarySourceModule? get() = null @@ -120,13 +120,13 @@ class TestKtLibraryModule( GlobalSearchScope.filesScope(project, psiFiles.map { it.virtualFile }) } -class TestKtLibrarySourceModule( +class KtLibrarySourceModuleByCompilerConfiguration( project: Project, testModule: TestModule, psiFiles: List, testServices: TestServices, override val binaryLibrary: KtLibraryModule, -) : TestKtModule(project, testModule, psiFiles, testServices), KtLibrarySourceModule { +) : KtModuleByCompilerConfiguration(project, testModule, psiFiles, testServices), KtLibrarySourceModule { override val ktModule: KtModule get() = this override val contentScope: GlobalSearchScope get() = GlobalSearchScope.filesScope(project, psiFiles.map { it.virtualFile }) diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleImpl.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleImpl.kt new file mode 100644 index 00000000000..1ca49207e16 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleImpl.kt @@ -0,0 +1,83 @@ +/* + * 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.openapi.project.Project +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.analysis.project.structure.* +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices +import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices +import java.nio.file.Path + +interface KtModuleWithModifiableDependencies { + val directRegularDependencies: MutableList + val directRefinementDependencies: MutableList + val directFriendDependencies: MutableList +} + +class KtSourceModuleImpl( + override val moduleName: String, + override val platform: TargetPlatform, + override val languageVersionSettings: LanguageVersionSettings, + override val project: Project, + override val contentScope: GlobalSearchScope, +) : KtSourceModule, KtModuleWithModifiableDependencies { + override val analyzerServices: PlatformDependentAnalyzerServices get() = platform.getAnalyzerServices() + + override val directRegularDependencies: MutableList = mutableListOf() + override val directRefinementDependencies: MutableList = mutableListOf() + override val directFriendDependencies: MutableList = mutableListOf() +} + +class KtJdkModuleImpl( + override val sdkName: String, + override val platform: TargetPlatform, + override val contentScope: GlobalSearchScope, + override val project: Project, + private val binaryRoots: Collection, +) : KtSdkModule, KtModuleWithModifiableDependencies { + override val analyzerServices: PlatformDependentAnalyzerServices + get() = platform.getAnalyzerServices() + + override fun getBinaryRoots(): Collection = binaryRoots + + override val directRegularDependencies: MutableList = mutableListOf() + override val directRefinementDependencies: MutableList = mutableListOf() + override val directFriendDependencies: MutableList = mutableListOf() +} + +class KtLibraryModuleImpl( + override val libraryName: String, + override val platform: TargetPlatform, + override val contentScope: GlobalSearchScope, + override val project: Project, + private val binaryRoots: Collection, + override var librarySources: KtLibrarySourceModule?, + val isBuitinsContainingStdlib: Boolean, +) : KtLibraryModule, KtModuleWithModifiableDependencies { + override val analyzerServices: PlatformDependentAnalyzerServices get() = platform.getAnalyzerServices() + override fun getBinaryRoots(): Collection = binaryRoots + + override val directRegularDependencies: MutableList = mutableListOf() + override val directRefinementDependencies: MutableList = mutableListOf() + override val directFriendDependencies: MutableList = mutableListOf() +} + +class KtLibrarySourceModuleImpl( + override val libraryName: String, + override val platform: TargetPlatform, + override val contentScope: GlobalSearchScope, + override val project: Project, + override val binaryLibrary: KtLibraryModule, +) : KtLibrarySourceModule, KtModuleWithModifiableDependencies { + override val analyzerServices: PlatformDependentAnalyzerServices get() = platform.getAnalyzerServices() + + override val directRegularDependencies: MutableList = mutableListOf() + override val directRefinementDependencies: MutableList = mutableListOf() + override val directFriendDependencies: MutableList = mutableListOf() +} \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt new file mode 100644 index 00000000000..d671cc54498 --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt @@ -0,0 +1,249 @@ +/* + * 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.openapi.project.Project +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiManager +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.search.ProjectScope +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure +import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule +import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.allDirectDependenciesOfType +import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager +import org.jetbrains.kotlin.analysis.utils.errors.checkIsInstance +import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.test.TestInfrastructureInternals +import org.jetbrains.kotlin.test.model.DependencyRelation +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.* +import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator +import org.jetbrains.kotlin.test.util.KtTestUtil +import org.jetbrains.kotlin.utils.KotlinPaths +import org.jetbrains.kotlin.utils.PathUtil +import org.jetbrains.kotlin.utils.addIfNotNull +import java.nio.file.Path +import kotlin.io.path.exists +import kotlin.io.path.extension +import kotlin.io.path.nameWithoutExtension + +fun interface KtMainModuleFactory { + fun createMainModule( + testModule: TestModule, + testServices: TestServices, + project: Project, + ): KtModuleWithFiles +} + +object KtMainModuleFactoryForSourceModules : KtMainModuleFactory { + override fun createMainModule( + testModule: TestModule, + testServices: TestServices, + project: Project, + ): KtModuleWithFiles { + val psiFiles = TestModuleStructureFactory.createSourcePsiFiles(testModule, testServices, project) + return KtModuleWithFiles( + KtSourceModuleImpl( + testModule.name, + testModule.targetPlatform, + testModule.languageVersionSettings, + project, + GlobalSearchScope.filesScope(project, psiFiles.mapTo(mutableSetOf()) { it.virtualFile }), + ), + psiFiles + ) + } +} + +object TestModuleStructureFactory { + @OptIn(TestInfrastructureInternals::class) + fun createProjectStructureByTestStructure( + moduleStructure: TestModuleStructure, + testServices: TestServices, + project: Project, + mainModuleFactory: KtMainModuleFactory + ): KtModuleProjectStructure { + val modulesFromTestServices = moduleStructure.modules.map { testModule -> + testModule.toKtModule(testServices, project, mainModuleFactory) + } + val moduleByName = modulesFromTestServices.associateBy { getModuleName(it.ktModule) } + val binaryModulesBySourceRoots = mutableMapOf, KtBinaryModule>() + + moduleStructure.modules.forEach { testModule -> + val ktModule = moduleByName.getValue(testModule.name).ktModule + checkIsInstance(ktModule) + + addModuleDependencies(testModule, moduleByName, ktModule) + + buildList { + addIfNotNull(getJdkModule(testModule, project)) + addAll(getStdlibModules(testModule, project)) + addAll(getLibraryModules(testServices, testModule, project)) + addAll(createLibrariesByCompilerConfigurators(testModule, testServices, project)) + }.forEach { library -> + val cachedLibrary = binaryModulesBySourceRoots.getOrPut(library.getBinaryRoots().toSet()) { library } + ktModule.directRegularDependencies.add(cachedLibrary) + } + + } + return KtModuleProjectStructure(modulesFromTestServices, binaryModulesBySourceRoots.values) { module -> + module.allDirectDependenciesOfType().first { it.isBuitinsContainingStdlib } + } + } + + @OptIn(TestInfrastructureInternals::class) + private fun createLibrariesByCompilerConfigurators( + testModule: TestModule, + testServices: TestServices, + project: Project + ): List { + val compilerConfiguration = createCompilerConfiguration(testModule, testServices.environmentConfigurators) + val contentRoots = compilerConfiguration[CLIConfigurationKeys.CONTENT_ROOTS, emptyList()] + return contentRoots + .filterIsInstance() + .map { root -> createKtLibraryModuleByJar(root.file.toPath(), project, isBuitinsContainingStdlib = false) } + } + + + private fun getModuleName(ktModule: KtModule) = when (ktModule) { + is KtSourceModuleImpl -> ktModule.moduleName + is KtLibraryModuleImpl -> ktModule.libraryName + is KtLibrarySourceModuleImpl -> ktModule.libraryName + else -> error("Unknown module ${ktModule::class}") + } + + private fun addModuleDependencies( + testModule: TestModule, + moduleByName: Map, + ktModule: KtModule + ) { + requireIsInstance(ktModule) + testModule.allDependencies.forEach { dependency -> + val dependencyKtModule = moduleByName.getValue(dependency.moduleName).ktModule + when (dependency.relation) { + DependencyRelation.RegularDependency -> ktModule.directRegularDependencies.add(dependencyKtModule) + DependencyRelation.FriendDependency -> ktModule.directFriendDependencies.add(dependencyKtModule) + DependencyRelation.DependsOnDependency -> ktModule.directRefinementDependencies.add(dependencyKtModule) + } + } + } + + private fun getLibraryModules( + testServices: TestServices, + testModule: TestModule, + project: Project + ): List { + val configurationKind = JvmEnvironmentConfigurator.extractConfigurationKind(testModule.directives) + return JvmEnvironmentConfigurator + .getLibraryFilesExceptRealRuntime( testServices, configurationKind, testModule.directives) + .map { it.toPath().toAbsolutePath() } + .map { jar -> + createKtLibraryModuleByJar( + jar, + project, + isBuitinsContainingStdlib = jar.nameWithoutExtension == "kotlin-stdlib-jvm-minimal-for-test" + ) + } + } + + private fun createKtLibraryModuleByJar( + jar: Path, + project: Project, + libraryName: String = jar.nameWithoutExtension, + isBuitinsContainingStdlib: Boolean = false, + ): KtLibraryModuleImpl { + check(jar.extension == "jar") + check(jar.exists()) + return KtLibraryModuleImpl( + libraryName, + JvmPlatforms.defaultJvmPlatform, + ProjectScope.getLibrariesScope(project), + project, + listOf(jar), + librarySources = null, + isBuitinsContainingStdlib, + ) + } + + private fun getStdlibModules( + testModule: TestModule, + project: Project + ): List { + val configurationKind = JvmEnvironmentConfigurator.extractConfigurationKind(testModule.directives) + if (!configurationKind.withRuntime) return emptyList() + return listOf( + KotlinPaths.Jar.StdLib to PathUtil.KOTLIN_JAVA_STDLIB_NAME, + ).map { (jar, name) -> + val lib = PathUtil.kotlinPathsForDistDirectory.jar(jar).toPath().toAbsolutePath() + createKtLibraryModuleByJar(lib, project, name, isBuitinsContainingStdlib = jar == KotlinPaths.Jar.StdLib) + } + } + + private fun getJdkModule( + testModule: TestModule, + project: Project + ): KtJdkModuleImpl? { + val jdkKind = JvmEnvironmentConfigurator.extractJdkKind(testModule.directives) + + val jdkSourceRoots = buildList { + JvmEnvironmentConfigurator.getJdkHome(jdkKind)?.let { add(it.toPath()) } + JvmEnvironmentConfigurator.getJdkClasspathRoot(jdkKind)?.let { add(it.toPath()) } + }.mapTo(mutableListOf()) { it.toAbsolutePath() } + + if (jdkSourceRoots.isEmpty()) return null + + return KtJdkModuleImpl( + "jdk", + JvmPlatforms.defaultJvmPlatform, + ProjectScope.getLibrariesScope(project), + project, + jdkSourceRoots + ) + } + + private fun TestModule.toKtModule( + testServices: TestServices, + project: Project, + mainModuleFactory: KtMainModuleFactory, + ): KtModuleWithFiles { + return mainModuleFactory.createMainModule(this, testServices, project) + } + + fun createSourcePsiFiles( + testModule: TestModule, + testServices: TestServices, + project: Project + ): List { + return testModule.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}") + } + } + } + + +} + 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 deleted file mode 100644 index 52444c7f0ca..00000000000 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/projectStructureUtils.kt +++ /dev/null @@ -1,56 +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.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.* -import org.jetbrains.kotlin.test.util.KtTestUtil - -fun getKtFilesFromModule(testServices: TestServices, testModule: TestModule): List { - val moduleInfoProvider = testServices.ktModuleProvider - return when (val moduleInfo = moduleInfoProvider.getModule(testModule.name)) { - 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 index e9d1b96562f..fab982b0144 100644 --- 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 @@ -52,7 +52,7 @@ class AnalysisApiEnvironmentManagerImpl( } override fun initializeProjectStructure() { - val ktModules = testServices.ktModuleProvider.getAllModules() + val ktModules = testServices.ktModuleProvider.getModuleStructure() val useSiteModule = testServices.moduleStructure.modules.first() val useSiteCompilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(useSiteModule) 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 index 17f8090f480..d2c2cea3c73 100644 --- 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 @@ -29,7 +29,7 @@ class AnalysisApiTestCompilerConfiguratorProvider( private val allProjectBinaryRoots by lazy { StandaloneProjectFactory.getAllBinaryRoots( - testServices.ktModuleProvider.getAllModules().map { it.ktModule }, + testServices.ktModuleProvider.getModuleStructure().allKtModules(), testServices.environmentManager.getProjectEnvironment() ) } 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 index 6c60a61d5ef..8785e78ab2e 100644 --- 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 @@ -12,7 +12,7 @@ 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.analysis.api.standalone.base.project.structure.KtModuleProjectStructure import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.NotNullableUserDataProperty import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder @@ -40,7 +40,7 @@ abstract class AnalysisApiTestConfigurator { open fun preprocessTestDataPath(path: Path): Path = path - abstract fun createModules(moduleStructure: TestModuleStructure, testServices: TestServices, project: Project): List + abstract fun createModules(moduleStructure: TestModuleStructure, testServices: TestServices, project: Project): KtModuleProjectStructure fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) { serviceRegistrars.forEach { it.registerProjectExtensionPoints(project, testServices) } diff --git a/analysis/low-level-api-fir/build.gradle.kts b/analysis/low-level-api-fir/build.gradle.kts index eb81e3f0e51..e16fdaf7754 100644 --- a/analysis/low-level-api-fir/build.gradle.kts +++ b/analysis/low-level-api-fir/build.gradle.kts @@ -43,6 +43,11 @@ dependencies { testImplementation(project(":analysis:symbol-light-classes")) testRuntimeOnly(project(":core:descriptors.runtime")) + + + // We use 'api' instead of 'implementation' because other modules might be using these jars indirectly + testApi(project(":plugins:fir-plugin-prototype")) + testApi(projectTests(":plugins:fir-plugin-prototype")) } sourceSets { 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 0bea5289239..6eb5c7f4f8d 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 @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider +import org.jetbrains.kotlin.fir.deserialization.EmptyModuleDataProvider import org.jetbrains.kotlin.fir.deserialization.LibraryPathFilter import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider import org.jetbrains.kotlin.fir.deserialization.MultipleModuleDataProvider @@ -261,11 +262,17 @@ internal object LLFirSessionFactory { addAll(dependsOnDependenciesOnLibs) } + if (allDependencies.isEmpty()) { + return EmptyModuleDataProvider(sourceModule.platform, sourceModule.analyzerServices) + } + allDependencies.forEach { it.bindSession(session) } val moduleDataWithFilters: Map = allDependencies.associateWith { moduleData -> - LibraryPathFilter.LibraryList((moduleData.module as KtBinaryModule).getBinaryRoots().toSet()) + val ktBinaryModule = moduleData.module as KtBinaryModule + val moduleBinaryRoots = ktBinaryModule.getBinaryRoots().mapTo(mutableSetOf()) { it.toAbsolutePath() } + LibraryPathFilter.LibraryList(moduleBinaryRoots) } return MultipleModuleDataProvider(moduleDataWithFilters) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt index 40474d374fa..dac50fd8380 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt @@ -13,10 +13,7 @@ import kotlinx.collections.immutable.toPersistentMap import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor import org.jetbrains.kotlin.analysis.low.level.api.fir.util.executeWithoutPCE -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.project.structure.KtSourceModule +import org.jetbrains.kotlin.analysis.project.structure.* import org.jetbrains.kotlin.analysis.providers.createLibrariesModificationTracker import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker import org.jetbrains.kotlin.analysis.utils.caches.getValue @@ -38,7 +35,9 @@ class LLFirSessionProviderStorage(val project: Project) { val firPhaseRunner = LLFirPhaseRunner() val builtinTypes = BuiltinTypes() - val builtinsAndCloneableSession = LLFirSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes) + val stdlibModule = project.getService(ProjectStructureProvider::class.java).getStdlibWithBuiltinsModule(rootModule) + ?: error("Stdlib was not found for ${rootModule.moduleDescription}") + val builtinsAndCloneableSession = LLFirSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes, stdlibModule) val cache = sessionsCache.getOrPut(rootModule) { FromModuleViewSessionCache() } val (sessions, session) = cache.withMappings(project) { mappings -> val sessions = mutableMapOf().apply { putAll(mappings) } 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 2d11f821fda..33bc19b9dbc 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 @@ -9,11 +9,10 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based 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.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.KtSourceModuleByCompilerConfiguration import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.KtFile @@ -34,6 +33,7 @@ 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.* +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.FirLowLevelCompilerBasedTestConfigurator abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() { @OptIn(TestInfrastructureInternals::class) @@ -64,14 +64,14 @@ abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() { override fun analyze(module: TestModule): FirOutputArtifact { val moduleInfoProvider = testServices.ktModuleProvider - val moduleInfo = moduleInfoProvider.getModule(module.name) as TestKtSourceModule + val ktModule = moduleInfoProvider.getModule(module.name) as KtSourceModuleByCompilerConfiguration val project = testServices.compilerConfigurationProvider.getProject(module) - val resolveState = createResolveStateForNoCaching(moduleInfo, project) + val resolveState = createResolveStateForNoCaching(ktModule, project) val allFirFiles = module.files.filter { it.isKtFile }.zip( - moduleInfo.psiFiles + ktModule.psiFiles .filterIsInstance() .map { psiFile -> psiFile.getOrBuildFirFile(resolveState) } ) @@ -87,6 +87,7 @@ abstract class AbstractCompilerBasedTestForFir : AbstractCompilerBasedTest() { override fun runTest(filePath: String) { val configuration = testConfiguration(filePath, configuration) + if (ignoreTest(filePath, configuration)) { return } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt index e52e2d548f0..6071a3a783b 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/SealedClassesInheritorsCaclulatorPreAnalysisHandler.kt @@ -8,12 +8,13 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based 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.getKtFilesFromModule +import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider 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.psi.KtFile import org.jetbrains.kotlin.test.services.PreAnalysisHandler import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestServices @@ -28,7 +29,7 @@ class SealedClassesInheritorsCaclulatorPreAnalysisHandler( override fun prepareSealedClassInheritors(moduleStructure: TestModuleStructure) { val ktFilesByModule = moduleStructure.modules.associateWith { testModule -> - getKtFilesFromModule(testServices, testModule) + testServices.ktModuleProvider.getModuleFiles(testModule).filterIsInstance() } ktFilesByModule.forEach { (testModule, ktFiles) -> 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 162495f58f3..df5b9e5f535 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,10 +5,11 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.test.base +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest abstract class AbstractLowLevelApiSingleModuleTest : AbstractAnalysisApiBasedTest() { - override val configurator: AnalysisApiTestConfigurator get() = FirLowLevelAnalysisApiTestConfigurator + override val configurator: AnalysisApiTestConfigurator = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false) } \ 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/FirLowLevelCompilerBasedTestConfigurator.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelCompilerBasedTestConfigurator.kt new file mode 100644 index 00000000000..4ea5f095f4f --- /dev/null +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelCompilerBasedTestConfigurator.kt @@ -0,0 +1,83 @@ +/* + * 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 com.intellij.psi.search.ProjectScope +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.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 +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles +import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule +import org.jetbrains.kotlin.analysis.project.structure.allDirectDependenciesOfType +import org.jetbrains.kotlin.analysis.test.framework.base.registerAnalysisApiBaseTestServices +import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtLibraryModuleImpl +import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtSourceModuleByCompilerConfiguration +import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory +import org.jetbrains.kotlin.platform.TargetPlatform + +object FirLowLevelCompilerBasedTestConfigurator : AnalysisApiTestConfigurator() { + override val analyseInDependentSession: Boolean get() = false + + override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) { + builder.apply { + } + } + + override val serviceRegistrars: List = listOf( + AnalysisApiBaseTestServiceRegistrar, + AnalysisApiFirTestServiceRegistrar, + ) + + override fun createModules( + moduleStructure: TestModuleStructure, + testServices: TestServices, + project: Project + ): KtModuleProjectStructure { + val mainModules = moduleStructure.modules.map { testModule -> + val files = TestModuleStructureFactory.createSourcePsiFiles(testModule, testServices, project) + KtModuleWithFiles( + KtSourceModuleByCompilerConfiguration(project, testModule, files, testServices), + files + ) + } + return KtModuleProjectStructure( + mainModules = mainModules, + binaryModules = mainModules.asSequence().flatMap { it.ktModule.allDirectDependenciesOfType() }.asIterable(), + stdlibFor = { module -> + createFakeStdlibModule(module, project) + } + ) + } + + private fun createFakeStdlibModule( + module: KtModule, + project: Project + ): KtLibraryModule = KtLibraryModuleImpl( + libraryName = "fake-std-lib", + platform = module.platform, + contentScope = ProjectScope.getLibrariesScope(project), + project = project, + binaryRoots = emptyList(), + librarySources = null, + isBuitinsContainingStdlib = true + ) + + override fun doOutOfBlockModification(file: KtFile) { + error("Should not be called for compiler based tests") + } +} diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/compilerPluginConfiguration.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/compilerPluginConfiguration.kt new file mode 100644 index 00000000000..11f919df665 --- /dev/null +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/compilerPluginConfiguration.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.low.level.api.fir.test.base + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.config.AnalysisFlag +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.fir.plugin.services.ExtensionRegistrarConfigurator +import org.jetbrains.kotlin.fir.plugin.services.PluginAnnotationsProvider +import org.jetbrains.kotlin.test.Constructor +import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder +import org.jetbrains.kotlin.test.directives.model.Directive +import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability +import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives +import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.AbstractEnvironmentConfigurator + +private object CompilerPluginsDirectives : SimpleDirectivesContainer() { + val WITH_FIR_TEST_COMPILER_PLUGIN by directive( + description = "Configure test compiler plugin from :plugins:fir-plugin-prototype module", + applicability = DirectiveApplicability.Global + ) +} + +internal fun TestConfigurationBuilder.configureOptionalTestCompilerPlugin() { + useDirectives(CompilerPluginsDirectives) + + useConfigurators( + ::PluginAnnotationsProvider.enabledByDirective(CompilerPluginsDirectives.WITH_FIR_TEST_COMPILER_PLUGIN), + ::ExtensionRegistrarConfigurator.enabledByDirective(CompilerPluginsDirectives.WITH_FIR_TEST_COMPILER_PLUGIN), + ) +} + +private fun Constructor.enabledByDirective( + directive: Directive +): Constructor { + val originalConstructor = this + return { testServices -> EnabledByDirectiveConfiguratorDecorator(originalConstructor(testServices), directive) } +} + +private class EnabledByDirectiveConfiguratorDecorator( + private val original: AbstractEnvironmentConfigurator, + private val directive: Directive +) : AbstractEnvironmentConfigurator() { + override fun configureCompileConfigurationWithAdditionalConfigurationKeys(configuration: CompilerConfiguration, module: TestModule) { + if (directive !in module.directives) return + + original.configureCompileConfigurationWithAdditionalConfigurationKeys(configuration, module) + } + + override fun provideAdditionalAnalysisFlags( + directives: RegisteredDirectives, + languageVersion: LanguageVersion + ): Map, Any?> = original.provideAdditionalAnalysisFlags(directives, languageVersion) + + override fun registerCompilerExtensions(project: Project, module: TestModule, configuration: CompilerConfiguration) { + if (directive !in module.directives) return + + original.registerCompilerExtensions(project, module, configuration) + } +} \ 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/configurators/AnalysisApiFirSourceTestConfigurator.kt similarity index 66% rename from analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/FirLowLevelAnalysisApiTestConfigurator.kt rename to analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirSourceTestConfigurator.kt index c7798b4bedb..70255b70da7 100644 --- 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/configurators/AnalysisApiFirSourceTestConfigurator.kt @@ -1,31 +1,33 @@ /* - * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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 +package org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators 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.api.impl.base.test.configurators.AnalysisApiBaseTestServiceRegistrar +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.SealedClassesInheritorsCaclulatorPreAnalysisHandler +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirTestServiceRegistrar +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.configureOptionalTestCompilerPlugin import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory -import org.jetbrains.kotlin.analysis.test.framework.project.structure.toKtSourceModules +import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtMainModuleFactoryForSourceModules +import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory 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 +class AnalysisApiFirSourceTestConfigurator(override val analyseInDependentSession: Boolean) : AnalysisApiTestConfigurator() { override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) { builder.apply { usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler) + configureOptionalTestCompilerPlugin() } } @@ -38,12 +40,17 @@ object FirLowLevelAnalysisApiTestConfigurator : AnalysisApiTestConfigurator() { moduleStructure: TestModuleStructure, testServices: TestServices, project: Project - ): List { - return moduleStructure.toKtSourceModules(testServices, project) + ): KtModuleProjectStructure { + return TestModuleStructureFactory.createProjectStructureByTestStructure( + moduleStructure, + testServices, + project, + KtMainModuleFactoryForSourceModules, + ) } override fun doOutOfBlockModification(file: KtFile) { ServiceManager.getService(file.project, KotlinModificationTrackerFactory::class.java) .incrementModificationsCount() } -} +} \ No newline at end of file diff --git a/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ProjectStructureProvider.kt b/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ProjectStructureProvider.kt index 72bdb608c53..8d8c5010876 100644 --- a/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ProjectStructureProvider.kt +++ b/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ProjectStructureProvider.kt @@ -20,7 +20,7 @@ public abstract class ProjectStructureProvider { // TODO: We rather need a session or facade that maintains this information. public abstract fun getKtLibraryModules(): Collection - public abstract fun getStdlibModule(module: KtModule): KtLibraryModule? + public abstract fun getStdlibWithBuiltinsModule(module: KtModule): KtLibraryModule? } /** diff --git a/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ktModuleUtils.kt b/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ktModuleUtils.kt index 0af0178d9fd..7b06a21a565 100644 --- a/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ktModuleUtils.kt +++ b/analysis/project-structure/src/org/jetbrains/kotlin/analysis/project/structure/ktModuleUtils.kt @@ -6,13 +6,31 @@ package org.jetbrains.kotlin.analysis.project.structure /** - * A list of all modules current module can depend onwith regular dependency + * A list of all modules current module can depend on with regular dependency * * @see KtModule.directRegularDependencies */ public inline fun KtModule.directRegularDependenciesOfType(): Sequence = directRegularDependencies.asSequence().filterIsInstance() +/** + * A list of all modules current module can depend on with friend dependency + * + * @see KtModule.directFriendDependencies + */ +public inline fun KtModule.directFriendDependenciesOfType(): Sequence = + directFriendDependencies.asSequence().filterIsInstance() + +/** + * A list of all modules current module can depend on with refinement dependency + * + * @see KtModule.directRefinementDependencies + */ +public inline fun KtModule.directRefinementDependenciesOfType(): Sequence = + directRefinementDependencies.asSequence().filterIsInstance() + + + /** * A list of all other modules current module can depend on. * 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 index e2320fe1415..2f6a423b027 100644 --- 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 @@ -8,7 +8,7 @@ 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.api.standalone.base.project.structure.KtModuleProjectStructure 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 @@ -35,7 +35,7 @@ object AnalysisApiSymbolLightClassesDecompiledTestConfigurator : AnalysisApiTest moduleStructure: TestModuleStructure, testServices: TestServices, project: Project - ): List { + ): KtModuleProjectStructure { 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/source/AbstractSymbolLightClassesFacadeForSourceTest.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/source/AbstractSymbolLightClassesFacadeForSourceTest.kt index ec340619fb4..c6a8ba56ada 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,7 +5,7 @@ package org.jetbrains.kotlin.light.classes.symbol.source -import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesFacadeTest abstract class AbstractSymbolLightClassesFacadeForSourceTest : 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 74d65e6952b..089a1604f9a 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,7 +5,7 @@ package org.jetbrains.kotlin.light.classes.symbol.source -import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesTest abstract class AbstractSymbolLightClassesForSourceTest : 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 f95b9ae4e85..2b971334d07 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,7 +5,7 @@ package org.jetbrains.kotlin.light.classes.symbol.source -import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator import org.jetbrains.kotlin.light.classes.symbol.base.AbstractSymbolLightClassesLoadingTest abstract class AbstractSymbolLightClassesLoadingForSourceTest : diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ModuleDataProvider.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ModuleDataProvider.kt index 4ce319c2dc2..0aefee167c5 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ModuleDataProvider.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ModuleDataProvider.kt @@ -55,3 +55,12 @@ class MultipleModuleDataProvider(private val moduleDataWithFilters: Map get() = emptyList() + + override fun getModuleData(path: Path?): FirModuleData? = null +} diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/AbstractEnvironmentConfigurator.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/AbstractEnvironmentConfigurator.kt index 335aec5ac65..066f8683e53 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/AbstractEnvironmentConfigurator.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/AbstractEnvironmentConfigurator.kt @@ -25,6 +25,12 @@ abstract class AbstractEnvironmentConfigurator : ServicesAndDirectivesContainer abstract fun registerCompilerExtensions(project: Project, module: TestModule, configuration: CompilerConfiguration) } +class EnvironmentConfiguratorsProvider(internal val environmentConfigurators: List) : TestService + +internal val TestServices.environmentConfiguratorsProvider: EnvironmentConfiguratorsProvider by TestServices.testServiceAccessor() +val TestServices.environmentConfigurators: List + get() = environmentConfiguratorsProvider.environmentConfigurators + abstract class EnvironmentConfigurator(protected val testServices: TestServices) : AbstractEnvironmentConfigurator() { protected val moduleStructure: TestModuleStructure get() = testServices.moduleStructure diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/impl/TestConfigurationImpl.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/impl/TestConfigurationImpl.kt index fd439a61433..141897c03c1 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/impl/TestConfigurationImpl.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/impl/TestConfigurationImpl.kt @@ -97,6 +97,7 @@ class TestConfigurationImpl( init { testServices.apply { + register(EnvironmentConfiguratorsProvider::class, EnvironmentConfiguratorsProvider(this@TestConfigurationImpl.environmentConfigurators)) @OptIn(ExperimentalStdlibApi::class) val sourceFilePreprocessors = sourcePreprocessors.map { it.invoke(this@apply) } val sourceFileProvider = SourceFileProviderImpl(this, sourceFilePreprocessors) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt index e251ae29bcd..daa23cb3e9d 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt @@ -103,6 +103,51 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig else -> error("Too many jdk kinds passed: ${jdkKinds.joinToArrayString()}") } } + + fun getLibraryFilesExceptRealRuntime( + testServices: TestServices, + configurationKind: ConfigurationKind, + directives: RegisteredDirectives + ): List { + val provider = testServices.standardLibrariesPathProvider + val files = mutableListOf() + if (configurationKind.withRuntime) { + files.add(provider.kotlinTestJarForTests()) + } else if (configurationKind.withMockRuntime) { + files.add(provider.minimalRuntimeJarForTests()) + files.add(provider.scriptRuntimeJarForTests()) + } + if (configurationKind.withReflection) { + files.add(provider.reflectJarForTests()) + } + files.add(KtTestUtil.getAnnotationsJar()) + + if (JvmEnvironmentConfigurationDirectives.STDLIB_JDK8 in directives) { + files.add(provider.runtimeJarForTestsWithJdk8()) + } + files.add(KtTestUtil.getAnnotationsJar()) + return files + } + + fun getJdkHome(jdkKindTestJdkKind: TestJdkKind): File? = when (jdkKindTestJdkKind) { + TestJdkKind.MOCK_JDK -> null + TestJdkKind.MODIFIED_MOCK_JDK -> null + TestJdkKind.FULL_JDK_6 -> File(System.getenv("JDK_16") ?: error("Environment variable JDK_16 is not set")) + TestJdkKind.FULL_JDK_11 -> KtTestUtil.getJdk11Home() + TestJdkKind.FULL_JDK_17 -> KtTestUtil.getJdk17Home() + TestJdkKind.FULL_JDK -> if (SystemInfo.IS_AT_LEAST_JAVA9) File(System.getProperty("java.home")) else null + TestJdkKind.ANDROID_API -> null + } + + fun getJdkClasspathRoot(jdkKind: TestJdkKind): File? = when (jdkKind) { + TestJdkKind.MOCK_JDK -> KtTestUtil.findMockJdkRtJar() + TestJdkKind.MODIFIED_MOCK_JDK -> KtTestUtil.findMockJdkRtModified() + TestJdkKind.ANDROID_API -> KtTestUtil.findAndroidApiJar() + TestJdkKind.FULL_JDK_6 -> null + TestJdkKind.FULL_JDK_11 -> null + TestJdkKind.FULL_JDK_17 -> null + TestJdkKind.FULL_JDK -> null + } } override val directiveContainers: List @@ -136,34 +181,19 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig configureDefaultJvmTarget(configuration) val registeredDirectives = module.directives - when (extractJdkKind(registeredDirectives)) { - TestJdkKind.MOCK_JDK -> { - configuration.addJvmClasspathRoot(KtTestUtil.findMockJdkRtJar()) - configuration.put(JVMConfigurationKeys.NO_JDK, true) - } - TestJdkKind.MODIFIED_MOCK_JDK -> { - configuration.addJvmClasspathRoot(KtTestUtil.findMockJdkRtModified()) - configuration.put(JVMConfigurationKeys.NO_JDK, true) - } - TestJdkKind.FULL_JDK_6 -> { - val jdk6 = System.getenv("JDK_16") ?: error("Environment variable JDK_16 is not set") - configuration.put(JVMConfigurationKeys.JDK_HOME, File(jdk6)) - } - TestJdkKind.FULL_JDK_11 -> { - configuration.put(JVMConfigurationKeys.JDK_HOME, KtTestUtil.getJdk11Home()) - } - TestJdkKind.FULL_JDK_17 -> { - configuration.put(JVMConfigurationKeys.JDK_HOME, KtTestUtil.getJdk17Home()) - } - TestJdkKind.FULL_JDK -> { - if (SystemInfo.IS_AT_LEAST_JAVA9) { - configuration.put(JVMConfigurationKeys.JDK_HOME, File(System.getProperty("java.home"))) - } - } - TestJdkKind.ANDROID_API -> { - configuration.addJvmClasspathRoot(KtTestUtil.findAndroidApiJar()) + val jdkKind = extractJdkKind(registeredDirectives) + getJdkHome(jdkKind)?.let { configuration.put(JVMConfigurationKeys.JDK_HOME, it) } + getJdkClasspathRoot(jdkKind)?.let { configuration.addJvmClasspathRoot(it) } + + when (jdkKind) { + TestJdkKind.MOCK_JDK, TestJdkKind.MODIFIED_MOCK_JDK, TestJdkKind.ANDROID_API -> { configuration.put(JVMConfigurationKeys.NO_JDK, true) } + + TestJdkKind.FULL_JDK_6 -> {} + TestJdkKind.FULL_JDK_11 -> {} + TestJdkKind.FULL_JDK_17 -> {} + TestJdkKind.FULL_JDK -> {} } val configurationKind = extractConfigurationKind(registeredDirectives).also { @@ -180,7 +210,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig if (configurationKind.withRuntime) { configuration.configureStandardLibs(PathUtil.kotlinPathsForDistDirectory, K2JVMCompilerArguments().also { it.noReflect = true }) } - configuration.addJvmClasspathRoots(getLibraryFilesExceptRealRuntime(configurationKind, module.directives)) + configuration.addJvmClasspathRoots(getLibraryFilesExceptRealRuntime(testServices, configurationKind, module.directives)) val isIr = module.targetBackend?.isIR == true configuration.put(JVMConfigurationKeys.IR, isIr) @@ -373,25 +403,6 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig ) } - private fun getLibraryFilesExceptRealRuntime(configurationKind: ConfigurationKind, directives: RegisteredDirectives): List { - val provider = testServices.standardLibrariesPathProvider - val files = mutableListOf() - if (configurationKind.withRuntime) { - files.add(provider.kotlinTestJarForTests()) - } else if (configurationKind.withMockRuntime) { - files.add(provider.minimalRuntimeJarForTests()) - files.add(provider.scriptRuntimeJarForTests()) - } - if (configurationKind.withReflection) { - files.add(provider.reflectJarForTests()) - } - files.add(KtTestUtil.getAnnotationsJar()) - if (JvmEnvironmentConfigurationDirectives.STDLIB_JDK8 in directives) { - files.add(provider.runtimeJarForTestsWithJdk8()) - } - files.add(KtTestUtil.getAnnotationsJar()) - return files - } }