FIR: refactor delegate unwrapping
Not implemented override checker will use those to pretend to make delegeted members (before checking similarly pretended fake overrides)
This commit is contained in:
committed by
TeamCityServer
parent
ef890464d8
commit
856838f82c
+3
-45
@@ -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 S : FirCallableSymbol<D>, reified D : FirCallableMemberDeclaration<D>> S.unwrapDelegateTarget(
|
||||
subClassLookupTag: ConeClassLikeLookupTag,
|
||||
noinline directOverridden: S.() -> List<S>,
|
||||
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 : FirCallableSymbol<*>> S.unwrapIntersectionOverride(directOverridden: S.() -> List<S>): S? {
|
||||
if (this.fir.isIntersectionOverride) return directOverridden().firstOrNull { it.fir.delegatedWrapperData != null }
|
||||
return this
|
||||
}
|
||||
|
||||
private fun generateDelegatedFunction(
|
||||
subClass: IrClass,
|
||||
firSubClass: FirClass<*>,
|
||||
|
||||
+32
@@ -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<D : FirCallableDeclaration<*>>(
|
||||
var <D : FirCallableDeclaration<*>>
|
||||
D.delegatedWrapperData: DelegatedWrapperData<D>? by FirDeclarationDataRegistry.data(DelegatedWrapperDataKey)
|
||||
|
||||
inline fun <reified S : FirCallableSymbol<D>, reified D : FirCallableMemberDeclaration<D>> S.unwrapDelegateTarget(
|
||||
subClassLookupTag: ConeClassLikeLookupTag,
|
||||
noinline directOverridden: S.() -> List<S>,
|
||||
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 : FirCallableSymbol<*>> S.unwrapIntersectionOverride(directOverridden: S.() -> List<S>): 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"
|
||||
|
||||
@@ -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 <reified D : FirCallableDeclaration<*>> D.baseForIntersectionOverride
|
||||
inline val <reified S : FirCallableSymbol<*>> 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 <reified D : FirCallableDeclaration<*>> D.originalIfFakeOverride(): D? =
|
||||
originalForSubstitutionOverride ?: baseForIntersectionOverride
|
||||
|
||||
|
||||
Reference in New Issue
Block a user