[fir2ir] Fix conversion of modules with source built-ins

In the Kotlin compiler project, built-in classes are resolved to source
declarations. It's not an issue for usual file analysis in the IDE, as
referenced built-ins are analyzed on demand.

Fir2ir, however, fetches built-in classes at once without checking its
resolution state, breaking code compilation in the IDE.

^KTIJ-27061 Fixed
This commit is contained in:
Yan Zhulanow
2023-09-12 23:54:51 +09:00
committed by Space Team
parent ac18f6e16e
commit 480bac7537
2 changed files with 29 additions and 7 deletions
@@ -19,6 +19,8 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhaseWithCallableMembers
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.toLookupTag
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -30,6 +32,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.name.StandardClassIds
@@ -68,9 +71,19 @@ class Fir2IrClassifierStorage(
@OptIn(IrSymbolInternals::class)
fun preCacheBuiltinClasses() {
for ((classId, irBuiltinSymbol) in typeConverter.classIdToSymbolMap) {
fun getResolvedClass(classId: ClassId): FirRegularClass? {
// toSymbol() can return null when using an old stdlib that's missing some types
val firClass = classId.toSymbol(session)?.fir as FirRegularClass? ?: continue
val firClass = classId.toSymbol(session)?.fir as FirRegularClass? ?: return null
// Built-in classes may come from sources in the Kotlin project, and so have unresolved types in signatures.
// Still, we need return types for all members to make a list of 'IrDeclarations'. Also see 'Fir2IrLazyClass.declarations'.
firClass.lazyResolveToPhaseWithCallableMembers(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
return firClass
}
for ((classId, irBuiltinSymbol) in typeConverter.classIdToSymbolMap) {
val firClass = getResolvedClass(classId) ?: continue
val irClass = irBuiltinSymbol.owner
classCache[firClass] = irClass
classifiersGenerator.processClassHeader(firClass, irClass)
@@ -78,7 +91,7 @@ class Fir2IrClassifierStorage(
}
for ((primitiveClassId, primitiveArrayId) in StandardClassIds.primitiveArrayTypeByElementType) {
// toSymbol() can return null when using an old stdlib that's missing some types
val firClass = primitiveArrayId.toLookupTag().toSymbol(session)?.fir as FirRegularClass? ?: continue
val firClass = getResolvedClass(primitiveArrayId) ?: continue
val irType = typeConverter.classIdToTypeMap[primitiveClassId]
val irClass = irBuiltIns.primitiveArrayForType[irType]!!.owner
classCache[firClass] = irClass
@@ -12,13 +12,16 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.getFunctions
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.ir.BuiltInOperatorNames
import org.jetbrains.kotlin.ir.IrBuiltIns
@@ -655,15 +658,21 @@ class IrBuiltInsOverFir(
}
private fun findFunction(functionSymbol: FirNamedFunctionSymbol): IrSimpleFunctionSymbol {
functionSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
val irParent = findIrParent(functionSymbol)
return components.declarationStorage.getOrCreateIrFunction(functionSymbol.fir, irParent).symbol
}
private fun findProperties(packageName: FqName, name: Name): List<IrPropertySymbol> {
return symbolProvider.getTopLevelPropertySymbols(packageName, name).map { firOpSymbol ->
val irParent = findIrParent(firOpSymbol)
components.declarationStorage.getOrCreateIrProperty(firOpSymbol.fir, irParent).symbol
}
return symbolProvider.getTopLevelPropertySymbols(packageName, name).map { findProperty(it) }
}
private fun findProperty(propertySymbol: FirPropertySymbol): IrPropertySymbol {
propertySymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
val irParent = findIrParent(propertySymbol)
return components.declarationStorage.getOrCreateIrProperty(propertySymbol.fir, irParent).symbol
}
private fun findIrParent(firSymbol: FirCallableSymbol<*>): IrDeclarationParent? {