From a43ed57be533f7cc82fcc81b25d3488dfc23be17 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Tue, 19 Jul 2022 17:14:53 +0200 Subject: [PATCH] [LL FIR] add basic supoport of handling not under content root modules --- .../level/api/fir/LLFirResolveStateService.kt | 14 ++- .../LLFirNonUnderContentRootSessionFactory.kt | 111 ++++++++++++++++++ ...yOrLibrarySourceResolvableModuleSession.kt | 1 + .../LLFirNonUnderContentRootSession.kt | 21 ++++ .../sessions/LLFirSessionProviderStorage.kt | 4 + .../api/fir/sessions/LLFirSourcesSession.kt | 1 + ...nderContentRootResolvableResolveSession.kt | 38 ++++++ 7 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNonUnderContentRootSession.kt create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirNotUnderContentRootResolvableResolveSession.kt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt index 502ff6e1f1e..663f36e7862 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/LLFirResolveStateService.kt @@ -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") } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt new file mode 100644 index 00000000000..d4310aeda8f --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirNonUnderContentRootSessionFactory.kt @@ -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() + + fun getNonUnderContentRootSession( + module: KtNotUnderContentRootModule, + sessions: MutableMap + ): 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) + } +} + diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt index 8d257963a85..83b8d123b12 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirLibraryOrLibrarySourceResolvableModuleSession.kt @@ -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( diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNonUnderContentRootSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNonUnderContentRootSession.kt new file mode 100644 index 00000000000..ad2d0c599c5 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNonUnderContentRootSession.kt @@ -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) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt index c5c1dee5959..2fa232fe7c3 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionProviderStorage.kt @@ -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() @@ -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}") } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt index 5a06d9293aa..3fa5f9f4c44 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSourcesSession.kt @@ -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 diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirNotUnderContentRootResolvableResolveSession.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirNotUnderContentRootResolvableResolveSession.kt new file mode 100644 index 00000000000..6775cf0e9e3 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/state/LLFirNotUnderContentRootResolvableResolveSession.kt @@ -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 = + emptyList() + + override fun collectDiagnosticsForFile(ktFile: KtFile, filter: DiagnosticCheckerFilter): Collection = + emptyList() + + override fun getModuleKind(module: KtModule): ModuleKind { + return when { + module == this.useSiteKtModule -> ModuleKind.RESOLVABLE_MODULE + else -> ModuleKind.BINARY_MODULE + } + } +} +