001/*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.jetbrains.jet.lang.resolve.calls.tasks;
018
019import com.google.common.collect.Sets;
020import org.jetbrains.annotations.NotNull;
021import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
022import org.jetbrains.jet.lang.psi.Call;
023import org.jetbrains.jet.lang.psi.JetReferenceExpression;
024import org.jetbrains.jet.lang.resolve.BindingTrace;
025import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
026import org.jetbrains.jet.lang.resolve.calls.context.*;
027import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
028import org.jetbrains.jet.lang.resolve.scopes.JetScope;
029import org.jetbrains.jet.lang.types.JetType;
030
031import java.util.Collection;
032import java.util.Set;
033
034/**
035 * Stores candidates for call resolution.
036 */
037public class ResolutionTask<D extends CallableDescriptor, F extends D> extends CallResolutionContext<ResolutionTask<D, F>> {
038    private final Collection<ResolutionCandidate<D>> candidates;
039    private final Set<ResolvedCallWithTrace<F>> resolvedCalls = Sets.newLinkedHashSet();
040    private DescriptorCheckStrategy checkingStrategy;
041    public final JetReferenceExpression reference;
042    public final TracingStrategy tracing;
043
044    public ResolutionTask(
045            @NotNull Collection<ResolutionCandidate<D>> candidates, @NotNull JetReferenceExpression reference,
046            @NotNull TracingStrategy tracing, BindingTrace trace, JetScope scope, Call call, JetType expectedType,
047            DataFlowInfo dataFlowInfo, ResolveMode resolveMode, CheckValueArgumentsMode checkArguments,
048            ExpressionPosition expressionPosition, ResolutionResultsCache resolutionResultsCache
049    ) {
050        super(trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments, expressionPosition, resolutionResultsCache);
051        this.candidates = candidates;
052        this.reference = reference;
053        this.tracing = tracing;
054    }
055
056    public ResolutionTask(@NotNull Collection<ResolutionCandidate<D>> candidates, @NotNull JetReferenceExpression reference, @NotNull BasicCallResolutionContext context) {
057        this(candidates, reference, TracingStrategyImpl.create(reference, context.call), context.trace, context.scope, context.call,
058             context.expectedType, context.dataFlowInfo, context.resolveMode, context.checkArguments,
059             context.expressionPosition, context.resolutionResultsCache);
060    }
061
062    @NotNull
063    public Collection<ResolutionCandidate<D>> getCandidates() {
064        return candidates;
065    }
066
067    @NotNull
068    public Set<ResolvedCallWithTrace<F>> getResolvedCalls() {
069        return resolvedCalls;
070    }
071
072    public void setCheckingStrategy(DescriptorCheckStrategy strategy) {
073        checkingStrategy = strategy;
074    }
075
076    public boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
077        if (checkingStrategy != null && !checkingStrategy.performAdvancedChecks(descriptor, trace, tracing)) {
078            return false;
079        }
080        return true;
081    }
082
083    @Override
084    protected ResolutionTask<D, F> create(
085            @NotNull BindingTrace trace,
086            @NotNull JetScope scope,
087            @NotNull DataFlowInfo dataFlowInfo,
088            @NotNull JetType expectedType,
089            @NotNull ExpressionPosition expressionPosition
090    ) {
091        ResolutionTask<D, F> newTask = new ResolutionTask<D, F>(
092                candidates, reference, tracing, trace, scope, call, expectedType, dataFlowInfo, resolveMode, checkArguments,
093                expressionPosition, resolutionResultsCache);
094        newTask.setCheckingStrategy(checkingStrategy);
095        return newTask;
096    }
097
098    @Override
099    protected ResolutionTask<D, F> self() {
100        return this;
101    }
102
103    public ResolutionTask<D, F> replaceCall(@NotNull Call newCall) {
104        return new ResolutionTask<D, F>(
105                candidates, reference, tracing, trace, scope, newCall, expectedType, dataFlowInfo, resolveMode, checkArguments,
106                expressionPosition, resolutionResultsCache);
107    }
108
109    public interface DescriptorCheckStrategy {
110        <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing);
111    }
112
113    @Override
114    public String toString() {
115        return candidates.toString();
116    }
117}