KT-62859 [LL FIR] Compute origin per declaration in StubBasedFirDeserializedSymbolProvider
Since `createStubBasedFirSymbolProviderForClassFiles` works for
builtins (after 866368cf), the provider sometimes has to handle
declarations from builtins (`Any?.toString()` or `arrayOf`, for example)
To provide correct origin for such declarations, we have to compute
the origin on the per-declaration basis instead of always setting
`Library` or `BuiltIn` origin
Providing correct origins should improve the consistency of
deserialized fir declarations
To reduce duplication, `getContainerSource` now also uses
`getDeclarationOriginFor`
This commit is contained in:
+6
-1
@@ -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 {
|
||||
|
||||
+38
-11
@@ -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<FirNamedFunctionSymbol>(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,
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -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,
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user