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 d56e522043a..e316366ab61 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,11 +6,13 @@ package org.jetbrains.kotlin.analysis.api.standalone.base.project.structure import com.intellij.psi.PsiFile +import com.intellij.psi.PsiFileSystemItem +import com.intellij.psi.PsiJavaFile +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory.findJvmRootsForJavaFiles 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, @@ -20,6 +22,12 @@ data class KtModuleProjectStructure( mainModules.mapTo(this) { it.ktModule } addAll(binaryModules) } + + fun allSourceFiles(): List = buildList { + val files = mainModules.flatMap { it.files } + addAll(files) + addAll(findJvmRootsForJavaFiles(files.filterIsInstance())) + } } data class KtModuleWithFiles( 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 920142615b0..f1e0f663a9d 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 @@ -10,9 +10,12 @@ import com.intellij.codeInsight.InferredAnnotationsManager import com.intellij.mock.MockProject import com.intellij.openapi.Disposable import com.intellij.psi.PsiDirectory +import com.intellij.psi.PsiFileSystemItem import com.intellij.psi.PsiJavaFile import com.intellij.psi.impl.file.impl.JavaFileManager +import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.ProjectScope +import com.intellij.util.io.URLUtil.JAR_SEPARATOR import org.jetbrains.kotlin.analysis.project.structure.* import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.jvm.compiler.* @@ -35,17 +38,20 @@ import java.nio.file.Path object StandaloneProjectFactory { fun createProjectEnvironment( projectDisposable: Disposable, - applicationDisposable: Disposable + applicationDisposable: Disposable, + compilerConfiguration: CompilerConfiguration = CompilerConfiguration(), ): KotlinCoreProjectEnvironment { val applicationEnvironment = - KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForTests(applicationDisposable, CompilerConfiguration()) + KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForTests(applicationDisposable, compilerConfiguration) return KotlinCoreProjectEnvironment(projectDisposable, applicationEnvironment) } fun registerServicesForProjectEnvironment( environment: KotlinCoreProjectEnvironment, - modules: KtModuleProjectStructure, + projectStructureProvider: ProjectStructureProvider, + modules: List, + sourceFiles: List, languageVersionSettings: LanguageVersionSettings, jdkHome: Path?, ) { @@ -54,8 +60,8 @@ object StandaloneProjectFactory { KotlinCoreEnvironment.registerProjectExtensionPoints(project.extensionArea) KotlinCoreEnvironment.registerProjectServices(project) - project.registerService(ProjectStructureProvider::class.java, KtStaticModuleProvider(modules)) - initialiseVirtualFileFinderServices(modules, environment, jdkHome, languageVersionSettings) + project.registerService(ProjectStructureProvider::class.java, projectStructureProvider) + initialiseVirtualFileFinderServices(environment, modules, sourceFiles, languageVersionSettings, jdkHome) initialiseAnnotationServices(project) project.setupHighestLanguageLevel() @@ -67,20 +73,16 @@ object StandaloneProjectFactory { } private fun initialiseVirtualFileFinderServices( - modules: KtModuleProjectStructure, environment: KotlinCoreProjectEnvironment, + modules: List, + sourceFiles: List, + languageVersionSettings: LanguageVersionSettings, jdkHome: Path?, - languageVersionSettings: LanguageVersionSettings ) { val project = environment.project - val allSourceFiles = buildList { - 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.allKtModules(), environment) + val allSourceFileRoots = sourceFiles.map { JavaRoot(it.virtualFile, JavaRoot.RootType.SOURCE) } + val libraryRoots = getAllBinaryRoots(modules, environment) libraryRoots.forEach { environment.addSourcesToClasspath(it.file) } val sourceAndLibraryRoots = buildList { @@ -93,7 +95,10 @@ object StandaloneProjectFactory { javaFileManager.initialize( JvmDependenciesIndexImpl(sourceAndLibraryRoots), - listOf(createPackagePartsProvider(languageVersionSettings, project, libraryRoots)), + listOf( + createPackagePartsProvider(languageVersionSettings, project, libraryRoots) + .invoke(ProjectScope.getLibrariesScope(project)) + ), SingleJavaFileRootsIndex(emptyList()), true ) @@ -109,7 +114,7 @@ object StandaloneProjectFactory { project.registerService(VirtualFileFinderFactory::class.java, finderFactory) } - private fun findJvmRootsForJavaFiles(files: List): List { + fun findJvmRootsForJavaFiles(files: List): List { if (files.isEmpty()) return emptyList() val result = mutableSetOf() for (file in files) { @@ -134,8 +139,9 @@ object StandaloneProjectFactory { ): List = withAllTransitiveDependencies(modules) .filterIsInstance() .flatMap { it.getBinaryRoots() } - .map { - val jar = environment.environment.jarFileSystem.findFileByPath(it.toAbsolutePath().toString() + "!/")!! + .mapNotNull { path -> + val jar = environment.environment.jarFileSystem.findFileByPath(path.toAbsolutePath().toString() + JAR_SEPARATOR) + ?: return@mapNotNull null JavaRoot(jar, JavaRoot.RootType.BINARY) } @@ -171,8 +177,8 @@ object StandaloneProjectFactory { languageVersionSettings: LanguageVersionSettings, project: MockProject, libraryRoots: List - ): JvmPackagePartProvider { - return JvmPackagePartProvider(languageVersionSettings, ProjectScope.getLibrariesScope(project)).apply { + ): (GlobalSearchScope) -> JvmPackagePartProvider = { scope -> + JvmPackagePartProvider(languageVersionSettings, scope).apply { addRoots(libraryRoots, MessageCollector.NONE) (ModuleAnnotationsResolver .getInstance(project) as CliModuleAnnotationsResolver) 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 fab982b0144..80883777412 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 @@ -8,13 +8,13 @@ package org.jetbrains.kotlin.analysis.test.framework.services import com.intellij.openapi.Disposable import com.intellij.openapi.application.Application import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtStaticModuleProvider import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreApplicationEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings -import org.jetbrains.kotlin.test.ApplicationEnvironmentDisposer import org.jetbrains.kotlin.test.services.* abstract class AnalysisApiEnvironmentManager : TestService { @@ -52,13 +52,15 @@ class AnalysisApiEnvironmentManagerImpl( } override fun initializeProjectStructure() { - val ktModules = testServices.ktModuleProvider.getModuleStructure() + val ktModuleProjectStructure = testServices.ktModuleProvider.getModuleStructure() val useSiteModule = testServices.moduleStructure.modules.first() val useSiteCompilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(useSiteModule) StandaloneProjectFactory.registerServicesForProjectEnvironment( _projectEnvironment, - ktModules, + KtStaticModuleProvider(ktModuleProjectStructure), + ktModuleProjectStructure.allKtModules(), + ktModuleProjectStructure.allSourceFiles(), useSiteCompilerConfiguration.languageVersionSettings, useSiteCompilerConfiguration.get(JVMConfigurationKeys.JDK_HOME)?.toPath(), )