diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTest.kt index 5f099ef758b..29d6e25a03f 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/AbstractCompilerBasedTest.kt @@ -5,48 +5,14 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based -import com.intellij.mock.MockProject import com.intellij.openapi.Disposable -import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer -import com.intellij.psi.PsiElement -import com.intellij.psi.PsiElementFinder -import com.intellij.psi.search.GlobalSearchScope -import com.intellij.psi.search.ProjectScope -import org.jetbrains.kotlin.analysis.api.InvalidWayOfUsingAnalysisSession -import org.jetbrains.kotlin.analysis.api.KtAnalysisSessionProvider -import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSessionProvider -import org.jetbrains.kotlin.analysis.low.level.api.fir.FirIdeResolveStateService import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirSealedClassInheritorsProcessorFactory -import org.jetbrains.kotlin.analysis.low.level.api.fir.api.PackagePartProviderFactory 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.SealedClassInheritorsProviderTestImpl import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.FirLazyTransformerForIDE import org.jetbrains.kotlin.analysis.project.structure.* -import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory -import org.jetbrains.kotlin.analysis.providers.KotlinModificationTrackerFactory -import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory -import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory -import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticModificationTrackerFactory -import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory -import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport -import org.jetbrains.kotlin.asJava.finder.JavaElementFinder -import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM -import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots -import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots -import org.jetbrains.kotlin.config.JVMConfigurationKeys -import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider -import org.jetbrains.kotlin.light.classes.symbol.IDEKotlinAsJavaFirSupport -import org.jetbrains.kotlin.load.kotlin.PackagePartProvider -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices import org.jetbrains.kotlin.test.TestConfiguration import org.jetbrains.kotlin.test.bind import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder @@ -54,17 +20,12 @@ import org.jetbrains.kotlin.test.builders.testConfiguration import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact -import org.jetbrains.kotlin.test.frontend.fir.getAnalyzerServices import org.jetbrains.kotlin.test.model.* import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest import org.jetbrains.kotlin.test.services.* -import org.jetbrains.kotlin.utils.addIfNotNull import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.TestInfo -import java.io.File -import java.nio.file.Path -import java.nio.file.Paths abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() { private var _disposable: Disposable? = null @@ -149,194 +110,3 @@ abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() { return false } } - - -class TestProjectModuleProvider( - private val testServices: TestServices -) : TestService { - private val cache = mutableMapOf() - - fun registerModuleInfo(project: Project, testModule: TestModule, ktFiles: Map) { - cache[testModule.name] = TestSourceProjectModule(project, testModule, ktFiles, testServices) - } - - fun getModuleInfoByKtFile(ktFile: KtFile): TestSourceProjectModule = - cache.values.first { moduleSourceInfo -> - ktFile in moduleSourceInfo.ktFiles - } - - fun getModule(moduleName: String): TestSourceProjectModule = - cache.getValue(moduleName) -} - -val TestServices.projectModuleProvider: TestProjectModuleProvider by TestServices.testServiceAccessor() - -class ModuleRegistrarPreAnalysisHandler( - testServices: TestServices, - private val parentDisposable: Disposable -) : PreAnalysisHandler(testServices) { - - private val moduleInfoProvider = testServices.projectModuleProvider - - override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) { - // todo rework after all modules will have the same Project instance - val ktFilesByModule = moduleStructure.modules.associateWith { testModule -> - val project = testServices.compilerConfigurationProvider.getProject(testModule) - testServices.sourceFileProvider.getKtFilesForSourceFiles(testModule.files, project) - } - - val allKtFiles = ktFilesByModule.values.flatMap { it.values.toList() } - - ktFilesByModule.forEach { (testModule, ktFiles) -> - val project = testServices.compilerConfigurationProvider.getProject(testModule) - moduleInfoProvider.registerModuleInfo(project, testModule, ktFiles) - (project as MockProject).registerTestServices(testModule, allKtFiles, testServices) - } - } -} - -@OptIn(ExperimentalStdlibApi::class) -class TestSourceProjectModule( - private val project: Project, - val testModule: TestModule, - val testFilesToKtFiles: Map, - testServices: TestServices, -) : SourceProjectModule { - private val moduleProvider = testServices.projectModuleProvider - private val compilerConfigurationProvider = testServices.compilerConfigurationProvider - private val configuration = compilerConfigurationProvider.getCompilerConfiguration(testModule) - - - val ktFiles = testFilesToKtFiles.values.toSet() - - override val name: Name get() = Name.identifier(testModule.name) - - override val regularDependencies: List by lazy(LazyThreadSafetyMode.PUBLICATION) { - buildList { - testModule.allDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) } - addIfNotNull( - libraryByRoots( - (configuration.jvmModularRoots + configuration.jvmClasspathRoots).map(File::toPath) - ) - ) - } - } - override val dependsOnDependencies: List by lazy(LazyThreadSafetyMode.PUBLICATION) { - testModule.dependsOnDependencies - .map { moduleProvider.getModule(it.moduleName) } - } - override val friendDependencies: List by lazy(LazyThreadSafetyMode.PUBLICATION) { - buildList { - testModule.friendDependencies.mapTo(this) { moduleProvider.getModule(it.moduleName) } - addIfNotNull( - libraryByRoots(configuration[JVMConfigurationKeys.FRIEND_PATHS].orEmpty().map(Paths::get)) - ) - } - } - - private fun libraryByRoots(roots: List): LibraryByRoots? { - if (roots.isEmpty()) return null - return LibraryByRoots( - roots, - this@TestSourceProjectModule, - project - ) - } - - override val searchScope: GlobalSearchScope = - TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, testFilesToKtFiles.values) - - override val languageVersionSettings: LanguageVersionSettings - get() = testModule.languageVersionSettings - - override val platform: TargetPlatform - get() = testModule.targetPlatform - - override val analyzerServices: PlatformDependentAnalyzerServices - get() = testModule.targetPlatform.getAnalyzerServices() -} - -private class LibraryByRoots( - private val roots: List, - private val sourceModule: SourceProjectModule, - private val project: Project, -) : LibraryProjectModule { - override val name: Name get() = Name.special("") - override val regularDependencies: List get() = emptyList() - override val dependsOnDependencies: List get() = emptyList() - override val friendDependencies: List get() = emptyList() - override val searchScope: GlobalSearchScope get() = ProjectScope.getLibrariesScope(project) - override val platform: TargetPlatform get() = sourceModule.platform - override val analyzerServices: PlatformDependentAnalyzerServices get() = sourceModule.analyzerServices - override fun getBinaryRoots(): Collection = roots -} - -fun MockProject.registerTestServices( - testModule: TestModule, - allKtFiles: List, - testServices: TestServices, -) { - registerService( - PackagePartProviderFactory::class.java, - object : PackagePartProviderFactory() { - override fun createPackagePartProvider(scope: GlobalSearchScope): PackagePartProvider { - val factory = testServices.compilerConfigurationProvider.getPackagePartProviderFactory(testModule) - return factory(scope) - } - } - ) - registerService( - FirSealedClassInheritorsProcessorFactory::class.java, - object : FirSealedClassInheritorsProcessorFactory() { - override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider { - return SealedClassInheritorsProviderTestImpl() - } - } - ) - registerService( - ProjectModuleScopeProvider::class.java, - object : ProjectModuleScopeProvider() { - override fun getModuleLibrariesScope(sourceModule: SourceProjectModule): GlobalSearchScope { - val libraries = sourceModule.dependenciesOfType() - val scopes = libraries.map { it.searchScope }.toList() - if (scopes.isEmpty()) return GlobalSearchScope.EMPTY_SCOPE - return GlobalSearchScope.union(scopes) - } - } - ) - registerService(FirIdeResolveStateService::class.java) - registerService( - KotlinModificationTrackerFactory::class.java, - KotlinStaticModificationTrackerFactory::class.java - ) - registerService(KotlinDeclarationProviderFactory::class.java, KotlinStaticDeclarationProviderFactory(allKtFiles)) - registerService(KotlinPackageProviderFactory::class.java, KotlinStaticPackageProviderFactory(allKtFiles)) - registerService(ProjectStructureProvider::class.java, TestKotlinProjectStructureProvider(testServices)) - reRegisterJavaElementFinder(this) -} - -private class TestKotlinProjectStructureProvider(testServices: TestServices) : ProjectStructureProvider() { - private val moduleInfoProvider = testServices.projectModuleProvider - override fun getProjectModuleForKtElement(element: PsiElement): ProjectModule { - val containingFile = element.containingFile as KtFile - return moduleInfoProvider.getModuleInfoByKtFile(containingFile) - } -} - -@OptIn(InvalidWayOfUsingAnalysisSession::class) -private fun reRegisterJavaElementFinder(project: Project) { - PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java) - with(project as MockProject) { - picoContainer.registerComponentInstance( - KtAnalysisSessionProvider::class.qualifiedName, - KtFirAnalysisSessionProvider(this) - ) - picoContainer.unregisterComponent(KotlinAsJavaSupport::class.qualifiedName) - picoContainer.registerComponentInstance( - KotlinAsJavaSupport::class.qualifiedName, - IDEKotlinAsJavaFirSupport(project) - ) - } - @Suppress("DEPRECATION") - PsiElementFinder.EP.getPoint(project).registerExtension(JavaElementFinder(project)) -} diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt new file mode 100644 index 00000000000..94bff16beb7 --- /dev/null +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/ModuleRegistrarPreAnalysisHandler.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based + +import com.intellij.mock.MockProject +import com.intellij.openapi.Disposable +import org.jetbrains.kotlin.test.services.* + +class ModuleRegistrarPreAnalysisHandler( + testServices: TestServices, + private val parentDisposable: Disposable +) : PreAnalysisHandler(testServices) { + private val moduleInfoProvider = testServices.projectModuleProvider + + override fun preprocessModuleStructure(moduleStructure: TestModuleStructure) { + // todo rework after all modules will have the same Project instance + val ktFilesByModule = moduleStructure.modules.associateWith { testModule -> + val project = testServices.compilerConfigurationProvider.getProject(testModule) + testServices.sourceFileProvider.getKtFilesForSourceFiles(testModule.files, project) + } + + val allKtFiles = ktFilesByModule.values.flatMap { it.values.toList() } + + ktFilesByModule.forEach { (testModule, ktFiles) -> + val project = testServices.compilerConfigurationProvider.getProject(testModule) + moduleInfoProvider.registerModuleInfo(project, testModule, ktFiles) + (project as MockProject).registerTestServices(testModule, allKtFiles, testServices) + } + } +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/TestSourceSetProjectModule.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/TestSourceSetProjectModule.kt index 7b713746209..c3b06edca1e 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/TestSourceSetProjectModule.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/TestSourceSetProjectModule.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt index ef470a09558..1d9642ced4f 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/compiler/based/testServices.kt @@ -44,11 +44,11 @@ fun MockProject.registerTestServices( ) { registerService( PackagePartProviderFactory::class.java, - TestPackagePartProvider(testServices, testModule) + PackagePartProviderTestImpl(testServices, testModule) ) registerService( FirSealedClassInheritorsProcessorFactory::class.java, - TestFirSealedClassInheritorsProcessorFactory() + FirSealedClassInheritorsProcessorFactoryTestImpl() ) registerService(KtModuleScopeProvider::class.java, KtModuleScopeProviderImpl()) registerService(FirIdeResolveStateService::class.java) @@ -58,17 +58,17 @@ fun MockProject.registerTestServices( ) registerService(KotlinDeclarationProviderFactory::class.java, KotlinStaticDeclarationProviderFactory(allKtFiles)) registerService(KotlinPackageProviderFactory::class.java, KotlinStaticPackageProviderFactory(allKtFiles)) - registerService(ProjectStructureProvider::class.java, TestKotlinProjectStructureProvider(testServices)) + registerService(ProjectStructureProvider::class.java, KotlinProjectStructureProviderTestImpl(testServices)) reRegisterJavaElementFinder(this) } -class TestFirSealedClassInheritorsProcessorFactory : FirSealedClassInheritorsProcessorFactory() { +private class FirSealedClassInheritorsProcessorFactoryTestImpl : FirSealedClassInheritorsProcessorFactory() { override fun createSealedClassInheritorsProvider(): SealedClassInheritorsProvider { return SealedClassInheritorsProviderTestImpl() } } -private class TestPackagePartProvider( +private class PackagePartProviderTestImpl( private val testServices: TestServices, private val testModule: TestModule ) : PackagePartProviderFactory() { @@ -78,7 +78,7 @@ private class TestPackagePartProvider( } } -private class TestKotlinProjectStructureProvider(testServices: TestServices) : ProjectStructureProvider() { +private class KotlinProjectStructureProviderTestImpl(testServices: TestServices) : ProjectStructureProvider() { private val moduleInfoProvider = testServices.projectModuleProvider override fun getKtModuleForKtElement(element: PsiElement): KtModule { val containingFile = element.containingFile as KtFile diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiTest.kt index a75591dc972..34652312e2e 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/AbstractLowLevelApiTest.kt @@ -132,5 +132,3 @@ abstract class AbstractLowLevelApiTest : TestWithDisposable() { } } -fun String.indexOfOrNull(substring: String) = - indexOf(substring).takeIf { it >= 0 } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/ExpressionMarkersSourceFilePreprocessor.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/ExpressionMarkersSourceFilePreprocessor.kt index 646e90e4ae6..20930635bfd 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/ExpressionMarkersSourceFilePreprocessor.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/base/ExpressionMarkersSourceFilePreprocessor.kt @@ -99,4 +99,7 @@ class ExpressionMarkerProvider : TestService { .dropLastWhile { it is PsiWhiteSpace } } +private fun String.indexOfOrNull(substring: String) = + indexOf(substring).takeIf { it >= 0 } + val TestServices.expressionMarkerProvider: ExpressionMarkerProvider by TestServices.testServiceAccessor()