FIR: Implement delayed binding of overriddens in the delegated members
fixes the problem when overridden symbols on delegated members were build on the incomplete fake overrides leading to the incorrect generation of the function for default parameter and thus to the codegen error (see withDefaultsMultipleFilesOrder test for an example)
This commit is contained in:
committed by
TeamCityServer
parent
c9b6847d83
commit
873a7c6ef1
@@ -293,6 +293,24 @@ internal tailrec fun FirCallableSymbol<*>.unwrapCallRepresentative(root: FirCall
|
||||
return overriddenSymbol.unwrapCallRepresentative(this)
|
||||
}
|
||||
|
||||
internal fun FirSimpleFunction.processOverriddenFunctionSymbols(
|
||||
containingClass: FirClass,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
processor: (FirNamedFunctionSymbol) -> Unit
|
||||
) {
|
||||
val scope = containingClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
||||
scope.processFunctionsByName(name) {}
|
||||
scope.processOverriddenFunctionsFromSuperClasses(symbol, containingClass) {
|
||||
if (it.fir.visibility == Visibilities.Private) {
|
||||
return@processOverriddenFunctionsFromSuperClasses ProcessorAction.NEXT
|
||||
}
|
||||
processor(it)
|
||||
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirSimpleFunction.generateOverriddenFunctionSymbols(
|
||||
containingClass: FirClass,
|
||||
session: FirSession,
|
||||
@@ -301,20 +319,12 @@ internal fun FirSimpleFunction.generateOverriddenFunctionSymbols(
|
||||
fakeOverrideGenerator: FakeOverrideGenerator,
|
||||
): List<IrSimpleFunctionSymbol> {
|
||||
val superClasses = containingClass.getSuperTypesAsIrClasses(declarationStorage) ?: return emptyList()
|
||||
|
||||
val scope = containingClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
||||
scope.processFunctionsByName(name) {}
|
||||
val overriddenSet = mutableSetOf<IrSimpleFunctionSymbol>()
|
||||
scope.processOverriddenFunctionsFromSuperClasses(symbol, containingClass) {
|
||||
if (it.fir.visibility == Visibilities.Private) {
|
||||
return@processOverriddenFunctionsFromSuperClasses ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
processOverriddenFunctionSymbols(containingClass, session, scopeSession) {
|
||||
for (overridden in fakeOverrideGenerator.getOverriddenSymbolsInSupertypes(it, superClasses)) {
|
||||
overriddenSet += overridden
|
||||
}
|
||||
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
return overriddenSet.toList()
|
||||
@@ -353,6 +363,27 @@ private fun FirClass.getSuperTypesAsIrClasses(
|
||||
return irClass.superTypes.mapNotNull { it.classifierOrNull?.owner as? IrClass }.toSet()
|
||||
}
|
||||
|
||||
internal fun FirProperty.processOverriddenPropertySymbols(
|
||||
containingClass: FirClass,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
processor: (FirPropertySymbol) -> Unit
|
||||
): List<IrPropertySymbol> {
|
||||
val scope = containingClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
||||
scope.processPropertiesByName(name) {}
|
||||
val overriddenSet = mutableSetOf<IrPropertySymbol>()
|
||||
scope.processOverriddenPropertiesFromSuperClasses(symbol, containingClass) {
|
||||
if (it.fir.visibility == Visibilities.Private) {
|
||||
return@processOverriddenPropertiesFromSuperClasses ProcessorAction.NEXT
|
||||
}
|
||||
processor(it)
|
||||
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
return overriddenSet.toList()
|
||||
}
|
||||
|
||||
internal fun FirProperty.generateOverriddenPropertySymbols(
|
||||
containingClass: FirClass,
|
||||
session: FirSession,
|
||||
@@ -361,20 +392,12 @@ internal fun FirProperty.generateOverriddenPropertySymbols(
|
||||
fakeOverrideGenerator: FakeOverrideGenerator,
|
||||
): List<IrPropertySymbol> {
|
||||
val superClasses = containingClass.getSuperTypesAsIrClasses(declarationStorage) ?: return emptyList()
|
||||
|
||||
val scope = containingClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
||||
scope.processPropertiesByName(name) {}
|
||||
val overriddenSet = mutableSetOf<IrPropertySymbol>()
|
||||
scope.processOverriddenPropertiesFromSuperClasses(symbol, containingClass) {
|
||||
if (it.fir.visibility == Visibilities.Private) {
|
||||
return@processOverriddenPropertiesFromSuperClasses ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
processOverriddenPropertySymbols(containingClass, session, scopeSession) {
|
||||
for (overridden in fakeOverrideGenerator.getOverriddenSymbolsInSupertypes(it, superClasses)) {
|
||||
overriddenSet += overridden
|
||||
}
|
||||
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
return overriddenSet.toList()
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.DelegatedMemberGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
@@ -35,4 +36,5 @@ interface Fir2IrComponents {
|
||||
val annotationGenerator: AnnotationGenerator
|
||||
val callGenerator: CallAndReferenceGenerator
|
||||
val fakeOverrideGenerator: FakeOverrideGenerator
|
||||
val delegatedMemberGenerator: DelegatedMemberGenerator
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.DelegatedMemberGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer
|
||||
@@ -35,6 +36,7 @@ class Fir2IrComponentsStorage(
|
||||
override lateinit var annotationGenerator: AnnotationGenerator
|
||||
override lateinit var callGenerator: CallAndReferenceGenerator
|
||||
override lateinit var fakeOverrideGenerator: FakeOverrideGenerator
|
||||
override lateinit var delegatedMemberGenerator: DelegatedMemberGenerator
|
||||
|
||||
override val lock: IrLock
|
||||
get() = symbolTable.lock
|
||||
|
||||
@@ -9,10 +9,7 @@ import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.evaluate.evaluateConstants
|
||||
import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.CallAndReferenceGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.FakeOverrideGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
||||
@@ -270,6 +267,7 @@ class Fir2IrConverter(
|
||||
val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, irFactory, signatureComposer)
|
||||
val classifierStorage = Fir2IrClassifierStorage(components)
|
||||
components.classifierStorage = classifierStorage
|
||||
components.delegatedMemberGenerator = DelegatedMemberGenerator(components)
|
||||
val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor)
|
||||
components.declarationStorage = declarationStorage
|
||||
components.visibilityConverter = visibilityConverter
|
||||
|
||||
+1
-4
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_FQ_NAMES
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.backend.generators.DelegatedMemberGenerator
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
|
||||
@@ -104,8 +103,6 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
private val localStorage by threadLocal { Fir2IrLocalStorage() }
|
||||
|
||||
private val delegatedMemberGenerator = DelegatedMemberGenerator(components)
|
||||
|
||||
private fun areCompatible(firFunction: FirFunction, irFunction: IrFunction): Boolean {
|
||||
if (firFunction is FirSimpleFunction && irFunction is IrSimpleFunction) {
|
||||
if (irFunction.name != firFunction.name) return false
|
||||
@@ -891,7 +888,7 @@ class Fir2IrDeclarationStorage(
|
||||
fun createIrFieldAndDelegatedMembers(field: FirField, owner: FirClass, irClass: IrClass): IrField {
|
||||
val irField = createIrField(field, origin = IrDeclarationOrigin.DELEGATE)
|
||||
irField.setAndModifyParent(irClass)
|
||||
delegatedMemberGenerator.generate(irField, field, owner, irClass)
|
||||
components.delegatedMemberGenerator.generate(irField, field, owner, irClass)
|
||||
return irField
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -58,6 +58,8 @@ internal class ClassMemberGenerator(
|
||||
}
|
||||
}
|
||||
fakeOverrideGenerator.bindOverriddenSymbols(irClass.declarations)
|
||||
components.delegatedMemberGenerator.bindDelegatedMembersOverriddenSymbols(irClass)
|
||||
|
||||
klass.declarations.forEach { declaration ->
|
||||
when {
|
||||
declaration is FirTypeAlias -> {
|
||||
|
||||
+42
-18
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.scopes.processAllProperties
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
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.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
@@ -21,6 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isNothing
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
|
||||
@@ -31,10 +33,13 @@ import org.jetbrains.kotlin.ir.types.isUnit
|
||||
* methods and properties in the super-interface, and creates corresponding members in the subclass.
|
||||
* TODO: generic super interface types and generic delegated members.
|
||||
*/
|
||||
internal class DelegatedMemberGenerator(
|
||||
class DelegatedMemberGenerator(
|
||||
private val components: Fir2IrComponents
|
||||
) : Fir2IrComponents by components {
|
||||
|
||||
private val baseFunctionSymbols = mutableMapOf<IrFunction, List<FirNamedFunctionSymbol>>()
|
||||
private val basePropertySymbols = mutableMapOf<IrProperty, List<FirPropertySymbol>>()
|
||||
|
||||
// Generate delegated members for [subClass]. The synthetic field [irField] has the super interface type.
|
||||
fun generate(irField: IrField, firField: FirField, firSubClass: FirClass, subClass: IrClass) {
|
||||
val subClassLookupTag = firSubClass.symbol.toLookupTag()
|
||||
@@ -82,6 +87,28 @@ internal class DelegatedMemberGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
fun bindDelegatedMembersOverriddenSymbols(irClass: IrClass) {
|
||||
val superClasses by lazy(LazyThreadSafetyMode.NONE) {
|
||||
irClass.superTypes.mapNotNullTo(mutableSetOf()) { it.classifierOrNull?.owner as? IrClass }
|
||||
}
|
||||
for (declaration in irClass.declarations) {
|
||||
if (declaration.origin != IrDeclarationOrigin.DELEGATED_MEMBER) continue
|
||||
when (declaration) {
|
||||
is IrSimpleFunction -> {
|
||||
declaration.overriddenSymbols = baseFunctionSymbols[declaration]?.flatMap {
|
||||
fakeOverrideGenerator.getOverriddenSymbolsInSupertypes(it, superClasses)
|
||||
}?.filter { it.owner != declaration }.orEmpty()
|
||||
}
|
||||
is IrProperty -> {
|
||||
declaration.overriddenSymbols = basePropertySymbols[declaration]?.flatMap {
|
||||
fakeOverrideGenerator.getOverriddenSymbolsInSupertypes(it, superClasses)
|
||||
}?.filter { it.owner != declaration }.orEmpty()
|
||||
}
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateDelegatedFunction(
|
||||
subClass: IrClass,
|
||||
firSubClass: FirClass,
|
||||
@@ -94,15 +121,13 @@ internal class DelegatedMemberGenerator(
|
||||
delegateOverride, subClass, origin = IrDeclarationOrigin.DELEGATED_MEMBER,
|
||||
containingClass = firSubClass.symbol.toLookupTag()
|
||||
)
|
||||
delegateFunction.overriddenSymbols =
|
||||
delegateOverride.generateOverriddenFunctionSymbols(
|
||||
firSubClass,
|
||||
session,
|
||||
scopeSession,
|
||||
declarationStorage,
|
||||
fakeOverrideGenerator
|
||||
)
|
||||
.filter { it.owner != delegateFunction }
|
||||
val baseSymbols = mutableListOf<FirNamedFunctionSymbol>()
|
||||
// the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their
|
||||
// overridden symbols, otherwise in some cases they will be left in inconsistent state leading to the errors in IR
|
||||
delegateOverride.processOverriddenFunctionSymbols(firSubClass, session, scopeSession) {
|
||||
baseSymbols.add(it)
|
||||
}
|
||||
baseFunctionSymbols[delegateFunction] = baseSymbols
|
||||
annotationGenerator.generate(delegateFunction, delegateOverride)
|
||||
|
||||
val body = createDelegateBody(irField, delegateFunction, superFunction)
|
||||
@@ -166,14 +191,13 @@ internal class DelegatedMemberGenerator(
|
||||
firDelegateProperty, subClass, origin = IrDeclarationOrigin.DELEGATED_MEMBER,
|
||||
containingClass = firSubClass.symbol.toLookupTag()
|
||||
)
|
||||
delegateProperty.overriddenSymbols =
|
||||
firDelegateProperty.generateOverriddenPropertySymbols(
|
||||
firSubClass,
|
||||
session,
|
||||
scopeSession,
|
||||
declarationStorage,
|
||||
fakeOverrideGenerator
|
||||
)
|
||||
// the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their
|
||||
// overridden symbols, otherwise in some cases they will be left in inconsistent state leading to the errors in IR
|
||||
val baseSymbols = mutableListOf<FirPropertySymbol>()
|
||||
firDelegateProperty.processOverriddenPropertySymbols(firSubClass, session, scopeSession) {
|
||||
baseSymbols.add(it)
|
||||
}
|
||||
basePropertySymbols[delegateProperty] = baseSymbols
|
||||
annotationGenerator.generate(delegateProperty, firDelegateProperty)
|
||||
|
||||
delegateProperty.getter!!.body = createDelegateBody(irField, delegateProperty.getter!!, superProperty.getter!!)
|
||||
|
||||
Reference in New Issue
Block a user