[NI] Fix provideDelegate resolution.

For provideDelegate there is no real psi for resolution,
so we write corresponding call via special trace key.
This commit is contained in:
Stanislav Erokhin
2017-06-13 11:39:55 +03:00
committed by Mikhail Zarechenskiy
parent 7802492b08
commit a5dffafacd
4 changed files with 21 additions and 10 deletions
@@ -123,6 +123,7 @@ public interface BindingContext {
WritableSlice<Call, ResolvedCall<?>> RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<Call, ResolvedKotlinCall.OnlyResolvedKotlinCall> ONLY_RESOLVED_CALL = new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<KtExpression, Call> DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL = new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<Call, TailRecursionKind> TAIL_RECURSION_CALL = Slices.createSimpleSlice();
WritableSlice<KtElement, ConstraintSystemCompleter> CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice<>(DO_NOTHING);
WritableSlice<KtElement, Call> CALL = new BasicWritableSlice<>(DO_NOTHING);
@@ -337,6 +337,10 @@ class DelegatedPropertyResolver(
val (provideDelegateCall, provideDelegateResults) =
fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, functionName, delegateExpression)
if (provideDelegateResults.isSingleResult) {
context.trace.record(BindingContext.DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL, delegateExpression, provideDelegateCall)
}
context.trace.record(BindingContext.PROVIDE_DELEGATE_CALL, propertyDescriptor, provideDelegateCall)
return provideDelegateResults
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.resolve.calls.tower
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.replaceReturnType
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
@@ -42,7 +41,10 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import java.util.*
@@ -476,12 +478,12 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
}
override fun getSmartCastDispatchReceiverType(): KotlinType? = null // todo
}
fun ResolutionCandidateApplicability.toResolutionStatus(): ResolutionStatus = when (this) {
ResolutionCandidateApplicability.RESOLVED, ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY -> ResolutionStatus.SUCCESS
ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ResolutionStatus.RECEIVER_TYPE_ERROR
else -> ResolutionStatus.OTHER_ERROR
}
fun ResolutionCandidateApplicability.toResolutionStatus(): ResolutionStatus = when (this) {
ResolutionCandidateApplicability.RESOLVED, ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY -> ResolutionStatus.SUCCESS
ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ResolutionStatus.RECEIVER_TYPE_ERROR
else -> ResolutionStatus.OTHER_ERROR
}
class NewVariableAsFunctionResolvedCallImpl(
@@ -491,7 +493,7 @@ class NewVariableAsFunctionResolvedCallImpl(
): VariableAsFunctionResolvedCall, ResolvedCall<FunctionDescriptor> by functionCall
class StubOnlyResolvedCall<D : CallableDescriptor>(val candidate: SimpleKotlinResolutionCandidate): NewAbstractResolvedCall<D>() {
override fun getStatus() = ResolutionStatus.UNKNOWN_STATUS
override fun getStatus() = candidate.status.resultingApplicability.toResolutionStatus()
override fun getCandidateDescriptor(): D = candidate.candidateDescriptor as D
override fun getResultingDescriptor(): D = candidate.descriptorWithFreshTypes as D
@@ -433,8 +433,12 @@ class PSICallResolver(
if (oldReceiver is ExpressionReceiver) {
val ktExpression = KtPsiUtil.getLastElementDeparenthesized(oldReceiver.expression, context.statementFilter)
val onlyResolvedCall = ktExpression?.getCall(context.trace.bindingContext)?.let {
context.trace.get(BindingContext.ONLY_RESOLVED_CALL, it)
val bindingContext = context.trace.bindingContext
val call = bindingContext[BindingContext.DELEGATE_EXPRESSION_TO_PROVIDE_DELEGATE_CALL, ktExpression]
?: ktExpression?.getCall(bindingContext)
val onlyResolvedCall = call?.let {
bindingContext.get(BindingContext.ONLY_RESOLVED_CALL, it)
}
if (onlyResolvedCall != null) {
subCallArgument = SubKotlinCallArgumentImpl(CallMaker.makeExternalValueArgument(oldReceiver.expression),