Refactoring: start commonization of type-conversions

This commit is contained in:
Mikhail Zarechenskiy
2020-05-12 04:40:25 +03:00
parent cce9646c7d
commit d3d162f9c8
2 changed files with 70 additions and 22 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
@@ -16,21 +17,46 @@ import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForPossibleSamType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.typeUtil.isNothing
object SamTypeConversions {
fun conversionMightBeNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean {
return when (argument) {
is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType
is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true
else -> false
}
}
fun conversionMightBeNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean {
return argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype
}
fun conversionDefinitelyNotNeeded(
candidate: KotlinResolutionCandidate,
candidateParameter: ParameterDescriptor
): Boolean {
val callComponents = candidate.callComponents
val generatingAdditionalSamCandidateIsEnabled =
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument) &&
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitVarargAsArrayAfterSamArgument)
if (generatingAdditionalSamCandidateIsEnabled) return true
if (candidateParameter.type.isNothing()) return true
val samConversionOracle = callComponents.samConversionOracle
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)) {
if (!samConversionOracle.shouldRunSamConversionForFunction(candidate.resolvedCall.candidateDescriptor)) return true
}
return false
}
}
fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
argument: KotlinCallArgument,
candidateParameter: ParameterDescriptor
): UnwrappedType? {
val generatingAdditionalSamCandidateIsEnabled =
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument) &&
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitVarargAsArrayAfterSamArgument)
if (generatingAdditionalSamCandidateIsEnabled) return null
if (candidateParameter.type.isNothing()) return null
val samConversionOracle = callComponents.samConversionOracle
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)) {
if (!samConversionOracle.shouldRunSamConversionForFunction(resolvedCall.candidateDescriptor)) return null
}
if (SamTypeConversions.conversionDefinitelyNotNeeded(this, candidateParameter)) return null
val argumentIsFunctional = when (argument) {
is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType
@@ -42,11 +68,17 @@ fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
val originalExpectedType = argument.getExpectedType(candidateParameter.original, callComponents.languageVersionSettings)
val convertedTypeByOriginal =
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(originalExpectedType, samConversionOracle) ?: return null
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
originalExpectedType,
callComponents.samConversionOracle
) ?: return null
val candidateExpectedType = argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings)
val convertedTypeByCandidate =
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(candidateExpectedType, samConversionOracle)
callComponents.samConversionResolver.getFunctionTypeForPossibleSamType(
candidateExpectedType,
callComponents.samConversionOracle
)
assert(candidateExpectedType.constructor == originalExpectedType.constructor && convertedTypeByCandidate != null) {
"If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" +
@@ -11,21 +11,37 @@ import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.UnwrappedType
object SuspendTypeConversions {
fun conversionDefinitelyNotNeeded(
candidate: KotlinResolutionCandidate,
argument: KotlinCallArgument,
candidateParameter: ParameterDescriptor
): Boolean {
if (!candidate.callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SuspendConversion)) return true
if (argument !is SimpleKotlinCallArgument) return true
val argumentType = argument.receiver.stableType
if (!argumentType.isFunctionType) return true
if (argumentType.isSuspendFunctionType) return true
if (!candidateParameter.type.isSuspendFunctionType) return true
return false
}
fun KotlinResolutionCandidate.conversionMightBeNeededBeforeSubtypingCheck(): Boolean = true
fun KotlinResolutionCandidate.conversionMightBeNeededAfterSubtypingCheck(): Boolean = false
}
fun KotlinResolutionCandidate.getExpectedTypeWithSuspendConversion(
argument: KotlinCallArgument,
candidateParameter: ParameterDescriptor
): UnwrappedType? {
if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SuspendConversion)) return null
if (argument !is SimpleKotlinCallArgument) return null
val argumentType = argument.receiver.stableType
if (!argumentType.isFunctionType) return null
if (argumentType.isSuspendFunctionType) return null
if (SuspendTypeConversions.conversionDefinitelyNotNeeded(this, argument, candidateParameter)) return null
val parameterType = candidateParameter.type
if (!parameterType.isSuspendFunctionType) return null
val nonSuspendParameterType = createFunctionType(
callComponents.builtIns,
parameterType.annotations,