[LL FIR] add basic supoport of handling not under content root modules

This commit is contained in:
Ilya Kirillov
2022-07-19 17:14:53 +02:00
parent 7b48c892be
commit a43ed57be5
7 changed files with 186 additions and 4 deletions
@@ -14,11 +14,9 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProviderStorage
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirLibraryOrLibrarySourceResolvableResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirNotUnderContentRootResolvableResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableResolveSession
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.analysis.utils.caches.strongCachedValue
import java.util.concurrent.ConcurrentHashMap
@@ -64,6 +62,14 @@ internal class LLFirResolveSessionService(project: Project) {
sessionProvider,
)
}
is KtNotUnderContentRootModule -> {
LLFirNotUnderContentRootResolvableResolveSession(
useSiteSession.moduleComponents.globalResolveComponents,
sessionProviderStorage.project,
useSiteKtModule,
sessionProvider,
)
}
else -> {
error("Unexpected $useSiteKtModule")
}
@@ -0,0 +1,111 @@
/*
* Copyright 2010-2022 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.analysis.low.level.api.fir.project.structure
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseManager
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirDependentModuleProvidersBySessions
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirNonUnderContentRootSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableModuleSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionInvalidator
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
import org.jetbrains.kotlin.fir.extensions.FirEmptyPredicateBasedProvider
import org.jetbrains.kotlin.fir.extensions.FirPredicateBasedProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.*
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
import java.util.concurrent.ConcurrentHashMap
internal class LLFirNonUnderContentRootSessionFactory(private val project: Project) {
private val cache = ConcurrentHashMap<KtNotUnderContentRootModule, LLFirResolvableModuleSession>()
fun getNonUnderContentRootSession(
module: KtNotUnderContentRootModule,
sessions: MutableMap<KtModule, LLFirResolvableModuleSession>
): LLFirResolvableModuleSession {
return cache.getOrPut(module) { createSession(module, LLFirSessionInvalidator { cache.clear() }) }.also { sessions[module] = it }
}
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
private fun createSession(
module: KtNotUnderContentRootModule,
sessionInvalidator: LLFirSessionInvalidator
): LLFirResolvableModuleSession {
val builtinsSession = LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(JvmPlatforms.unspecifiedJvmPlatform)
val languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT
val scopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
val globalResolveComponents = LLFirGlobalResolveComponents(module, project)
val components = LLFirModuleResolveComponents(module, globalResolveComponents, scopeProvider)
val contentScope = module.contentScope
val session = LLFirNonUnderContentRootSession(module, project, components, builtinsSession.builtinTypes)
components.session = session
return session.apply session@{
val moduleData = LLFirKtModuleBasedModuleData(module).apply { bindSession(this@session) }
registerModuleData(moduleData)
register(FirKotlinScopeProvider::class, scopeProvider)
registerIdeComponents(project)
registerCommonComponents(languageVersionSettings)
registerCommonJavaComponents(JavaModuleResolver.getInstance(project))
registerResolveComponents()
registerJavaSpecificResolveComponents()
val provider = LLFirProvider(
this,
components,
project.createDeclarationProvider(contentScope),
project.createPackageProvider(contentScope)
)
register(FirProvider::class, provider)
register(FirPhaseManager::class, LLFirPhaseManager(sessionInvalidator))
val dependencyProvider = LLFirDependentModuleProvidersBySessions(this) {
add(builtinsSession)
}
register(
FirSymbolProvider::class,
LLFirModuleWithDependenciesSymbolProvider(
this,
dependencyProvider,
providers = listOfNotNull(
provider.symbolProvider,
)
)
)
register(FirPredicateBasedProvider::class, FirEmptyPredicateBasedProvider())
register(FirDependenciesSymbolProvider::class, dependencyProvider)
register(FirDependenciesSymbolProvider::class, dependencyProvider)
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
}
}
companion object {
fun getInstance(project: Project): LLFirNonUnderContentRootSessionFactory =
project.getService(LLFirNonUnderContentRootSessionFactory::class.java)
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveCompone
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
import org.jetbrains.kotlin.fir.BuiltinTypes
internal class LLFirLibraryOrLibrarySourceResolvableModuleSession(
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2020 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.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirFileBuilder
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
internal class LLFirNonUnderContentRootSession @PrivateSessionConstructor constructor(
override val ktModule: KtNotUnderContentRootModule,
override val project: Project,
override val moduleComponents: LLFirModuleResolveComponents,
builtinTypes: BuiltinTypes,
) : LLFirResolvableModuleSession(builtinTypes)
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker
import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsSessionFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirNonUnderContentRootSessionFactory
class LLFirSessionProviderStorage(val project: Project) {
private val sessionsCache = ConcurrentHashMap<KtModule, FromModuleViewSessionCache>()
@@ -59,6 +60,9 @@ class LLFirSessionProviderStorage(val project: Project) {
configureSession = configureSession,
)
}
is KtNotUnderContentRootModule ->
LLFirNonUnderContentRootSessionFactory.getInstance(project)
.getNonUnderContentRootSession(useSiteKtModule, sessions)
else -> error("Unexpected ${useSiteKtModule::class.simpleName}")
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirFileBuilder
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2022 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.analysis.low.level.api.fir.state
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.diagnostics.KtPsiDiagnostic
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
internal class LLFirNotUnderContentRootResolvableResolveSession(
override val globalComponents: LLFirGlobalResolveComponents,
override val project: Project,
override val useSiteKtModule: KtModule,
sessionProvider: LLFirSessionProvider,
) : LLFirResolvableResolveSession(sessionProvider) {
override fun getDiagnostics(element: KtElement, filter: DiagnosticCheckerFilter): List<KtPsiDiagnostic> =
emptyList()
override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection<KtPsiDiagnostic> =
emptyList()
override fun getModuleKind(module: KtModule): ModuleKind {
return when {
module == this.useSiteKtModule -> ModuleKind.RESOLVABLE_MODULE
else -> ModuleKind.BINARY_MODULE
}
}
}