From b316aa7d1d6641227f98590bd883ca7ad3390d08 Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Sat, 1 Jul 2023 13:55:56 +0300 Subject: [PATCH] [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 --- .../AnalysisApiBaseTestServiceRegistrar.kt | 3 + .../impl/KotlinStaticDeclarationProvider.kt | 19 +++- .../FirStandaloneServiceRegistrar.kt | 2 +- analysis/low-level-api-fir/build.gradle.kts | 1 + .../structure/LLFirBuiltinsSessionFactory.kt | 4 +- .../structure/LLFirLibraryProviderFactory.kt | 82 ----------------- ...FirModuleWithDependenciesSymbolProvider.kt | 6 +- .../sessions/LLFirAbstractSessionFactory.kt | 37 +++++++- .../fir/sessions/LLFirCommonSessionFactory.kt | 35 ++++++++ .../api/fir/sessions/LLFirJsSessionFactory.kt | 15 ++++ .../fir/sessions/LLFirJvmSessionFactory.kt | 43 +++++++++ .../fir/sessions/LLFirNativeSessionFactory.kt | 36 ++++++++ .../api/fir/sessions/LLFirSessionCache.kt | 3 +- ...bBasedDeserializedSymbolProviderFactory.kt | 26 +----- ...StubBasedFirDeserializedSymbolProvider.kt} | 4 +- .../StubBasedFirSymbolProviderFactories.kt | 88 +++++++++++++++++++ .../testsWithStdLib/annotations/Volatile.kt | 2 - 17 files changed, 284 insertions(+), 122 deletions(-) delete mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibraryProviderFactory.kt rename analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/{JvmStubBasedFirDeserializedSymbolProvider.kt => StubBasedFirDeserializedSymbolProvider.kt} (99%) create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirSymbolProviderFactories.kt diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt index 58a554ef606..7cc6e1b9f8c 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt @@ -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") } } diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt index 451c4f0ebbb..0a46c9bb36d 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt @@ -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 diff --git a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/FirStandaloneServiceRegistrar.kt b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/FirStandaloneServiceRegistrar.kt index d0e2c0e42e2..c0428195e87 100644 --- a/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/FirStandaloneServiceRegistrar.kt +++ b/analysis/analysis-api-standalone/analysis-api-fir-standalone-base/src/org/jetbrains/kotlin/analysis/api/standalone/base/project/structure/FirStandaloneServiceRegistrar.kt @@ -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) } } diff --git a/analysis/low-level-api-fir/build.gradle.kts b/analysis/low-level-api-fir/build.gradle.kts index cb12f3fa995..dd25be19caf 100644 --- a/analysis/low-level-api-fir/build.gradle.kts +++ b/analysis/low-level-api-fir/build.gradle.kts @@ -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")) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt index 9add1881ca5..7716e3c859e 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt @@ -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, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibraryProviderFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibraryProviderFactory.kt deleted file mode 100644 index 4f7651037ea..00000000000 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirLibraryProviderFactory.kt +++ /dev/null @@ -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 { - 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 - ) - ) - } - } -} \ No newline at end of file diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirModuleWithDependenciesSymbolProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirModuleWithDependenciesSymbolProvider.kt index 32d307e8144..1f9dbbd6e6b 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirModuleWithDependenciesSymbolProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirModuleWithDependenciesSymbolProvider.kt @@ -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)) } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt index 152633a4231..df200002ce0 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirAbstractSessionFactory.kt @@ -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 + 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, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirCommonSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirCommonSessionFactory.kt index 5386ff89589..051475765b0 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirCommonSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirCommonSessionFactory.kt @@ -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 { + 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) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJsSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJsSessionFactory.kt index 79b4b224de9..ecd7dd9c618 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJsSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJsSessionFactory.kt @@ -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 { + return emptyList() // TODO(kirpichenkov) + } + private fun LLFirSession.registerModuleIndependentJsComponents() { register(FirVisibilityChecker::class, FirVisibilityChecker.Default) register(ConeCallConflictResolverFactory::class, JsCallConflictResolverFactory) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt index 6e3cf8150eb..ce406a38454 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirJvmSessionFactory.kt @@ -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 { + 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 + ) + ) + } + } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNativeSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNativeSessionFactory.kt index 579fceae24b..c263b9ec622 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNativeSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirNativeSessionFactory.kt @@ -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 { + 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) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt index b47ff247b58..aca6518990d 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt @@ -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) } } } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt index 87225c458aa..06d9beaea29 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedDeserializedSymbolProviderFactory.kt @@ -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)) } } -} \ No newline at end of file +} diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedFirDeserializedSymbolProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirDeserializedSymbolProvider.kt similarity index 99% rename from analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedFirDeserializedSymbolProvider.kt rename to analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirDeserializedSymbolProvider.kt index 298b7ea57b3..94c6f9d39ff 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/JvmStubBasedFirDeserializedSymbolProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirDeserializedSymbolProvider.kt @@ -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, diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirSymbolProviderFactories.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirSymbolProviderFactories.kt new file mode 100644 index 00000000000..6b1c4378993 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirSymbolProviderFactories.kt @@ -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 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) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt index 17cf2fbcbcd..8171dbceeb9 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/Volatile.kt @@ -1,6 +1,4 @@ // FIR_IDENTICAL -// IGNORE_REVERSED_RESOLVE -// IGNORE_DIAGNOSTIC_API // !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER // !LANGUAGE: +MultiPlatformProjects