AA: make utils in StandaloneProjectFactory more general

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