[NI] Support implicit invoke calls on parenthesized receivers
This commit is contained in:
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.components.NewOverloadingConflictResol
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
@@ -39,8 +40,8 @@ class KotlinCallResolver(
|
||||
resolutionCallbacks: KotlinResolutionCallbacks,
|
||||
kotlinCall: KotlinCall,
|
||||
expectedType: UnwrappedType?,
|
||||
factoryProviderForInvoke: CandidateFactoryProviderForInvoke<KotlinResolutionCandidate>,
|
||||
collectAllCandidates: Boolean
|
||||
collectAllCandidates: Boolean,
|
||||
createFactoryProviderForInvoke: () -> CandidateFactoryProviderForInvoke<KotlinResolutionCandidate>
|
||||
): CallResolutionResult {
|
||||
kotlinCall.checkCallInvariants()
|
||||
|
||||
@@ -54,10 +55,20 @@ class KotlinCallResolver(
|
||||
scopeTower,
|
||||
kotlinCall.name,
|
||||
candidateFactory,
|
||||
factoryProviderForInvoke,
|
||||
createFactoryProviderForInvoke(),
|
||||
kotlinCall.explicitReceiver?.receiver
|
||||
)
|
||||
}
|
||||
KotlinCallKind.INVOKE -> {
|
||||
createProcessorWithReceiverValueOrEmpty(kotlinCall.explicitReceiver?.receiver) {
|
||||
createCallTowerProcessorForExplicitInvoke(
|
||||
scopeTower,
|
||||
candidateFactory,
|
||||
kotlinCall.dispatchReceiverForInvokeExtension?.receiver as ReceiverValueWithSmartCastInfo,
|
||||
it
|
||||
)
|
||||
}
|
||||
}
|
||||
KotlinCallKind.UNSUPPORTED -> throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -205,7 +205,11 @@ internal object CheckExplicitReceiverKindConsistency : ResolutionPart() {
|
||||
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
||||
when (resolvedCall.explicitReceiverKind) {
|
||||
NO_EXPLICIT_RECEIVER -> if (kotlinCall.explicitReceiver is SimpleKotlinCallArgument || kotlinCall.dispatchReceiverForInvokeExtension != null) hasError()
|
||||
DISPATCH_RECEIVER, EXTENSION_RECEIVER -> if (kotlinCall.explicitReceiver == null || kotlinCall.dispatchReceiverForInvokeExtension != null) hasError()
|
||||
DISPATCH_RECEIVER, EXTENSION_RECEIVER ->
|
||||
if (kotlinCall.callKind == KotlinCallKind.INVOKE && kotlinCall.dispatchReceiverForInvokeExtension == null ||
|
||||
kotlinCall.callKind != KotlinCallKind.INVOKE &&
|
||||
(kotlinCall.explicitReceiver == null || kotlinCall.dispatchReceiverForInvokeExtension != null)
|
||||
) hasError()
|
||||
BOTH_RECEIVERS -> if (kotlinCall.explicitReceiver == null || kotlinCall.dispatchReceiverForInvokeExtension == null) hasError()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.model
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.prepareReceiverRegardingCaptureTypes
|
||||
|
||||
|
||||
|
||||
@@ -43,27 +43,32 @@ fun KotlinCall.checkCallInvariants() {
|
||||
explicitReceiver.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants()
|
||||
dispatchReceiverForInvokeExtension.safeAs<SimpleKotlinCallArgument>()?.checkReceiverInvariants()
|
||||
|
||||
if (callKind != KotlinCallKind.FUNCTION) {
|
||||
assert(externalArgument == null) {
|
||||
"External argument is not allowed not for function call: $externalArgument."
|
||||
}
|
||||
assert(argumentsInParenthesis.isEmpty()) {
|
||||
"Arguments in parenthesis should be empty for not function call: $this "
|
||||
}
|
||||
assert(dispatchReceiverForInvokeExtension == null) {
|
||||
"Dispatch receiver for invoke should be null for not function call: $dispatchReceiverForInvokeExtension"
|
||||
}
|
||||
} else {
|
||||
assert(externalArgument == null || !externalArgument!!.isSpread) {
|
||||
"External argument cannot nave spread element: $externalArgument"
|
||||
when (callKind) {
|
||||
KotlinCallKind.FUNCTION, KotlinCallKind.INVOKE -> {
|
||||
assert(externalArgument == null || !externalArgument!!.isSpread) {
|
||||
"External argument cannot nave spread element: $externalArgument"
|
||||
}
|
||||
assert(externalArgument?.argumentName == null) {
|
||||
"Illegal external argument with name: $externalArgument"
|
||||
}
|
||||
assert(dispatchReceiverForInvokeExtension == null || !dispatchReceiverForInvokeExtension!!.isSafeCall) {
|
||||
"Dispatch receiver for invoke cannot be safe: $dispatchReceiverForInvokeExtension"
|
||||
}
|
||||
}
|
||||
|
||||
assert(externalArgument?.argumentName == null) {
|
||||
"Illegal external argument with name: $externalArgument"
|
||||
KotlinCallKind.VARIABLE -> {
|
||||
assert(externalArgument == null) {
|
||||
"External argument is not allowed not for function call: $externalArgument."
|
||||
}
|
||||
assert(argumentsInParenthesis.isEmpty()) {
|
||||
"Arguments in parenthesis should be empty for not function call: $this "
|
||||
}
|
||||
assert(dispatchReceiverForInvokeExtension == null) {
|
||||
"Dispatch receiver for invoke should be null for not function call: $dispatchReceiverForInvokeExtension"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
assert(dispatchReceiverForInvokeExtension == null || !dispatchReceiverForInvokeExtension!!.isSafeCall) {
|
||||
"Dispatch receiver for invoke cannot be safe: $dispatchReceiverForInvokeExtension"
|
||||
}
|
||||
KotlinCallKind.UNSUPPORTED -> error("Call with UNSUPPORTED kind")
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -207,6 +207,7 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
|
||||
CheckArguments,
|
||||
CheckExternalArgument
|
||||
),
|
||||
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
|
||||
UNSUPPORTED();
|
||||
|
||||
val resolutionSequence = resolutionPart.asList()
|
||||
|
||||
Reference in New Issue
Block a user