[NI] Prototype for SAM-conversion.

Supported:
- conversion in resolution parts. Also sam-with-receiver is supported automatically
- separate flag for kotlin function with java SAM as parameters

TODO:
- fix overload conflict error when function type is the same byte origin types is ordered
- consider case when parameter type is T, T <:> Runnable
- support vararg of Runnable

[NI] Turn off synthetic scope with SAM adapter functions if NI enabled
This commit is contained in:
Stanislav Erokhin
2018-05-01 23:46:15 +03:00
parent 4b8e95c243
commit 8f0b073c08
48 changed files with 889 additions and 26 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.kotlin.resolve.calls.checkers.*
import org.jetbrains.kotlin.resolve.calls.components.SamConversionTransformer
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.checkers.*
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
@@ -62,6 +63,7 @@ abstract class TargetPlatform(val platformName: String) {
) {
override fun configureModuleComponents(container: StorageComponentContainer) {
container.useInstance(SyntheticScopes.Empty)
container.useInstance(SamConversionTransformer.Empty)
container.useInstance(TypeSpecificityComparator.NONE)
}
}
@@ -209,10 +209,14 @@ class KotlinToResolvedCallTransformer(
for (valueArgument in resolvedCall.call.valueArguments) {
val argumentMapping = resolvedCall.getArgumentMapping(valueArgument!!)
val (expectedType, callPosition) = when (argumentMapping) {
is ArgumentMatch -> Pair(
getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context),
CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument)
)
is ArgumentMatch -> {
val expectedType = resolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument)
?: getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context)
Pair(
expectedType,
CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument)
)
}
else -> Pair(TypeUtils.NO_EXPECTED_TYPE, CallPosition.Unknown)
}
val newContext =
@@ -522,6 +526,8 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
private var extensionReceiver = resolvedCallAtom.extensionReceiverArgument?.receiver?.receiverValue
private var dispatchReceiver = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue
private var smartCastDispatchReceiverType: KotlinType? = null
private var expedtedTypeForSamConvertedArgumentMap: MutableMap<ValueArgument, UnwrappedType>? = null
override val kotlinCall: KotlinCall get() = resolvedCallAtom.atom
@@ -610,6 +616,22 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
TypeApproximator().approximateToSuperType(substituted, TypeApproximatorConfiguration.CapturedTypesApproximation) ?: substituted
}
calculateExpedtedTypeForSamConvertedArgumentMap(substitutor)
}
fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
expedtedTypeForSamConvertedArgumentMap?.get(valueArgument)
private fun calculateExpedtedTypeForSamConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
if (resolvedCallAtom.argumentsWithConversion.isEmpty()) return
expedtedTypeForSamConvertedArgumentMap = hashMapOf()
for ((argument, description) in resolvedCallAtom.argumentsWithConversion) {
val typeWithFreshVariables = resolvedCallAtom.substitutor.safeSubstitute(description.convertedTypeByCandidateParameter)
val expectedType = substitutor?.safeSubstitute(typeWithFreshVariables) ?: typeWithFreshVariables
expedtedTypeForSamConvertedArgumentMap!![argument.psiCallArgument.valueArgument] = expectedType
}
}
init {