[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.isInfixCall
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionStatelessCallbacks 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.KotlinCall
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.isHiddenInResolution
@@ -50,4 +51,7 @@ class KotlinResolutionStatelessCallbacksImpl(
override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean = override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean =
receiver?.psiExpression is KtSuperExpression receiver?.psiExpression is KtSuperExpression
override fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower =
(argument as CallableReferenceKotlinCallArgumentImpl).scopeTowerForResolution
} }
@@ -121,6 +121,7 @@ class FunctionExpressionImpl(
} }
class CallableReferenceKotlinCallArgumentImpl( class CallableReferenceKotlinCallArgumentImpl(
val scopeTowerForResolution: ImplicitScopeTower,
override val valueArgument: ValueArgument, override val valueArgument: ValueArgument,
override val dataFlowInfoBeforeThisArgument: DataFlowInfo, override val dataFlowInfoBeforeThisArgument: DataFlowInfo,
override val dataFlowInfoAfterThisArgument: 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) ktExpression, argumentName, lhsNewResult, name)
} }
@@ -62,7 +62,6 @@ class CallableReferenceResolver(
) { ) {
fun processCallableReferenceArgument( fun processCallableReferenceArgument(
scopeTower: ImplicitScopeTower,
csBuilder: ConstraintSystemBuilder, csBuilder: ConstraintSystemBuilder,
postponedArgument: PostponedCallableReferenceArgument postponedArgument: PostponedCallableReferenceArgument
): KotlinCallDiagnostic? { ): KotlinCallDiagnostic? {
@@ -73,6 +72,8 @@ class CallableReferenceResolver(
if (subLHSCall != null) { if (subLHSCall != null) {
csBuilder.addInnerCall(subLHSCall.resolvedCall) csBuilder.addInnerCall(subLHSCall.resolvedCall)
} }
val scopeTower = callComponents.statelessCallbacks.getScopeTowerForCallableReferenceArgument(argument)
val candidates = runRHSResolution(scopeTower, argument, expectedType) { checkCallableReference -> val candidates = runRHSResolution(scopeTower, argument, expectedType) { checkCallableReference ->
csBuilder.runTransaction { checkCallableReference(this); false } 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.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.UnwrappedType
// stateless component // stateless component
@@ -29,6 +30,7 @@ interface KotlinResolutionStatelessCallbacks {
fun isSuperOrDelegatingConstructorCall(kotlinCall: KotlinCall): Boolean fun isSuperOrDelegatingConstructorCall(kotlinCall: KotlinCall): Boolean
fun isHiddenInResolution(descriptor: DeclarationDescriptor, kotlinCall: KotlinCall): Boolean fun isHiddenInResolution(descriptor: DeclarationDescriptor, kotlinCall: KotlinCall): Boolean
fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean
fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower
} }
// This components hold state (trace). Work with this carefully. // This components hold state (trace). Work with this carefully.
@@ -80,7 +80,7 @@ class KotlinCallCompleter(
if (topLevelCall.prepareForCompletion(expectedType)) { if (topLevelCall.prepareForCompletion(expectedType)) {
val c = candidate.lastCall.constraintSystem.asCallCompleterContext() val c = candidate.lastCall.constraintSystem.asCallCompleterContext()
resolveCallableReferenceArguments(c, candidate.lastCall) resolveCallableReferenceArguments(c)
topLevelCall.competeCall(c, resolutionCallbacks) topLevelCall.competeCall(c, resolutionCallbacks)
return toCompletedBaseResolvedCall(c, candidate, resolutionCallbacks) return toCompletedBaseResolvedCall(c, candidate, resolutionCallbacks)
@@ -89,11 +89,10 @@ class KotlinCallCompleter(
return ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate) return ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate)
} }
// todo do not use topLevelCall private fun resolveCallableReferenceArguments(c: Context) {
private fun resolveCallableReferenceArguments(c: Context, topLevelCall: SimpleKotlinResolutionCandidate) {
for (callableReferenceArgument in c.postponedArguments) { for (callableReferenceArgument in c.postponedArguments) {
if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue
callableReferenceResolver.processCallableReferenceArgument(topLevelCall.scopeTower, c.getBuilder(), callableReferenceArgument) callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), callableReferenceArgument)
} }
} }