diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/LLStubBasedLibrarySymbolProviderFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/LLStubBasedLibrarySymbolProviderFactory.kt index 8a6fc70ccff..4a43722be93 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/LLStubBasedLibrarySymbolProviderFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/LLStubBasedLibrarySymbolProviderFactory.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.psi.KtFile @LLFirInternals class LLStubBasedLibrarySymbolProviderFactory(private val project: Project) : LLFirLibrarySymbolProviderFactory() { @@ -107,7 +108,6 @@ private class StubBasedBuiltInsSymbolProvider( kotlinScopeProvider, project, createBuiltInsScope(project), - FirDeclarationOrigin.BuiltIns ) { private val syntheticFunctionInterfaceProvider = FirBuiltinSyntheticFunctionInterfaceProvider( session, @@ -119,6 +119,11 @@ private class StubBasedBuiltInsSymbolProvider( return super.getClassLikeSymbolByClassId(classId) ?: syntheticFunctionInterfaceProvider.getClassLikeSymbolByClassId(classId) } + + override fun getDeclarationOriginFor(file: KtFile): FirDeclarationOrigin { + // this provider operates only on builtins files, no need to check anything + return FirDeclarationOrigin.BuiltIns + } } private fun createBuiltInsScope(project: Project): GlobalSearchScope { diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirDeserializedSymbolProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirDeserializedSymbolProvider.kt index 964e556b2c0..0bfc5f631bf 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirDeserializedSymbolProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/stubBased/deserialization/StubBasedFirDeserializedSymbolProvider.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.load.kotlin.FacadeClassSource import org.jetbrains.kotlin.name.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.stubs.impl.* @@ -53,7 +54,6 @@ internal open class StubBasedFirDeserializedSymbolProvider( private val kotlinScopeProvider: FirKotlinScopeProvider, project: Project, scope: GlobalSearchScope, - private val initialOrigin: FirDeclarationOrigin ) : LLFirKotlinSymbolProvider(session) { private val moduleData = moduleDataProvider.getModuleData(null) @@ -83,6 +83,24 @@ internal open class StubBasedFirDeserializedSymbolProvider( final override val packageProvider = project.createPackageProvider(scope) + /** + * Computes the origin for the declarations coming from [file]. + * + * We assume that a stub Kotlin declaration might come only from Library or from BuiltIns. + * We do the decision based upon the extension of the [file]. + * + * This method is left open so the inheritors can provide more optimal/strict implementations. + */ + protected open fun getDeclarationOriginFor(file: KtFile): FirDeclarationOrigin { + val virtualFile = file.virtualFile + + return if (virtualFile.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION) { + FirDeclarationOrigin.BuiltIns + } else { + FirDeclarationOrigin.Library + } + } + private fun findAndDeserializeTypeAlias( classId: ClassId, context: StubBasedFirDeserializationContext?, @@ -98,7 +116,8 @@ internal open class StubBasedFirDeserializedSymbolProvider( classId.packageFqName, classId.relativeClassName, classLikeDeclaration, - null, null, symbol, initialOrigin + null, null, symbol, + initialOrigin = getDeclarationOriginFor(classLikeDeclaration.containingKtFile) ) rootContext.memberDeserializer.loadTypeAlias(classLikeDeclaration, symbol) } @@ -131,7 +150,7 @@ internal open class StubBasedFirDeserializedSymbolProvider( parentContext = context, containerSource = JvmStubDeserializedContainerSource(classId), deserializeNestedClass = this::getClass, - initialOrigin = initialOrigin + initialOrigin = getDeclarationOriginFor(classLikeDeclaration.containingKtFile) ) return symbol } @@ -147,15 +166,20 @@ internal open class StubBasedFirDeserializedSymbolProvider( return ArrayList(topLevelFunctions.size).apply { for (function in topLevelFunctions) { val functionStub = function.stub as? KotlinFunctionStubImpl ?: loadStubByElement(function) - val containerSource = getFacadeContainerSource(function.containingKtFile, functionStub?.origin) + val functionFile = function.containingKtFile + val containerSource = getContainerSource(functionFile, functionStub?.origin) + val functionOrigin = getDeclarationOriginFor(functionFile) - if (initialOrigin != FirDeclarationOrigin.BuiltIns && containerSource.className.internalName in KotlinBuiltins) { + if (functionOrigin != FirDeclarationOrigin.BuiltIns && + containerSource is FacadeClassSource && + containerSource.className.internalName in KotlinBuiltins + ) { continue } val symbol = FirNamedFunctionSymbol(callableId) val rootContext = StubBasedFirDeserializationContext - .createRootContext(session, moduleData, callableId, function, symbol, initialOrigin, containerSource) + .createRootContext(session, moduleData, callableId, function, symbol, functionOrigin, containerSource) add(rootContext.memberDeserializer.loadFunction(function, null, session, symbol).symbol) } @@ -168,11 +192,13 @@ internal open class StubBasedFirDeserializedSymbolProvider( return buildList { for (property in topLevelProperties) { val propertyStub = property.stub as? KotlinPropertyStubImpl ?: loadStubByElement(property) - val containerSource = getFacadeContainerSource(property.containingKtFile, propertyStub?.origin) + val propertyFile = property.containingKtFile + val containerSource = getContainerSource(propertyFile, propertyStub?.origin) + val propertyOrigin = getDeclarationOriginFor(propertyFile) val symbol = FirPropertySymbol(callableId) val rootContext = StubBasedFirDeserializationContext - .createRootContext(session, moduleData, callableId, property, symbol, initialOrigin, containerSource) + .createRootContext(session, moduleData, callableId, property, symbol, propertyOrigin, containerSource) add(rootContext.memberDeserializer.loadProperty(property, null, symbol).symbol) } @@ -180,7 +206,7 @@ internal open class StubBasedFirDeserializedSymbolProvider( } private fun getContainerSource(file: KtFile, origin: KotlinStubOrigin?): DeserializedContainerSource { - if (file.virtualFile.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION) { + if (getDeclarationOriginFor(file) == FirDeclarationOrigin.BuiltIns) { require(origin is KotlinStubOrigin.Facade) { "Expected builtins file to have Facade origin, got origin=$origin instead" } @@ -289,6 +315,7 @@ internal open class StubBasedFirDeserializedSymbolProvider( @FirSymbolProviderInternals override fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? { val annotationDeserializer = StubBasedAnnotationDeserializer(session) + val classOrigin = getDeclarationOriginFor(classLikeDeclaration.containingKtFile) val deserializationContext = StubBasedFirDeserializationContext( moduleData, classId.packageFqName, @@ -299,13 +326,13 @@ internal open class StubBasedFirDeserializedSymbolProvider( parent = null, containingSymbol = null, owner = null, - initialOrigin + classOrigin ), annotationDeserializer, containerSource = null, outerClassSymbol = null, outerTypeParameters = emptyList(), - initialOrigin, + classOrigin, classLikeDeclaration, ) 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 index 4f565ef94b8..68a51de2668 100644 --- 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 @@ -73,7 +73,7 @@ internal fun createStubBasedFirSymbolProviderForScopeLimitedByFiles( project, baseScope, fileFilter, symbolProviderFactory = { reducedScope: GlobalSearchScope -> StubBasedFirDeserializedSymbolProvider( - session, moduleDataProvider, kotlinScopeProvider, project, reducedScope, FirDeclarationOrigin.Library, + session, moduleDataProvider, kotlinScopeProvider, project, reducedScope, ) } )