Creating resolved and resolution atoms for callable references

This commit is contained in:
Victor Petukhov
2021-09-20 17:01:31 +03:00
parent 5ec97093fa
commit ca13aea26a
8 changed files with 48 additions and 23 deletions
@@ -139,7 +139,8 @@ class CallableReferenceKotlinCallArgumentImpl(
val ktCallableReferenceExpression: KtCallableReferenceExpression,
override val argumentName: Name?,
override val lhsResult: LHSResult,
override val rhsName: Name
override val rhsName: Name,
override val call: KotlinCall
) : CallableReferenceKotlinCallArgument, PSIKotlinCallArgument()
class CollectionLiteralKotlinCallArgumentImpl(
@@ -79,7 +79,7 @@ class ResolvedAtomCompleter(
when (resolvedAtom) {
is ResolvedCollectionLiteralAtom -> completeCollectionLiteralCalls(resolvedAtom)
is ResolvedCallableReferenceAtom -> completeCallableReference(resolvedAtom)
is ResolvedCallableReferenceArgumentAtom -> completeCallableReferenceArgument(resolvedAtom)
is ResolvedLambdaAtom -> completeLambda(resolvedAtom)
is ResolvedCallAtom -> completeResolvedCall(resolvedAtom, emptyList())
is ResolvedSubCallArgument -> completeSubCallArgument(resolvedAtom)
@@ -60,9 +60,8 @@ class CallableReferenceAdaptation(
* C::foo <-> Object
* D.E::foo <-> Expression
*/
fun createCallableReferenceProcessor(factory: CallableReferencesCandidateFactory): ScopeTowerProcessor<CallableReferenceCandidate> {
val lhsResult = factory.argument.lhsResult
when (lhsResult) {
fun createCallableReferenceProcessor(factory: CallableReferencesCandidateFactory): ScopeTowerProcessor<CallableReferenceResolutionCandidate> {
when (val lhsResult = factory.kotlinCall.lhsResult) {
LHSResult.Empty, LHSResult.Error, is LHSResult.Expression -> {
val explicitReceiver = (lhsResult as? LHSResult.Expression)?.lshCallArgument?.receiver
return factory.createCallableProcessor(explicitReceiver)
@@ -165,8 +165,9 @@ class KotlinCallCompleter(
callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionPerArgument) &&
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitVarargAsArrayAfterSamArgument)
if (samConversionPerArgumentWithWarningsForVarargAfterSam && resolvedCall.candidateDescriptor is SyntheticMemberDescriptor<*>) {
val declarationDescriptor = resolvedCall.candidateDescriptor.baseDescriptorForSynthetic as? FunctionDescriptor ?: return
val candidateDescriptor = resolvedCall.candidateDescriptor
if (samConversionPerArgumentWithWarningsForVarargAfterSam && candidateDescriptor is SyntheticMemberDescriptor<*>) {
val declarationDescriptor = candidateDescriptor.baseDescriptorForSynthetic as? FunctionDescriptor ?: return
if (declarationDescriptor.valueParameters.lastOrNull()?.isVararg == true) {
diagnosticHolder.addDiagnostic(
@@ -421,8 +421,8 @@ class KotlinConstraintSystemCompleter(
is ResolvedCallAtom -> freshVariablesSubstitutor.freshVariables.map { it.freshTypeConstructor }
is PostponedCallableReferenceAtom ->
getVariablesFromRevisedExpectedType(revisedExpectedType).orEmpty() +
candidate?.freshSubstitutor?.freshVariables?.map { it.freshTypeConstructor }.orEmpty()
is ResolvedCallableReferenceAtom -> candidate?.freshSubstitutor?.freshVariables?.map { it.freshTypeConstructor }.orEmpty()
candidate?.freshVariablesSubstitutor?.freshVariables?.map { it.freshTypeConstructor }.orEmpty()
is ResolvedCallableReferenceArgumentAtom -> candidate?.freshVariablesSubstitutor?.freshVariables?.map { it.freshTypeConstructor }.orEmpty()
is ResolvedLambdaAtom -> listOfNotNull(typeVariableForLambdaReturnType?.freshTypeConstructor)
else -> emptyList()
}
@@ -493,7 +493,7 @@ class KotlinConstraintSystemCompleter(
fun ResolvedAtom.check(): ResolvedAtom? {
val suitableCall = when (this) {
is ResolvedCallAtom -> typeVariable in freshVariablesSubstitutor.freshVariables
is ResolvedCallableReferenceAtom -> candidate?.freshSubstitutor?.freshVariables?.let { typeVariable in it } ?: false
is ResolvedCallableReferenceArgumentAtom -> candidate?.freshVariablesSubstitutor?.freshVariables?.let { typeVariable in it } ?: false
is ResolvedLambdaAtom -> typeVariable == typeVariableForLambdaReturnType
else -> false
}
@@ -120,13 +120,13 @@ sealed class LHSResult {
object Error : LHSResult()
}
interface CallableReferenceKotlinCallArgument : PostponableKotlinCallArgument {
interface CallableReferenceKotlinCallArgument : PostponableKotlinCallArgument, CallableReferenceResolutionAtom {
override val isSpread: Boolean
get() = false
val lhsResult: LHSResult
override val lhsResult: LHSResult
val rhsName: Name
override val call: KotlinCall
}
interface CollectionLiteralKotlinCallArgument : PostponableKotlinCallArgument
@@ -7,15 +7,14 @@ package org.jetbrains.kotlin.resolve.calls.model
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.components.ReturnArgumentsInfo
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper
import org.jetbrains.kotlin.resolve.calls.components.extractInputOutputTypesFromCallableReferenceExpectedType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.components.*
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.*
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
@@ -32,6 +31,20 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
*/
interface ResolutionAtom
sealed interface CallableReferenceResolutionAtom : ResolutionAtom {
val lhsResult: LHSResult
val rhsName: Name
val call: KotlinCall
}
class CallableReferenceKotlinCall(
override val call: KotlinCall,
override val lhsResult: LHSResult,
override val rhsName: Name,
) : CallableReferenceResolutionAtom
sealed interface ResolvedCallableReferenceAtom
sealed class ResolvedAtom {
abstract val atom: ResolutionAtom? // CallResolutionResult has no ResolutionAtom
@@ -163,10 +176,10 @@ fun ResolvedLambdaAtom.unwrap(): ResolvedLambdaAtom {
return if (resultArgumentsInfo != null) this else subResolvedAtoms!!.single() as ResolvedLambdaAtom
}
abstract class ResolvedCallableReferenceAtom(
abstract class ResolvedCallableReferenceArgumentAtom(
override val atom: CallableReferenceKotlinCallArgument,
override val expectedType: UnwrappedType?
) : PostponedResolvedAtom() {
) : PostponedResolvedAtom(), ResolvedCallableReferenceAtom {
var candidate: CallableReferenceResolutionCandidate? = null
private set
@@ -185,8 +198,7 @@ abstract class ResolvedCallableReferenceAtom(
class EagerCallableReferenceAtom(
atom: CallableReferenceKotlinCallArgument,
expectedType: UnwrappedType?
) : ResolvedCallableReferenceAtom(atom, expectedType) {
) : ResolvedCallableReferenceArgumentAtom(atom, expectedType) {
override val inputTypes: Collection<UnwrappedType> get() = emptyList()
override val outputType: UnwrappedType? get() = null
@@ -196,7 +208,7 @@ class EagerCallableReferenceAtom(
sealed class AbstractPostponedCallableReferenceAtom(
atom: CallableReferenceKotlinCallArgument,
expectedType: UnwrappedType?
) : ResolvedCallableReferenceAtom(atom, expectedType) {
) : ResolvedCallableReferenceArgumentAtom(atom, expectedType) {
override val inputTypes: Collection<UnwrappedType>
get() = extractInputOutputTypesFromCallableReferenceExpectedType(expectedType)?.inputTypes ?: listOfNotNull(expectedType)
@@ -64,7 +64,19 @@ fun KotlinDiagnosticsHolder.addError(error: ConstraintSystemError) {
addDiagnostic(error.asDiagnostic())
}
class MutableResolvedCallAtom(
class ResolvedCallableReferenceCallAtom(
atom: KotlinCall,
candidateDescriptor: CallableDescriptor,
explicitReceiverKind: ExplicitReceiverKind,
dispatchReceiverArgument: SimpleKotlinCallArgument?,
extensionReceiverArgument: SimpleKotlinCallArgument?,
reflectionCandidateType: UnwrappedType? = null,
candidate: CallableReferenceResolutionCandidate? = null
) : MutableResolvedCallAtom(
atom, candidateDescriptor, explicitReceiverKind, dispatchReceiverArgument, extensionReceiverArgument, reflectionCandidateType, candidate
), ResolvedCallableReferenceAtom
open class MutableResolvedCallAtom(
override val atom: KotlinCall,
override val candidateDescriptor: CallableDescriptor, // original candidate descriptor
override val explicitReceiverKind: ExplicitReceiverKind,