[NI] Use right scope for callable reference resolution

Previously was used scope for top-level call. It isn't correct because
if we have callable reference inside lambda -> scope is different.
This commit is contained in:
Stanislav Erokhin
2017-07-10 11:35:07 +03:00
parent da003d48ff
commit ff1e230828
6 changed files with 13 additions and 6 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionStatelessCallbacks
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
import org.jetbrains.kotlin.resolve.isHiddenInResolution
@@ -50,4 +51,7 @@ class KotlinResolutionStatelessCallbacksImpl(
override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean =
receiver?.psiExpression is KtSuperExpression
override fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower =
(argument as CallableReferenceKotlinCallArgumentImpl).scopeTowerForResolution
}
@@ -121,6 +121,7 @@ class FunctionExpressionImpl(
}
class CallableReferenceKotlinCallArgumentImpl(
val scopeTowerForResolution: ImplicitScopeTower,
override val valueArgument: ValueArgument,
override val dataFlowInfoBeforeThisArgument: DataFlowInfo,
override val dataFlowInfoAfterThisArgument: DataFlowInfo,
@@ -553,7 +553,7 @@ class PSICallResolver(
}
}
return CallableReferenceKotlinCallArgumentImpl(valueArgument, startDataFlowInfo, newDataFlowInfo,
return CallableReferenceKotlinCallArgumentImpl(ASTScopeTower(context), valueArgument, startDataFlowInfo, newDataFlowInfo,
ktExpression, argumentName, lhsNewResult, name)
}
@@ -62,7 +62,6 @@ class CallableReferenceResolver(
) {
fun processCallableReferenceArgument(
scopeTower: ImplicitScopeTower,
csBuilder: ConstraintSystemBuilder,
postponedArgument: PostponedCallableReferenceArgument
): KotlinCallDiagnostic? {
@@ -73,6 +72,8 @@ class CallableReferenceResolver(
if (subLHSCall != null) {
csBuilder.addInnerCall(subLHSCall.resolvedCall)
}
val scopeTower = callComponents.statelessCallbacks.getScopeTowerForCallableReferenceArgument(argument)
val candidates = runRHSResolution(scopeTower, argument, expectedType) { checkCallableReference ->
csBuilder.runTransaction { checkCallableReference(this); false }
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.types.UnwrappedType
// stateless component
@@ -29,6 +30,7 @@ interface KotlinResolutionStatelessCallbacks {
fun isSuperOrDelegatingConstructorCall(kotlinCall: KotlinCall): Boolean
fun isHiddenInResolution(descriptor: DeclarationDescriptor, kotlinCall: KotlinCall): Boolean
fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean
fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower
}
// This components hold state (trace). Work with this carefully.
@@ -80,7 +80,7 @@ class KotlinCallCompleter(
if (topLevelCall.prepareForCompletion(expectedType)) {
val c = candidate.lastCall.constraintSystem.asCallCompleterContext()
resolveCallableReferenceArguments(c, candidate.lastCall)
resolveCallableReferenceArguments(c)
topLevelCall.competeCall(c, resolutionCallbacks)
return toCompletedBaseResolvedCall(c, candidate, resolutionCallbacks)
@@ -89,11 +89,10 @@ class KotlinCallCompleter(
return ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate)
}
// todo do not use topLevelCall
private fun resolveCallableReferenceArguments(c: Context, topLevelCall: SimpleKotlinResolutionCandidate) {
private fun resolveCallableReferenceArguments(c: Context) {
for (callableReferenceArgument in c.postponedArguments) {
if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue
callableReferenceResolver.processCallableReferenceArgument(topLevelCall.scopeTower, c.getBuilder(), callableReferenceArgument)
callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), callableReferenceArgument)
}
}