diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt index 5bc798de0f9..45aa9a6207a 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt @@ -5,18 +5,12 @@ package org.jetbrains.kotlin.fir.backend.generators -import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.backend.* -import org.jetbrains.kotlin.fir.baseForIntersectionOverride import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.isIntersectionOverride -import org.jetbrains.kotlin.fir.isSubstitutionOverride -import org.jetbrains.kotlin.fir.originalForSubstitutionOverride import org.jetbrains.kotlin.fir.scopes.* -import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData -import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.scopes.impl.unwrapDelegateTarget import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl @@ -51,7 +45,7 @@ internal class DelegatedMemberGenerator( declarationStorage.getIrFunctionSymbol(unwrapped.symbol).owner as? IrSimpleFunction ?: return@processAllFunctions - if (isJavaDefault(unwrapped)) { + if (unwrapped.isJavaDefault) { return@processAllFunctions } @@ -83,42 +77,6 @@ internal class DelegatedMemberGenerator( } } - private inline fun , reified D : FirCallableMemberDeclaration> S.unwrapDelegateTarget( - subClassLookupTag: ConeClassLikeLookupTag, - noinline directOverridden: S.() -> List, - firField: FirField, - firSubClass: FirClass<*>, - ): D? { - val unwrappedIntersectionSymbol = - this.unwrapIntersectionOverride(directOverridden) ?: return null - - val callable = unwrappedIntersectionSymbol.fir as? D ?: return null - - val delegatedWrapperData = callable.delegatedWrapperData ?: return null - if (delegatedWrapperData.containingClass != subClassLookupTag) return null - if (delegatedWrapperData.delegateField != firField) return null - - val wrapped = delegatedWrapperData.wrapped as? D ?: return null - val wrappedSymbol = wrapped.symbol as? S ?: return null - - return when { - wrappedSymbol.fir.isSubstitutionOverride && - (wrappedSymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag == firSubClass.symbol.toLookupTag() -> - wrapped.originalForSubstitutionOverride - else -> wrapped - } - } - - private fun isJavaDefault(function: FirSimpleFunction): Boolean { - if (function.isIntersectionOverride) return isJavaDefault(function.baseForIntersectionOverride!!) - return function.origin == FirDeclarationOrigin.Enhancement && function.modality == Modality.OPEN - } - - private fun > S.unwrapIntersectionOverride(directOverridden: S.() -> List): S? { - if (this.fir.isIntersectionOverride) return directOverridden().firstOrNull { it.fir.delegatedWrapperData != null } - return this - } - private fun generateDelegatedFunction( subClass: IrClass, firSubClass: FirClass<*>, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt index 25d5c849157..807265a732a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDelegatedMemberScope.kt @@ -9,6 +9,9 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.isIntersectionOverride +import org.jetbrains.kotlin.fir.isSubstitutionOverride +import org.jetbrains.kotlin.fir.originalForSubstitutionOverride import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag @@ -162,6 +165,35 @@ class DelegatedWrapperData>( var > D.delegatedWrapperData: DelegatedWrapperData? by FirDeclarationDataRegistry.data(DelegatedWrapperDataKey) +inline fun , reified D : FirCallableMemberDeclaration> S.unwrapDelegateTarget( + subClassLookupTag: ConeClassLikeLookupTag, + noinline directOverridden: S.() -> List, + firField: FirField, + firSubClass: FirClass<*>, +): D? { + val unwrappedIntersectionSymbol = this.unwrapIntersectionOverride(directOverridden) ?: return null + + val callable = unwrappedIntersectionSymbol.fir as? D ?: return null + + val delegatedWrapperData = callable.delegatedWrapperData ?: return null + if (delegatedWrapperData.containingClass != subClassLookupTag) return null + if (delegatedWrapperData.delegateField != firField) return null + + val wrapped = delegatedWrapperData.wrapped as? D ?: return null + val wrappedSymbol = wrapped.symbol as? S ?: return null + + return when { + wrappedSymbol.fir.isSubstitutionOverride && + (wrappedSymbol.fir.dispatchReceiverType as? ConeClassLikeType)?.lookupTag == firSubClass.symbol.toLookupTag() -> + wrapped.originalForSubstitutionOverride + else -> wrapped + } +} + +fun > S.unwrapIntersectionOverride(directOverridden: S.() -> List): S? { + if (this.fir.isIntersectionOverride) return directOverridden().firstOrNull { it.fir.delegatedWrapperData != null } + return this +} // From the definition of function interfaces in the Java specification (pt. 9.8): // "methods that are members of I that do not have the same signature as any public instance method of the class Object" diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt index ed307ebf44b..566ffa8166b 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/ClassMembers.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol @@ -29,7 +30,6 @@ fun FirCallableDeclaration<*>.containingClass(): ConeClassLikeLookupTag? { private object ContainingClassKey : FirDeclarationDataKey() var FirCallableDeclaration<*>.containingClassAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey) - val FirCallableDeclaration<*>.isIntersectionOverride get() = origin == FirDeclarationOrigin.IntersectionOverride val FirCallableDeclaration<*>.isSubstitutionOverride get() = origin == FirDeclarationOrigin.SubstitutionOverride val FirCallableDeclaration<*>.isSubstitutionOrIntersectionOverride get() = isSubstitutionOverride || isIntersectionOverride @@ -46,6 +46,12 @@ inline val > D.baseForIntersectionOverride inline val > S.baseForIntersectionOverride: S? get() = fir.baseForIntersectionOverride?.symbol as S? +val FirSimpleFunction.isJavaDefault: Boolean + get() { + if (isIntersectionOverride) return baseForIntersectionOverride!!.isJavaDefault + return origin == FirDeclarationOrigin.Enhancement && modality == Modality.OPEN + } + inline fun > D.originalIfFakeOverride(): D? = originalForSubstitutionOverride ?: baseForIntersectionOverride