diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index 7d73948e5b1..aeb26304a77 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -32,16 +32,15 @@ import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil import org.jetbrains.kotlin.cli.common.modules.ModuleBuilder import org.jetbrains.kotlin.cli.common.modules.ModuleChunk import org.jetbrains.kotlin.cli.common.profiling.ProfilingCompilerPerformanceManager -import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil -import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler +import org.jetbrains.kotlin.cli.jvm.compiler.* +import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.compileModulesUsingFrontendIrAndLightTree +import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.createProjectEnvironment import org.jetbrains.kotlin.cli.jvm.config.ClassicFrontendSpecificJvmConfigurationKeys import org.jetbrains.kotlin.codegen.CompilationException import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.incremental.components.ExpectActualTracker -import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.InlineConstTracker +import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion @@ -156,25 +155,35 @@ class K2JVMCompiler : CLICompiler() { } val chunk = moduleChunk.modules - KotlinToJVMBytecodeCompiler.configureSourceRoots(configuration, chunk, buildFile) - val environment = createCoreEnvironment( - rootDisposable, configuration, messageCollector, - chunk.map { input -> input.getModuleName() + "-" + input.getModuleType() }.let { names -> - names.singleOrNull() ?: names.joinToString() + configuration.configureSourceRoots(chunk, buildFile) + + if (configuration.getBoolean(CommonConfigurationKeys.USE_FIR)) { + val projectEnvironment = + createProjectEnvironment(configuration, rootDisposable, EnvironmentConfigFiles.JVM_CONFIG_FILES, messageCollector) + + compileModulesUsingFrontendIrAndLightTree( + projectEnvironment, configuration, messageCollector, buildFile, chunk + ) + } else { + val environment = createCoreEnvironment( + rootDisposable, configuration, messageCollector, + chunk.map { input -> input.getModuleName() + "-" + input.getModuleType() }.let { names -> + names.singleOrNull() ?: names.joinToString() + } + ) ?: return COMPILATION_ERROR + environment.registerJavacIfNeeded(arguments).let { + if (!it) return COMPILATION_ERROR } - ) ?: return COMPILATION_ERROR - environment.registerJavacIfNeeded(arguments).let { - if (!it) return COMPILATION_ERROR + + if (environment.getSourceFiles().isEmpty() && !arguments.allowNoSourceFiles && buildFile == null) { + if (arguments.version) return OK + + messageCollector.report(ERROR, "No source files") + return COMPILATION_ERROR + } + + KotlinToJVMBytecodeCompiler.compileModules(environment, buildFile, chunk) } - - if (environment.getSourceFiles().isEmpty() && !arguments.allowNoSourceFiles && buildFile == null) { - if (arguments.version) return OK - - messageCollector.report(ERROR, "No source files") - return COMPILATION_ERROR - } - - KotlinToJVMBytecodeCompiler.compileModules(environment, buildFile, chunk) return OK } catch (e: CompilationException) { messageCollector.report( diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt index 931c177ab24..418f1b51afc 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/FirKotlinToJvmBytecodeCompiler.kt @@ -88,13 +88,13 @@ object FirKotlinToJvmBytecodeCompiler { val isMultiModuleChunk = chunk.size > 1 // TODO: run lowerings for all modules in the chunk, then run codegen for all modules. - val project = (projectEnvironment as? PsiBasedProjectEnvironment)?.project + val project = (projectEnvironment as? VfsBasedProjectEnvironment)?.project for (module in chunk) { val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile) val context = CompilationContext( module, module.getSourceFiles( - allSources, (projectEnvironment as? PsiBasedProjectEnvironment)?.localFileSystem, isMultiModuleChunk, buildFile + allSources, (projectEnvironment as? VfsBasedProjectEnvironment)?.localFileSystem, isMultiModuleChunk, buildFile ), projectEnvironment, messageCollector, @@ -112,7 +112,7 @@ object FirKotlinToJvmBytecodeCompiler { } val mainClassFqName: FqName? = runIf(chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { - findMainClass(outputs.single().first) + findMainClass(outputs.single().first.fir) } return writeOutputs( @@ -179,7 +179,7 @@ object FirKotlinToJvmBytecodeCompiler { AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound } - var sourceScope = (projectEnvironment as PsiBasedProjectEnvironment).getSearchScopeByPsiFiles(ktFiles) + + var sourceScope = (projectEnvironment as VfsBasedProjectEnvironment).getSearchScopeByPsiFiles(ktFiles) + projectEnvironment.getSearchScopeForProjectJavaSources() var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() @@ -307,7 +307,7 @@ object FirKotlinToJvmBytecodeCompiler { ) val generationState = GenerationState.Builder( - (projectEnvironment as PsiBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES, + (projectEnvironment as VfsBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES, moduleFragment.descriptor, dummyBindingContext, ktFiles, moduleConfiguration ).codegenFactory( @@ -366,38 +366,38 @@ object FirKotlinToJvmBytecodeCompiler { val firExtensionRegistrars: List, val irGenerationExtensions: Collection ) - - private fun findMainClass(firResult: FirResult): FqName? { - // TODO: replace with proper main function detector, KT-44557 - val compatibleClasses = mutableListOf() - val visitor = object : FirVisitorVoid() { - lateinit var file: FirFile - - override fun visitElement(element: FirElement) {} - - override fun visitFile(file: FirFile) { - this.file = file - file.acceptChildren(this) - } - - override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) { - if (simpleFunction.name.asString() != "main") return - if (simpleFunction.typeParameters.isNotEmpty()) return - when (simpleFunction.valueParameters.size) { - 0 -> {} - 1 -> { - val parameterType = simpleFunction.valueParameters.single().returnTypeRef.coneType - if (!parameterType.isArrayType || parameterType.arrayElementType()?.isString != true) return - } - else -> return - } - - compatibleClasses += FqName.fromSegments( - file.packageFqName.pathSegments().map { it.asString() } + "${file.name.removeSuffix(".kt").capitalize()}Kt" - ) - } - } - firResult.fir.forEach { it.accept(visitor) } - return compatibleClasses.singleOrNull() - } +} + +internal fun findMainClass(fir: List): FqName? { + // TODO: replace with proper main function detector, KT-44557 + val compatibleClasses = mutableListOf() + val visitor = object : FirVisitorVoid() { + lateinit var file: FirFile + + override fun visitElement(element: FirElement) {} + + override fun visitFile(file: FirFile) { + this.file = file + file.acceptChildren(this) + } + + override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) { + if (simpleFunction.name.asString() != "main") return + if (simpleFunction.typeParameters.isNotEmpty()) return + when (simpleFunction.valueParameters.size) { + 0 -> {} + 1 -> { + val parameterType = simpleFunction.valueParameters.single().returnTypeRef.coneType + if (!parameterType.isArrayType || parameterType.arrayElementType()?.isString != true) return + } + else -> return + } + + compatibleClasses += FqName.fromSegments( + file.packageFqName.pathSegments().map { it.asString() } + "${file.name.removeSuffix(".kt").capitalize()}Kt" + ) + } + } + fir.forEach { it.accept(visitor) } + return compatibleClasses.singleOrNull() } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 15af17f0d17..8e34772c428 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -198,39 +198,11 @@ class KotlinCoreEnvironment private constructor( val configuration: CompilerConfiguration = initialConfiguration.apply { setupJdkClasspathRoots(configFiles) }.copy() init { - PersistentFSConstants::class.java.getDeclaredField("ourMaxIntellisenseFileSize") - .apply { isAccessible = true } - .setInt(null, FileUtilRt.LARGE_FOR_CONTENT_LOADING) - + projectEnvironment.configureProjectEnvironment(configuration, configFiles) val project = projectEnvironment.project - - val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) - - if (configuration.getBoolean(JVMConfigurationKeys.USE_FAST_JAR_FILE_SYSTEM)) { - messageCollector?.report( - STRONG_WARNING, - "Using new faster version of JAR FS: it should make your build faster, but the new implementation is experimental" - ) - } - - (projectEnvironment as? ProjectEnvironment)?.registerExtensionsFromPlugins(configuration) - // otherwise consider that project environment is properly configured before passing to the environment - // TODO: consider some asserts to check important extension points - project.registerService(DeclarationProviderFactoryService::class.java, CliDeclarationProviderFactoryService(sourceFiles)) - val isJvm = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES - project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(isJvm)) - - registerProjectServicesForCLI(projectEnvironment) - - registerProjectServices(projectEnvironment.project) - - for (extension in CompilerConfigurationExtension.getInstances(project)) { - extension.updateConfiguration(configuration) - } - - sourceFiles += createKtFiles(project) + sourceFiles += createSourceFilesFromSourceRoots(configuration, project, getSourceRootsCheckingForDuplicates()) collectAdditionalSources(project) @@ -238,6 +210,8 @@ class KotlinCoreEnvironment private constructor( val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl + val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) + val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME) val releaseTarget = configuration.get(JVMConfigurationKeys.JDK_RELEASE) val javaModuleFinder = CliJavaModuleFinder( @@ -449,9 +423,6 @@ class KotlinCoreEnvironment private constructor( fun getSourceFiles(): List = sourceFiles - private fun createKtFiles(project: Project): List = - createSourceFilesFromSourceRoots(configuration, project, getSourceRootsCheckingForDuplicates()) - internal fun report(severity: CompilerMessageSeverity, message: String) = configuration.report(severity, message) companion object { @@ -585,6 +556,38 @@ class KotlinCoreEnvironment private constructor( } } + @JvmStatic + fun ProjectEnvironment.configureProjectEnvironment( + configuration: CompilerConfiguration, + configFiles: EnvironmentConfigFiles + ) { + PersistentFSConstants::class.java.getDeclaredField("ourMaxIntellisenseFileSize") + .apply { isAccessible = true } + .setInt(null, FileUtilRt.LARGE_FOR_CONTENT_LOADING) + + if (configuration.getBoolean(JVMConfigurationKeys.USE_FAST_JAR_FILE_SYSTEM)) { + configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)?.report( + STRONG_WARNING, + "Using new faster version of JAR FS: it should make your build faster, but the new implementation is experimental" + ) + } + + registerExtensionsFromPlugins(configuration) + // otherwise consider that project environment is properly configured before passing to the environment + // TODO: consider some asserts to check important extension points + + val isJvm = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES + project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(isJvm)) + + registerProjectServicesForCLI(this) + + registerProjectServices(project) + + for (extension in CompilerConfigurationExtension.getInstances(project)) { + extension.updateConfiguration(configuration) + } + } + private fun createApplicationEnvironment( parentDisposable: Disposable, configuration: CompilerConfiguration, unitTestMode: Boolean ): KotlinCoreApplicationEnvironment { @@ -723,7 +726,7 @@ class KotlinCoreEnvironment private constructor( } } - private fun registerProjectServicesForCLI(@Suppress("UNUSED_PARAMETER") projectEnvironment: JavaCoreProjectEnvironment) { + fun registerProjectServicesForCLI(@Suppress("UNUSED_PARAMETER") projectEnvironment: JavaCoreProjectEnvironment) { /** * Note that Kapt may restart code analysis process, and CLI services should be aware of that. * Use PsiManager.getModificationTracker() to ensure that all the data you cached is still valid. diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 9f8640fe577..713bf82a1b7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -85,7 +85,7 @@ object KotlinToJVMBytecodeCompiler { if (projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR)) { val extendedAnalysisMode = projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS) val projectEnvironment = - PsiBasedProjectEnvironment( + VfsBasedProjectEnvironment( environment.project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) ) { environment.createPackagePartProvider(it) } @@ -139,52 +139,6 @@ object KotlinToJVMBytecodeCompiler { return writeOutputs(environment.project, projectConfiguration, chunk, outputs, mainClassFqName) } - internal fun configureSourceRoots(configuration: CompilerConfiguration, chunk: List, buildFile: File? = null) { - for (module in chunk) { - val commonSources = getBuildFilePaths(buildFile, module.getCommonSourceFiles()).toSet() - - for (path in getBuildFilePaths(buildFile, module.getSourceFiles())) { - configuration.addKotlinSourceRoot(path, isCommon = path in commonSources) - } - } - - for (module in chunk) { - for ((path, packagePrefix) in module.getJavaSourceRoots()) { - configuration.addJavaSourceRoot(File(path), packagePrefix) - } - } - - val isJava9Module = chunk.any { module -> - module.getJavaSourceRoots().any { (path, packagePrefix) -> - val file = File(path) - packagePrefix == null && - (file.name == PsiJavaModule.MODULE_INFO_FILE || - (file.isDirectory && file.listFiles()!!.any { it.name == PsiJavaModule.MODULE_INFO_FILE })) - } - } - - for (module in chunk) { - for (classpathRoot in module.getClasspathRoots()) { - if (isJava9Module) { - configuration.add(CLIConfigurationKeys.CONTENT_ROOTS, JvmModulePathRoot(File(classpathRoot))) - } - configuration.add(CLIConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(File(classpathRoot))) - } - } - - for (module in chunk) { - val modularJdkRoot = module.modularJdkRoot - if (modularJdkRoot != null) { - // We use the SDK of the first module in the chunk, which is not always correct because some other module in the chunk - // might depend on a different SDK - configuration.put(JVMConfigurationKeys.JDK_HOME, File(modularJdkRoot)) - break - } - } - - configuration.addAll(JVMConfigurationKeys.MODULES, chunk) - } - fun compileBunchOfSources(environment: KotlinCoreEnvironment): Boolean { val moduleVisibilityManager = ModuleVisibilityManager.SERVICE.getInstance(environment.project) @@ -427,3 +381,49 @@ object KotlinToJVMBytecodeCompiler { return state } } + +internal fun CompilerConfiguration.configureSourceRoots(chunk: List, buildFile: File? = null) { + for (module in chunk) { + val commonSources = getBuildFilePaths(buildFile, module.getCommonSourceFiles()).toSet() + + for (path in getBuildFilePaths(buildFile, module.getSourceFiles())) { + addKotlinSourceRoot(path, isCommon = path in commonSources) + } + } + + for (module in chunk) { + for ((path, packagePrefix) in module.getJavaSourceRoots()) { + addJavaSourceRoot(File(path), packagePrefix) + } + } + + val isJava9Module = chunk.any { module -> + module.getJavaSourceRoots().any { (path, packagePrefix) -> + val file = File(path) + packagePrefix == null && + (file.name == PsiJavaModule.MODULE_INFO_FILE || + (file.isDirectory && file.listFiles()!!.any { it.name == PsiJavaModule.MODULE_INFO_FILE })) + } + } + + for (module in chunk) { + for (classpathRoot in module.getClasspathRoots()) { + if (isJava9Module) { + add(CLIConfigurationKeys.CONTENT_ROOTS, JvmModulePathRoot(File(classpathRoot))) + } + add(CLIConfigurationKeys.CONTENT_ROOTS, JvmClasspathRoot(File(classpathRoot))) + } + } + + for (module in chunk) { + val modularJdkRoot = module.modularJdkRoot + if (modularJdkRoot != null) { + // We use the SDK of the first module in the chunk, which is not always correct because some other module in the chunk + // might depend on a different SDK + put(JVMConfigurationKeys.JDK_HOME, File(modularJdkRoot)) + break + } + } + + addAll(JVMConfigurationKeys.MODULES, chunk) +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/PsiBasedProjectEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt similarity index 97% rename from compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/PsiBasedProjectEnvironment.kt rename to compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt index 0b800bb4e3c..56f0717aabb 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/PsiBasedProjectEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/VfsBasedProjectEnvironment.kt @@ -42,11 +42,12 @@ class PsiBasedProjectFileSearchScope(val psiSearchScope: GlobalSearchScope) : Ab PsiBasedProjectFileSearchScope(GlobalSearchScope.notScope(psiSearchScope)) } -class PsiBasedProjectEnvironment( +open class VfsBasedProjectEnvironment( val project: Project, val localFileSystem: VirtualFileSystem, - val getPackagePartProviderFn: (GlobalSearchScope) -> PackagePartProvider + private val getPackagePartProviderFn: (GlobalSearchScope) -> PackagePartProvider ) : AbstractProjectEnvironment { + override fun getKotlinClassFinder(fileSearchScope: AbstractProjectFileSearchScope): KotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(fileSearchScope.asPsiSearchScope()) @@ -105,7 +106,7 @@ private fun AbstractProjectFileSearchScope.asPsiSearchScope() = } fun KotlinCoreEnvironment.toAbstractProjectEnvironment(): AbstractProjectEnvironment = - PsiBasedProjectEnvironment( + VfsBasedProjectEnvironment( project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), { createPackagePartProvider(it) } ) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/coreEnvironmentUtils.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/coreEnvironmentUtils.kt index 8e97b5bef90..61d8d05bfc7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/coreEnvironmentUtils.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/coreEnvironmentUtils.kt @@ -30,22 +30,20 @@ fun CompilerConfiguration.report(severity: CompilerMessageSeverity, message: Str get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)?.report(severity, message, location) } -fun createSourceFilesFromSourceRoots( +inline fun List.forAllFiles( configuration: CompilerConfiguration, project: Project, - sourceRoots: List, - reportLocation: CompilerMessageLocation? = null -): MutableList { + reportLocation: CompilerMessageLocation? = null, + body: (VirtualFile, Boolean) -> Unit +) { val localFileSystem = VirtualFileManager.getInstance() .getFileSystem(StandardFileSystems.FILE_PROTOCOL) - val psiManager = PsiManager.getInstance(project) val processedFiles = hashSetOf() - val result = mutableListOf() val virtualFileCreator = PreprocessedFileCreator(project) - for ((sourceRootPath, isCommon) in sourceRoots) { + for ((sourceRootPath, isCommon) in this) { val vFile = localFileSystem.findFileByPath(sourceRootPath) if (vFile == null) { val message = "Source file or directory not found: $sourceRootPath" @@ -70,17 +68,28 @@ fun createSourceFilesFromSourceRoots( val virtualFile = localFileSystem.findFileByPath(file.absolutePath)?.let(virtualFileCreator::create) if (virtualFile != null && processedFiles.add(virtualFile)) { - val psiFile = psiManager.findFile(virtualFile) - if (psiFile is KtFile) { - result.add(psiFile) - if (isCommon) { - psiFile.isCommonSource = true - } - } + body(virtualFile, isCommon) } } } +} +fun createSourceFilesFromSourceRoots( + configuration: CompilerConfiguration, + project: Project, + sourceRoots: List, + reportLocation: CompilerMessageLocation? = null +): MutableList { + val psiManager = PsiManager.getInstance(project) + val result = mutableListOf() + sourceRoots.forAllFiles(configuration, project, reportLocation) { virtualFile, isCommon -> + psiManager.findFile(virtualFile)?.let { + if (it is KtFile) { + it.isCommonSource = isCommon + result.add(it) + } + } + } return result } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt new file mode 100644 index 00000000000..fe90289f421 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipeline.kt @@ -0,0 +1,445 @@ +/* + * 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.cli.jvm.compiler.pipeline + +import com.intellij.core.CoreJavaFileManager +import com.intellij.ide.highlighter.JavaFileType +import com.intellij.openapi.Disposable +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileManager +import com.intellij.openapi.vfs.VirtualFileSystem +import com.intellij.psi.PsiManager +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.util.io.URLUtil +import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices +import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension +import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl +import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots +import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.jvm.compiler.* +import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.Companion.configureProjectEnvironment +import org.jetbrains.kotlin.cli.jvm.config.* +import org.jetbrains.kotlin.cli.jvm.index.JavaRoot +import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesDynamicCompoundIndex +import org.jetbrains.kotlin.cli.jvm.index.JvmDependenciesIndexImpl +import org.jetbrains.kotlin.cli.jvm.index.SingleJavaFileRootsIndex +import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder +import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver +import org.jetbrains.kotlin.codegen.ClassBuilderFactories +import org.jetbrains.kotlin.codegen.CodegenFactory +import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory +import org.jetbrains.kotlin.fir.DependencyListForCliModule +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver +import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension +import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers +import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider +import org.jetbrains.kotlin.fir.moduleData +import org.jetbrains.kotlin.fir.pipeline.buildFirViaLightTree +import org.jetbrains.kotlin.fir.pipeline.convertToIr +import org.jetbrains.kotlin.fir.pipeline.runCheckers +import org.jetbrains.kotlin.fir.pipeline.runResolution +import org.jetbrains.kotlin.fir.session.FirSessionFactory +import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment +import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope +import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory +import org.jetbrains.kotlin.load.kotlin.PackagePartProvider +import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory +import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider +import org.jetbrains.kotlin.modules.Module +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.CommonPlatforms +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus +import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver +import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices +import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver +import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices +import org.jetbrains.kotlin.utils.addToStdlib.runIf +import java.io.File + +fun compileModulesUsingFrontendIrAndLightTree( + projectEnvironment: AbstractProjectEnvironment, + compilerConfiguration: CompilerConfiguration, + messageCollector: MessageCollector, + buildFile: File?, + chunk: List +): Boolean { + require(projectEnvironment is VfsBasedProjectEnvironment) // TODO: abstract away this requirement + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() + + messageCollector.report( + CompilerMessageSeverity.STRONG_WARNING, + "ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir" + ) + + val outputs = mutableMapOf() + var mainClassFqName: FqName? = null + + for (module in chunk) { + val moduleConfiguration = compilerConfiguration.copy().applyModuleProperties(module, buildFile).apply { + addAll(JVMConfigurationKeys.FRIEND_PATHS, module.getFriendPaths()) + } + val platformSources = linkedSetOf() + val commonSources = linkedSetOf() + + // !! + compilerConfiguration.kotlinSourceRoots.forAllFiles(compilerConfiguration, projectEnvironment.project) { virtualFile, isCommon -> + val file = File(virtualFile.canonicalPath ?: virtualFile.path) + if (!file.isFile) error("TODO: better error: file not found $virtualFile") + if (isCommon) commonSources.add(file) + else platformSources.add(file) + } + + val diagnosticsReporter = DiagnosticReporterFactory.createReporter() + + val (moduleMainClassName, generationState) = compileModule( + ModuleCompilerInput( + TargetId(module), + CommonPlatforms.defaultCommonPlatform, commonSources, + JvmPlatforms.unspecifiedJvmPlatform, platformSources, + moduleConfiguration + ), + ModuleCompilerEnvironment(projectEnvironment, diagnosticsReporter) + ) + FirDiagnosticsCompilerResultsReporter.reportToMessageCollector( + diagnosticsReporter, + messageCollector, + moduleConfiguration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) + ) + outputs[module] = generationState + + // TODO: consider what to do if many modules contain main class + if (mainClassFqName == null) { + mainClassFqName = moduleMainClassName + } + } + + return writeOutputs( + (projectEnvironment as? VfsBasedProjectEnvironment)?.project, + compilerConfiguration, + chunk, + outputs, + mainClassFqName + ) +} + +fun compileModule( + input: ModuleCompilerInput, + environment: ModuleCompilerEnvironment +): ModuleCompilerOutput { + var sourcesScope = environment.projectEnvironment.getSearchScopeByIoFiles(input.platformSources) //!! + val sessionProvider = FirProjectSessionProvider() + val extendedAnalysisMode = input.configuration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS) + + val commonSession = runIf( + input.commonSources.isNotEmpty() && input.configuration.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) + ) { + val commonSourcesScope = environment.projectEnvironment.getSearchScopeByIoFiles(input.commonSources) //!! + sourcesScope -= commonSourcesScope + createSession( + "${input.targetId.name}-common", + input.commonPlatform, + input.configuration, + environment.projectEnvironment, + commonSourcesScope, + CommonPlatformAnalyzerServices, + sessionProvider, + extendedAnalysisMode, + needRegisterJavaElementFinder = false + ) + } + + val session = createSession( + input.targetId.name, + input.platform, + input.configuration, + environment.projectEnvironment, + sourcesScope, + JvmPlatformAnalyzerServices, + sessionProvider, + extendedAnalysisMode, + needRegisterJavaElementFinder = true + ) { + if (commonSession != null) { + sourceDependsOnDependencies(listOf(commonSession.moduleData)) + } + friendDependencies(input.configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList()) + } + + // raw fir + val commonRawFir = commonSession?.buildFirViaLightTree(input.commonSources) + val rawFir = session.buildFirViaLightTree(input.platformSources) + + // resolution + commonSession?.apply { + val (commonScopeSession, commonFir) = runResolution(commonRawFir!!) + // TODO: find out what to do with commonFir + runCheckers(commonScopeSession, commonFir, environment.diagnosticsReporter) + } + + val (scopeSession, fir) = session.runResolution(rawFir) + // checkers + session.runCheckers(scopeSession, fir, environment.diagnosticsReporter) + + val mainClassFqName: FqName? = runIf(input.configuration.get(JVMConfigurationKeys.OUTPUT_JAR) != null) { + findMainClass(fir) + } + + val extensions = JvmGeneratorExtensionsImpl(input.configuration) + + // fir2ir + val irGenerationExtensions = (environment.projectEnvironment as? VfsBasedProjectEnvironment)?.project?.let { IrGenerationExtension.getInstances(it) } + val (irModuleFragment, symbolTable, components) = session.convertToIr(scopeSession, fir, extensions, irGenerationExtensions ?: emptyList()) + + // IR + val codegenFactory = JvmIrCodegenFactory( + input.configuration, + input.configuration.get(CLIConfigurationKeys.PHASE_CONFIG), + jvmGeneratorExtensions = extensions + ) + val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext + + val generationState = GenerationState.Builder( + (environment.projectEnvironment as VfsBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES, + irModuleFragment.descriptor, dummyBindingContext, emptyList()/* !! */, + input.configuration + ).codegenFactory( + codegenFactory + ).targetId( + input.targetId + ).moduleName( + input.targetId.name + ).outDirectory( + input.configuration[JVMConfigurationKeys.OUTPUT_DIRECTORY] + ).onIndependentPartCompilationEnd( + createOutputFilesFlushingCallbackIfPossible(input.configuration) + ).isIrBackend( + true + ).jvmBackendClassResolver( + FirJvmBackendClassResolver(components) + ).diagnosticReporter( + environment.diagnosticsReporter + ).build() + + generationState.beforeCompile() + codegenFactory.generateModuleInFrontendIRMode( + generationState, irModuleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components) + ) + CodegenFactory.doCheckCancelled(generationState) + generationState.factory.done() + + return ModuleCompilerOutput(mainClassFqName, generationState) +} + +fun createSession( + name: String, + platform: TargetPlatform, + moduleConfiguration: CompilerConfiguration, + projectEnvironment: AbstractProjectEnvironment, + sourceScope: AbstractProjectFileSearchScope, + analyzerServices: PlatformDependentAnalyzerServices, + sessionProvider: FirProjectSessionProvider?, + extendedAnalysisMode: Boolean, + needRegisterJavaElementFinder: Boolean, + dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {}, +): FirSession { + var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries() + + val providerAndScopeForIncrementalCompilation = + createComponentsForIncrementalCompilation(moduleConfiguration, projectEnvironment, sourceScope)?.also { + librariesScope -= it.scope + } + + return FirSessionFactory.createSessionWithDependencies( + Name.identifier(name), + platform, + analyzerServices, + externalSessionProvider = sessionProvider, + projectEnvironment, + moduleConfiguration.languageVersionSettings, + sourceScope, + librariesScope, + lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER), + providerAndScopeForIncrementalCompilation, + extensionRegistrars = (projectEnvironment as? VfsBasedProjectEnvironment)?.let { FirExtensionRegistrar.getInstances(it.project) } + ?: emptyList(), + needRegisterJavaElementFinder = needRegisterJavaElementFinder, + dependenciesConfigurator = { + dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() }) + dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() }) + friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList()) + dependenciesConfigurator() + } + ) { + if (extendedAnalysisMode) { + registerExtendedCommonCheckers() + } + } +} + +private fun createComponentsForIncrementalCompilation( + compilerConfiguration: CompilerConfiguration, + projectEnvironment: AbstractProjectEnvironment, + sourceScope: AbstractProjectFileSearchScope +): FirSessionFactory.ProviderAndScopeForIncrementalCompilation? { + val targetIds = compilerConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId) + val incrementalComponents = compilerConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) + if (targetIds == null || incrementalComponents == null) return null + val directoryWithIncrementalPartsFromPreviousCompilation = + compilerConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY] + ?: return null + val incrementalCompilationScope = directoryWithIncrementalPartsFromPreviousCompilation.walk() + .filter { it.extension == "class" } + .let { projectEnvironment.getSearchScopeByIoFiles(it.asIterable()) } + .takeIf { !it.isEmpty } + ?: return null + val packagePartProvider = IncrementalPackagePartProvider( + projectEnvironment.getPackagePartProvider(sourceScope), + targetIds.map(incrementalComponents::getIncrementalCache) + ) + return FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, incrementalCompilationScope) +} + +private class ProjectEnvironmentWithCoreEnvironmentEmulation( + project: Project, + localFileSystem: VirtualFileSystem, + getPackagePartProviderFn: (GlobalSearchScope) -> PackagePartProvider, + val initialRoots: List, + val configuration: CompilerConfiguration +) : VfsBasedProjectEnvironment(project, localFileSystem, getPackagePartProviderFn) { + + val packagePartProviders = mutableListOf() + + override fun getPackagePartProvider(fileSearchScope: AbstractProjectFileSearchScope): PackagePartProvider { + return super.getPackagePartProvider(fileSearchScope).also { + (it as? JvmPackagePartProvider)?.run { + (it as? JvmPackagePartProvider)?.run { + addRoots(initialRoots, configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)) + packagePartProviders += this + (ModuleAnnotationsResolver.getInstance(project) as CliModuleAnnotationsResolver).addPackagePartProvider(this) + } + } + } + } +} + +fun createProjectEnvironment( + configuration: CompilerConfiguration, + parentDisposable: Disposable, + configFiles: EnvironmentConfigFiles, + messageCollector: MessageCollector +): VfsBasedProjectEnvironment { + setupIdeaStandaloneExecution() + val appEnv = KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForProduction(parentDisposable, configuration) + // TODO: get rid of projEnv too - seems that all needed components could be easily extracted + val projectEnvironment = KotlinCoreEnvironment.ProjectEnvironment(parentDisposable, appEnv, configuration) + + projectEnvironment.configureProjectEnvironment(configuration, configFiles) + + val project = projectEnvironment.project + val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) + + val javaFileManager = ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl + + val releaseTarget = configuration.get(JVMConfigurationKeys.JDK_RELEASE) + + val javaModuleFinder = + CliJavaModuleFinder(configuration.get(JVMConfigurationKeys.JDK_HOME), messageCollector, javaFileManager, project, releaseTarget) + + val outputDirectory = + configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory() + ?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath + + val classpathRootsResolver = ClasspathRootsResolver( + PsiManager.getInstance(project), + messageCollector, + configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES), + { contentRootToVirtualFile(it, localFileSystem, projectEnvironment.jarFileSystem, messageCollector) }, + javaModuleFinder, + !configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE), + outputDirectory?.let { localFileSystem.findFileByPath(it) }, + javaFileManager, + releaseTarget + ) + + val (initialRoots, javaModules) = + classpathRootsResolver.convertClasspathRoots(configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS)) + + val (roots, singleJavaFileRoots) = + initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION } + + // REPL and kapt2 update classpath dynamically + val rootsIndex = JvmDependenciesDynamicCompoundIndex().apply { + addIndex(JvmDependenciesIndexImpl(roots)) + indexedRoots.forEach { + projectEnvironment.addSourcesToClasspath(it.file) +// javaFileManager.addToClasspath(it.file) + } + } + + project.registerService( + JavaModuleResolver::class.java, + CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList(), project) + ) + + val finderFactory = CliVirtualFileFinderFactory(rootsIndex, releaseTarget != null) + project.registerService(MetadataFinderFactory::class.java, finderFactory) + project.registerService(VirtualFileFinderFactory::class.java, finderFactory) + + return ProjectEnvironmentWithCoreEnvironmentEmulation( + project, + localFileSystem, + { JvmPackagePartProvider(configuration.languageVersionSettings, it) }, + initialRoots, configuration + ).also { + javaFileManager.initialize( + rootsIndex, + it.packagePartProviders, + SingleJavaFileRootsIndex(singleJavaFileRoots), + configuration.getBoolean(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING) + ) + } +} + +private fun contentRootToVirtualFile(root: JvmContentRoot, locaFileSystem: VirtualFileSystem, jarFileSystem: VirtualFileSystem, messageCollector: MessageCollector): VirtualFile? = + when (root) { + // TODO: find out why non-existent location is not reported for JARs, add comment or fix + is JvmClasspathRoot -> + if (root.file.isFile) jarFileSystem.findJarRoot(root.file) else locaFileSystem.findExistingRoot(root, "Classpath entry", messageCollector) + is JvmModulePathRoot -> + if (root.file.isFile) jarFileSystem.findJarRoot(root.file) else locaFileSystem.findExistingRoot(root, "Java module root", messageCollector) + is JavaSourceRoot -> + locaFileSystem.findExistingRoot(root, "Java source root", messageCollector) + else -> + throw IllegalStateException("Unexpected root: $root") + } + +private fun VirtualFileSystem.findJarRoot(file: File): VirtualFile? = + findFileByPath("$file${URLUtil.JAR_SEPARATOR}") + +private fun VirtualFileSystem.findExistingRoot(root: JvmContentRoot, rootDescription: String, messageCollector: MessageCollector): VirtualFile? { + return findFileByPath(root.file.absolutePath).also { + if (it == null) { + messageCollector.report( + CompilerMessageSeverity.STRONG_WARNING, + "$rootDescription points to a non-existent location: ${root.file}" + ) + } + } +} diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt new file mode 100644 index 00000000000..4507f980e06 --- /dev/null +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/pipeline/compilerPipelineData.kt @@ -0,0 +1,39 @@ +/* + * 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.cli.jvm.compiler.pipeline + +import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector +import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment +import org.jetbrains.kotlin.modules.TargetId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.platform.TargetPlatform +import java.io.File + +// --- + +data class ModuleCompilerInput( + val targetId: TargetId, + val commonPlatform: TargetPlatform, + val commonSources: Collection, + val platform: TargetPlatform, + val platformSources: Collection, + val configuration: CompilerConfiguration +) + +data class ModuleCompilerEnvironment( + val projectEnvironment: AbstractProjectEnvironment, + val diagnosticsReporter: BaseDiagnosticsCollector +) + +data class ModuleCompilerOutput( + val mainClassName: FqName?, + val generationState: GenerationState +) + +// --- + diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 24f67d77660..aca3e4941e8 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -166,7 +166,8 @@ class Fir2IrConverter( private fun registerFileAndClasses(file: FirFile, moduleFragment: IrModuleFragment) { val fileEntry = when (file.origin) { - FirDeclarationOrigin.Source -> PsiIrFileEntry(file.psi as KtFile) + FirDeclarationOrigin.Source -> + file.psi?.let { PsiIrFileEntry(it as KtFile) } ?: NaiveSourceBasedFileEntryImpl(file.path ?: file.name) FirDeclarationOrigin.Synthetic -> NaiveSourceBasedFileEntryImpl(file.name) else -> error("Unsupported file origin: ${file.origin}") } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt index a70b7e84c83..253d55be2d9 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirFrontendFacade.kt @@ -12,9 +12,9 @@ import com.intellij.psi.search.ProjectScope import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension -import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectFileSearchScope import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM +import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots import org.jetbrains.kotlin.config.JVMConfigurationKeys @@ -36,7 +36,9 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives import org.jetbrains.kotlin.test.directives.model.DirectivesContainer -import org.jetbrains.kotlin.test.model.* +import org.jetbrains.kotlin.test.model.FrontendFacade +import org.jetbrains.kotlin.test.model.FrontendKinds +import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.* class FirFrontendFacade( @@ -83,7 +85,7 @@ class FirFrontendFacade( module.targetPlatform, module.targetPlatform.getAnalyzerServices(), moduleInfoProvider.firSessionProvider, - PsiBasedProjectEnvironment( + VfsBasedProjectEnvironment( project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), { packagePartProviderFactory.invoke(it) } ), diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt index 7ea4432900e..737b057bea5 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/AbstractFirBaseDiagnosticsTest.kt @@ -21,13 +21,13 @@ import org.jetbrains.kotlin.checkers.diagnostics.SyntaxErrorDiagnostic import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectFileSearchScope import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM +import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.diagnostics.KtDiagnostic +import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.fir.builder.BodyBuildingMode import org.jetbrains.kotlin.fir.builder.PsiHandlingMode import org.jetbrains.kotlin.fir.builder.RawFirBuilder @@ -89,7 +89,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() { info.platform, info.analyzerServices, externalSessionProvider = sessionProvider, - PsiBasedProjectEnvironment( + VfsBasedProjectEnvironment( project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), { environment.createPackagePartProvider(it) } ), diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt index e33f6fdf5bb..6d334e658fa 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/fir/SessionTestUtils.kt @@ -10,8 +10,8 @@ import com.intellij.openapi.vfs.StandardFileSystems import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.ObsoleteTestInfrastructure -import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.PsiBasedProjectFileSearchScope +import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.fir.session.FirSessionFactory @@ -63,7 +63,11 @@ fun createSessionForTests( JvmPlatforms.unspecifiedJvmPlatform, JvmPlatformAnalyzerServices, externalSessionProvider = null, - PsiBasedProjectEnvironment(project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), getPackagePartProvider), + VfsBasedProjectEnvironment( + project, + VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), + getPackagePartProvider + ), languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, PsiBasedProjectFileSearchScope(sourceScope), PsiBasedProjectFileSearchScope(librariesScope),