Remove old resolution algorithm.
This commit is contained in:
@@ -16,12 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.Pair;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -39,14 +35,10 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollectors;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolveOldInference;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
@@ -66,10 +58,6 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
|
||||
import static org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS;
|
||||
import static org.jetbrains.kotlin.resolve.calls.context.CandidateResolveMode.EXIT_ON_FIRST_ERROR;
|
||||
import static org.jetbrains.kotlin.resolve.calls.context.CandidateResolveMode.FULLY;
|
||||
import static org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.CANDIDATES_WITH_WRONG_RECEIVER;
|
||||
import static org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
|
||||
@@ -77,27 +65,19 @@ import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
public class CallResolver {
|
||||
private ExpressionTypingServices expressionTypingServices;
|
||||
private TypeResolver typeResolver;
|
||||
private CandidateResolver candidateResolver;
|
||||
private ArgumentTypeResolver argumentTypeResolver;
|
||||
private GenericCandidateResolver genericCandidateResolver;
|
||||
private CallCompleter callCompleter;
|
||||
private NewResolveOldInference newCallResolver;
|
||||
private final TaskPrioritizer taskPrioritizer;
|
||||
private final ResolutionResultsHandler resolutionResultsHandler;
|
||||
@NotNull private KotlinBuiltIns builtIns;
|
||||
private final KotlinBuiltIns builtIns;
|
||||
|
||||
private static final PerformanceCounter callResolvePerfCounter = PerformanceCounter.Companion.create("Call resolve", ExpressionTypingVisitorDispatcher.typeInfoPerfCounter);
|
||||
private static final PerformanceCounter candidatePerfCounter = PerformanceCounter.Companion.create("Call resolve candidate analysis", true);
|
||||
|
||||
public static boolean useNewResolve = !"false".equals(System.getProperty("kotlin.internal.new_resolve"));
|
||||
|
||||
public CallResolver(
|
||||
@NotNull TaskPrioritizer taskPrioritizer,
|
||||
@NotNull ResolutionResultsHandler resolutionResultsHandler,
|
||||
@NotNull KotlinBuiltIns builtIns
|
||||
) {
|
||||
this.taskPrioritizer = taskPrioritizer;
|
||||
this.resolutionResultsHandler = resolutionResultsHandler;
|
||||
this.builtIns = builtIns;
|
||||
}
|
||||
|
||||
@@ -113,12 +93,6 @@ public class CallResolver {
|
||||
this.typeResolver = typeResolver;
|
||||
}
|
||||
|
||||
// component dependency cycle
|
||||
@Inject
|
||||
public void setCandidateResolver(@NotNull CandidateResolver candidateResolver) {
|
||||
this.candidateResolver = candidateResolver;
|
||||
}
|
||||
|
||||
// component dependency cycle
|
||||
@Inject
|
||||
public void setArgumentTypeResolver(@NotNull ArgumentTypeResolver argumentTypeResolver) {
|
||||
@@ -149,10 +123,9 @@ public class CallResolver {
|
||||
assert calleeExpression instanceof KtSimpleNameExpression;
|
||||
KtSimpleNameExpression nameExpression = (KtSimpleNameExpression) calleeExpression;
|
||||
Name referencedName = nameExpression.getReferencedNameAsName();
|
||||
CallableDescriptorCollectors<VariableDescriptor> callableDescriptorCollectors = CallableDescriptorCollectors.VARIABLES;
|
||||
return computeTasksAndResolveCall(
|
||||
context, referencedName, nameExpression,
|
||||
callableDescriptorCollectors, CallTransformer.VARIABLE_CALL_TRANSFORMER, ResolveKind.VARIABLE);
|
||||
ResolveKind.VARIABLE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -162,7 +135,7 @@ public class CallResolver {
|
||||
) {
|
||||
return computeTasksAndResolveCall(
|
||||
context, nameExpression.getReferencedNameAsName(), nameExpression,
|
||||
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.MEMBER_CALL_TRANSFORMER, ResolveKind.CALLABLE_REFERENCE);
|
||||
ResolveKind.CALLABLE_REFERENCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -175,7 +148,7 @@ public class CallResolver {
|
||||
BasicCallResolutionContext callResolutionContext = BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS);
|
||||
return computeTasksAndResolveCall(
|
||||
callResolutionContext, name, functionReference,
|
||||
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER, ResolveKind.FUNCTION);
|
||||
ResolveKind.FUNCTION);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -185,7 +158,6 @@ public class CallResolver {
|
||||
) {
|
||||
return computeTasksAndResolveCall(
|
||||
context, OperatorNameConventions.INVOKE, tracing,
|
||||
CallableDescriptorCollectors.FUNCTIONS, CallTransformer.FUNCTION_CALL_TRANSFORMER,
|
||||
ResolveKind.INVOKE);
|
||||
}
|
||||
|
||||
@@ -194,12 +166,10 @@ public class CallResolver {
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull Name name,
|
||||
@NotNull KtReferenceExpression referenceExpression,
|
||||
@NotNull CallableDescriptorCollectors<D> collectors,
|
||||
@NotNull CallTransformer<D, F> callTransformer,
|
||||
@NotNull ResolveKind kind
|
||||
) {
|
||||
TracingStrategy tracing = TracingStrategyImpl.create(referenceExpression, context.call);
|
||||
return computeTasksAndResolveCall(context, name, tracing, collectors, callTransformer, kind);
|
||||
return computeTasksAndResolveCall(context, name, tracing, kind);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -207,21 +177,14 @@ public class CallResolver {
|
||||
@NotNull final BasicCallResolutionContext context,
|
||||
@NotNull final Name name,
|
||||
@NotNull final TracingStrategy tracing,
|
||||
@NotNull final CallableDescriptorCollectors<D> collectors,
|
||||
@NotNull final CallTransformer<D, F> callTransformer,
|
||||
@NotNull final ResolveKind kind
|
||||
) {
|
||||
return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<F>>() {
|
||||
@Override
|
||||
public OverloadResolutionResults<F> invoke() {
|
||||
TaskContextForMigration<D, F> contextForMigration = new TaskContextForMigration<D, F>(
|
||||
kind, callTransformer, name, null,
|
||||
new Function0<List<ResolutionTask<D, F>>>() {
|
||||
@Override
|
||||
public List<ResolutionTask<D, F>> invoke() {
|
||||
return taskPrioritizer.<D, F>computePrioritizedTasks(context, name, tracing, collectors);
|
||||
}
|
||||
});
|
||||
TaskContextForMigration<D> contextForMigration = new TaskContextForMigration<D>(
|
||||
kind, name, null
|
||||
);
|
||||
return doResolveCallOrGetCachedResults(context, contextForMigration, tracing);
|
||||
}
|
||||
});
|
||||
@@ -231,10 +194,9 @@ public class CallResolver {
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksFromCandidatesAndResolvedCall(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull KtReferenceExpression referenceExpression,
|
||||
@NotNull Collection<ResolutionCandidate<D>> candidates,
|
||||
@NotNull CallTransformer<D, F> callTransformer
|
||||
@NotNull Collection<ResolutionCandidate<D>> candidates
|
||||
) {
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, candidates, callTransformer,
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, candidates,
|
||||
TracingStrategyImpl.create(referenceExpression, context.call));
|
||||
}
|
||||
|
||||
@@ -242,21 +204,14 @@ public class CallResolver {
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResults<F> computeTasksFromCandidatesAndResolvedCall(
|
||||
@NotNull final BasicCallResolutionContext context,
|
||||
@NotNull final Collection<ResolutionCandidate<D>> candidates,
|
||||
@NotNull final CallTransformer<D, F> callTransformer,
|
||||
@NotNull final TracingStrategy tracing
|
||||
) {
|
||||
return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<F>>() {
|
||||
@Override
|
||||
public OverloadResolutionResults<F> invoke() {
|
||||
TaskContextForMigration<D, F> contextForMigration = new TaskContextForMigration<D, F>(
|
||||
ResolveKind.GIVEN_CANDIDATES, callTransformer, null, candidates,
|
||||
new Function0<List<ResolutionTask<D, F>>>() {
|
||||
@Override
|
||||
public List<ResolutionTask<D, F>> invoke() {
|
||||
return taskPrioritizer.<D, F>computePrioritizedTasksFromCandidates(
|
||||
context, candidates, tracing);
|
||||
}
|
||||
});
|
||||
TaskContextForMigration<D> contextForMigration = new TaskContextForMigration<D>(
|
||||
ResolveKind.GIVEN_CANDIDATES, null, candidates
|
||||
);
|
||||
return doResolveCallOrGetCachedResults(context, contextForMigration, tracing);
|
||||
}
|
||||
});
|
||||
@@ -304,8 +259,6 @@ public class CallResolver {
|
||||
KtArrayAccessExpression arrayAccessExpression = (KtArrayAccessExpression) context.call.getCallElement();
|
||||
return computeTasksAndResolveCall(
|
||||
context, name, arrayAccessExpression,
|
||||
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES,
|
||||
CallTransformer.FUNCTION_CALL_TRANSFORMER,
|
||||
ResolveKind.FUNCTION);
|
||||
}
|
||||
|
||||
@@ -314,7 +267,7 @@ public class CallResolver {
|
||||
KtSimpleNameExpression expression = (KtSimpleNameExpression) calleeExpression;
|
||||
return computeTasksAndResolveCall(
|
||||
context, expression.getReferencedNameAsName(), expression,
|
||||
CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES, CallTransformer.FUNCTION_CALL_TRANSFORMER, ResolveKind.FUNCTION);
|
||||
ResolveKind.FUNCTION);
|
||||
}
|
||||
else if (calleeExpression instanceof KtConstructorCalleeExpression) {
|
||||
return resolveCallForConstructor(context, (KtConstructorCalleeExpression) calleeExpression);
|
||||
@@ -388,7 +341,7 @@ public class CallResolver {
|
||||
Collection<ResolutionCandidate<CallableDescriptor>> candidates = candidatesAndContext.getFirst();
|
||||
context = candidatesAndContext.getSecond();
|
||||
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, functionReference, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER);
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, functionReference, candidates);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -479,7 +432,7 @@ public class CallResolver {
|
||||
return checkArgumentTypesAndFail(context);
|
||||
}
|
||||
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, candidates, CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing);
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, candidates, tracing);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -529,22 +482,14 @@ public class CallResolver {
|
||||
return callResolvePerfCounter.time(new Function0<OverloadResolutionResults<FunctionDescriptor>>() {
|
||||
@Override
|
||||
public OverloadResolutionResults<FunctionDescriptor> invoke() {
|
||||
final BasicCallResolutionContext basicCallResolutionContext =
|
||||
BasicCallResolutionContext basicCallResolutionContext =
|
||||
BasicCallResolutionContext.create(context, call, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, dataFlowInfoForArguments);
|
||||
|
||||
final Set<ResolutionCandidate<CallableDescriptor>> candidates = Collections.singleton(candidate);
|
||||
Set<ResolutionCandidate<CallableDescriptor>> candidates = Collections.singleton(candidate);
|
||||
|
||||
TaskContextForMigration<CallableDescriptor, FunctionDescriptor> contextForMigration =
|
||||
new TaskContextForMigration<CallableDescriptor, FunctionDescriptor>(
|
||||
ResolveKind.GIVEN_CANDIDATES, CallTransformer.FUNCTION_CALL_TRANSFORMER, null, candidates,
|
||||
new Function0<List<ResolutionTask<CallableDescriptor, FunctionDescriptor>>>() {
|
||||
@Override
|
||||
public List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> invoke() {
|
||||
|
||||
return taskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
|
||||
basicCallResolutionContext, candidates, tracing);
|
||||
}
|
||||
}
|
||||
TaskContextForMigration<CallableDescriptor> contextForMigration =
|
||||
new TaskContextForMigration<CallableDescriptor>(
|
||||
ResolveKind.GIVEN_CANDIDATES, null, candidates
|
||||
);
|
||||
|
||||
|
||||
@@ -555,7 +500,7 @@ public class CallResolver {
|
||||
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCallOrGetCachedResults(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull TaskContextForMigration<D, F> contextForMigration,
|
||||
@NotNull TaskContextForMigration<D> contextForMigration,
|
||||
@NotNull TracingStrategy tracing
|
||||
) {
|
||||
Call call = context.call;
|
||||
@@ -627,7 +572,7 @@ public class CallResolver {
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCall(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull TaskContextForMigration<D, F> contextForMigration,
|
||||
@NotNull TaskContextForMigration<D> contextForMigration,
|
||||
@NotNull TracingStrategy tracing
|
||||
) {
|
||||
if (context.checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
|
||||
@@ -656,151 +601,11 @@ public class CallResolver {
|
||||
else {
|
||||
return (OverloadResolutionResultsImpl<F>) newCallResolver.runResolveForGivenCandidates(context, tracing, contextForMigration.givenCandidates);
|
||||
}
|
||||
|
||||
//return doResolveCall(context, contextForMigration.lazyTasks.invoke(), contextForMigration.callTransformer, tracing);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCall(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull List<ResolutionTask<D, F>> prioritizedTasks, // high to low priority
|
||||
@NotNull CallTransformer<D, F> callTransformer,
|
||||
@NotNull TracingStrategy tracing
|
||||
) {
|
||||
Collection<ResolvedCall<F>> allCandidates = Lists.newArrayList();
|
||||
OverloadResolutionResultsImpl<F> successfulResults = null;
|
||||
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
|
||||
OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null;
|
||||
for (ResolutionTask<D, F> task : prioritizedTasks) {
|
||||
if (task.getCandidates().isEmpty()) continue;
|
||||
|
||||
TemporaryBindingTrace taskTrace =
|
||||
TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.call.getCalleeExpression());
|
||||
OverloadResolutionResultsImpl<F> results = performResolution(task.replaceBindingTrace(taskTrace), callTransformer);
|
||||
|
||||
|
||||
allCandidates.addAll(task.getResolvedCalls());
|
||||
|
||||
if (successfulResults != null) continue;
|
||||
|
||||
if (results.isSuccess() || results.isAmbiguity()) {
|
||||
taskTrace.commit();
|
||||
successfulResults = results;
|
||||
}
|
||||
if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) {
|
||||
results.setTrace(taskTrace);
|
||||
successfulResults = results;
|
||||
}
|
||||
boolean updateResults = traceForFirstNonemptyCandidateSet == null
|
||||
|| (resultsForFirstNonemptyCandidateSet.getResultCode() == CANDIDATES_WITH_WRONG_RECEIVER
|
||||
&& results.getResultCode() != CANDIDATES_WITH_WRONG_RECEIVER);
|
||||
if (!task.getCandidates().isEmpty() && !results.isNothing() && updateResults) {
|
||||
traceForFirstNonemptyCandidateSet = taskTrace;
|
||||
resultsForFirstNonemptyCandidateSet = results;
|
||||
}
|
||||
|
||||
if (successfulResults != null && !context.collectAllCandidates) break;
|
||||
}
|
||||
OverloadResolutionResultsImpl<F> results;
|
||||
if (successfulResults != null) {
|
||||
results = successfulResults;
|
||||
}
|
||||
else if (traceForFirstNonemptyCandidateSet == null) {
|
||||
tracing.unresolvedReference(context.trace);
|
||||
argumentTypeResolver.checkTypesWithNoCallee(context, SHAPE_FUNCTION_ARGUMENTS);
|
||||
results = OverloadResolutionResultsImpl.<F>nameNotFound();
|
||||
}
|
||||
else {
|
||||
traceForFirstNonemptyCandidateSet.commit();
|
||||
results = resultsForFirstNonemptyCandidateSet;
|
||||
}
|
||||
results.setAllCandidates(context.collectAllCandidates ? allCandidates : null);
|
||||
return results;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> performResolution(
|
||||
@NotNull ResolutionTask<D, F> task,
|
||||
@NotNull CallTransformer<D, F> callTransformer
|
||||
) {
|
||||
CandidateResolveMode mode = task.collectAllCandidates ? FULLY : EXIT_ON_FIRST_ERROR;
|
||||
List<CallCandidateResolutionContext<D>> contexts = collectCallCandidateContext(task, callTransformer, mode);
|
||||
boolean isSuccess = ContainerUtil.exists(contexts, new Condition<CallCandidateResolutionContext<D>>() {
|
||||
@Override
|
||||
public boolean value(CallCandidateResolutionContext<D> context) {
|
||||
return context.candidateCall.getStatus().possibleTransformToSuccess();
|
||||
}
|
||||
});
|
||||
if (!isSuccess && mode == EXIT_ON_FIRST_ERROR) {
|
||||
contexts = collectCallCandidateContext(task, callTransformer, FULLY);
|
||||
}
|
||||
|
||||
for (CallCandidateResolutionContext<D> context : contexts) {
|
||||
addResolvedCall(task, callTransformer, context);
|
||||
}
|
||||
|
||||
OverloadResolutionResultsImpl<F> results = resolutionResultsHandler.computeResultAndReportErrors(
|
||||
task, task.tracing, task.getResolvedCalls());
|
||||
if (!results.isSingleResult() && !results.isIncomplete()) {
|
||||
argumentTypeResolver.checkTypesWithNoCallee(task.toBasic());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor, F extends D> List<CallCandidateResolutionContext<D>> collectCallCandidateContext(
|
||||
@NotNull final ResolutionTask<D, F> task,
|
||||
@NotNull final CallTransformer<D, F> callTransformer,
|
||||
@NotNull final CandidateResolveMode candidateResolveMode
|
||||
) {
|
||||
final List<CallCandidateResolutionContext<D>> candidateResolutionContexts = ContainerUtil.newArrayList();
|
||||
for (final ResolutionCandidate<D> resolutionCandidate : task.getCandidates()) {
|
||||
if (DeprecationUtilKt.isHiddenInResolution(resolutionCandidate.getDescriptor())) continue;
|
||||
|
||||
candidatePerfCounter.time(new Function0<Unit>() {
|
||||
@Override
|
||||
public Unit invoke() {
|
||||
TemporaryBindingTrace candidateTrace = TemporaryBindingTrace.create(
|
||||
task.trace, "trace to resolve candidate");
|
||||
Collection<CallCandidateResolutionContext<D>> contexts =
|
||||
callTransformer.createCallContexts(resolutionCandidate, task, candidateTrace, candidateResolveMode);
|
||||
for (CallCandidateResolutionContext<D> context : contexts) {
|
||||
candidateResolver.performResolutionForCandidateCall(context, task.checkArguments);
|
||||
candidateResolutionContexts.add(context);
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
}
|
||||
return candidateResolutionContexts;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor, F extends D> void addResolvedCall(
|
||||
@NotNull ResolutionTask<D, F> task,
|
||||
@NotNull CallTransformer<D, F> callTransformer,
|
||||
@NotNull CallCandidateResolutionContext<D> context) {
|
||||
/* important for 'variable as function case': temporary bind reference to descriptor (will be rewritten)
|
||||
to have a binding to variable while 'invoke' call resolve */
|
||||
task.tracing.bindReference(context.candidateCall.getTrace(), context.candidateCall);
|
||||
|
||||
Collection<MutableResolvedCall<F>> resolvedCalls = callTransformer.transformCall(context, this, task);
|
||||
|
||||
for (MutableResolvedCall<F> resolvedCall : resolvedCalls) {
|
||||
BindingTrace trace = resolvedCall.getTrace();
|
||||
task.tracing.bindReference(trace, resolvedCall);
|
||||
task.tracing.bindResolvedCall(trace, resolvedCall);
|
||||
task.addResolvedCall(resolvedCall);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TaskContextForMigration<D extends CallableDescriptor, F extends D> {
|
||||
@NotNull
|
||||
final Function0<List<ResolutionTask<D, F>>> lazyTasks;
|
||||
|
||||
@NotNull
|
||||
final CallTransformer<D, F> callTransformer;
|
||||
private static class TaskContextForMigration<D extends CallableDescriptor> {
|
||||
|
||||
@Nullable
|
||||
final Name name;
|
||||
@@ -813,12 +618,9 @@ public class CallResolver {
|
||||
|
||||
private TaskContextForMigration(
|
||||
@NotNull ResolveKind kind,
|
||||
@NotNull CallTransformer<D, F> transformer,
|
||||
@Nullable Name name,
|
||||
@Nullable Collection<ResolutionCandidate<D>> candidates, @NotNull Function0<List<ResolutionTask<D, F>>> tasks
|
||||
@Nullable Collection<ResolutionCandidate<D>> candidates
|
||||
) {
|
||||
lazyTasks = tasks;
|
||||
callTransformer = transformer;
|
||||
this.name = name;
|
||||
givenCandidates = candidates;
|
||||
resolveKind = kind;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -16,88 +16,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.ChainedTemporaryBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CandidateResolveMode;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask;
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CallTransformer treats specially 'variable as function' call case, other cases keeps unchanged (base realization).
|
||||
*
|
||||
* For the call 'b.foo(1)' where foo is a variable that has method 'invoke' (for example of function type)
|
||||
* CallTransformer creates two contexts, two calls in each, and performs second ('invoke') call resolution:
|
||||
*
|
||||
* context#1. calls: 'b.foo' 'invoke(1)'
|
||||
* context#2. calls: 'foo' 'b.invoke(1)'
|
||||
*
|
||||
* If success VariableAsFunctionResolvedCall is created.
|
||||
*/
|
||||
public class CallTransformer<D extends CallableDescriptor, F extends D> {
|
||||
public class CallTransformer {
|
||||
private CallTransformer() {}
|
||||
|
||||
/**
|
||||
* Returns two contexts for 'variable as function' case (in FUNCTION_CALL_TRANSFORMER), one context otherwise
|
||||
*/
|
||||
@NotNull
|
||||
public Collection<CallCandidateResolutionContext<D>> createCallContexts(@NotNull ResolutionCandidate<D> candidate,
|
||||
@NotNull ResolutionTask<D, F> task,
|
||||
@NotNull TemporaryBindingTrace candidateTrace,
|
||||
@NotNull CandidateResolveMode candidateResolveMode
|
||||
) {
|
||||
ResolvedCallImpl<D> candidateCall = ResolvedCallImpl.create(candidate, candidateTrace, task.tracing, task.dataFlowInfoForArguments);
|
||||
return Collections.singleton(CallCandidateResolutionContext.create(candidateCall, task, candidateTrace, task.tracing, task.call,
|
||||
null, candidateResolveMode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns collection of resolved calls for 'invoke' for 'variable as function' case (in FUNCTION_CALL_TRANSFORMER),
|
||||
* the resolved call from callCandidateResolutionContext otherwise
|
||||
*/
|
||||
@NotNull
|
||||
public Collection<MutableResolvedCall<F>> transformCall(@NotNull CallCandidateResolutionContext<D> callCandidateResolutionContext,
|
||||
@NotNull CallResolver callResolver,
|
||||
@NotNull ResolutionTask<D, F> task
|
||||
) {
|
||||
return Collections.singleton((MutableResolvedCall<F>) callCandidateResolutionContext.candidateCall);
|
||||
}
|
||||
|
||||
|
||||
public static CallTransformer<CallableDescriptor, CallableDescriptor> MEMBER_CALL_TRANSFORMER = new CallTransformer<CallableDescriptor, CallableDescriptor>();
|
||||
|
||||
public static CallTransformer<VariableDescriptor, VariableDescriptor> VARIABLE_CALL_TRANSFORMER = new CallTransformer<VariableDescriptor, VariableDescriptor>();
|
||||
|
||||
public static Call stripCallArguments(@NotNull Call call) {
|
||||
return new DelegatingCall(call) {
|
||||
@Override
|
||||
@@ -155,112 +89,6 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
|
||||
};
|
||||
}
|
||||
|
||||
public static CallTransformer<CallableDescriptor, FunctionDescriptor> FUNCTION_CALL_TRANSFORMER = new CallTransformer<CallableDescriptor, FunctionDescriptor>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<CallCandidateResolutionContext<CallableDescriptor>> createCallContexts(@NotNull ResolutionCandidate<CallableDescriptor> candidate,
|
||||
@NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task, @NotNull TemporaryBindingTrace candidateTrace,
|
||||
@NotNull CandidateResolveMode candidateResolveMode
|
||||
) {
|
||||
|
||||
if (candidate.getDescriptor() instanceof FunctionDescriptor) {
|
||||
return super.createCallContexts(candidate, task, candidateTrace, candidateResolveMode);
|
||||
}
|
||||
|
||||
assert candidate.getDescriptor() instanceof VariableDescriptor;
|
||||
|
||||
boolean hasReceiver = candidate.getReceiverArgument() != null;
|
||||
Call variableCall = stripCallArguments(task.call);
|
||||
ResolutionCandidate<CallableDescriptor> variableCandidate = ResolutionCandidate.create(
|
||||
variableCall,
|
||||
candidate.getDescriptor(),
|
||||
candidate.getDispatchReceiver(),
|
||||
candidate.getReceiverArgument(),
|
||||
candidate.getExplicitReceiverKind(),
|
||||
null);
|
||||
if (!hasReceiver) {
|
||||
CallCandidateResolutionContext<CallableDescriptor> context = CallCandidateResolutionContext.create(
|
||||
ResolvedCallImpl.create(variableCandidate, candidateTrace, task.tracing, task.dataFlowInfoForArguments),
|
||||
task, candidateTrace, task.tracing, variableCall, null, candidateResolveMode);
|
||||
return Collections.singleton(context);
|
||||
}
|
||||
CallCandidateResolutionContext<CallableDescriptor> contextWithReceiver = createContextWithChainedTrace(
|
||||
variableCandidate, variableCall, candidateTrace, task, null, candidateResolveMode);
|
||||
|
||||
Call variableCallWithoutReceiver = stripReceiver(variableCall);
|
||||
ResolutionCandidate<CallableDescriptor> candidateWithoutReceiver = ResolutionCandidate.create(
|
||||
variableCallWithoutReceiver,
|
||||
candidate.getDescriptor(),
|
||||
candidate.getDispatchReceiver(),
|
||||
null,
|
||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null);
|
||||
|
||||
CallCandidateResolutionContext<CallableDescriptor> contextWithoutReceiver = createContextWithChainedTrace(
|
||||
candidateWithoutReceiver, variableCallWithoutReceiver, candidateTrace, task, variableCall.getExplicitReceiver(),
|
||||
candidateResolveMode);
|
||||
|
||||
return Lists.newArrayList(contextWithReceiver, contextWithoutReceiver);
|
||||
}
|
||||
|
||||
private CallCandidateResolutionContext<CallableDescriptor> createContextWithChainedTrace(
|
||||
@NotNull ResolutionCandidate<CallableDescriptor> candidate, @NotNull Call call, @NotNull TemporaryBindingTrace temporaryTrace,
|
||||
@NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task, @Nullable Receiver receiverValue,
|
||||
@NotNull CandidateResolveMode candidateResolveMode
|
||||
) {
|
||||
ChainedTemporaryBindingTrace chainedTrace = ChainedTemporaryBindingTrace.create(temporaryTrace, "chained trace to resolve candidate", candidate);
|
||||
ResolvedCallImpl<CallableDescriptor> resolvedCall = ResolvedCallImpl.create(candidate, chainedTrace, task.tracing, task.dataFlowInfoForArguments);
|
||||
return CallCandidateResolutionContext.create(resolvedCall, task, chainedTrace, task.tracing, call, receiverValue,
|
||||
candidateResolveMode);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<MutableResolvedCall<FunctionDescriptor>> transformCall(
|
||||
@NotNull CallCandidateResolutionContext<CallableDescriptor> context,
|
||||
@NotNull CallResolver callResolver,
|
||||
@NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task
|
||||
) {
|
||||
CallableDescriptor descriptor = context.candidateCall.getCandidateDescriptor();
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
return super.transformCall(context, callResolver, task);
|
||||
}
|
||||
|
||||
assert descriptor instanceof VariableDescriptor;
|
||||
KotlinType returnType = descriptor.getReturnType();
|
||||
if (returnType == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final MutableResolvedCall<VariableDescriptor> variableResolvedCall = (MutableResolvedCall)context.candidateCall;
|
||||
|
||||
KtExpression calleeExpression = task.call.getCalleeExpression();
|
||||
if (calleeExpression == null) return Collections.emptyList();
|
||||
|
||||
ExpressionReceiver variableReceiver = ExpressionReceiver.Companion.create(
|
||||
calleeExpression, variableResolvedCall.getResultingDescriptor().getType(), context.trace.getBindingContext());
|
||||
Call functionCall = new CallForImplicitInvoke(context.explicitExtensionReceiverForInvoke, variableReceiver, task.call);
|
||||
|
||||
DelegatingBindingTrace variableCallTrace = context.candidateCall.getTrace();
|
||||
BasicCallResolutionContext basicCallResolutionContext = BasicCallResolutionContext.create(
|
||||
context.replaceBindingTrace(variableCallTrace).replaceContextDependency(ContextDependency.DEPENDENT),
|
||||
functionCall, context.checkArguments, context.dataFlowInfoForArguments);
|
||||
|
||||
// 'invoke' call resolve
|
||||
TracingStrategyForInvoke tracingForInvoke = new TracingStrategyForInvoke(
|
||||
calleeExpression, functionCall, variableReceiver.getType());
|
||||
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallForInvoke(
|
||||
basicCallResolutionContext, tracingForInvoke);
|
||||
Collection<MutableResolvedCall<FunctionDescriptor>> calls = ((OverloadResolutionResultsImpl<FunctionDescriptor>)results).getResultingCalls();
|
||||
|
||||
return Collections2.transform(calls, new Function<MutableResolvedCall<FunctionDescriptor>, MutableResolvedCall<FunctionDescriptor>>() {
|
||||
@Override
|
||||
public MutableResolvedCall<FunctionDescriptor> apply(MutableResolvedCall<FunctionDescriptor> functionResolvedCall) {
|
||||
return new VariableAsFunctionResolvedCallImpl(functionResolvedCall, variableResolvedCall);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
public static class CallForImplicitInvoke extends DelegatingCall {
|
||||
private final Call outerCall;
|
||||
private final Receiver explicitExtensionReceiver;
|
||||
|
||||
-259
@@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.resolve.calls.tasks.collectors
|
||||
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isStaticNestedClass
|
||||
import org.jetbrains.kotlin.resolve.LibrarySourceHacks
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassValueDescriptor
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.*
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
interface CallableDescriptorCollector<D : CallableDescriptor> {
|
||||
|
||||
fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<D>
|
||||
|
||||
fun getNonExtensionsByName(scope: HierarchicalScope, name: Name, location: LookupLocation): Collection<D>
|
||||
|
||||
// todo this is hack for static members priority
|
||||
fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<D>
|
||||
|
||||
fun getMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<D>
|
||||
|
||||
fun getStaticMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<D>
|
||||
|
||||
fun getExtensionsByName(scope: HierarchicalScope, syntheticScopes: SyntheticScopes, name: Name, receiverTypes: Collection<KotlinType>, location: LookupLocation): Collection<D>
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> CallableDescriptorCollector<D>.withDefaultFilter() = filtered { !LibrarySourceHacks.shouldSkip(it) }
|
||||
|
||||
private val FUNCTIONS_COLLECTOR = FunctionCollector.withDefaultFilter()
|
||||
private val VARIABLES_COLLECTOR = VariableCollector.withDefaultFilter()
|
||||
|
||||
class CallableDescriptorCollectors<D : CallableDescriptor>(val collectors: List<CallableDescriptorCollector<D>>) :
|
||||
Iterable<CallableDescriptorCollector<D>> {
|
||||
override fun iterator(): Iterator<CallableDescriptorCollector<D>> = collectors.iterator()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
companion object {
|
||||
|
||||
@JvmField val FUNCTIONS_AND_VARIABLES: CallableDescriptorCollectors<CallableDescriptor> =
|
||||
CallableDescriptorCollectors(listOf(
|
||||
FUNCTIONS_COLLECTOR as CallableDescriptorCollector<CallableDescriptor>,
|
||||
VARIABLES_COLLECTOR as CallableDescriptorCollector<CallableDescriptor>
|
||||
))
|
||||
|
||||
@JvmField val FUNCTIONS: CallableDescriptorCollectors<CallableDescriptor> =
|
||||
CallableDescriptorCollectors(listOf(FUNCTIONS_COLLECTOR as CallableDescriptorCollector<CallableDescriptor>))
|
||||
|
||||
@JvmField val VARIABLES: CallableDescriptorCollectors<VariableDescriptor> = CallableDescriptorCollectors(listOf(VARIABLES_COLLECTOR))
|
||||
}
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor> CallableDescriptorCollectors<D>.filtered(filter: (D) -> Boolean): CallableDescriptorCollectors<D> =
|
||||
CallableDescriptorCollectors(this.collectors.map { it.filtered(filter) })
|
||||
|
||||
private object FunctionCollector : CallableDescriptorCollector<FunctionDescriptor> {
|
||||
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
return lexicalScope.collectAllFromMeAndParent {
|
||||
if (it is LexicalChainedScope && it.isStaticScope) {
|
||||
it.getContributedFunctions(name, location).filter { it.extensionReceiverParameter == null }
|
||||
}
|
||||
else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
return lexicalScope.collectAllFromMeAndParent {
|
||||
if (it is LexicalScope && it.ownerDescriptor is FunctionDescriptor) {
|
||||
it.getContributedFunctions(name, location).filter { it.extensionReceiverParameter == null } +
|
||||
getConstructors(it.getContributedClassifier(name, location))
|
||||
}
|
||||
else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNonExtensionsByName(scope: HierarchicalScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
return scope.collectFunctions(name, location).filter { it.extensionReceiverParameter == null } + getConstructors(scope, name, location)
|
||||
}
|
||||
|
||||
override fun getMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
val receiverScope = receiver.memberScope
|
||||
val members = receiverScope.getContributedFunctions(name, location)
|
||||
val constructors = getConstructors(receiverScope.memberScopeAsImportingScope(), name, location, { !isStaticNestedClass(it) })
|
||||
|
||||
if (name == OperatorNameConventions.INVOKE && KotlinBuiltIns.isExtensionFunctionType(receiver)) {
|
||||
// If we're looking for members of an extension function type, we ignore the non-extension "invoke"s
|
||||
// that originate from the Function{n} class and only consider the synthesized "invoke" extensions.
|
||||
// Otherwise confusing errors will be reported because the non-extension here beats the extension
|
||||
// (because declarations beat synthesized members)
|
||||
val (candidatesForReplacement, irrelevantInvokes) =
|
||||
members.partition { it is FunctionInvokeDescriptor && it.valueParameters.isNotEmpty() }
|
||||
return createSynthesizedInvokes(candidatesForReplacement) + candidatesForReplacement + irrelevantInvokes + constructors
|
||||
}
|
||||
|
||||
return members + constructors
|
||||
}
|
||||
|
||||
override fun getStaticMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
return getConstructors(receiver.memberScope.memberScopeAsImportingScope(), name, location, { isStaticNestedClass(it) })
|
||||
}
|
||||
|
||||
override fun getExtensionsByName(scope: HierarchicalScope, syntheticScopes: SyntheticScopes, name: Name, receiverTypes: Collection<KotlinType>, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
val functions = scope.collectFunctions(name, location)
|
||||
val (extensions, nonExtensions) = functions.partition { it.extensionReceiverParameter != null }
|
||||
val syntheticExtensions = syntheticScopes.collectSyntheticExtensionFunctions(receiverTypes, name, location)
|
||||
|
||||
if (name == OperatorNameConventions.INVOKE) {
|
||||
// Create synthesized "invoke" extensions for each non-extension "invoke" found in the scope
|
||||
return extensions + createSynthesizedInvokes(nonExtensions) + syntheticExtensions
|
||||
}
|
||||
|
||||
return extensions + syntheticExtensions
|
||||
}
|
||||
|
||||
private fun getConstructors(
|
||||
scope: HierarchicalScope,
|
||||
name: Name,
|
||||
location: LookupLocation,
|
||||
filterClassPredicate: (ClassDescriptor) -> Boolean = { true }
|
||||
): Collection<FunctionDescriptor> {
|
||||
val classifier = scope.findClassifier(name, location)
|
||||
return getConstructors(classifier, filterClassPredicate)
|
||||
}
|
||||
|
||||
private fun getConstructors(
|
||||
classifier: ClassifierDescriptor?,
|
||||
filterClassPredicate: (ClassDescriptor) -> Boolean = { true }
|
||||
): Collection<FunctionDescriptor> {
|
||||
if (classifier !is ClassDescriptor || ErrorUtils.isError(classifier) || !filterClassPredicate(classifier)
|
||||
// Constructors of singletons shouldn't be callable from the code
|
||||
|| classifier.kind.isSingleton) {
|
||||
return listOf()
|
||||
}
|
||||
return classifier.constructors
|
||||
}
|
||||
|
||||
override fun toString() = "FUNCTIONS"
|
||||
}
|
||||
|
||||
private object VariableCollector : CallableDescriptorCollector<VariableDescriptor> {
|
||||
override fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
val result = SmartList<VariableDescriptor>()
|
||||
result.addIfNotNull(lexicalScope.findLocalVariable(name))
|
||||
// Although local objects are prohibited, we'll include objects declared in current scope so that their usages are still resolved.
|
||||
result.addIfNotNull(getContributedFakeDescriptorForObject(lexicalScope, name, location))
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
return lexicalScope.collectAllFromMeAndParent {
|
||||
if (it is LexicalChainedScope && it.isStaticScope) {
|
||||
it.getContributedVariables(name, location)
|
||||
}
|
||||
else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getContributedFakeDescriptorForObject(scope: LexicalScope, name: Name, location: LookupLocation): VariableDescriptor? {
|
||||
val classifier = scope.getContributedClassifier(name, location)
|
||||
if (classifier !is ClassDescriptor || !classifier.hasClassValueDescriptor) return null
|
||||
return FakeCallableDescriptorForObject(classifier)
|
||||
}
|
||||
|
||||
private fun findFakeDescriptorForObject(scope: HierarchicalScope, name: Name, location: LookupLocation): VariableDescriptor? {
|
||||
val classifier = scope.findClassifier(name, location)
|
||||
if (classifier !is ClassDescriptor || !classifier.hasClassValueDescriptor) return null
|
||||
|
||||
return FakeCallableDescriptorForObject(classifier)
|
||||
}
|
||||
|
||||
override fun getNonExtensionsByName(scope: HierarchicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
val properties = scope.collectVariables(name, location).filter { it.extensionReceiverParameter == null }
|
||||
val fakeDescriptor = findFakeDescriptorForObject(scope, name, location)
|
||||
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
|
||||
}
|
||||
|
||||
override fun getMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
val memberScope = receiver.memberScope
|
||||
val properties = memberScope.getContributedVariables(name, location)
|
||||
val fakeDescriptor = findFakeDescriptorForObject(memberScope.memberScopeAsImportingScope(), name, location)
|
||||
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
|
||||
}
|
||||
|
||||
override fun getStaticMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
override fun getExtensionsByName(scope: HierarchicalScope, syntheticScopes: SyntheticScopes, name: Name, receiverTypes: Collection<KotlinType>, location: LookupLocation): Collection<VariableDescriptor> {
|
||||
// property may have an extension function type, we check the applicability later to avoid an early computing of deferred types
|
||||
return scope.collectVariables(name, location) +
|
||||
syntheticScopes.collectSyntheticExtensionProperties(receiverTypes, name, location)
|
||||
}
|
||||
|
||||
override fun toString() = "VARIABLES"
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> CallableDescriptorCollector<D>.filtered(filter: (D) -> Boolean): CallableDescriptorCollector<D> {
|
||||
val delegate = this
|
||||
return object : CallableDescriptorCollector<D> {
|
||||
override fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<D> {
|
||||
return delegate.getLocalNonExtensionsByName(lexicalScope, name, location).filter(filter)
|
||||
}
|
||||
|
||||
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<D> {
|
||||
return delegate.getStaticInheritanceByName(lexicalScope, name, location)
|
||||
}
|
||||
|
||||
override fun getNonExtensionsByName(scope: HierarchicalScope, name: Name, location: LookupLocation): Collection<D> {
|
||||
return delegate.getNonExtensionsByName(scope, name, location).filter(filter)
|
||||
}
|
||||
|
||||
override fun getMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<D> {
|
||||
return delegate.getMembersByName(receiver, name, location).filter(filter)
|
||||
}
|
||||
|
||||
override fun getStaticMembersByName(receiver: KotlinType, name: Name, location: LookupLocation): Collection<D> {
|
||||
return delegate.getStaticMembersByName(receiver, name, location).filter(filter)
|
||||
}
|
||||
|
||||
override fun getExtensionsByName(scope: HierarchicalScope, syntheticScopes: SyntheticScopes, name: Name, receiverTypes: Collection<KotlinType>, location: LookupLocation): Collection<D> {
|
||||
return delegate.getExtensionsByName(scope, syntheticScopes, name, receiverTypes, location).filter(filter)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return delegate.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.resolve.calls.tasks;
|
||||
|
||||
import com.intellij.util.SmartList;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.psi.Call;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.StatementFilter;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Stores candidates for call resolution.
|
||||
*/
|
||||
public class ResolutionTask<D extends CallableDescriptor, F extends D> extends CallResolutionContext<ResolutionTask<D, F>> {
|
||||
private final Function0<Collection<ResolutionCandidate<D>>> lazyCandidates;
|
||||
private final Collection<MutableResolvedCall<F>> resolvedCalls;
|
||||
public final TracingStrategy tracing;
|
||||
|
||||
private ResolutionTask(
|
||||
@NotNull Function0<Collection<ResolutionCandidate<D>>> lazyCandidates,
|
||||
@NotNull TracingStrategy tracing,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull Call call,
|
||||
@NotNull KotlinType expectedType,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull ContextDependency contextDependency,
|
||||
@NotNull CheckArgumentTypesMode checkArguments,
|
||||
@NotNull ResolutionResultsCache resolutionResultsCache,
|
||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
|
||||
@NotNull CallChecker callChecker,
|
||||
@NotNull StatementFilter statementFilter,
|
||||
@NotNull Collection<MutableResolvedCall<F>> resolvedCalls,
|
||||
boolean isAnnotationContext,
|
||||
boolean isDebuggerContext,
|
||||
boolean collectAllCandidates,
|
||||
@NotNull CallPosition callPosition
|
||||
) {
|
||||
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
|
||||
dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
|
||||
this.lazyCandidates = lazyCandidates;
|
||||
this.resolvedCalls = resolvedCalls;
|
||||
this.tracing = tracing;
|
||||
}
|
||||
|
||||
public ResolutionTask(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull TracingStrategy tracing,
|
||||
@NotNull Function0<Collection<ResolutionCandidate<D>>> lazyCandidates
|
||||
) {
|
||||
this(lazyCandidates, tracing,
|
||||
context.trace, context.scope, context.call,
|
||||
context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments,
|
||||
context.resolutionResultsCache, context.dataFlowInfoForArguments,
|
||||
context.callChecker,
|
||||
context.statementFilter, new SmartList<MutableResolvedCall<F>>(),
|
||||
context.isAnnotationContext, context.isDebuggerContext, context.collectAllCandidates, context.callPosition);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ResolutionCandidate<D>> getCandidates() {
|
||||
return lazyCandidates.invoke();
|
||||
}
|
||||
|
||||
public void addResolvedCall(@NotNull MutableResolvedCall<F> resolvedCall) {
|
||||
resolvedCalls.add(resolvedCall);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<MutableResolvedCall<F>> getResolvedCalls() {
|
||||
return resolvedCalls;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResolutionTask<D, F> create(
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull KotlinType expectedType,
|
||||
@NotNull ContextDependency contextDependency,
|
||||
@NotNull ResolutionResultsCache resolutionResultsCache,
|
||||
@NotNull StatementFilter statementFilter,
|
||||
boolean collectAllCandidates,
|
||||
@NotNull CallPosition callPosition
|
||||
) {
|
||||
return new ResolutionTask<D, F>(
|
||||
lazyCandidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
|
||||
resolutionResultsCache, dataFlowInfoForArguments,
|
||||
callChecker,
|
||||
statementFilter, resolvedCalls,
|
||||
isAnnotationContext, isDebuggerContext, collectAllCandidates, callPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return lazyCandidates.toString();
|
||||
}
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.kotlin.resolve.calls.tasks
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||
|
||||
class ResolutionTaskHolder<D : CallableDescriptor, F : D>(
|
||||
private val storageManager: StorageManager,
|
||||
private val basicCallResolutionContext: BasicCallResolutionContext,
|
||||
private val priorityProvider: ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>>,
|
||||
private val tracing: TracingStrategy
|
||||
) {
|
||||
private val candidatesList = ArrayList<() -> Collection<ResolutionCandidate<D>>>()
|
||||
private var internalTasks: List<ResolutionTask<D, F>>? = null
|
||||
|
||||
fun addCandidates(lazyCandidates: () -> Collection<ResolutionCandidate<D>>) {
|
||||
assertNotFinished()
|
||||
candidatesList.add(storageManager.createLazyValue { lazyCandidates().toReadOnlyList() })
|
||||
}
|
||||
|
||||
private fun assertNotFinished() {
|
||||
assert(internalTasks == null) { "Can't add candidates after the resulting tasks were computed." }
|
||||
}
|
||||
|
||||
fun getTasks(): List<ResolutionTask<D, F>> {
|
||||
if (internalTasks == null) {
|
||||
val tasks = ArrayList<ResolutionTask<D, F>>()
|
||||
for (priority in (0..priorityProvider.getMaxPriority()).reversed()) {
|
||||
for (candidateIndex in candidatesList.indices) {
|
||||
val lazyCandidates = {
|
||||
candidatesList[candidateIndex]().filter { priorityProvider.getPriority(it) == priority }.toReadOnlyList()
|
||||
}
|
||||
tasks.add(ResolutionTask<D, F>(basicCallResolutionContext, tracing, lazyCandidates))
|
||||
}
|
||||
}
|
||||
|
||||
internalTasks = tasks
|
||||
}
|
||||
return internalTasks!!
|
||||
}
|
||||
|
||||
interface PriorityProvider<D> {
|
||||
fun getPriority(candidate: D): Int
|
||||
|
||||
fun getMaxPriority(): Int
|
||||
}
|
||||
}
|
||||
@@ -1,538 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.kotlin.resolve.calls.tasks
|
||||
|
||||
import com.google.common.collect.Lists
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getUnaryPlusOrMinusOperatorFunctionName
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.createLookupLocation
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollector
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollectors
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.collectors.filtered
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
|
||||
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
||||
import org.jetbrains.kotlin.resolve.selectMostSpecificInEachOverridableGroup
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class TaskPrioritizer(
|
||||
private val storageManager: StorageManager,
|
||||
private val smartCastManager: SmartCastManager,
|
||||
private val dynamicCallableDescriptors: DynamicCallableDescriptors,
|
||||
private val syntheticScopes: SyntheticScopes
|
||||
) {
|
||||
|
||||
fun <D : CallableDescriptor, F : D> computePrioritizedTasks(
|
||||
context: BasicCallResolutionContext,
|
||||
name: Name,
|
||||
tracing: TracingStrategy,
|
||||
callableDescriptorCollectors: CallableDescriptorCollectors<D>
|
||||
): List<ResolutionTask<D, F>> {
|
||||
val explicitReceiver = context.call.explicitReceiver
|
||||
val result = ResolutionTaskHolder<D, F>(storageManager, context, PriorityProviderImpl<D>(context), tracing)
|
||||
val taskPrioritizerContext = TaskPrioritizerContext(name, result, context, context.scope, callableDescriptorCollectors)
|
||||
|
||||
when (explicitReceiver) {
|
||||
is QualifierReceiver -> {
|
||||
val qualifierReceiver: QualifierReceiver = explicitReceiver
|
||||
val receiverScope = LexicalScope.empty(qualifierReceiver.getNestedClassesAndPackageMembersScope().memberScopeAsImportingScope(),
|
||||
qualifierReceiver.descriptor)
|
||||
doComputeTasks(null, taskPrioritizerContext.replaceScope(receiverScope))
|
||||
computeTasksForClassObjectReceiver(qualifierReceiver, taskPrioritizerContext)
|
||||
}
|
||||
is ReceiverValue? -> {
|
||||
doComputeTasks(explicitReceiver, taskPrioritizerContext)
|
||||
|
||||
// Temporary fix for code migration (unaryPlus()/unaryMinus())
|
||||
val unaryConventionName = getUnaryPlusOrMinusOperatorFunctionName(context.call)
|
||||
if (unaryConventionName != null) {
|
||||
val deprecatedName = if (name == OperatorNameConventions.UNARY_PLUS)
|
||||
OperatorNameConventions.PLUS
|
||||
else
|
||||
OperatorNameConventions.MINUS
|
||||
|
||||
val additionalContext = TaskPrioritizerContext(deprecatedName, result, context, context.scope, callableDescriptorCollectors)
|
||||
doComputeTasks(explicitReceiver, additionalContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.getTasks()
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> computeTasksForClassObjectReceiver(
|
||||
qualifier: Qualifier,
|
||||
taskPrioritizerContext: TaskPrioritizerContext<D, F>
|
||||
) {
|
||||
if (qualifier is ClassQualifier) {
|
||||
val companionObject = qualifier.classValueReceiver ?: return
|
||||
val classifierDescriptor = qualifier.classifier
|
||||
doComputeTasks(companionObject, taskPrioritizerContext.filterCollectors {
|
||||
when {
|
||||
classifierDescriptor is ClassDescriptor && classifierDescriptor.companionObjectDescriptor != null -> {
|
||||
// nested classes and objects should not be accessible via short reference to companion object
|
||||
it !is ConstructorDescriptor && it !is FakeCallableDescriptorForObject
|
||||
}
|
||||
DescriptorUtils.isEnumEntry(classifierDescriptor) -> {
|
||||
// objects nested in enum should not be accessible via enum entries reference
|
||||
it !is FakeCallableDescriptorForObject
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> doComputeTasks(receiver: ReceiverValue?, c: TaskPrioritizerContext<D, F>) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
val receiverWithTypes = ReceiverWithTypes(receiver, c.context)
|
||||
|
||||
val resolveInvoke = c.context.call.dispatchReceiver != null
|
||||
if (resolveInvoke) {
|
||||
addCandidatesForInvoke(receiverWithTypes, c)
|
||||
return
|
||||
}
|
||||
val implicitReceivers = c.scope.getImplicitReceiversHierarchy().map { it.value }
|
||||
if (receiver != null) {
|
||||
addCandidatesForExplicitReceiver(receiverWithTypes, implicitReceivers, c, isExplicit = true)
|
||||
addMembers(receiverWithTypes, c, staticMembers = true, isExplicit = true)
|
||||
return
|
||||
}
|
||||
addCandidatesForNoReceiver(implicitReceivers, c)
|
||||
}
|
||||
|
||||
private inner class ReceiverWithTypes(
|
||||
val value: ReceiverValue?,
|
||||
private val context: ResolutionContext<*>
|
||||
) {
|
||||
val types: Collection<KotlinType> by lazy { smartCastManager.getSmartCastVariants(value!!, context) }
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addCandidatesForExplicitReceiver(
|
||||
explicitReceiver: ReceiverWithTypes,
|
||||
implicitReceivers: Collection<ReceiverValue>,
|
||||
c: TaskPrioritizerContext<D, F>,
|
||||
isExplicit: Boolean
|
||||
) {
|
||||
val explicitReceiverTypeIsDynamic = explicitReceiver.value!!.type.isDynamic()
|
||||
|
||||
fun addMembersAndExtensionsWithFilter(filter: (CallableDescriptor) -> Boolean) {
|
||||
// If the explicit receiver is erroneous, an error function is returned by getMembersByName().
|
||||
// An error function should not be sorted out by our custom filters to prevent looking for extension functions.
|
||||
if (explicitReceiver.types.any { it.isError }) return
|
||||
|
||||
addMembers(explicitReceiver, c, staticMembers = false, isExplicit = isExplicit, filter = filter)
|
||||
if (!explicitReceiverTypeIsDynamic) {
|
||||
addExtensionCandidates(explicitReceiver, implicitReceivers, c, isExplicit, filter)
|
||||
}
|
||||
}
|
||||
|
||||
// Members and extensions with 'operator' and 'infix' modifiers have higher priority
|
||||
if (isConventionCall(c.context.call)) {
|
||||
addMembersAndExtensionsWithFilter { d: CallableDescriptor -> d is FunctionDescriptor && d.isOperator }
|
||||
}
|
||||
if (isInfixCall(c.context.call)) {
|
||||
addMembersAndExtensionsWithFilter { d: CallableDescriptor -> d is FunctionDescriptor && d.isInfix }
|
||||
}
|
||||
|
||||
addMembers(explicitReceiver, c, staticMembers = false, isExplicit = isExplicit)
|
||||
|
||||
if (explicitReceiverTypeIsDynamic) {
|
||||
addCandidatesForDynamicReceiver(explicitReceiver, implicitReceivers, c, isExplicit)
|
||||
}
|
||||
else {
|
||||
addExtensionCandidates(explicitReceiver, implicitReceivers, c, isExplicit)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addExtensionCandidates(
|
||||
explicitReceiver: ReceiverWithTypes,
|
||||
implicitReceivers: Collection<ReceiverValue>,
|
||||
c: TaskPrioritizerContext<D, F>,
|
||||
isExplicit: Boolean,
|
||||
filter: ((CallableDescriptor) -> Boolean)? = null
|
||||
) {
|
||||
for (callableDescriptorCollector in c.callableDescriptorCollectors) {
|
||||
//member extensions
|
||||
for (implicitReceiver in implicitReceivers) {
|
||||
addMemberExtensionCandidates(
|
||||
implicitReceiver,
|
||||
explicitReceiver,
|
||||
callableDescriptorCollector,
|
||||
c,
|
||||
createKind(EXTENSION_RECEIVER, isExplicit)
|
||||
)
|
||||
}
|
||||
//extensions
|
||||
c.result.addCandidates {
|
||||
val extensions = callableDescriptorCollector.getExtensionsByName(
|
||||
c.scope, syntheticScopes, c.name, explicitReceiver.types, createLookupLocation(c))
|
||||
val filteredExtensions = if (filter == null) extensions else extensions.filter(filter)
|
||||
|
||||
convertWithImpliedThis(
|
||||
c.scope,
|
||||
explicitReceiver.value,
|
||||
filteredExtensions,
|
||||
createKind(EXTENSION_RECEIVER, isExplicit),
|
||||
c.context.call
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addMembers(
|
||||
explicitReceiver: ReceiverWithTypes,
|
||||
c: TaskPrioritizerContext<D, F>,
|
||||
staticMembers: Boolean,
|
||||
isExplicit: Boolean,
|
||||
filter: ((CallableDescriptor) -> Boolean)? = null
|
||||
) {
|
||||
for (callableDescriptorCollector in c.callableDescriptorCollectors) {
|
||||
c.result.addCandidates {
|
||||
val members = Lists.newArrayList<ResolutionCandidate<D>>()
|
||||
for (type in explicitReceiver.types) {
|
||||
val membersForThisVariant = if (staticMembers) {
|
||||
callableDescriptorCollector.getStaticMembersByName(type, c.name, createLookupLocation(c))
|
||||
}
|
||||
else {
|
||||
callableDescriptorCollector.getMembersByName(type, c.name, createLookupLocation(c))
|
||||
}
|
||||
val filteredMembers = if (filter == null) membersForThisVariant else membersForThisVariant.filter(filter)
|
||||
|
||||
val dispatchReceiver =
|
||||
if (explicitReceiver.value is ImplicitClassReceiver && type != explicitReceiver.value.type) {
|
||||
CastImplicitClassReceiver(explicitReceiver.value.classDescriptor, type)
|
||||
}
|
||||
else {
|
||||
explicitReceiver.value
|
||||
}
|
||||
convertWithReceivers(
|
||||
filteredMembers,
|
||||
dispatchReceiver,
|
||||
null,
|
||||
members,
|
||||
createKind(DISPATCH_RECEIVER, isExplicit),
|
||||
c.context.call
|
||||
)
|
||||
}
|
||||
|
||||
if (explicitReceiver.types.size > 1) {
|
||||
members.retainAll( members.selectMostSpecificInEachOverridableGroup { descriptor } )
|
||||
}
|
||||
|
||||
members
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addCandidatesForDynamicReceiver(
|
||||
explicitReceiver: ReceiverWithTypes,
|
||||
implicitReceivers: Collection<ReceiverValue>,
|
||||
c: TaskPrioritizerContext<D, F>,
|
||||
isExplicit: Boolean
|
||||
) {
|
||||
val onlyDynamicReceivers = c.replaceCollectors(c.callableDescriptorCollectors.onlyDynamicReceivers<D>())
|
||||
addExtensionCandidates(explicitReceiver, implicitReceivers, onlyDynamicReceivers, isExplicit)
|
||||
|
||||
c.result.addCandidates {
|
||||
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(c.context.call, c.scope.ownerDescriptor)
|
||||
|
||||
val dynamicDescriptors = c.callableDescriptorCollectors.flatMap {
|
||||
it.getNonExtensionsByName(dynamicScope.memberScopeAsImportingScope(), c.name, createLookupLocation(c))
|
||||
}
|
||||
|
||||
convertWithReceivers(dynamicDescriptors, explicitReceiver.value, null, createKind(DISPATCH_RECEIVER, isExplicit), c.context.call)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createKind(kind: ExplicitReceiverKind, isExplicit: Boolean): ExplicitReceiverKind {
|
||||
if (isExplicit) return kind
|
||||
return ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addMemberExtensionCandidates(
|
||||
dispatchReceiver: ReceiverValue,
|
||||
receiverParameter: ReceiverWithTypes,
|
||||
callableDescriptorCollector: CallableDescriptorCollector<D>,
|
||||
c: TaskPrioritizerContext<D, F>,
|
||||
receiverKind: ExplicitReceiverKind
|
||||
) {
|
||||
c.result.addCandidates {
|
||||
val memberExtensions =
|
||||
callableDescriptorCollector.getExtensionsByName(dispatchReceiver.type.memberScope.memberScopeAsImportingScope(), syntheticScopes, c.name, receiverParameter.types, createLookupLocation(c))
|
||||
convertWithReceivers(memberExtensions, dispatchReceiver, receiverParameter.value, receiverKind, c.context.call)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addCandidatesForNoReceiver(
|
||||
implicitReceivers: Collection<ReceiverValue>,
|
||||
c: TaskPrioritizerContext<D, F>
|
||||
) {
|
||||
val lookupLocation = createLookupLocation(c)
|
||||
|
||||
//locals
|
||||
c.callableDescriptorCollectors.forEach {
|
||||
c.result.addCandidates {
|
||||
convertWithImpliedThisAndNoReceiver(
|
||||
c.scope,
|
||||
it.getLocalNonExtensionsByName(c.scope, c.name, lookupLocation),
|
||||
c.context.call
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val implicitReceiversWithTypes = implicitReceivers.map { ReceiverWithTypes(it, c.context) }
|
||||
|
||||
//try all implicit receivers as explicit
|
||||
for (implicitReceiver in implicitReceiversWithTypes) {
|
||||
addCandidatesForExplicitReceiver(implicitReceiver, implicitReceivers, c, isExplicit = false)
|
||||
}
|
||||
|
||||
// static members hack
|
||||
c.callableDescriptorCollectors.forEach {
|
||||
c.result.addCandidates {
|
||||
val descriptors = it.getStaticInheritanceByName(c.scope, c.name, lookupLocation)
|
||||
convertWithImpliedThisAndNoReceiver(c.scope, descriptors, c.context.call)
|
||||
}
|
||||
}
|
||||
|
||||
//nonlocals
|
||||
c.callableDescriptorCollectors.forEach {
|
||||
c.result.addCandidates {
|
||||
val descriptors = it.getNonExtensionsByName(c.scope, c.name, lookupLocation)
|
||||
.filter { c.scope is ImportingScope || !ExpressionTypingUtils.isLocal(c.scope.ownerDescriptor, it) }
|
||||
convertWithImpliedThisAndNoReceiver(c.scope, descriptors, c.context.call)
|
||||
}
|
||||
}
|
||||
|
||||
//static (only for better error reporting)
|
||||
for (implicitReceiver in implicitReceiversWithTypes) {
|
||||
addMembers(implicitReceiver, c, staticMembers = true, isExplicit = false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createLookupLocation(c: TaskPrioritizerContext<*, *>) = c.context.call.createLookupLocation()
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addCandidatesForInvoke(explicitReceiver: ReceiverWithTypes, c: TaskPrioritizerContext<D, F>) {
|
||||
val implicitReceivers = c.scope.getImplicitReceiversHierarchy().map { it.value }
|
||||
|
||||
// For 'a.foo()' where foo has function type,
|
||||
// a is explicitReceiver, foo is variableReceiver.
|
||||
val variableReceiver = c.context.call.dispatchReceiver
|
||||
assert(variableReceiver != null) { "'Invoke' call hasn't got variable receiver" }
|
||||
|
||||
// For invocation a.foo() explicit receiver 'a'
|
||||
// can be a receiver for 'foo' variable
|
||||
// or for 'invoke' function.
|
||||
|
||||
// (1) a.foo + foo.invoke()
|
||||
if (explicitReceiver.value == null) {
|
||||
addCandidatesForExplicitReceiver(ReceiverWithTypes(variableReceiver!!, c.context), implicitReceivers, c, isExplicit = true)
|
||||
}
|
||||
|
||||
// (2) foo + a.invoke()
|
||||
|
||||
// 'invoke' is member extension to explicit receiver while variable receiver is 'this object'
|
||||
//trait A
|
||||
//trait Foo { fun A.invoke() }
|
||||
|
||||
if (explicitReceiver.value != null) {
|
||||
//a.foo()
|
||||
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver!!, explicitReceiver, c, BOTH_RECEIVERS)
|
||||
return
|
||||
}
|
||||
// with (a) { foo() }
|
||||
for (implicitReceiver in implicitReceivers) {
|
||||
addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(variableReceiver!!, ReceiverWithTypes(implicitReceiver, c.context), c, DISPATCH_RECEIVER)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, F : D> addCandidatesWhenInvokeIsMemberAndExtensionToExplicitReceiver(
|
||||
dispatchReceiver: ReceiverValue,
|
||||
receiverParameter: ReceiverWithTypes,
|
||||
c: TaskPrioritizerContext<D, F>,
|
||||
receiverKind: ExplicitReceiverKind
|
||||
) {
|
||||
for (callableDescriptorCollector in c.callableDescriptorCollectors) {
|
||||
addMemberExtensionCandidates(dispatchReceiver, receiverParameter, callableDescriptorCollector, c, receiverKind)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> convertWithReceivers(
|
||||
descriptors: Collection<D>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
extensionReceiver: ReceiverValue?,
|
||||
explicitReceiverKind: ExplicitReceiverKind,
|
||||
call: Call
|
||||
): Collection<ResolutionCandidate<D>> {
|
||||
val result = Lists.newArrayList<ResolutionCandidate<D>>()
|
||||
convertWithReceivers(descriptors, dispatchReceiver, extensionReceiver, result, explicitReceiverKind, call)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> convertWithReceivers(
|
||||
descriptors: Collection<D>,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
extensionReceiver: ReceiverValue?,
|
||||
result: MutableCollection<ResolutionCandidate<D>>,
|
||||
explicitReceiverKind: ExplicitReceiverKind,
|
||||
call: Call
|
||||
) {
|
||||
for (descriptor in descriptors) {
|
||||
val candidate = ResolutionCandidate.create<D>(call, descriptor)
|
||||
candidate.dispatchReceiver = dispatchReceiver
|
||||
candidate.setReceiverArgument(extensionReceiver)
|
||||
candidate.explicitReceiverKind = explicitReceiverKind
|
||||
result.add(candidate)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> convertWithImpliedThisAndNoReceiver(
|
||||
scope: LexicalScope,
|
||||
descriptors: Collection<D>,
|
||||
call: Call,
|
||||
knownSubstitutor: TypeSubstitutor? = null
|
||||
): Collection<ResolutionCandidate<D>> {
|
||||
return convertWithImpliedThis(scope, null, descriptors, NO_EXPLICIT_RECEIVER, call, knownSubstitutor)
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> convertWithImpliedThis(
|
||||
scope: LexicalScope,
|
||||
receiverValue: ReceiverValue?,
|
||||
descriptors: Collection<D>,
|
||||
receiverKind: ExplicitReceiverKind,
|
||||
call: Call,
|
||||
knownSubstitutor: TypeSubstitutor? = null
|
||||
): Collection<ResolutionCandidate<D>> {
|
||||
val result = Lists.newArrayList<ResolutionCandidate<D>>()
|
||||
for (descriptor in descriptors) {
|
||||
val candidate = ResolutionCandidate.create(call, descriptor, null, receiverValue, receiverKind, knownSubstitutor)
|
||||
if (setImpliedThis(scope, candidate, knownSubstitutor)) {
|
||||
result.add(candidate)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> setImpliedThis(
|
||||
scope: LexicalScope,
|
||||
candidate: ResolutionCandidate<D>,
|
||||
knownSubstitutor: TypeSubstitutor?
|
||||
): Boolean {
|
||||
val dispatchReceiver = candidate.descriptor.dispatchReceiverParameter ?: return true
|
||||
val substitutedDispatchReceiver = knownSubstitutor?.let {
|
||||
dispatchReceiver.substitute(it) ?: return false
|
||||
} ?: dispatchReceiver
|
||||
|
||||
val receivers = scope.getImplicitReceiversHierarchy()
|
||||
for (receiver in receivers) {
|
||||
if (KotlinTypeChecker.DEFAULT.isSubtypeOf(receiver.type, substitutedDispatchReceiver.type)) {
|
||||
candidate.dispatchReceiver = substitutedDispatchReceiver.value
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor, F : D> computePrioritizedTasksFromCandidates(
|
||||
context: BasicCallResolutionContext,
|
||||
candidates: Collection<ResolutionCandidate<D>>,
|
||||
tracing: TracingStrategy
|
||||
): List<ResolutionTask<D, F>> {
|
||||
val result = ResolutionTaskHolder<D, F>(storageManager, context, PriorityProviderImpl<D>(context), tracing)
|
||||
result.addCandidates {
|
||||
candidates
|
||||
}
|
||||
return result.getTasks()
|
||||
}
|
||||
|
||||
private class PriorityProviderImpl<D : CallableDescriptor>(private val context: BasicCallResolutionContext) :
|
||||
ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>> {
|
||||
|
||||
override fun getPriority(candidate: ResolutionCandidate<D>)
|
||||
= if (hasImplicitDynamicReceiver(candidate)) 0
|
||||
else (if (!isVisible(candidate) || hasLowPriority(candidate)) 0 else 2) + (if (isSynthesized(candidate)) 0 else 1)
|
||||
|
||||
override fun getMaxPriority() = 3
|
||||
|
||||
private fun isVisible(candidate: ResolutionCandidate<D>?): Boolean {
|
||||
if (candidate == null) return false
|
||||
val candidateDescriptor = candidate.descriptor
|
||||
if (ErrorUtils.isError(candidateDescriptor)) return true
|
||||
return Visibilities.isVisible(candidate.dispatchReceiver, candidateDescriptor, context.scope.ownerDescriptor)
|
||||
}
|
||||
|
||||
private fun hasLowPriority(candidate: ResolutionCandidate<D>?): Boolean {
|
||||
if (candidate == null) return false
|
||||
return candidate.descriptor.hasLowPriorityInOverloadResolution()
|
||||
}
|
||||
|
||||
private fun isSynthesized(candidate: ResolutionCandidate<D>): Boolean {
|
||||
val descriptor = candidate.descriptor
|
||||
return descriptor is CallableMemberDescriptor && isOrOverridesSynthesized(descriptor)
|
||||
}
|
||||
|
||||
fun hasImplicitDynamicReceiver(candidate: ResolutionCandidate<D>): Boolean {
|
||||
return (!candidate.explicitReceiverKind.isDispatchReceiver || candidate.call.explicitReceiver == null)
|
||||
&& candidate.descriptor.isDynamic()
|
||||
}
|
||||
}
|
||||
|
||||
private class TaskPrioritizerContext<D : CallableDescriptor, F : D>(
|
||||
val name: Name,
|
||||
val result: ResolutionTaskHolder<D, F>,
|
||||
val context: BasicCallResolutionContext,
|
||||
val scope: LexicalScope,
|
||||
val callableDescriptorCollectors: CallableDescriptorCollectors<D>
|
||||
) {
|
||||
fun replaceScope(newScope: LexicalScope): TaskPrioritizerContext<D, F> {
|
||||
return TaskPrioritizerContext(name, result, context, newScope, callableDescriptorCollectors)
|
||||
}
|
||||
|
||||
fun replaceCollectors(newCollectors: CallableDescriptorCollectors<D>): TaskPrioritizerContext<D, F> {
|
||||
return TaskPrioritizerContext(name, result, context, scope, newCollectors)
|
||||
}
|
||||
|
||||
fun filterCollectors(filter: (D) -> Boolean): TaskPrioritizerContext<D, F> {
|
||||
return TaskPrioritizerContext(name, result, context, scope, callableDescriptorCollectors.filtered(filter))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -25,12 +25,8 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollector
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollectors
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -227,14 +223,3 @@ fun DeclarationDescriptor.isDynamic(): Boolean {
|
||||
return dispatchReceiverParameter != null && dispatchReceiverParameter.type.isDynamic()
|
||||
}
|
||||
|
||||
class CollectorForDynamicReceivers<D: CallableDescriptor>(val delegate: CallableDescriptorCollector<D>) : CallableDescriptorCollector<D> by delegate {
|
||||
override fun getExtensionsByName(scope: HierarchicalScope, syntheticScopes: SyntheticScopes, name: Name, receiverTypes: Collection<KotlinType>, location: LookupLocation): Collection<D> {
|
||||
return delegate.getExtensionsByName(scope, syntheticScopes, name, receiverTypes, location).filter {
|
||||
it.extensionReceiverParameter?.type?.isDynamic() ?: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor> CallableDescriptorCollectors<D>.onlyDynamicReceivers(): CallableDescriptorCollectors<D> {
|
||||
return CallableDescriptorCollectors(this.map { CollectorForDynamicReceivers(it) })
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -22,12 +22,9 @@ import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTaskHolder
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
|
||||
@@ -189,7 +186,6 @@ class LazyOperationsLog(
|
||||
}.appendQuoted()
|
||||
}
|
||||
o is ResolutionCandidate<*> -> DescriptorRenderer.COMPACT.render(o.descriptor).appendQuoted()
|
||||
o is ResolutionTaskHolder<*, *> -> o.field<BasicCallResolutionContext>("basicCallResolutionContext").call.callElement.getDebugText().appendQuoted()
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user