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:
Jinseong Jeon
2021-02-12 22:25:58 -08:00
committed by TeamCityServer
parent ef890464d8
commit 856838f82c
3 changed files with 42 additions and 46 deletions
@@ -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"