[LL] ensure that stub based symbol provider works on class files

This makes `.originalElements` calls redundant, no need to filter duplicates.
Additionally, it ensures that ktDeclaration's are from cls,
so all types are fully qualified and stubs contain all additional information,
required to build resolved fir e.g.,
fully qualified names are split as classIds, flexible types, etc

Merge-request: KT-MR-10449
Merged-by: Anna Kozlova <Anna.Kozlova@jetbrains.com>
This commit is contained in:
Anna Kozlova
2023-06-05 12:46:11 +00:00
committed by Space Team
parent c78997d0f2
commit b96e5b072a
2 changed files with 11 additions and 17 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization 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.project.Project
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.DelegatingGlobalSearchScope import com.intellij.psi.search.DelegatingGlobalSearchScope
@@ -20,7 +21,6 @@ import org.jetbrains.kotlin.fir.java.FirJavaFacade
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
@LLFirInternals @LLFirInternals
class JvmStubBasedDeserializedSymbolProviderFactory : JvmFirDeserializedSymbolProviderFactory() { class JvmStubBasedDeserializedSymbolProviderFactory : JvmFirDeserializedSymbolProviderFactory() {
@@ -47,7 +47,7 @@ class JvmStubBasedDeserializedSymbolProviderFactory : JvmFirDeserializedSymbolPr
project, project,
object : DelegatingGlobalSearchScope(project, scope) { object : DelegatingGlobalSearchScope(project, scope) {
override fun contains(file: VirtualFile): Boolean { override fun contains(file: VirtualFile): Boolean {
if (file.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION) { if (file.extension != JavaClassFileType.INSTANCE.defaultExtension) {
return false return false
} }
return super.contains(file) return super.contains(file)
@@ -81,7 +81,7 @@ internal open class JvmStubBasedFirDeserializedSymbolProvider(
context: StubBasedFirDeserializationContext?, context: StubBasedFirDeserializationContext?,
): Pair<FirTypeAliasSymbol?, DeserializedTypeAliasPostProcessor?> { ): Pair<FirTypeAliasSymbol?, DeserializedTypeAliasPostProcessor?> {
val classLikeDeclaration = val classLikeDeclaration =
(context?.classLikeDeclaration ?: declarationProvider.getClassLikeDeclarationByClassId(classId))?.originalElement (context?.classLikeDeclaration ?: declarationProvider.getClassLikeDeclarationByClassId(classId))
if (classLikeDeclaration is KtTypeAlias) { if (classLikeDeclaration is KtTypeAlias) {
val symbol = FirTypeAliasSymbol(classId) val symbol = FirTypeAliasSymbol(classId)
val postProcessor: DeserializedTypeAliasPostProcessor = { val postProcessor: DeserializedTypeAliasPostProcessor = {
@@ -106,9 +106,9 @@ internal open class JvmStubBasedFirDeserializedSymbolProvider(
): FirRegularClassSymbol? { ): FirRegularClassSymbol? {
val (classLikeDeclaration, context) = val (classLikeDeclaration, context) =
if (parentContext?.classLikeDeclaration != null) { if (parentContext?.classLikeDeclaration != null) {
parentContext.classLikeDeclaration.originalElement to null parentContext.classLikeDeclaration to null
} else { } else {
(declarationProvider.getClassLikeDeclarationByClassId(classId)?.originalElement ?: return null) to parentContext (declarationProvider.getClassLikeDeclarationByClassId(classId) ?: return null) to parentContext
} }
val symbol = FirRegularClassSymbol(classId) val symbol = FirRegularClassSymbol(classId)
@@ -140,12 +140,9 @@ internal open class JvmStubBasedFirDeserializedSymbolProvider(
foundFunctions: Collection<KtNamedFunction>?, foundFunctions: Collection<KtNamedFunction>?,
): List<FirNamedFunctionSymbol> { ): List<FirNamedFunctionSymbol> {
val topLevelFunctions = foundFunctions ?: declarationProvider.getTopLevelFunctions(callableId) val topLevelFunctions = foundFunctions ?: declarationProvider.getTopLevelFunctions(callableId)
val origins = if (topLevelFunctions.size > 1) mutableSetOf<KtNamedFunction>() else null
return topLevelFunctions return topLevelFunctions
.mapNotNull { function -> .mapNotNull { function ->
val original = function.originalElement as? KtNamedFunction ?: return@mapNotNull null val file = function.containingKtFile
if (origins != null && !origins.add(original)) return@mapNotNull null
val file = original.containingKtFile
val virtualFile = file.virtualFile val virtualFile = file.virtualFile
if (virtualFile.extension == MetadataPackageFragment.METADATA_FILE_EXTENSION) return@mapNotNull null if (virtualFile.extension == MetadataPackageFragment.METADATA_FILE_EXTENSION) return@mapNotNull null
if (initialOrigin != FirDeclarationOrigin.BuiltIns && file.packageFqName.asString() if (initialOrigin != FirDeclarationOrigin.BuiltIns && file.packageFqName.asString()
@@ -153,22 +150,19 @@ internal open class JvmStubBasedFirDeserializedSymbolProvider(
) return@mapNotNull null ) return@mapNotNull null
val symbol = FirNamedFunctionSymbol(callableId) val symbol = FirNamedFunctionSymbol(callableId)
val rootContext = val rootContext =
StubBasedFirDeserializationContext.createRootContext(session, moduleData, callableId, original, symbol, initialOrigin) StubBasedFirDeserializationContext.createRootContext(session, moduleData, callableId, function, symbol, initialOrigin)
rootContext.memberDeserializer.loadFunction(original, null, session, symbol).symbol rootContext.memberDeserializer.loadFunction(function, null, session, symbol).symbol
} }
} }
private fun loadPropertiesByCallableId(callableId: CallableId, foundProperties: Collection<KtProperty>?): List<FirPropertySymbol> { private fun loadPropertiesByCallableId(callableId: CallableId, foundProperties: Collection<KtProperty>?): List<FirPropertySymbol> {
val topLevelProperties = foundProperties ?: declarationProvider.getTopLevelProperties(callableId) val topLevelProperties = foundProperties ?: declarationProvider.getTopLevelProperties(callableId)
val origins = if (topLevelProperties.size > 1) mutableSetOf<KtProperty>() else null
return topLevelProperties return topLevelProperties
.mapNotNull { property -> .map { property ->
val original = property.originalElement as? KtProperty ?: return@mapNotNull null
if (origins != null && !origins.add(original)) return@mapNotNull null
val symbol = FirPropertySymbol(callableId) val symbol = FirPropertySymbol(callableId)
val rootContext = val rootContext =
StubBasedFirDeserializationContext.createRootContext(session, moduleData, callableId, original, symbol, initialOrigin) StubBasedFirDeserializationContext.createRootContext(session, moduleData, callableId, property, symbol, initialOrigin)
rootContext.memberDeserializer.loadProperty(original, null, symbol).symbol rootContext.memberDeserializer.loadProperty(property, null, symbol).symbol
} }
} }