FIR2IR: use FirSamResolverImpl to get function type for possible SAM type

This commit is contained in:
Jinseong Jeon
2020-12-10 12:28:50 -08:00
committed by TeamCityServer
parent d5a6991b2d
commit 4a24f0fab3
2 changed files with 10 additions and 20 deletions
@@ -17,13 +17,12 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.FirSamResolverImpl
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedTypeForSAMConversion
import org.jetbrains.kotlin.fir.resolve.calls.isFunctional
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.inference.isKMutableProperty
import org.jetbrains.kotlin.fir.resolve.resolveFunctionTypeIfSamInterface
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -48,6 +47,7 @@ class CallAndReferenceGenerator(
private val approximator = object : AbstractTypeApproximator(session.typeContext) {}
private val adapterGenerator = AdapterGenerator(components, conversionScope)
private val samResolver = FirSamResolverImpl(session, scopeSession)
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
@@ -621,10 +621,7 @@ class CallAndReferenceGenerator(
return false
}
// On the other hand, the actual type should be either a functional type or a subtype of a class that has a contributed `invoke`.
val lookupTag = parameter.returnTypeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag
val firRegularClass = lookupTag?.toFirRegularClass(session)
// TODO: cache SAM interface to resolved function type, as [SamResolution] does?
val expectedFunctionType = firRegularClass?.resolveFunctionTypeIfSamInterface(session, scopeSession)
val expectedFunctionType = samResolver.getFunctionTypeForPossibleSamType(parameter.returnTypeRef.coneType)
return argument.isFunctional(session, scopeSession, expectedFunctionType)
}
@@ -45,7 +45,7 @@ val SAM_PARAMETER_NAME = Name.identifier("block")
class FirSamResolverImpl(
private val firSession: FirSession,
private val scopeSession: ScopeSession,
private val outerClassManager: FirOuterClassManager,
private val outerClassManager: FirOuterClassManager? = null,
) : FirSamResolver() {
private val resolvedFunctionType: MutableMap<FirRegularClass, Any> = mutableMapOf()
@@ -206,13 +206,17 @@ class FirSamResolverImpl(
resolvePhase = FirResolvePhase.BODY_RESOLVE
}.apply {
containingClassAttr = outerClassManager.outerClass(firRegularClass.symbol)?.toLookupTag()
containingClassAttr = outerClassManager?.outerClass(firRegularClass.symbol)?.toLookupTag()
}
}
private fun resolveFunctionTypeIfSamInterface(firRegularClass: FirRegularClass): ConeLookupTagBasedType? {
return resolvedFunctionType.getOrPut(firRegularClass) {
firRegularClass.resolveFunctionTypeIfSamInterface(firSession, scopeSession) ?: NULL_STUB
if (!firRegularClass.status.isFun) return@getOrPut NULL_STUB
val abstractMethod = firRegularClass.getSingleAbstractMethodOrNull(firSession, scopeSession) ?: return@getOrPut NULL_STUB
// TODO: val shouldConvertFirstParameterToDescriptor = samWithReceiverResolvers.any { it.shouldConvertFirstSamParameterToReceiver(abstractMethod) }
abstractMethod.getFunctionTypeForAbstractMethod()
} as? ConeLookupTagBasedType
}
@@ -222,17 +226,6 @@ class FirSamResolverImpl(
}
}
fun FirRegularClass.resolveFunctionTypeIfSamInterface(
session: FirSession,
scopeSession: ScopeSession
): ConeLookupTagBasedType? {
if (!this.status.isFun) return null
val abstractMethod = getSingleAbstractMethodOrNull(session, scopeSession) ?: return null
// TODO: val shouldConvertFirstParameterToDescriptor = samWithReceiverResolvers.any { it.shouldConvertFirstSamParameterToReceiver(abstractMethod) }
return abstractMethod.getFunctionTypeForAbstractMethod()
}
private fun FirRegularClass.getSingleAbstractMethodOrNull(
session: FirSession,
scopeSession: ScopeSession,