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.FirSuperReference
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
import org.jetbrains.kotlin.fir.render 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.getExpectedTypeForSAMConversion
import org.jetbrains.kotlin.fir.resolve.calls.isFunctional import org.jetbrains.kotlin.fir.resolve.calls.isFunctional
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.inference.isKMutableProperty 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.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -48,6 +47,7 @@ class CallAndReferenceGenerator(
private val approximator = object : AbstractTypeApproximator(session.typeContext) {} private val approximator = object : AbstractTypeApproximator(session.typeContext) {}
private val adapterGenerator = AdapterGenerator(components, conversionScope) private val adapterGenerator = AdapterGenerator(components, conversionScope)
private val samResolver = FirSamResolverImpl(session, scopeSession)
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() } private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
@@ -621,10 +621,7 @@ class CallAndReferenceGenerator(
return false 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`. // 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 expectedFunctionType = samResolver.getFunctionTypeForPossibleSamType(parameter.returnTypeRef.coneType)
val firRegularClass = lookupTag?.toFirRegularClass(session)
// TODO: cache SAM interface to resolved function type, as [SamResolution] does?
val expectedFunctionType = firRegularClass?.resolveFunctionTypeIfSamInterface(session, scopeSession)
return argument.isFunctional(session, scopeSession, expectedFunctionType) return argument.isFunctional(session, scopeSession, expectedFunctionType)
} }
@@ -45,7 +45,7 @@ val SAM_PARAMETER_NAME = Name.identifier("block")
class FirSamResolverImpl( class FirSamResolverImpl(
private val firSession: FirSession, private val firSession: FirSession,
private val scopeSession: ScopeSession, private val scopeSession: ScopeSession,
private val outerClassManager: FirOuterClassManager, private val outerClassManager: FirOuterClassManager? = null,
) : FirSamResolver() { ) : FirSamResolver() {
private val resolvedFunctionType: MutableMap<FirRegularClass, Any> = mutableMapOf() private val resolvedFunctionType: MutableMap<FirRegularClass, Any> = mutableMapOf()
@@ -206,13 +206,17 @@ class FirSamResolverImpl(
resolvePhase = FirResolvePhase.BODY_RESOLVE resolvePhase = FirResolvePhase.BODY_RESOLVE
}.apply { }.apply {
containingClassAttr = outerClassManager.outerClass(firRegularClass.symbol)?.toLookupTag() containingClassAttr = outerClassManager?.outerClass(firRegularClass.symbol)?.toLookupTag()
} }
} }
private fun resolveFunctionTypeIfSamInterface(firRegularClass: FirRegularClass): ConeLookupTagBasedType? { private fun resolveFunctionTypeIfSamInterface(firRegularClass: FirRegularClass): ConeLookupTagBasedType? {
return resolvedFunctionType.getOrPut(firRegularClass) { 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 } 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( private fun FirRegularClass.getSingleAbstractMethodOrNull(
session: FirSession, session: FirSession,
scopeSession: ScopeSession, scopeSession: ScopeSession,