[LL FIR] create a single builtin symbol provider which will be reused for the whole project when no stdlib is available

Previously, every kotlin stdlib containing builtins was searched causing resolution ambiguities.

^KTIJ-26760 fixed
This commit is contained in:
Ilya Kirillov
2023-08-24 13:42:52 +02:00
committed by Space Team
parent e8db349f24
commit 5ab408859b
2 changed files with 36 additions and 43 deletions
@@ -6,20 +6,20 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.analysis.decompiler.psi.BuiltInsVirtualFileProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirBuiltinsAndCloneableSessionProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirBuiltinsAndCloneableSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.createStubBasedFirSymbolProviderForBuiltins
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.StubBasedFirDeserializedSymbolProvider
import org.jetbrains.kotlin.analysis.project.structure.KtBuiltinsModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.fir.session.registerCommonJavaComponents
import org.jetbrains.kotlin.fir.session.registerModuleData
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.isCommon
@@ -46,7 +47,6 @@ import org.jetbrains.kotlin.platform.isJs
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import java.util.concurrent.ConcurrentHashMap
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
@@ -97,7 +97,7 @@ class LLFirBuiltinsSessionFactory(private val project: Project) {
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
val symbolProvider = createCompositeSymbolProvider(this) {
add(createStubBasedFirSymbolProviderForBuiltins(project, session, moduleData, kotlinScopeProvider))
add(StubBasedBuiltInsSymbolProvider(project, session, moduleData, kotlinScopeProvider))
add(FirExtensionSyntheticFunctionInterfaceProvider(session, moduleData, kotlinScopeProvider))
add(FirCloneableSymbolProvider(session, moduleData, kotlinScopeProvider))
}
@@ -114,6 +114,36 @@ class LLFirBuiltinsSessionFactory(private val project: Project) {
}
}
private class StubBasedBuiltInsSymbolProvider(
project: Project,
session: FirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
) : StubBasedFirDeserializedSymbolProvider(
session,
SingleModuleDataProvider(moduleData),
kotlinScopeProvider,
project,
createBuiltInsScope(project),
FirDeclarationOrigin.BuiltIns
) {
private val syntheticFunctionInterfaceProvider = FirBuiltinSyntheticFunctionInterfaceProvider(
session,
moduleData,
kotlinScopeProvider
)
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
return super.getClassLikeSymbolByClassId(classId)
?: syntheticFunctionInterfaceProvider.getClassLikeSymbolByClassId(classId)
}
}
private fun createBuiltInsScope(project: Project): GlobalSearchScope {
val builtInFiles = BuiltInsVirtualFileProvider.getInstance().getBuiltInVirtualFiles()
return GlobalSearchScope.filesScope(project, builtInFiles)
}
private fun TargetPlatform.getAnalyzerServices() = when {
isJvm() -> JvmPlatformAnalyzerServices
isJs() -> JvmPlatformAnalyzerServices/*TODO*/
@@ -11,16 +11,12 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInFileType
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSyntheticFunctionInterfaceProvider
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.library.KLIB_METADATA_FILE_EXTENSION
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
internal fun createStubBasedFirSymbolProviderForClassFiles(
@@ -56,39 +52,6 @@ internal fun createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(
fileFilter = { file -> file.extension == KLIB_METADATA_FILE_EXTENSION },
)
internal fun createStubBasedFirSymbolProviderForBuiltins(
project: Project,
session: FirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
): StubBasedFirDeserializedSymbolProvider {
return createFirSymbolProviderForScopeLimitedByFiles(
project, DelegatingGlobalSearchScope.allScope(project),
fileFilter = { file -> file.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION },
symbolProviderFactory = { reducedScope: GlobalSearchScope ->
object : StubBasedFirDeserializedSymbolProvider(
session,
SingleModuleDataProvider(moduleData),
kotlinScopeProvider,
project,
reducedScope,
FirDeclarationOrigin.BuiltIns
) {
private val syntheticFunctionInterfaceProvider = FirBuiltinSyntheticFunctionInterfaceProvider(
session,
moduleData,
kotlinScopeProvider
)
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
return super.getClassLikeSymbolByClassId(classId)
?: syntheticFunctionInterfaceProvider.getClassLikeSymbolByClassId(classId)
}
}
}
)
}
internal fun createStubBasedFirSymbolProviderForScopeLimitedByFiles(
project: Project,
baseScope: GlobalSearchScope,