changed local extensions priority

local extensions aren't longer chosen before members
This commit is contained in:
Svetlana Isakova
2013-06-07 13:41:57 +04:00
parent 132d74200b
commit 3cf133bff7
20 changed files with 210 additions and 203 deletions
@@ -36,9 +36,7 @@ public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
private final PriorityProvider<ResolutionCandidate<D>> priorityProvider;
private final boolean isSafeCall;
private final Collection<Collection<ResolutionCandidate<D>>> localExtensions = Sets.newLinkedHashSet();
private final Collection<Collection<ResolutionCandidate<D>>> members = Sets.newLinkedHashSet();
private final Collection<Collection<ResolutionCandidate<D>>> nonLocalExtensions = Sets.newLinkedHashSet();
private final Collection<Collection<ResolutionCandidate<D>>> candidatesList = Lists.newArrayList();
private List<ResolutionTask<D, F>> tasks = null;
@@ -59,44 +57,19 @@ public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
return candidates;
}
public void addLocalExtensions(@NotNull Collection<ResolutionCandidate<D>> candidates) {
public void addCandidates(@NotNull Collection<ResolutionCandidate<D>> candidates) {
if (!candidates.isEmpty()) {
localExtensions.add(setIsSafeCall(candidates));
}
}
public void addMembers(@NotNull Collection<ResolutionCandidate<D>> candidates) {
if (!candidates.isEmpty()) {
members.add(setIsSafeCall(candidates));
}
}
public void addNonLocalExtensions(@NotNull Collection<ResolutionCandidate<D>> candidates) {
if (!candidates.isEmpty()) {
nonLocalExtensions.add(setIsSafeCall(candidates));
candidatesList.add(setIsSafeCall(candidates));
}
}
public List<ResolutionTask<D, F>> getTasks() {
if (tasks == null) {
tasks = Lists.newArrayList();
List<Collection<ResolutionCandidate<D>>> candidateList = Lists.newArrayList();
// If the call is of the form super.foo(), it can actually be only a member
// But if there's no appropriate member, we would like to report that super cannot be a receiver for an extension
// Thus, put members first
if (TaskPrioritizer.getReceiverSuper(basicCallResolutionContext.call.getExplicitReceiver()) != null) {
candidateList.addAll(members);
candidateList.addAll(localExtensions);
}
else {
candidateList.addAll(localExtensions);
candidateList.addAll(members);
}
candidateList.addAll(nonLocalExtensions);
for (int priority = priorityProvider.getMaxPriority(); priority >= 0; priority--) {
final int finalPriority = priority;
for (Collection<ResolutionCandidate<D>> candidates : candidateList) {
for (Collection<ResolutionCandidate<D>> candidates : candidatesList) {
Collection<ResolutionCandidate<D>> filteredCandidates = Collections2.filter(candidates, new Predicate<ResolutionCandidate<D>>() {
@Override
public boolean apply(@Nullable ResolutionCandidate<D> input) {
@@ -147,29 +147,26 @@ public class TaskPrioritizer {
if (receiver.exists()) {
List<ReceiverValue> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name));
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
//noinspection unchecked,RedundantTypeArguments
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
for (ReceiverValue variant : variantsForExplicitReceiver) {
Collection<? extends D> membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name);
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject);
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant),
Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject);
}
result.addLocalExtensions(locals);
result.addMembers(members);
result.addCandidates(members);
for (ReceiverValue implicitReceiver : implicitReceivers) {
Collection<? extends D> memberExtensions = callableDescriptorCollector.getNonMembersByName(
implicitReceiver.getType().getMemberScope(), name);
List<ReceiverValue> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
result.addNonLocalExtensions(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver, hasExplicitThisObject));
result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver,
variantsForExplicitReceiver, hasExplicitThisObject));
}
result.addNonLocalExtensions(nonlocals);
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(
scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name));
result.addCandidates(extensionFunctions);
}
else {
Collection<ResolutionCandidate<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector
@@ -180,12 +177,12 @@ public class TaskPrioritizer {
//noinspection unchecked,RedundantTypeArguments
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
result.addLocalExtensions(locals);
result.addCandidates(locals);
for (ReceiverValue implicitReceiver : implicitReceivers) {
doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector);
}
result.addNonLocalExtensions(nonlocals);
result.addCandidates(nonlocals);
}
}