org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTaskHolder Maven / Gradle / Ivy
/*
* 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.resolve.calls.tasks;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext;
import java.util.Collection;
import java.util.List;
public class ResolutionTaskHolder {
private final BasicCallResolutionContext basicCallResolutionContext;
private final PriorityProvider> priorityProvider;
private final TracingStrategy tracing;
private final boolean isSafeCall;
private final Collection>> candidatesList = Lists.newArrayList();
private List> tasks = null;
public ResolutionTaskHolder(
@NotNull BasicCallResolutionContext basicCallResolutionContext,
@NotNull PriorityProvider> priorityProvider,
@NotNull TracingStrategy tracing
) {
this.basicCallResolutionContext = basicCallResolutionContext;
this.priorityProvider = priorityProvider;
this.tracing = tracing;
this.isSafeCall = JetPsiUtil.isSafeCall(basicCallResolutionContext.call);
}
public Collection> setIsSafeCall(@NotNull Collection> candidates) {
for (ResolutionCandidate candidate : candidates) {
candidate.setSafeCall(isSafeCall);
}
return candidates;
}
public void addCandidates(@NotNull Collection> candidates) {
assertNotFinished();
if (!candidates.isEmpty()) {
candidatesList.add(setIsSafeCall(candidates));
}
}
public void addCandidates(@NotNull List>> candidatesList) {
assertNotFinished();
for (Collection> candidates : candidatesList) {
addCandidates(candidates);
}
}
private void assertNotFinished() {
assert tasks == null : "Can't add candidates after the resulting tasks were computed.";
}
public List> getTasks() {
if (tasks == null) {
tasks = Lists.newArrayList();
for (int priority = priorityProvider.getMaxPriority(); priority >= 0; priority--) {
final int finalPriority = priority;
for (Collection> candidates : candidatesList) {
Collection> filteredCandidates = Collections2.filter(
candidates, new Predicate>() {
@Override
public boolean apply(@Nullable ResolutionCandidate input) {
return finalPriority == priorityProvider.getPriority(input);
}
}
);
if (!filteredCandidates.isEmpty()) {
tasks.add(new ResolutionTask(filteredCandidates, basicCallResolutionContext, tracing));
}
}
}
}
return tasks;
}
public interface PriorityProvider {
int getPriority(D candidate);
int getMaxPriority();
}
}