Abstract FIR cli pipeline from core environment and related entities

This commit is contained in:
Ilya Chernikov
2021-08-03 12:17:22 +02:00
committed by TeamCityServer
parent 40614507d3
commit caa44e413d
21 changed files with 497 additions and 211 deletions
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.cli.common
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.isSubpackageOf
import org.jetbrains.kotlin.psi.KtFile
@@ -28,11 +28,11 @@ import org.jetbrains.kotlin.utils.KotlinPaths
import java.io.File
import kotlin.system.exitProcess
fun checkKotlinPackageUsage(environment: KotlinCoreEnvironment, files: Collection<KtFile>): Boolean {
if (environment.configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE)) {
fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collection<KtFile>): Boolean {
if (configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE)) {
return true
}
val messageCollector = environment.configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
val kotlinPackage = FqName("kotlin")
for (file in files) {
if (file.packageFqName.isSubpackageOf(kotlinPackage)) {
@@ -5,17 +5,8 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.VirtualFileSystem
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
@@ -26,6 +17,7 @@ import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
@@ -34,16 +26,23 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
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.declarations.FirFile
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.pipeline.buildFirFromKtFiles
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.resolve.ScopeSession
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.fir.session.FirSessionFactory.createSessionWithDependencies
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.Module
@@ -66,42 +65,36 @@ import kotlin.collections.set
object FirKotlinToJvmBytecodeCompiler {
fun compileModulesUsingFrontendIR(
environment: KotlinCoreEnvironment,
projectEnvironment: AbstractProjectEnvironment,
projectConfiguration: CompilerConfiguration,
messageCollector: MessageCollector,
allSources: List<KtFile>,
buildFile: File?,
chunk: List<Module>,
extendedAnalysisMode: Boolean
): Boolean {
val project = environment.project
val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER)
val performanceManager = projectConfiguration.get(CLIConfigurationKeys.PERF_MANAGER)
environment.messageCollector.report(
messageCollector.report(
STRONG_WARNING,
"ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir"
)
val psiFinderExtensionPoint = PsiElementFinder.EP.getPoint(project)
if (psiFinderExtensionPoint.extensionList.any { it is JavaElementFinder }) {
psiFinderExtensionPoint.unregisterExtension(JavaElementFinder::class.java)
}
val projectConfiguration = environment.configuration
val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
val outputs = newLinkedHashMapWithExpectedSize<Module, GenerationState>(chunk.size)
val targetIds = environment.configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
val incrementalComponents = environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
val targetIds = projectConfiguration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
val incrementalComponents = projectConfiguration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
val isMultiModuleChunk = chunk.size > 1
for (module in chunk) {
val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile)
val context = CompilationContext(
module,
project,
environment,
module.getSourceFiles(
allSources, (projectEnvironment as? PsiBasedProjectEnvironment)?.localFileSystem, isMultiModuleChunk, buildFile
),
projectEnvironment,
messageCollector,
moduleConfiguration,
localFileSystem,
isMultiModuleChunk,
buildFile,
performanceManager,
targetIds,
incrementalComponents,
@@ -109,8 +102,6 @@ object FirKotlinToJvmBytecodeCompiler {
)
val generationState = context.compileModule() ?: return false
outputs[module] = generationState
Disposer.dispose(environment.project)
}
val mainClassFqName: FqName? =
@@ -118,17 +109,18 @@ object FirKotlinToJvmBytecodeCompiler {
TODO(".jar output is not yet supported for -Xuse-fir: KT-42868")
else null
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
return writeOutputs(
(projectEnvironment as? PsiBasedProjectEnvironment)?.project, projectConfiguration, chunk, outputs, mainClassFqName
)
}
private fun CompilationContext.compileModule(): GenerationState? {
performanceManager?.notifyAnalysisStarted()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = module.getSourceFiles(environment, localFileSystem, isMultiModuleChunk, buildFile)
if (!checkKotlinPackageUsage(environment, ktFiles)) return null
if (!checkKotlinPackageUsage(moduleConfiguration, allSources)) return null
val firAnalyzerFacade = runFrontend(ktFiles).also {
val firResult = runFrontend(allSources).also {
performanceManager?.notifyAnalysisFinished()
} ?: return null
@@ -136,16 +128,15 @@ object FirKotlinToJvmBytecodeCompiler {
performanceManager?.notifyIRTranslationStarted()
val extensions = JvmGeneratorExtensionsImpl(moduleConfiguration)
val fir2IrResult = firAnalyzerFacade.convertToIr(extensions)
val session = firAnalyzerFacade.session
val fir2IrResult = firResult.session.convertToIr(firResult.scopeSession, firResult.fir, extensions)
performanceManager?.notifyIRTranslationFinished()
val generationState = runBackend(
ktFiles,
allSources,
fir2IrResult,
extensions,
session
firResult.session
)
performanceManager?.notifyIRGenerationFinished()
@@ -155,22 +146,28 @@ object FirKotlinToJvmBytecodeCompiler {
return generationState
}
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>): FirAnalyzerFacade? {
private class FirResult(
val session: FirSession,
val scopeSession: ScopeSession,
val fir: List<FirFile>
)
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>): FirResult? {
@Suppress("NAME_SHADOWING")
var ktFiles = ktFiles
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, environment.messageCollector).isHasErrors or errorsFound
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, messageCollector).isHasErrors or errorsFound
}
var sourceScope = GlobalSearchScope.filesWithoutLibrariesScope(project, ktFiles.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
var sourceScope = (projectEnvironment as PsiBasedProjectEnvironment).getSearchScopeByPsiFiles(ktFiles) +
projectEnvironment.getSearchScopeForProjectJavaSources()
var librariesScope = ProjectScope.getLibrariesScope(project)
var librariesScope = projectEnvironment.getSearchScopeForProjectLibraries()
val providerAndScopeForIncrementalCompilation = createComponentsForIncrementalCompilation(sourceScope)
providerAndScopeForIncrementalCompilation?.scope?.let {
librariesScope = librariesScope.intersectWith(GlobalSearchScope.notScope(it))
librariesScope -= it
}
val languageVersionSettings = moduleConfiguration.languageVersionSettings
@@ -183,7 +180,7 @@ object FirKotlinToJvmBytecodeCompiler {
name: String,
platform: TargetPlatform,
analyzerServices: PlatformDependentAnalyzerServices,
sourceScope: GlobalSearchScope,
sourceScope: AbstractProjectFileSearchScope,
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {}
): FirSession {
return createSessionWithDependencies(
@@ -191,32 +188,30 @@ object FirKotlinToJvmBytecodeCompiler {
platform,
analyzerServices,
externalSessionProvider = sessionProvider,
project,
projectEnvironment,
languageVersionSettings,
sourceScope,
librariesScope,
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
lookupTracker = moduleConfiguration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
providerAndScopeForIncrementalCompilation,
getPackagePartProvider = { environment.createPackagePartProvider(it) },
dependenciesConfigurator = {
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
dependenciesConfigurator()
},
sessionConfigurator = {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
)
) {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
}
val commonSession = runIf(
languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) && commonKtFiles.isNotEmpty()
) {
val commonSourcesScope = GlobalSearchScope.filesWithoutLibrariesScope(project, commonKtFiles.map { it.virtualFile })
sourceScope = sourceScope.intersectWith(GlobalSearchScope.notScope(commonSourcesScope))
val commonSourcesScope = projectEnvironment.getSearchScopeByPsiFiles(commonKtFiles)
sourceScope -= commonSourcesScope
ktFiles = ktFiles.filterNot { it.isCommonSource == true }
createSession(
"${module.getModuleName()}-common",
@@ -238,41 +233,39 @@ object FirKotlinToJvmBytecodeCompiler {
friendDependencies(module.getFriendPaths())
}
val commonAnalyzerFacade = commonSession?.let { FirAnalyzerFacade(it, languageVersionSettings, commonKtFiles) }
val firAnalyzerFacade = FirAnalyzerFacade(session, languageVersionSettings, ktFiles)
val commonRawFir = commonSession?.buildFirFromKtFiles(commonKtFiles)
val rawFir = session.buildFirFromKtFiles(ktFiles)
commonAnalyzerFacade?.runResolution()
val allFirDiagnostics = mutableListOf<FirDiagnostic>()
commonAnalyzerFacade?.runCheckers()?.values?.flattenTo(allFirDiagnostics)
firAnalyzerFacade.runResolution()
firAnalyzerFacade.runCheckers().values.flattenTo(allFirDiagnostics)
val hasErrors = FirDiagnosticsCompilerResultsReporter.reportDiagnostics(allFirDiagnostics, environment.messageCollector)
commonSession?.apply {
val (commonScopeSession, commonFir) = runResolution(commonRawFir!!)
runCheckers(commonScopeSession, commonFir).values.flattenTo(allFirDiagnostics)
}
return firAnalyzerFacade.takeUnless { syntaxErrors || hasErrors }
val (scopeSession, fir) = session.runResolution(rawFir)
session.runCheckers(scopeSession, fir).values.flattenTo(allFirDiagnostics)
val hasErrors = FirDiagnosticsCompilerResultsReporter.reportDiagnostics(allFirDiagnostics, messageCollector)
return if (syntaxErrors || hasErrors) null else FirResult(session, scopeSession, fir)
}
private fun CompilationContext.createComponentsForIncrementalCompilation(
sourceScope: GlobalSearchScope
sourceScope: AbstractProjectFileSearchScope
): FirSessionFactory.ProviderAndScopeForIncrementalCompilation? {
if (targetIds == null || incrementalComponents == null) return null
val fileSystem = environment.projectEnvironment.environment.localFileSystem
val directoryWithIncrementalPartsFromPreviousCompilation =
moduleConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY]
?: return null
val previouslyCompiledFiles = directoryWithIncrementalPartsFromPreviousCompilation.walk()
val incrementalCompilationScope = directoryWithIncrementalPartsFromPreviousCompilation.walk()
.filter { it.extension == "class" }
.mapNotNull { fileSystem.findFileByIoFile(it) }
.toList()
.takeIf { it.isNotEmpty() }
.let { projectEnvironment.getSearchScopeByIoFiles(it.asIterable()) }
.takeIf { !it.isEmpty }
?: return null
val packagePartProvider = IncrementalPackagePartProvider(
environment.createPackagePartProvider(sourceScope),
projectEnvironment.getPackagePartProvider(sourceScope),
targetIds.map(incrementalComponents::getIncrementalCache)
)
val incrementalCompilationScope = GlobalSearchScope.filesWithoutLibrariesScope(
project,
previouslyCompiledFiles
)
return FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, incrementalCompilationScope)
}
@@ -291,7 +284,7 @@ object FirKotlinToJvmBytecodeCompiler {
)
val generationState = GenerationState.Builder(
environment.project, ClassBuilderFactories.BINARIES,
(projectEnvironment as PsiBasedProjectEnvironment).project, ClassBuilderFactories.BINARIES,
moduleFragment.descriptor, dummyBindingContext, ktFiles,
moduleConfiguration
).codegenFactory(
@@ -326,7 +319,7 @@ object FirKotlinToJvmBytecodeCompiler {
generationState.collectedExtraJvmDiagnostics,
dummyBindingContext.diagnostics
),
environment.messageCollector
messageCollector
)
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
@@ -335,12 +328,10 @@ object FirKotlinToJvmBytecodeCompiler {
private class CompilationContext(
val module: Module,
val project: Project,
val environment: KotlinCoreEnvironment,
val allSources: List<KtFile>,
val projectEnvironment: AbstractProjectEnvironment,
val messageCollector: MessageCollector,
val moduleConfiguration: CompilerConfiguration,
val localFileSystem: VirtualFileSystem,
val isMultiModuleChunk: Boolean,
val buildFile: File?,
val performanceManager: CommonCompilerPerformanceManager?,
val targetIds: List<TargetId>?,
val incrementalComponents: IncrementalCompilationComponents?,
@@ -84,7 +84,19 @@ object KotlinToJVMBytecodeCompiler {
val projectConfiguration = environment.configuration
if (projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR)) {
val extendedAnalysisMode = projectConfiguration.getBoolean(CommonConfigurationKeys.USE_FIR_EXTENDED_CHECKERS)
return FirKotlinToJvmBytecodeCompiler.compileModulesUsingFrontendIR(environment, buildFile, chunk, extendedAnalysisMode)
val projectEnvironment =
PsiBasedProjectEnvironment(
environment.project,
VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
{ environment.createPackagePartProvider(it) }
)
return FirKotlinToJvmBytecodeCompiler.compileModulesUsingFrontendIR(
projectEnvironment,
environment.configuration,
environment.messageCollector,
environment.getSourceFiles(),
buildFile, chunk, extendedAnalysisMode
)
}
val result = repeatAnalysisIfNeeded(analyze(environment), environment)
@@ -106,14 +118,14 @@ object KotlinToJVMBytecodeCompiler {
for (module in chunk) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = module.getSourceFiles(environment, localFileSystem, chunk.size > 1, buildFile)
if (!checkKotlinPackageUsage(environment, ktFiles)) return false
val ktFiles = module.getSourceFiles(environment.getSourceFiles(), localFileSystem, chunk.size > 1, buildFile)
if (!checkKotlinPackageUsage(environment.configuration, ktFiles)) return false
val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile)
outputs[module] = generate(environment, moduleConfiguration, result, ktFiles, module)
}
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
return writeOutputs(environment.project, projectConfiguration, chunk, outputs, mainClassFqName)
}
@@ -171,7 +183,7 @@ object KotlinToJVMBytecodeCompiler {
moduleVisibilityManager.addFriendPath(path)
}
if (!checkKotlinPackageUsage(environment, environment.getSourceFiles())) return false
if (!checkKotlinPackageUsage(environment.configuration, environment.getSourceFiles())) return false
val generationState = analyzeAndGenerate(environment) ?: return false
@@ -0,0 +1,120 @@
/*
* 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
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.VirtualFileSystem
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.java.FirJavaElementFinder
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
import java.io.File
class PsiBasedProjectFileSearchScope(val psiSearchScope: GlobalSearchScope) : AbstractProjectFileSearchScope {
override val isEmpty: Boolean
get() = psiSearchScope == GlobalSearchScope.EMPTY_SCOPE
override operator fun minus(other: AbstractProjectFileSearchScope): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(psiSearchScope.intersectWith(GlobalSearchScope.notScope(other.asPsiSearchScope())))
override operator fun plus(other: AbstractProjectFileSearchScope): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(psiSearchScope.uniteWith(other.asPsiSearchScope()))
override operator fun not(): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(GlobalSearchScope.notScope(psiSearchScope))
}
class PsiBasedProjectEnvironment(
val project: Project,
val localFileSystem: VirtualFileSystem,
val getPackagePartProviderFn: (GlobalSearchScope) -> PackagePartProvider
) : AbstractProjectEnvironment {
override fun getKotlinClassFinder(fileSearchScope: AbstractProjectFileSearchScope): KotlinClassFinder =
VirtualFileFinderFactory.getInstance(project).create(fileSearchScope.asPsiSearchScope())
override fun getJavaClassFinder(fileSearchScope: AbstractProjectFileSearchScope): JavaClassFinder =
JavaClassFinderImpl().apply {
this.setProjectInstance(project)
this.setScope(fileSearchScope.asPsiSearchScope())
}
override fun getJavaSymbolProvider(
firSession: FirSession,
baseModuleData: FirModuleData,
fileSearchScope: AbstractProjectFileSearchScope
): JavaSymbolProvider =
JavaSymbolProvider(firSession, baseModuleData, project, fileSearchScope.asPsiSearchScope())
override fun getPackagePartProvider(fileSearchScope: AbstractProjectFileSearchScope): PackagePartProvider =
getPackagePartProviderFn(fileSearchScope.asPsiSearchScope())
override fun registerAsJavaElementFinder(firSession: FirSession) {
val psiFinderExtensionPoint = PsiElementFinder.EP.getPoint(project)
if (psiFinderExtensionPoint.extensionList.any { it is JavaElementFinder }) {
psiFinderExtensionPoint.unregisterExtension(JavaElementFinder::class.java)
}
psiFinderExtensionPoint.registerExtension(FirJavaElementFinder(firSession, project), project)
}
override fun getSearchScopeByIoFiles(files: Iterable<File>, allowOutOfProjectRoots: Boolean): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(
files
.mapNotNull { localFileSystem.findFileByPath(it.absolutePath) }
.toList()
.takeIf { it.isNotEmpty() }
?.let {
if (allowOutOfProjectRoots) GlobalSearchScope.filesWithLibrariesScope(project, it)
else GlobalSearchScope.filesWithoutLibrariesScope(project, it)
} ?: GlobalSearchScope.EMPTY_SCOPE
)
fun getSearchScopeByPsiFiles(files: Iterable<PsiFile>, allowOutOfProjectRoots: Boolean= false): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(
files.map { it.virtualFile }.let {
if (allowOutOfProjectRoots) GlobalSearchScope.filesWithLibrariesScope(project, it)
else GlobalSearchScope.filesWithoutLibrariesScope(project, it)
}
)
override fun getSearchScopeForProjectLibraries(): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(ProjectScope.getLibrariesScope(project))
override fun getSearchScopeForProjectJavaSources(): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
}
private fun AbstractProjectFileSearchScope.asPsiSearchScope() =
when {
this === AbstractProjectFileSearchScope.EMPTY -> GlobalSearchScope.EMPTY_SCOPE
this === AbstractProjectFileSearchScope.ANY -> GlobalSearchScope.notScope(GlobalSearchScope.EMPTY_SCOPE)
else -> (this as PsiBasedProjectFileSearchScope).psiSearchScope
}
fun KotlinCoreEnvironment.toAbstractProjectEnvironment(): AbstractProjectEnvironment =
PsiBasedProjectEnvironment(
project, VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
{ createPackagePartProvider(it) }
)
fun GlobalSearchScope.toAbstractProjectFileSearchScope(): AbstractProjectFileSearchScope =
PsiBasedProjectFileSearchScope(this)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileSystem
@@ -29,8 +30,8 @@ import org.jetbrains.kotlin.psi.KtFile
import java.io.File
fun Module.getSourceFiles(
environment: KotlinCoreEnvironment,
localFileSystem: VirtualFileSystem,
allSourceFiles: List<KtFile>,
localFileSystem: VirtualFileSystem?,
multiModuleChunk: Boolean,
buildFile: File?
): List<KtFile> {
@@ -39,17 +40,17 @@ fun Module.getSourceFiles(
assert(buildFile != null) { "Compiling multiple modules, but build file is null" }
val (moduleSourceDirs, moduleSourceFiles) =
getBuildFilePaths(buildFile, getSourceFiles())
.mapNotNull(localFileSystem::findFileByPath)
.mapNotNull(localFileSystem!!::findFileByPath)
.partition(VirtualFile::isDirectory)
environment.getSourceFiles().filter { file ->
allSourceFiles.filter { file ->
val virtualFile = file.virtualFile
virtualFile in moduleSourceFiles || moduleSourceDirs.any { dir ->
VfsUtilCore.isAncestor(dir, virtualFile, true)
}
}
} else {
environment.getSourceFiles()
allSourceFiles
}
}
@@ -115,7 +116,7 @@ fun writeOutput(
}
fun writeOutputs(
environment: KotlinCoreEnvironment,
project: Project?,
projectConfiguration: CompilerConfiguration,
chunk: List<Module>,
outputs: Map<Module, GenerationState>,
@@ -133,7 +134,7 @@ fun writeOutputs(
if (projectConfiguration.getBoolean(JVMConfigurationKeys.COMPILE_JAVA)) {
val singleModule = chunk.singleOrNull()
if (singleModule != null) {
return JavacWrapper.getInstance(environment.project).use {
return JavacWrapper.getInstance(project!!).use {
it.compile(File(singleModule.getOutputDirectory()))
}
} else {
@@ -142,7 +143,6 @@ fun writeOutputs(
"A chunk contains multiple modules (${chunk.joinToString { it.getModuleName() }}). " +
"-Xuse-javac option couldn't be used to compile java files"
)
JavacWrapper.getInstance(environment.project).close()
}
}
@@ -101,7 +101,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
return ExitCode.COMPILATION_ERROR
}
checkKotlinPackageUsage(environment, environment.getSourceFiles())
checkKotlinPackageUsage(environment.configuration, environment.getSourceFiles())
try {
val metadataVersion =