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.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
@LLFirInternals
|
@LLFirInternals
|
||||||
class LLStubBasedLibrarySymbolProviderFactory(private val project: Project) : LLFirLibrarySymbolProviderFactory() {
|
class LLStubBasedLibrarySymbolProviderFactory(private val project: Project) : LLFirLibrarySymbolProviderFactory() {
|
||||||
@@ -107,7 +108,6 @@ private class StubBasedBuiltInsSymbolProvider(
|
|||||||
kotlinScopeProvider,
|
kotlinScopeProvider,
|
||||||
project,
|
project,
|
||||||
createBuiltInsScope(project),
|
createBuiltInsScope(project),
|
||||||
FirDeclarationOrigin.BuiltIns
|
|
||||||
) {
|
) {
|
||||||
private val syntheticFunctionInterfaceProvider = FirBuiltinSyntheticFunctionInterfaceProvider(
|
private val syntheticFunctionInterfaceProvider = FirBuiltinSyntheticFunctionInterfaceProvider(
|
||||||
session,
|
session,
|
||||||
@@ -119,6 +119,11 @@ private class StubBasedBuiltInsSymbolProvider(
|
|||||||
return super.getClassLikeSymbolByClassId(classId)
|
return super.getClassLikeSymbolByClassId(classId)
|
||||||
?: syntheticFunctionInterfaceProvider.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 {
|
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.resolve.providers.FirSymbolProviderInternals
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.stubs.impl.*
|
import org.jetbrains.kotlin.psi.stubs.impl.*
|
||||||
@@ -53,7 +54,6 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
private val kotlinScopeProvider: FirKotlinScopeProvider,
|
private val kotlinScopeProvider: FirKotlinScopeProvider,
|
||||||
project: Project,
|
project: Project,
|
||||||
scope: GlobalSearchScope,
|
scope: GlobalSearchScope,
|
||||||
private val initialOrigin: FirDeclarationOrigin
|
|
||||||
) : LLFirKotlinSymbolProvider(session) {
|
) : LLFirKotlinSymbolProvider(session) {
|
||||||
private val moduleData = moduleDataProvider.getModuleData(null)
|
private val moduleData = moduleDataProvider.getModuleData(null)
|
||||||
|
|
||||||
@@ -83,6 +83,24 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
|
|
||||||
final override val packageProvider = project.createPackageProvider(scope)
|
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(
|
private fun findAndDeserializeTypeAlias(
|
||||||
classId: ClassId,
|
classId: ClassId,
|
||||||
context: StubBasedFirDeserializationContext?,
|
context: StubBasedFirDeserializationContext?,
|
||||||
@@ -98,7 +116,8 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
classId.packageFqName,
|
classId.packageFqName,
|
||||||
classId.relativeClassName,
|
classId.relativeClassName,
|
||||||
classLikeDeclaration,
|
classLikeDeclaration,
|
||||||
null, null, symbol, initialOrigin
|
null, null, symbol,
|
||||||
|
initialOrigin = getDeclarationOriginFor(classLikeDeclaration.containingKtFile)
|
||||||
)
|
)
|
||||||
rootContext.memberDeserializer.loadTypeAlias(classLikeDeclaration, symbol)
|
rootContext.memberDeserializer.loadTypeAlias(classLikeDeclaration, symbol)
|
||||||
}
|
}
|
||||||
@@ -131,7 +150,7 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
parentContext = context,
|
parentContext = context,
|
||||||
containerSource = JvmStubDeserializedContainerSource(classId),
|
containerSource = JvmStubDeserializedContainerSource(classId),
|
||||||
deserializeNestedClass = this::getClass,
|
deserializeNestedClass = this::getClass,
|
||||||
initialOrigin = initialOrigin
|
initialOrigin = getDeclarationOriginFor(classLikeDeclaration.containingKtFile)
|
||||||
)
|
)
|
||||||
return symbol
|
return symbol
|
||||||
}
|
}
|
||||||
@@ -147,15 +166,20 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
return ArrayList<FirNamedFunctionSymbol>(topLevelFunctions.size).apply {
|
return ArrayList<FirNamedFunctionSymbol>(topLevelFunctions.size).apply {
|
||||||
for (function in topLevelFunctions) {
|
for (function in topLevelFunctions) {
|
||||||
val functionStub = function.stub as? KotlinFunctionStubImpl ?: loadStubByElement(function)
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val symbol = FirNamedFunctionSymbol(callableId)
|
val symbol = FirNamedFunctionSymbol(callableId)
|
||||||
val rootContext = StubBasedFirDeserializationContext
|
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)
|
add(rootContext.memberDeserializer.loadFunction(function, null, session, symbol).symbol)
|
||||||
}
|
}
|
||||||
@@ -168,11 +192,13 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
return buildList {
|
return buildList {
|
||||||
for (property in topLevelProperties) {
|
for (property in topLevelProperties) {
|
||||||
val propertyStub = property.stub as? KotlinPropertyStubImpl ?: loadStubByElement(property)
|
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 symbol = FirPropertySymbol(callableId)
|
||||||
val rootContext = StubBasedFirDeserializationContext
|
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)
|
add(rootContext.memberDeserializer.loadProperty(property, null, symbol).symbol)
|
||||||
}
|
}
|
||||||
@@ -180,7 +206,7 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getContainerSource(file: KtFile, origin: KotlinStubOrigin?): DeserializedContainerSource {
|
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) {
|
require(origin is KotlinStubOrigin.Facade) {
|
||||||
"Expected builtins file to have Facade origin, got origin=$origin instead"
|
"Expected builtins file to have Facade origin, got origin=$origin instead"
|
||||||
}
|
}
|
||||||
@@ -289,6 +315,7 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
@FirSymbolProviderInternals
|
@FirSymbolProviderInternals
|
||||||
override fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? {
|
override fun getClassLikeSymbolByClassId(classId: ClassId, classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeSymbol<*>? {
|
||||||
val annotationDeserializer = StubBasedAnnotationDeserializer(session)
|
val annotationDeserializer = StubBasedAnnotationDeserializer(session)
|
||||||
|
val classOrigin = getDeclarationOriginFor(classLikeDeclaration.containingKtFile)
|
||||||
val deserializationContext = StubBasedFirDeserializationContext(
|
val deserializationContext = StubBasedFirDeserializationContext(
|
||||||
moduleData,
|
moduleData,
|
||||||
classId.packageFqName,
|
classId.packageFqName,
|
||||||
@@ -299,13 +326,13 @@ internal open class StubBasedFirDeserializedSymbolProvider(
|
|||||||
parent = null,
|
parent = null,
|
||||||
containingSymbol = null,
|
containingSymbol = null,
|
||||||
owner = null,
|
owner = null,
|
||||||
initialOrigin
|
classOrigin
|
||||||
),
|
),
|
||||||
annotationDeserializer,
|
annotationDeserializer,
|
||||||
containerSource = null,
|
containerSource = null,
|
||||||
outerClassSymbol = null,
|
outerClassSymbol = null,
|
||||||
outerTypeParameters = emptyList(),
|
outerTypeParameters = emptyList(),
|
||||||
initialOrigin,
|
classOrigin,
|
||||||
classLikeDeclaration,
|
classLikeDeclaration,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -73,7 +73,7 @@ internal fun createStubBasedFirSymbolProviderForScopeLimitedByFiles(
|
|||||||
project, baseScope, fileFilter,
|
project, baseScope, fileFilter,
|
||||||
symbolProviderFactory = { reducedScope: GlobalSearchScope ->
|
symbolProviderFactory = { reducedScope: GlobalSearchScope ->
|
||||||
StubBasedFirDeserializedSymbolProvider(
|
StubBasedFirDeserializedSymbolProvider(
|
||||||
session, moduleDataProvider, kotlinScopeProvider, project, reducedScope, FirDeclarationOrigin.Library,
|
session, moduleDataProvider, kotlinScopeProvider, project, reducedScope,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user