FIR: Add IncrementalPackagePartsProvider usage in cli...

also refactor IncrementalPackagePartsProvider and parents to simplify
usage
This commit is contained in:
Ilya Chernikov
2021-02-02 10:34:14 +01:00
parent f8d50d585d
commit 3e458a1efb
10 changed files with 85 additions and 37 deletions
@@ -38,7 +38,7 @@ class JvmPackagePartProvider(
languageVersionSettings: LanguageVersionSettings,
private val scope: GlobalSearchScope
) : JvmPackagePartProviderBase<VirtualFile>() {
private val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
override val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
override val loadedModules: MutableList<ModuleMappingInfo<VirtualFile>> = SmartList()
@@ -61,6 +61,7 @@ import org.jetbrains.kotlin.fir.createSessionWithDependencies
import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
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
@@ -308,6 +309,8 @@ object KotlinToJVMBytecodeCompiler {
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)
for (module in chunk) {
performanceManager?.notifyAnalysisStarted()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
@@ -334,7 +337,14 @@ object KotlinToJVMBytecodeCompiler {
sourceScope,
librariesScope,
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
environment::createPackagePartProvider
getPackagePartProvider = { environment.createPackagePartProvider(it) },
getAdditionalModulePackagePartProvider = {
if (targetIds == null || incrementalComponents == null) null
else IncrementalPackagePartProvider(
environment.createPackagePartProvider(it),
targetIds.map(incrementalComponents::getIncrementalCache)
)
}
) {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
@@ -217,7 +217,7 @@ object TopDownAnalyzerFacadeForJVM {
val partProvider = packagePartProvider(sourceScope).let { fragment ->
if (targetIds == null || incrementalComponents == null) fragment
else IncrementalPackagePartProvider(fragment, targetIds.map(incrementalComponents::getIncrementalCache), storageManager)
else IncrementalPackagePartProvider(fragment, targetIds.map(incrementalComponents::getIncrementalCache))
}
// Note that it's necessary to create container for sources _after_ creation of container for dependencies because
@@ -19,8 +19,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
import org.jetbrains.kotlin.fir.analysis.checkersComponent
import org.jetbrains.kotlin.fir.analysis.extensions.additionalCheckers
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.caches.FirThreadUnsafeCachesFactory
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers
import org.jetbrains.kotlin.fir.extensions.BunchOfRegisteredExtensions
@@ -67,6 +65,8 @@ object FirSessionFactory {
sessionProvider: FirProjectSessionProvider,
scope: GlobalSearchScope,
project: Project,
additionalPackagePartProvider: PackagePartProvider? = null,
additionalScope: GlobalSearchScope? = null,
dependenciesProvider: FirSymbolProvider? = null,
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
lookupTracker: LookupTracker? = null,
@@ -83,14 +83,25 @@ object FirSessionFactory {
val firProvider = FirProviderImpl(this, kotlinScopeProvider)
register(FirProvider::class, firProvider)
val deserializedJvmSymbolsProvider =
if (additionalPackagePartProvider == null) null
else {
val javaSymbolProvider = JavaSymbolProvider(this, project, additionalScope ?: scope)
makeDeserializedJvmSymbolsProvider(
project, additionalScope ?: scope, additionalPackagePartProvider, javaSymbolProvider, kotlinScopeProvider
)
}
register(
FirSymbolProvider::class,
FirCompositeSymbolProvider(
this,
listOf(
listOfNotNull(
firProvider.symbolProvider,
JavaSymbolProvider(this, project, scope),
dependenciesProvider ?: FirDependenciesSymbolProviderImpl(this)
dependenciesProvider ?: FirDependenciesSymbolProviderImpl(this),
deserializedJvmSymbolsProvider
)
) as FirSymbolProvider
)
@@ -113,12 +124,6 @@ object FirSessionFactory {
packagePartProvider: PackagePartProvider,
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
): FirLibrarySession {
val javaClassFinder = JavaClassFinderImpl().apply {
this.setProjectInstance(project)
this.setScope(scope)
}
val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(scope)
return FirLibrarySession(moduleInfo, sessionProvider).apply {
registerThreadUnsafeCaches()
registerCommonComponents(languageVersionSettings)
@@ -127,17 +132,14 @@ object FirSessionFactory {
val kotlinScopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
val deserializedJvmSymbolsProvider = makeDeserializedJvmSymbolsProvider(
project, scope, packagePartProvider, javaSymbolProvider, kotlinScopeProvider
)
val symbolProvider = FirCompositeSymbolProvider(
this,
listOf(
KotlinDeserializedJvmSymbolsProvider(
this, project,
packagePartProvider,
javaSymbolProvider,
kotlinClassFinder,
javaClassFinder,
kotlinScopeProvider
),
deserializedJvmSymbolsProvider,
FirBuiltinSymbolProvider(this, kotlinScopeProvider),
FirCloneableSymbolProvider(this, kotlinScopeProvider),
javaSymbolProvider,
@@ -149,6 +151,25 @@ object FirSessionFactory {
}
}
private fun FirSession.makeDeserializedJvmSymbolsProvider(
project: Project,
scope: GlobalSearchScope,
packagePartProvider: PackagePartProvider,
javaSymbolProvider: JavaSymbolProvider,
kotlinScopeProvider: KotlinScopeProvider
): KotlinDeserializedJvmSymbolsProvider {
val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(scope)
val javaClassFinder = JavaClassFinderImpl().apply {
this.setProjectInstance(project)
this.setScope(scope)
}
return KotlinDeserializedJvmSymbolsProvider(
this, project, packagePartProvider, javaSymbolProvider, kotlinClassFinder, javaClassFinder, kotlinScopeProvider
)
}
@TestOnly
fun createEmptySession(): FirSession {
return object : FirSession(null) {}
@@ -26,7 +26,8 @@ fun createSessionWithDependencies(
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope,
lookupTracker: LookupTracker?,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?,
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
): FirSession {
return createSessionWithDependencies(
@@ -36,7 +37,8 @@ fun createSessionWithDependencies(
sourceScope,
librariesScope,
lookupTracker,
packagePartProvider,
getPackagePartProvider,
getAdditionalModulePackagePartProvider,
sessionConfigurator
) {
FirJvmModuleInfo(name, it, friendPaths, outputDirectory)
@@ -50,7 +52,8 @@ fun createSessionWithDependencies(
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope,
lookupTracker: LookupTracker?,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?,
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
): FirSession {
return createSessionWithDependencies(
@@ -60,7 +63,8 @@ fun createSessionWithDependencies(
sourceScope,
librariesScope,
lookupTracker,
packagePartProvider,
getPackagePartProvider,
getAdditionalModulePackagePartProvider,
sessionConfigurator
) {
FirJvmModuleInfo(module, it)
@@ -74,7 +78,8 @@ private inline fun createSessionWithDependencies(
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope,
lookupTracker: LookupTracker?,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?,
noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
moduleInfoProvider: (dependencies: List<ModuleInfo>) -> ModuleInfo,
): FirSession {
@@ -82,13 +87,15 @@ private inline fun createSessionWithDependencies(
val librariesModuleInfo = FirJvmModuleInfo.createForLibraries(moduleName)
FirSessionFactory.createLibrarySession(
librariesModuleInfo, provider, librariesScope,
project, packagePartProvider(librariesScope)
project, getPackagePartProvider(librariesScope)
)
return FirSessionFactory.createJavaModuleBasedSession(
moduleInfoProvider(listOf(librariesModuleInfo)),
provider,
sourceScope,
project,
additionalPackagePartProvider = getAdditionalModulePackagePartProvider(sourceScope),
additionalScope = librariesScope,
languageVersionSettings = languageVersionSettings,
lookupTracker = lookupTracker,
init = sessionConfigurator
@@ -24,16 +24,21 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.ClassData
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.storage.StorageManager
class IncrementalPackagePartProvider(
private val parent: PackagePartProvider,
incrementalCaches: List<IncrementalCache>,
storageManager: StorageManager
incrementalCaches: List<IncrementalCache>
) : PackagePartProvider {
lateinit var deserializationConfiguration: DeserializationConfiguration
private val moduleMappings = storageManager.createLazyValue {
init {
(parent as? JvmPackagePartProviderBase<*>)?.deserializationConfiguration?.let {
deserializationConfiguration = it
}
}
private val moduleMappings by lazy {
incrementalCaches.map { cache ->
ModuleMapping.loadModuleMapping(cache.getModuleMappingData(), "<incremental>", deserializationConfiguration) { version ->
// Incremental compilation should fall back to full rebuild if the minor component of the metadata version has changed
@@ -43,7 +48,7 @@ class IncrementalPackagePartProvider(
}
override fun findPackageParts(packageFqName: String): List<String> {
return (moduleMappings().mapNotNull { it.findPackageParts(packageFqName) }.flatMap { it.parts } +
return (moduleMappings.mapNotNull { it.findPackageParts(packageFqName) }.flatMap { it.parts } +
parent.findPackageParts(packageFqName)).distinct()
}
@@ -52,6 +57,6 @@ class IncrementalPackagePartProvider(
}
override fun getAllOptionalAnnotationClasses(): List<ClassData> =
moduleMappings().flatMap((JvmPackagePartProviderBase)::getAllOptionalAnnotationClasses) +
moduleMappings.flatMap((JvmPackagePartProviderBase)::getAllOptionalAnnotationClasses) +
parent.getAllOptionalAnnotationClasses()
}
@@ -104,7 +104,7 @@ object GenerationUtils {
val scope = GlobalSearchScope.filesScope(project, files.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
val librariesScope = ProjectScope.getLibrariesScope(project)
val session = createSessionForTests(project, scope, librariesScope, "main", packagePartProvider = packagePartProvider)
val session = createSessionForTests(project, scope, librariesScope, "main", getPackagePartProvider = packagePartProvider)
// TODO: add running checkers and check that it's safe to compile
val firAnalyzerFacade = FirAnalyzerFacade(session, configuration.languageVersionSettings, files)
@@ -37,7 +37,8 @@ fun createSessionForTests(
moduleName: String = "TestModule",
friendPaths: List<String> = emptyList(),
lookupTracker: LookupTracker? = null,
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider? = { null }
): FirSession {
return createSessionWithDependencies(
Name.identifier(moduleName),
@@ -48,7 +49,8 @@ fun createSessionForTests(
sourceScope,
librariesScope,
lookupTracker,
packagePartProvider
getPackagePartProvider,
getAdditionalModulePackagePartProvider
)
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
import org.jetbrains.kotlin.metadata.jvm.deserialization.PackageParts
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.ClassData
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider
abstract class JvmPackagePartProviderBase<MappingsKey> : PackagePartProvider, MetadataPartProvider {
@@ -18,6 +19,8 @@ abstract class JvmPackagePartProviderBase<MappingsKey> : PackagePartProvider, Me
protected abstract val loadedModules: MutableList<ModuleMappingInfo<MappingsKey>>
abstract val deserializationConfiguration : DeserializationConfiguration
override fun findPackageParts(packageFqName: String): List<String> {
val rootToPackageParts: Collection<PackageParts> = getPackageParts(packageFqName)
if (rootToPackageParts.isEmpty()) return emptyList()
@@ -19,7 +19,7 @@ class PackagePartFromClassLoaderProvider(
languageVersionSettings: LanguageVersionSettings,
messageCollector: MessageCollector
) : JvmPackagePartProviderBase<String>() {
private val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
override val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
override val loadedModules: MutableList<ModuleMappingInfo<String>> = SmartList()