Refactoring: start commonization of type-conversions
This commit is contained in:
+45
-13
@@ -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" +
|
||||
|
||||
+25
-9
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user