[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.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol 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.FirTypeRef
import org.jetbrains.kotlin.fir.types.toLookupTag import org.jetbrains.kotlin.fir.types.toLookupTag
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET 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.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
@@ -68,9 +71,19 @@ class Fir2IrClassifierStorage(
@OptIn(IrSymbolInternals::class) @OptIn(IrSymbolInternals::class)
fun preCacheBuiltinClasses() { 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 // 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 val irClass = irBuiltinSymbol.owner
classCache[firClass] = irClass classCache[firClass] = irClass
classifiersGenerator.processClassHeader(firClass, irClass) classifiersGenerator.processClassHeader(firClass, irClass)
@@ -78,7 +91,7 @@ class Fir2IrClassifierStorage(
} }
for ((primitiveClassId, primitiveArrayId) in StandardClassIds.primitiveArrayTypeByElementType) { for ((primitiveClassId, primitiveArrayId) in StandardClassIds.primitiveArrayTypeByElementType) {
// toSymbol() can return null when using an old stdlib that's missing some types // 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 irType = typeConverter.classIdToTypeMap[primitiveClassId]
val irClass = irBuiltIns.primitiveArrayForType[irType]!!.owner val irClass = irBuiltIns.primitiveArrayForType[irType]!!.owner
classCache[firClass] = irClass classCache[firClass] = irClass
@@ -12,13 +12,16 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.containingClassLookupTag 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.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.getFunctions import org.jetbrains.kotlin.fir.scopes.getFunctions
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol 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.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.ir.BuiltInOperatorNames import org.jetbrains.kotlin.ir.BuiltInOperatorNames
import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrBuiltIns
@@ -655,15 +658,21 @@ class IrBuiltInsOverFir(
} }
private fun findFunction(functionSymbol: FirNamedFunctionSymbol): IrSimpleFunctionSymbol { private fun findFunction(functionSymbol: FirNamedFunctionSymbol): IrSimpleFunctionSymbol {
functionSymbol.lazyResolveToPhase(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
val irParent = findIrParent(functionSymbol) val irParent = findIrParent(functionSymbol)
return components.declarationStorage.getOrCreateIrFunction(functionSymbol.fir, irParent).symbol return components.declarationStorage.getOrCreateIrFunction(functionSymbol.fir, irParent).symbol
} }
private fun findProperties(packageName: FqName, name: Name): List<IrPropertySymbol> { private fun findProperties(packageName: FqName, name: Name): List<IrPropertySymbol> {
return symbolProvider.getTopLevelPropertySymbols(packageName, name).map { firOpSymbol -> return symbolProvider.getTopLevelPropertySymbols(packageName, name).map { findProperty(it) }
val irParent = findIrParent(firOpSymbol) }
components.declarationStorage.getOrCreateIrProperty(firOpSymbol.fir, irParent).symbol
} 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? { private fun findIrParent(firSymbol: FirCallableSymbol<*>): IrDeclarationParent? {