FIR2IR: simplify analysis of companion' callable references
This commit is contained in:
+12
-20
@@ -367,30 +367,22 @@ class CallAndReferenceGenerator(
|
|||||||
|
|
||||||
internal fun convertToGetObject(
|
internal fun convertToGetObject(
|
||||||
qualifier: FirResolvedQualifier,
|
qualifier: FirResolvedQualifier,
|
||||||
callableReferenceAccess: FirCallableReferenceAccess? = null
|
callableReferenceAccess: FirCallableReferenceAccess?
|
||||||
): IrExpression? {
|
): IrExpression? {
|
||||||
val classSymbol = (qualifier.typeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)
|
val classSymbol = (qualifier.typeRef.coneType as? ConeClassLikeType)?.lookupTag?.toSymbol(session)
|
||||||
if (callableReferenceAccess != null && classSymbol is FirRegularClassSymbol) {
|
if (callableReferenceAccess != null && classSymbol is FirRegularClassSymbol) {
|
||||||
val classIdMatched = classSymbol.classId == qualifier.classId
|
val classIdMatched = classSymbol.classId == qualifier.classId
|
||||||
val companionClassIdMatched = classSymbol.fir.isCompanion && classSymbol.classId.outerClassId == qualifier.classId
|
if (!classIdMatched) {
|
||||||
val lastClassIfCompanion = conversionScope.lastClass()?.takeIf { it.isCompanion }
|
// Check whether we need get companion object as dispatch receiver
|
||||||
val callable =
|
if (!classSymbol.fir.isCompanion || classSymbol.classId.outerClassId != qualifier.classId) {
|
||||||
((callableReferenceAccess.calleeReference as FirResolvedNamedReference).resolvedSymbol as FirCallableSymbol<*>)
|
return null
|
||||||
val companionMemberReferenceThatNeedsDispatchReceiver = companionClassIdMatched &&
|
}
|
||||||
// TODO: this can't cover delegated members. See bb test kt38664.kt
|
val resolvedReference = callableReferenceAccess.calleeReference as FirResolvedNamedReference
|
||||||
// Make sure the reference indeed refers to a member of that companion
|
val callableId = (resolvedReference.resolvedSymbol as FirCallableSymbol<*>).callableId
|
||||||
classSymbol.fir.declarations.contains(callable.fir) &&
|
// Make sure the reference indeed refers to a member of that companion
|
||||||
// Built-in extensions are stored in the companion, e.g., String.Companion.
|
if (callableId.classId != classSymbol.classId) {
|
||||||
// Make sure this is not a reference to an extension function.
|
return null
|
||||||
!callable.isExtension &&
|
}
|
||||||
// Dispatch receiver is not needed if we're converting a callable reference inside that companion, e.g.,
|
|
||||||
// class Foo {
|
|
||||||
// companion object {
|
|
||||||
// val cp = Foo::member
|
|
||||||
// } }
|
|
||||||
lastClassIfCompanion?.classId != classSymbol.classId
|
|
||||||
if (!classIdMatched && !companionMemberReferenceThatNeedsDispatchReceiver) {
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val irType = qualifier.typeRef.toIrType()
|
val irType = qualifier.typeRef.toIrType()
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS
|
// IGNORE_BACKEND: JS
|
||||||
|
|
||||||
interface C<A : Any, B : Any> {
|
interface C<A : Any, B : Any> {
|
||||||
|
|||||||
Reference in New Issue
Block a user