Use Call instead of CallKey as a map key in ResolutionResultsCache
This commit is contained in:
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2013 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.jet.lang.psi;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.psi.Call.CallType;
|
|
||||||
|
|
||||||
public class CallKey {
|
|
||||||
private final CallType callType;
|
|
||||||
private final JetExpression element;
|
|
||||||
|
|
||||||
public CallKey(CallType callType, JetExpression element) {
|
|
||||||
this.callType = callType;
|
|
||||||
this.element = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static CallKey create(@NotNull CallType callType, @NotNull JetExpression element) {
|
|
||||||
return new CallKey(callType, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CallKey create(JetExpression element) {
|
|
||||||
return new CallKey(CallType.DEFAULT, element);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (!(o instanceof CallKey)) return false;
|
|
||||||
|
|
||||||
CallKey key = (CallKey) o;
|
|
||||||
|
|
||||||
if (callType != key.callType) return false;
|
|
||||||
if (element != null ? !element.equals(key.element) : key.element != null) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = callType != null ? callType.hashCode() : 0;
|
|
||||||
result = 31 * result + (element != null ? element.hashCode() : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -326,15 +326,15 @@ public class CallResolver {
|
|||||||
@NotNull CallTransformer<D, F> callTransformer,
|
@NotNull CallTransformer<D, F> callTransformer,
|
||||||
@NotNull TracingStrategy tracing
|
@NotNull TracingStrategy tracing
|
||||||
) {
|
) {
|
||||||
tracing.bindCall(context.trace, context.call);
|
Call call = context.call;
|
||||||
|
tracing.bindCall(context.trace, call);
|
||||||
|
|
||||||
OverloadResolutionResultsImpl<F> results = null;
|
OverloadResolutionResultsImpl<F> results = null;
|
||||||
TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call);
|
TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", call);
|
||||||
CallKey callKey = CallResolverUtil.createCallKey(context);
|
if (!CallResolverUtil.isInvokeCallOnVariable(call)) {
|
||||||
if (callKey != null) {
|
OverloadResolutionResultsImpl<F> cachedResults = context.resolutionResultsCache.getResolutionResults(call);
|
||||||
OverloadResolutionResultsImpl<F> cachedResults = context.resolutionResultsCache.getResolutionResults(callKey);
|
|
||||||
if (cachedResults != null) {
|
if (cachedResults != null) {
|
||||||
DelegatingBindingTrace deltasTraceForResolve = context.resolutionResultsCache.getResolutionTrace(callKey);
|
DelegatingBindingTrace deltasTraceForResolve = context.resolutionResultsCache.getResolutionTrace(call);
|
||||||
assert deltasTraceForResolve != null;
|
assert deltasTraceForResolve != null;
|
||||||
deltasTraceForResolve.addAllMyDataTo(traceToResolveCall);
|
deltasTraceForResolve.addAllMyDataTo(traceToResolveCall);
|
||||||
results = cachedResults;
|
results = cachedResults;
|
||||||
@@ -419,20 +419,20 @@ public class CallResolver {
|
|||||||
@NotNull DelegatingBindingTrace traceToResolveCall,
|
@NotNull DelegatingBindingTrace traceToResolveCall,
|
||||||
@NotNull TracingStrategy tracing
|
@NotNull TracingStrategy tracing
|
||||||
) {
|
) {
|
||||||
CallKey callKey = CallResolverUtil.createCallKey(context);
|
Call call = context.call;
|
||||||
if (callKey == null) return;
|
if (CallResolverUtil.isInvokeCallOnVariable(call)) return;
|
||||||
|
|
||||||
DelegatingBindingTrace deltasTraceToCacheResolve = new DelegatingBindingTrace(
|
DelegatingBindingTrace deltasTraceToCacheResolve = new DelegatingBindingTrace(
|
||||||
BindingContext.EMPTY, "delta trace for caching resolve of", context.call);
|
BindingContext.EMPTY, "delta trace for caching resolve of", context.call);
|
||||||
traceToResolveCall.addAllMyDataTo(deltasTraceToCacheResolve);
|
traceToResolveCall.addAllMyDataTo(deltasTraceToCacheResolve);
|
||||||
|
|
||||||
context.resolutionResultsCache.recordResolutionResults(callKey, results);
|
context.resolutionResultsCache.recordResolutionResults(call, results);
|
||||||
context.resolutionResultsCache.recordResolutionTrace(callKey, deltasTraceToCacheResolve);
|
context.resolutionResultsCache.recordResolutionTrace(call, deltasTraceToCacheResolve);
|
||||||
|
|
||||||
if (results.isSingleResult()) {
|
if (results.isSingleResult()) {
|
||||||
CallCandidateResolutionContext<F> contextForCallToCompleteTypeArgumentInference =
|
CallCandidateResolutionContext<F> contextForCallToCompleteTypeArgumentInference =
|
||||||
CallCandidateResolutionContext.createForCallBeingAnalyzed(results.getResultingCall(), context, tracing);
|
CallCandidateResolutionContext.createForCallBeingAnalyzed(results.getResultingCall(), context, tracing);
|
||||||
context.resolutionResultsCache.recordDeferredComputationForCall(callKey, contextForCallToCompleteTypeArgumentInference);
|
context.resolutionResultsCache.recordDeferredComputationForCall(call, contextForCallToCompleteTypeArgumentInference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,12 +586,13 @@ public class CallResolver {
|
|||||||
to have a binding to variable while 'invoke' call resolve */
|
to have a binding to variable while 'invoke' call resolve */
|
||||||
task.tracing.bindReference(context.candidateCall.getTrace(), context.candidateCall);
|
task.tracing.bindReference(context.candidateCall.getTrace(), context.candidateCall);
|
||||||
|
|
||||||
Collection<MutableResolvedCall<F>> calls = callTransformer.transformCall(context, this, task);
|
Collection<MutableResolvedCall<F>> resolvedCalls = callTransformer.transformCall(context, this, task);
|
||||||
|
|
||||||
for (MutableResolvedCall<F> call : calls) {
|
for (MutableResolvedCall<F> resolvedCall : resolvedCalls) {
|
||||||
task.tracing.bindReference(call.getTrace(), call);
|
BindingTrace trace = resolvedCall.getTrace();
|
||||||
task.tracing.bindResolvedCall(call.getTrace(), call);
|
task.tracing.bindReference(trace, resolvedCall);
|
||||||
task.addResolvedCall(call);
|
task.tracing.bindResolvedCall(trace, resolvedCall);
|
||||||
|
task.addResolvedCall(resolvedCall);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,16 +102,6 @@ public class CallResolverUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static CallKey createCallKey(@NotNull BasicCallResolutionContext context) {
|
|
||||||
if (isInvokeCallOnVariable(context.call)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
PsiElement callElement = context.call.getCallElement();
|
|
||||||
if (!(callElement instanceof JetExpression)) return null;
|
|
||||||
return CallKey.create(context.call.getCallType(), (JetExpression) callElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JetType getErasedReceiverType(
|
public static JetType getErasedReceiverType(
|
||||||
@NotNull ReceiverParameterDescriptor receiverParameterDescriptor,
|
@NotNull ReceiverParameterDescriptor receiverParameterDescriptor,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
|
||||||
@@ -273,15 +274,14 @@ public class CandidateResolver {
|
|||||||
|
|
||||||
private <D extends CallableDescriptor> void completeTypeInferenceForAllCandidatesForArgument(
|
private <D extends CallableDescriptor> void completeTypeInferenceForAllCandidatesForArgument(
|
||||||
@NotNull CallCandidateResolutionContext<D> context,
|
@NotNull CallCandidateResolutionContext<D> context,
|
||||||
@Nullable JetExpression argumentExpression
|
@Nullable Call call
|
||||||
) {
|
) {
|
||||||
// All candidates for inner calls are not needed, so there is no need to complete them
|
// All candidates for inner calls are not needed, so there is no need to complete them
|
||||||
if (context.collectAllCandidates) return;
|
if (context.collectAllCandidates) return;
|
||||||
|
|
||||||
if (argumentExpression == null) return;
|
if (call == null) return;
|
||||||
|
|
||||||
CallKey callKey = CallKey.create(argumentExpression);
|
OverloadResolutionResultsImpl<CallableDescriptor> resolutionResults = context.resolutionResultsCache.getResolutionResults(call);
|
||||||
OverloadResolutionResultsImpl<CallableDescriptor> resolutionResults = context.resolutionResultsCache.getResolutionResults(callKey);
|
|
||||||
if (resolutionResults == null) return;
|
if (resolutionResults == null) return;
|
||||||
|
|
||||||
completeTypeInferenceForAllCandidates(context.toBasic(), resolutionResults);
|
completeTypeInferenceForAllCandidates(context.toBasic(), resolutionResults);
|
||||||
@@ -390,6 +390,20 @@ public class CandidateResolver {
|
|||||||
recordReferenceForInvokeFunction(context);
|
recordReferenceForInvokeFunction(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static Call getCallForArgument(@Nullable JetExpression argument, @NotNull BindingContext bindingContext) {
|
||||||
|
if (!ExpressionTypingUtils.dependsOnExpectedType(argument)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (argument instanceof JetBlockExpression) {
|
||||||
|
JetElement lastStatement = JetPsiUtil.getLastStatementInABlock((JetBlockExpression) argument);
|
||||||
|
if (lastStatement instanceof JetExpression) {
|
||||||
|
return getCallForArgument((JetExpression) lastStatement, bindingContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BindingContextUtilPackage.getCorrespondingCall(argument, bindingContext);
|
||||||
|
}
|
||||||
|
|
||||||
private <D extends CallableDescriptor> void completeInferenceForArgument(
|
private <D extends CallableDescriptor> void completeInferenceForArgument(
|
||||||
@NotNull ValueArgument argument,
|
@NotNull ValueArgument argument,
|
||||||
@NotNull ValueParameterDescriptor parameterDescriptor,
|
@NotNull ValueParameterDescriptor parameterDescriptor,
|
||||||
@@ -401,8 +415,8 @@ public class CandidateResolver {
|
|||||||
JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument);
|
JetType expectedType = getEffectiveExpectedType(parameterDescriptor, argument);
|
||||||
context = context.replaceExpectedType(expectedType);
|
context = context.replaceExpectedType(expectedType);
|
||||||
|
|
||||||
JetExpression keyExpression = getDeferredComputationKeyExpression(expression);
|
Call call = getCallForArgument(expression, context.trace.getBindingContext());
|
||||||
CallCandidateResolutionContext<?> storedContextForArgument = context.resolutionResultsCache.getDeferredComputation(keyExpression);
|
CallCandidateResolutionContext<?> storedContextForArgument = context.resolutionResultsCache.getDeferredComputation(call);
|
||||||
|
|
||||||
PsiElement parent = expression.getParent();
|
PsiElement parent = expression.getParent();
|
||||||
if (parent instanceof JetWhenExpression && expression == ((JetWhenExpression) parent).getSubjectExpression()
|
if (parent instanceof JetWhenExpression && expression == ((JetWhenExpression) parent).getSubjectExpression()
|
||||||
@@ -412,7 +426,7 @@ public class CandidateResolver {
|
|||||||
if (storedContextForArgument == null) {
|
if (storedContextForArgument == null) {
|
||||||
JetType type = ArgumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression);
|
JetType type = ArgumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression);
|
||||||
checkResultArgumentType(type, argument, context);
|
checkResultArgumentType(type, argument, context);
|
||||||
completeTypeInferenceForAllCandidatesForArgument(context, keyExpression);
|
completeTypeInferenceForAllCandidatesForArgument(context, call);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +441,7 @@ public class CandidateResolver {
|
|||||||
JetType result = BindingContextUtils.updateRecordedType(
|
JetType result = BindingContextUtils.updateRecordedType(
|
||||||
type, expression, context.trace, isFairSafeCallExpression(expression, context.trace));
|
type, expression, context.trace, isFairSafeCallExpression(expression, context.trace));
|
||||||
|
|
||||||
completeTypeInferenceForAllCandidatesForArgument(context, keyExpression);
|
completeTypeInferenceForAllCandidatesForArgument(context, call);
|
||||||
|
|
||||||
DataFlowUtils.checkType(result, expression, contextForArgument);
|
DataFlowUtils.checkType(result, expression, contextForArgument);
|
||||||
}
|
}
|
||||||
@@ -447,10 +461,8 @@ public class CandidateResolver {
|
|||||||
for (ValueArgument argument : arguments) {
|
for (ValueArgument argument : arguments) {
|
||||||
JetExpression expression = argument.getArgumentExpression();
|
JetExpression expression = argument.getArgumentExpression();
|
||||||
|
|
||||||
JetExpression keyExpression = getDeferredComputationKeyExpression(expression);
|
Call call = getCallForArgument(expression, context.trace.getBindingContext());
|
||||||
|
CallCandidateResolutionContext<?> storedContextForArgument = context.resolutionResultsCache.getDeferredComputation(call);
|
||||||
CallCandidateResolutionContext<?> storedContextForArgument =
|
|
||||||
context.resolutionResultsCache.getDeferredComputation(keyExpression);
|
|
||||||
if (storedContextForArgument == null) continue;
|
if (storedContextForArgument == null) continue;
|
||||||
if (storedContextForArgument.candidateCall.isCompleted()) continue;
|
if (storedContextForArgument.candidateCall.isCompleted()) continue;
|
||||||
|
|
||||||
@@ -460,57 +472,6 @@ public class CandidateResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private JetExpression getDeferredComputationKeyExpression(@Nullable JetExpression expression) {
|
|
||||||
if (expression == null) return null;
|
|
||||||
return expression.accept(new JetVisitor<JetExpression, Void>() {
|
|
||||||
@Nullable
|
|
||||||
private JetExpression visitInnerExpression(@Nullable JetElement expression) {
|
|
||||||
if (expression == null) return null;
|
|
||||||
return expression.accept(this, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetExpression visitQualifiedExpression(@NotNull JetQualifiedExpression expression, Void data) {
|
|
||||||
return visitInnerExpression(expression.getSelectorExpression());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetExpression visitExpression(@NotNull JetExpression expression, Void data) {
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetExpression visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, Void data) {
|
|
||||||
return visitInnerExpression(expression.getExpression());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetExpression visitUnaryExpression(@NotNull JetUnaryExpression expression, Void data) {
|
|
||||||
return ExpressionTypingUtils.isUnaryExpressionDependentOnExpectedType(expression) ? expression : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetExpression visitLabeledExpression(@NotNull JetLabeledExpression expression, Void data) {
|
|
||||||
return visitInnerExpression(expression.getBaseExpression());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetExpression visitBlockExpression(@NotNull JetBlockExpression expression, Void data) {
|
|
||||||
JetElement lastStatement = JetPsiUtil.getLastStatementInABlock(expression);
|
|
||||||
if (lastStatement != null) {
|
|
||||||
return visitInnerExpression(lastStatement);
|
|
||||||
}
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JetExpression visitBinaryExpression(@NotNull JetBinaryExpression expression, Void data) {
|
|
||||||
return ExpressionTypingUtils.isBinaryExpressionDependentOnExpectedType(expression) ? expression : null;
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isFairSafeCallExpression(@NotNull JetExpression expression, @NotNull BindingTrace trace) {
|
private static boolean isFairSafeCallExpression(@NotNull JetExpression expression, @NotNull BindingTrace trace) {
|
||||||
// We are interested in type of the last call:
|
// We are interested in type of the last call:
|
||||||
// 'a.b?.foo()' is safe call, but 'a?.b.foo()' is not.
|
// 'a.b?.foo()' is safe call, but 'a?.b.foo()' is not.
|
||||||
|
|||||||
+7
-9
@@ -19,29 +19,27 @@ package org.jetbrains.jet.lang.resolve.calls.context;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.CallKey;
|
import org.jetbrains.jet.lang.psi.Call;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
|
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall;
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||||
|
|
||||||
public interface ResolutionResultsCache {
|
public interface ResolutionResultsCache {
|
||||||
|
|
||||||
<D extends CallableDescriptor> void recordResolutionResults(@NotNull CallKey callKey, @NotNull OverloadResolutionResultsImpl<D> results);
|
<D extends CallableDescriptor> void recordResolutionResults(@NotNull Call call, @NotNull OverloadResolutionResultsImpl<D> results);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
<D extends CallableDescriptor> OverloadResolutionResultsImpl<D> getResolutionResults(@NotNull CallKey callKey);
|
<D extends CallableDescriptor> OverloadResolutionResultsImpl<D> getResolutionResults(@NotNull Call call);
|
||||||
|
|
||||||
void recordResolutionTrace(@NotNull CallKey callKey, @NotNull DelegatingBindingTrace delegatingTrace);
|
void recordResolutionTrace(@NotNull Call call, @NotNull DelegatingBindingTrace delegatingTrace);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
DelegatingBindingTrace getResolutionTrace(@NotNull CallKey callKey);
|
DelegatingBindingTrace getResolutionTrace(@NotNull Call call);
|
||||||
|
|
||||||
<D extends CallableDescriptor> void recordDeferredComputationForCall(
|
<D extends CallableDescriptor> void recordDeferredComputationForCall(
|
||||||
@NotNull CallKey callKey,
|
@NotNull Call call,
|
||||||
@NotNull CallCandidateResolutionContext<D> deferredComputation
|
@NotNull CallCandidateResolutionContext<D> deferredComputation
|
||||||
);
|
);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
CallCandidateResolutionContext<?> getDeferredComputation(@Nullable JetExpression expression);
|
CallCandidateResolutionContext<?> getDeferredComputation(@Nullable Call call);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-23
@@ -17,12 +17,11 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.calls.context
|
package org.jetbrains.jet.lang.resolve.calls.context
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.jet.lang.psi.CallKey
|
|
||||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl
|
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl
|
||||||
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace
|
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression
|
import org.jetbrains.jet.lang.psi.JetExpression
|
||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import org.jetbrains.jet.lang.psi.Call.CallType.*
|
import org.jetbrains.jet.lang.psi.Call
|
||||||
|
|
||||||
class ResolutionResultsCacheImpl : ResolutionResultsCache {
|
class ResolutionResultsCacheImpl : ResolutionResultsCache {
|
||||||
private class CachedData(
|
private class CachedData(
|
||||||
@@ -31,40 +30,34 @@ class ResolutionResultsCacheImpl : ResolutionResultsCache {
|
|||||||
var deferredComputation: CallCandidateResolutionContext<*>? = null
|
var deferredComputation: CallCandidateResolutionContext<*>? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
private val data = HashMap<CallKey, CachedData>()
|
private val data = HashMap<Call, CachedData>()
|
||||||
|
|
||||||
private fun getOrCreateCachedInfo(callKey: CallKey) = data.getOrPut(callKey, { CachedData() })
|
private fun getOrCreateCachedInfo(call: Call) = data.getOrPut(call, { CachedData() })
|
||||||
|
|
||||||
override fun <D : CallableDescriptor?> recordResolutionResults(callKey: CallKey, results: OverloadResolutionResultsImpl<D>) {
|
override fun <D : CallableDescriptor?> recordResolutionResults(call: Call, results: OverloadResolutionResultsImpl<D>) {
|
||||||
getOrCreateCachedInfo(callKey).results = results
|
getOrCreateCachedInfo(call).results = results
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <D : CallableDescriptor?> getResolutionResults(callKey: CallKey): OverloadResolutionResultsImpl<D>? {
|
override fun <D : CallableDescriptor?> getResolutionResults(call: Call): OverloadResolutionResultsImpl<D>? {
|
||||||
return data[callKey]?.results as OverloadResolutionResultsImpl<D>?
|
return data[call]?.results as OverloadResolutionResultsImpl<D>?
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun recordResolutionTrace(callKey: CallKey, delegatingTrace: DelegatingBindingTrace) {
|
override fun recordResolutionTrace(call: Call, delegatingTrace: DelegatingBindingTrace) {
|
||||||
getOrCreateCachedInfo(callKey).resolutionTrace = delegatingTrace
|
getOrCreateCachedInfo(call).resolutionTrace = delegatingTrace
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getResolutionTrace(callKey: CallKey): DelegatingBindingTrace? {
|
override fun getResolutionTrace(call: Call): DelegatingBindingTrace? {
|
||||||
return data[callKey]?.resolutionTrace
|
return data[call]?.resolutionTrace
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <D : CallableDescriptor?> recordDeferredComputationForCall(callKey: CallKey, deferredComputation: CallCandidateResolutionContext<D>) {
|
override fun <D : CallableDescriptor?> recordDeferredComputationForCall(call: Call, deferredComputation: CallCandidateResolutionContext<D>) {
|
||||||
getOrCreateCachedInfo(callKey).deferredComputation = deferredComputation
|
getOrCreateCachedInfo(call).deferredComputation = deferredComputation
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDeferredComputation(expression: JetExpression?): CallCandidateResolutionContext<out CallableDescriptor?>? {
|
override fun getDeferredComputation(call: Call?): CallCandidateResolutionContext<out CallableDescriptor?>? {
|
||||||
if (expression == null) return null
|
if (call == null) return null
|
||||||
|
|
||||||
for (callType in listOf(DEFAULT, ARRAY_GET_METHOD, ARRAY_SET_METHOD, INVOKE)) {
|
return data[call]?.deferredComputation
|
||||||
val deferredComputation = data[CallKey.create(callType, expression)]?.deferredComputation
|
|
||||||
if (deferredComputation != null) {
|
|
||||||
return deferredComputation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addData(cache: ResolutionResultsCacheImpl) {
|
fun addData(cache: ResolutionResultsCacheImpl) {
|
||||||
|
|||||||
+16
-17
@@ -19,8 +19,7 @@ package org.jetbrains.jet.lang.resolve.calls.context;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.CallKey;
|
import org.jetbrains.jet.lang.psi.Call;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
|
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||||
|
|
||||||
@@ -37,57 +36,57 @@ public class TemporaryResolutionResultsCache implements ResolutionResultsCache {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void recordResolutionResults(
|
public <D extends CallableDescriptor> void recordResolutionResults(
|
||||||
@NotNull CallKey callKey,
|
@NotNull Call call,
|
||||||
@NotNull OverloadResolutionResultsImpl<D> results
|
@NotNull OverloadResolutionResultsImpl<D> results
|
||||||
) {
|
) {
|
||||||
innerCache.recordResolutionResults(callKey, results);
|
innerCache.recordResolutionResults(call, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> getResolutionResults(
|
public <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> getResolutionResults(
|
||||||
@NotNull CallKey callKey
|
@NotNull Call call
|
||||||
) {
|
) {
|
||||||
OverloadResolutionResultsImpl<D> results = innerCache.getResolutionResults(callKey);
|
OverloadResolutionResultsImpl<D> results = innerCache.getResolutionResults(call);
|
||||||
if (results != null) {
|
if (results != null) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
return parentCache.getResolutionResults(callKey);
|
return parentCache.getResolutionResults(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recordResolutionTrace(
|
public void recordResolutionTrace(
|
||||||
@NotNull CallKey callKey, @NotNull DelegatingBindingTrace delegatingTrace
|
@NotNull Call call, @NotNull DelegatingBindingTrace delegatingTrace
|
||||||
) {
|
) {
|
||||||
innerCache.recordResolutionTrace(callKey, delegatingTrace);
|
innerCache.recordResolutionTrace(call, delegatingTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public DelegatingBindingTrace getResolutionTrace(@NotNull CallKey callKey) {
|
public DelegatingBindingTrace getResolutionTrace(@NotNull Call call) {
|
||||||
DelegatingBindingTrace trace = innerCache.getResolutionTrace(callKey);
|
DelegatingBindingTrace trace = innerCache.getResolutionTrace(call);
|
||||||
if (trace != null) {
|
if (trace != null) {
|
||||||
return trace;
|
return trace;
|
||||||
}
|
}
|
||||||
return parentCache.getResolutionTrace(callKey);
|
return parentCache.getResolutionTrace(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void recordDeferredComputationForCall(
|
public <D extends CallableDescriptor> void recordDeferredComputationForCall(
|
||||||
@NotNull CallKey callKey,
|
@NotNull Call call,
|
||||||
@NotNull CallCandidateResolutionContext<D> deferredComputation
|
@NotNull CallCandidateResolutionContext<D> deferredComputation
|
||||||
) {
|
) {
|
||||||
innerCache.recordDeferredComputationForCall(callKey, deferredComputation);
|
innerCache.recordDeferredComputationForCall(call, deferredComputation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public CallCandidateResolutionContext<?> getDeferredComputation(@Nullable JetExpression expression) {
|
public CallCandidateResolutionContext<?> getDeferredComputation(@Nullable Call call) {
|
||||||
CallCandidateResolutionContext<?> computation = innerCache.getDeferredComputation(expression);
|
CallCandidateResolutionContext<?> computation = innerCache.getDeferredComputation(call);
|
||||||
if (computation != null) {
|
if (computation != null) {
|
||||||
return computation;
|
return computation;
|
||||||
}
|
}
|
||||||
return parentCache.getDeferredComputation(expression);
|
return parentCache.getDeferredComputation(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void commit() {
|
public void commit() {
|
||||||
|
|||||||
+16
@@ -526,4 +526,20 @@ public class ExpressionTypingUtils {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean dependsOnExpectedType(@Nullable JetExpression expression) {
|
||||||
|
JetExpression expr = JetPsiUtil.deparenthesize(expression, false);
|
||||||
|
if (expr == null) return false;
|
||||||
|
|
||||||
|
if (expr instanceof JetBinaryExpressionWithTypeRHS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (expr instanceof JetBinaryExpression) {
|
||||||
|
return isBinaryExpressionDependentOnExpectedType((JetBinaryExpression) expr);
|
||||||
|
}
|
||||||
|
if (expr instanceof JetUnaryExpression) {
|
||||||
|
return isUnaryExpressionDependentOnExpectedType((JetUnaryExpression) expr);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user