[AA] stub-based library symbol providers for non-JVM platforms

Use existing stub-based JVM library symbol provider for .knm and
.kotlin_metadata files. The only real difference is the scope filtering
by file types

KT-58769
This commit is contained in:
Pavel Kirpichenkov
2023-07-01 13:55:56 +03:00
committed by teamcity
parent 129b930bd7
commit b316aa7d1d
17 changed files with 284 additions and 122 deletions
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.Stand
import org.jetbrains.kotlin.analysis.decompiled.light.classes.ClsJavaStubByVirtualFileCache
import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory
import org.jetbrains.kotlin.analysis.decompiler.psi.BuiltInDefinitionFile
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInFileType
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
@@ -94,5 +95,7 @@ object AnalysisApiBaseTestServiceRegistrar: AnalysisApiTestServiceRegistrar() {
}
override fun registerApplicationServices(application: MockApplication, testServices: TestServices) {
testServices.environmentManager.getApplicationEnvironment().registerFileType(KotlinBuiltInFileType, "kotlin_builtins")
testServices.environmentManager.getApplicationEnvironment().registerFileType(KotlinBuiltInFileType, "kotlin_metadata")
}
}
@@ -23,6 +23,7 @@ import com.intellij.util.indexing.FileContentImpl
import com.intellij.util.io.URLUtil
import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInDecompiler
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInFileType
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
import org.jetbrains.kotlin.analysis.decompiler.stub.file.KotlinClsStubBuilder
import org.jetbrains.kotlin.analysis.project.structure.KtModule
@@ -315,10 +316,20 @@ public class KotlinStaticDeclarationProviderFactory(
override fun visitFile(file: VirtualFile): Boolean {
if (!file.isDirectory) {
val fileContent = FileContentImpl.createByFile(file)
if (binaryClassCache.isKotlinJvmCompiledFile(file, fileContent.content) &&
file.fileType == JavaClassFileType.INSTANCE
) {
(KotlinClsStubBuilder().buildFileStub(fileContent) as? KotlinFileStubImpl)?.let { stubs.put(file, it) }
when {
binaryClassCache.isKotlinJvmCompiledFile(file, fileContent.content) &&
file.fileType == JavaClassFileType.INSTANCE -> {
(KotlinClsStubBuilder().buildFileStub(fileContent) as? KotlinFileStubImpl)?.let { stubs.put(file, it) }
}
file.fileType == KotlinBuiltInFileType
&& file.extension != BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION -> {
(builtInDecompiler.stubBuilder.buildFileStub(fileContent) as? KotlinFileStubImpl)?.let {
stubs.put(
file,
it
)
}
}
}
}
return true
@@ -55,7 +55,7 @@ object FirStandaloneServiceRegistrar : AnalysisApiStandaloneServiceRegistrar {
registerService(LLFirBuiltinsSessionFactory::class.java)
registerService(JvmFirDeserializedSymbolProviderFactory::class.java, JvmStubBasedDeserializedSymbolProviderFactory::class.java)
registerService(KotlinReferenceProviderContributor::class.java, KotlinFirReferenceContributor::class.java)
registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerFirImpl::class.java )
registerService(ReadWriteAccessChecker::class.java, ReadWriteAccessCheckerFirImpl::class.java)
}
}
@@ -21,6 +21,7 @@ dependencies {
api(project(":analysis:analysis-api-impl-barebone"))
api(project(":js:js.config"))
api(project(":compiler:cli-common"))
implementation(project(":analysis:decompiled:decompiler-to-psi"))
testImplementation(project(":analysis:analysis-api-fir"))
implementation(project(":compiler:frontend.common"))
implementation(project(":compiler:fir:entrypoint"))
@@ -15,7 +15,7 @@ import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.annotations.TestOnly
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.JvmStubBasedFirDeserializedSymbolProvider
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
@@ -100,7 +100,7 @@ class LLFirBuiltinsSessionFactory(private val project: Project) {
val symbolProvider = createCompositeSymbolProvider(this) {
val moduleDataProvider = SingleModuleDataProvider(moduleData)
add(
object : JvmStubBasedFirDeserializedSymbolProvider(
object : StubBasedFirDeserializedSymbolProvider(
session,
moduleDataProvider,
kotlinScopeProvider,
@@ -1,82 +0,0 @@
/*
* 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 com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirDependenciesSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirJavaFacadeForBinaries
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
import org.jetbrains.kotlin.analysis.providers.createPackagePartProvider
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.load.java.createJavaClassFinder
import org.jetbrains.kotlin.utils.addIfNotNull
internal object LLFirLibraryProviderFactory {
fun createLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
builtinSymbolProvider: FirSymbolProvider,
): LLFirModuleWithDependenciesSymbolProvider {
return LLFirModuleWithDependenciesSymbolProvider(
session,
providers = createProjectLibraryProvidersForScope(
session,
moduleData,
kotlinScopeProvider,
project,
builtinTypes,
scope
),
LLFirDependenciesSymbolProvider(session, listOf(builtinSymbolProvider)),
)
}
fun createProjectLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
): List<FirSymbolProvider> {
val moduleDataProvider = SingleModuleDataProvider(moduleData)
val packagePartProvider = project.createPackagePartProvider(scope)
return buildList {
val firJavaFacade = LLFirJavaFacadeForBinaries(session, builtinTypes, project.createJavaClassFinder(scope), moduleDataProvider)
val service = project.getService(JvmFirDeserializedSymbolProviderFactory::class.java)
addAll(
service.createJvmFirDeserializedSymbolProviders(
project,
session,
moduleData,
kotlinScopeProvider,
moduleDataProvider,
firJavaFacade,
packagePartProvider,
scope
)
)
addIfNotNull(
OptionalAnnotationClassesProvider.createIfNeeded(
session,
moduleDataProvider,
kotlinScopeProvider,
packagePartProvider
)
)
}
}
}
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.JvmStubBasedFirDeserializedSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.StubBasedFirDeserializedSymbolProvider
import org.jetbrains.kotlin.analysis.utils.collections.buildSmartList
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.resolve.providers.FirNullSymbolNamesProvider
@@ -45,7 +45,7 @@ internal class LLFirModuleWithDependenciesSymbolProvider(
classId: ClassId,
classLikeDeclaration: KtClassLikeDeclaration,
): FirClassLikeSymbol<*>? = providers.firstNotNullOfOrNull { provider ->
if (provider !is JvmStubBasedFirDeserializedSymbolProvider) return@firstNotNullOfOrNull null
if (provider !is StubBasedFirDeserializedSymbolProvider) return@firstNotNullOfOrNull null
provider.getClassLikeSymbolByClassId(classId, classLikeDeclaration)
}
@@ -63,7 +63,7 @@ internal class LLFirModuleWithDependenciesSymbolProvider(
callableDeclaration: KtCallableDeclaration,
) {
providers.forEach { provider ->
if (provider !is JvmStubBasedFirDeserializedSymbolProvider) return@forEach
if (provider !is StubBasedFirDeserializedSymbolProvider) return@forEach
destination.addIfNotNull(provider.getTopLevelCallableSymbol(packageFqName, shortName, callableDeclaration))
}
}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.analysis.utils.trackers.CompositeModificationTracker
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.analysis.checkersComponent
@@ -59,6 +60,38 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
abstract fun createLibrarySession(module: KtModule): LLFirLibraryOrLibrarySourceResolvableModuleSession
abstract fun createBinaryLibrarySession(module: KtBinaryModule): LLFirLibrarySession
private fun createLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
builtinSymbolProvider: FirSymbolProvider,
): LLFirModuleWithDependenciesSymbolProvider {
return LLFirModuleWithDependenciesSymbolProvider(
session,
providers = createProjectLibraryProvidersForScope(
session,
moduleData,
kotlinScopeProvider,
project,
builtinTypes,
scope
),
LLFirDependenciesSymbolProvider(session, listOf(builtinSymbolProvider)),
)
}
abstract fun createProjectLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
): List<FirSymbolProvider>
fun createScriptSession(module: KtScriptModule): LLFirScriptSession {
val platform = module.platform
val builtinsSession = LLFirBuiltinsSessionFactory.getInstance(project).getBuiltinsSession(platform)
@@ -348,7 +381,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
val librariesSearchScope = ProjectScope.getLibrariesScope(project)
.intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope))
val restLibrariesProvider = LLFirLibraryProviderFactory.createProjectLibraryProvidersForScope(
val restLibrariesProvider = createProjectLibraryProvidersForScope(
session, moduleData, scopeProvider,
project, builtinTypes, librariesSearchScope
)
@@ -398,7 +431,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
val symbolProvider = LLFirLibraryProviderFactory.createLibraryProvidersForScope(
val symbolProvider = createLibraryProvidersForScope(
this,
moduleData,
kotlinScopeProvider,
@@ -6,18 +6,28 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.createStubBasedFirSymbolProviderForCommonMetadataFiles
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.providers.createPackagePartProvider
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirVisibilityChecker
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
import org.jetbrains.kotlin.fir.session.DefaultCallConflictResolverFactory
import org.jetbrains.kotlin.utils.addIfNotNull
@OptIn(SessionConfiguration::class)
internal class LLFirCommonSessionFactory(project: Project) : LLFirAbstractSessionFactory(project) {
@@ -61,6 +71,31 @@ internal class LLFirCommonSessionFactory(project: Project) : LLFirAbstractSessio
}
}
override fun createProjectLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
): List<FirSymbolProvider> {
val moduleDataProvider = SingleModuleDataProvider(moduleData)
val packagePartProvider = project.createPackagePartProvider(scope)
return buildList {
add(createStubBasedFirSymbolProviderForCommonMetadataFiles(project, scope, session, moduleDataProvider, kotlinScopeProvider))
add(createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(project, scope, session, moduleDataProvider, kotlinScopeProvider))
addIfNotNull(
OptionalAnnotationClassesProvider.createIfNeeded(
session,
moduleDataProvider,
kotlinScopeProvider,
packagePartProvider
)
)
}
}
private fun LLFirSession.registerModuleIndependentCommonComponents() {
register(FirVisibilityChecker::class, FirVisibilityChecker.Default)
register(ConeCallConflictResolverFactory::class, DefaultCallConflictResolverFactory)
@@ -6,10 +6,13 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirVisibilityChecker
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
@@ -18,6 +21,7 @@ import org.jetbrains.kotlin.fir.analysis.js.checkers.FirJsPlatformDiagnosticSupp
import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
import org.jetbrains.kotlin.fir.session.JsCallConflictResolverFactory
@@ -65,6 +69,17 @@ internal class LLFirJsSessionFactory(project: Project) : LLFirAbstractSessionFac
}
}
override fun createProjectLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
): List<FirSymbolProvider> {
return emptyList() // TODO(kirpichenkov)
}
private fun LLFirSession.registerModuleIndependentJsComponents() {
register(FirVisibilityChecker::class, FirVisibilityChecker.Default)
register(ConeCallConflictResolverFactory::class, JsCallConflictResolverFactory)
@@ -6,17 +6,24 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.*
import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.providers.createPackagePartProvider
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
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.load.java.createJavaClassFinder
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
import org.jetbrains.kotlin.utils.addIfNotNull
@OptIn(SessionConfiguration::class)
internal class LLFirJvmSessionFactory(project: Project) : LLFirAbstractSessionFactory(project) {
@@ -74,4 +81,40 @@ internal class LLFirJvmSessionFactory(project: Project) : LLFirAbstractSessionFa
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
}
}
override fun createProjectLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
): List<FirSymbolProvider> {
val moduleDataProvider = SingleModuleDataProvider(moduleData)
val packagePartProvider = project.createPackagePartProvider(scope)
return buildList {
val firJavaFacade = LLFirJavaFacadeForBinaries(session, builtinTypes, project.createJavaClassFinder(scope), moduleDataProvider)
val deserializedSymbolProviderFactory = project.getService(JvmFirDeserializedSymbolProviderFactory::class.java)
addAll(
deserializedSymbolProviderFactory.createJvmFirDeserializedSymbolProviders(
project,
session,
moduleData,
kotlinScopeProvider,
moduleDataProvider,
firJavaFacade,
packagePartProvider,
scope
)
)
addIfNotNull(
OptionalAnnotationClassesProvider.createIfNeeded(
session,
moduleDataProvider,
kotlinScopeProvider,
packagePartProvider
)
)
}
}
}
@@ -6,18 +6,27 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirModuleWithDependenciesSymbolProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.providers.createPackagePartProvider
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirVisibilityChecker
import org.jetbrains.kotlin.fir.SessionConfiguration
import org.jetbrains.kotlin.fir.analysis.FirDefaultOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
import org.jetbrains.kotlin.fir.session.DefaultCallConflictResolverFactory
import org.jetbrains.kotlin.utils.addIfNotNull
@OptIn(SessionConfiguration::class)
internal class LLFirNativeSessionFactory(project: Project) : LLFirAbstractSessionFactory(project) {
@@ -62,6 +71,33 @@ internal class LLFirNativeSessionFactory(project: Project) : LLFirAbstractSessio
}
}
override fun createProjectLibraryProvidersForScope(
session: LLFirSession,
moduleData: LLFirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider,
project: Project,
builtinTypes: BuiltinTypes,
scope: GlobalSearchScope,
): List<FirSymbolProvider> {
val moduleDataProvider = SingleModuleDataProvider(moduleData)
val packagePartProvider = project.createPackagePartProvider(scope)
return buildList {
add(
createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(
project, scope, session, moduleDataProvider, kotlinScopeProvider
)
)
addIfNotNull(
OptionalAnnotationClassesProvider.createIfNeeded(
session,
moduleDataProvider,
kotlinScopeProvider,
packagePartProvider
)
)
}
}
private fun LLFirSession.registerModuleIndependentNativeComponents() {
register(FirVisibilityChecker::class, FirVisibilityChecker.Default)
register(ConeCallConflictResolverFactory::class, DefaultCallConflictResolverFactory)
@@ -91,8 +91,7 @@ class LLFirSessionCache(private val project: Project) {
targetPlatform.all { it is JvmPlatform } -> LLFirJvmSessionFactory(project)
targetPlatform.all { it is JsPlatform } -> LLFirJsSessionFactory(project)
targetPlatform.all { it is NativePlatform } -> LLFirNativeSessionFactory(project)
// TODO(kirpichenkov): falling back to JVM. Common session factory hasn't been implemented correctly yet and breaks tests
else -> LLFirJvmSessionFactory(project)
else -> LLFirCommonSessionFactory(project)
}
}
}
@@ -7,15 +7,13 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserializatio
import com.intellij.ide.highlighter.JavaClassFileType
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 org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.JvmFirDeserializedSymbolProviderFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirJavaSymbolProvider
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin.Library
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.java.FirJavaFacade
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -37,26 +35,10 @@ class JvmStubBasedDeserializedSymbolProviderFactory : JvmFirDeserializedSymbolPr
return buildList {
//stub based provider here works over kotlin-only indices and thus provides only kotlin declarations
//in order to find java declarations, one need to explicitly setup java symbol provider.
//for ProtoBuf based provider (used in compiler), there is no need in separated java provider,
//for ProtoBuf based provider (used in compiler), there is no need in separated java provider,
//because all declarations are retrieved at once and are not distinguished
add(
JvmStubBasedFirDeserializedSymbolProvider(
session,
moduleDataProvider,
kotlinScopeProvider,
project,
object : DelegatingGlobalSearchScope(project, scope) {
override fun contains(file: VirtualFile): Boolean {
if (file.extension != JavaClassFileType.INSTANCE.defaultExtension) {
return false
}
return super.contains(file)
}
},
FirDeclarationOrigin.Library
)
)
add(createStubBasedFirSymbolProviderForClassFiles(project, scope, session, moduleDataProvider, kotlinScopeProvider))
add(LLFirJavaSymbolProvider(session, moduleData, project, scope))
}
}
}
}
@@ -35,7 +35,7 @@ import java.util.ArrayList
typealias DeserializedTypeAliasPostProcessor = (FirTypeAliasSymbol) -> Unit
/**
* [JvmStubBasedFirDeserializedSymbolProvider] works over existing stubs,
* [StubBasedFirDeserializedSymbolProvider] works over existing stubs,
* retrieving them by classId/callableId from [KotlinDeclarationProvider].
*
* It works in IDE only, in standalone mode works [JvmClassFileBasedSymbolProvider].
@@ -46,7 +46,7 @@ typealias DeserializedTypeAliasPostProcessor = (FirTypeAliasSymbol) -> Unit
*
* Same as [JvmClassFileBasedSymbolProvider], resulting fir elements are already resolved.
*/
internal open class JvmStubBasedFirDeserializedSymbolProvider(
internal open class StubBasedFirDeserializedSymbolProvider(
session: FirSession,
moduleDataProvider: SingleModuleDataProvider,
private val kotlinScopeProvider: FirKotlinScopeProvider,
@@ -0,0 +1,88 @@
/*
* Copyright 2010-2023 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.stubBased.deserialization
import com.intellij.ide.highlighter.JavaClassFileType
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 org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInFileType
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.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.library.KLIB_METADATA_FILE_EXTENSION
internal fun createStubBasedFirSymbolProviderForClassFiles(
project: Project,
baseScope: GlobalSearchScope,
session: FirSession,
moduleDataProvider: SingleModuleDataProvider,
kotlinScopeProvider: FirKotlinScopeProvider,
): FirSymbolProvider = createStubBasedFirSymbolProviderForScopeLimitedByFiles(
project, baseScope, session, moduleDataProvider, kotlinScopeProvider,
fileFilter = { file -> file.extension == JavaClassFileType.INSTANCE.defaultExtension },
)
internal fun createStubBasedFirSymbolProviderForCommonMetadataFiles(
project: Project,
baseScope: GlobalSearchScope,
session: FirSession,
moduleDataProvider: SingleModuleDataProvider,
kotlinScopeProvider: FirKotlinScopeProvider,
): FirSymbolProvider = createStubBasedFirSymbolProviderForScopeLimitedByFiles(
project, baseScope, session, moduleDataProvider, kotlinScopeProvider,
fileFilter = { file -> file.fileType == KotlinBuiltInFileType },
)
internal fun createStubBasedFirSymbolProviderForKotlinNativeMetadataFiles(
project: Project,
baseScope: GlobalSearchScope,
session: FirSession,
moduleDataProvider: SingleModuleDataProvider,
kotlinScopeProvider: FirKotlinScopeProvider,
): FirSymbolProvider = createStubBasedFirSymbolProviderForScopeLimitedByFiles(
project, baseScope, session, moduleDataProvider, kotlinScopeProvider,
fileFilter = { file -> file.extension == KLIB_METADATA_FILE_EXTENSION },
)
internal fun createStubBasedFirSymbolProviderForScopeLimitedByFiles(
project: Project,
baseScope: GlobalSearchScope,
session: FirSession,
moduleDataProvider: SingleModuleDataProvider,
kotlinScopeProvider: FirKotlinScopeProvider,
fileFilter: (VirtualFile) -> Boolean,
): StubBasedFirDeserializedSymbolProvider {
return createFirSymbolProviderForScopeLimitedByFiles(
project, baseScope, fileFilter,
symbolProviderFactory = { reducedScope: GlobalSearchScope ->
StubBasedFirDeserializedSymbolProvider(
session, moduleDataProvider, kotlinScopeProvider, project, reducedScope, FirDeclarationOrigin.Library,
)
}
)
}
private fun <T : FirSymbolProvider> createFirSymbolProviderForScopeLimitedByFiles(
project: Project,
baseScope: GlobalSearchScope,
fileFilter: (VirtualFile) -> Boolean,
symbolProviderFactory: (reducedScope: GlobalSearchScope) -> T,
): T {
val scopeWithFileFiltering = object : DelegatingGlobalSearchScope(project, baseScope) {
override fun contains(file: VirtualFile): Boolean {
if (!fileFilter(file)) {
return false
}
return super.contains(file)
}
}
return symbolProviderFactory(scopeWithFileFiltering)
}
@@ -1,6 +1,4 @@
// FIR_IDENTICAL
// IGNORE_REVERSED_RESOLVE
// IGNORE_DIAGNOSTIC_API
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER
// !LANGUAGE: +MultiPlatformProjects