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    
017    package org.jetbrains.jet.lang.resolve.calls.tasks;
018    
019    import com.google.common.collect.Sets;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
022    import org.jetbrains.jet.lang.psi.Call;
023    import org.jetbrains.jet.lang.psi.JetReferenceExpression;
024    import org.jetbrains.jet.lang.resolve.BindingTrace;
025    import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
026    import org.jetbrains.jet.lang.resolve.calls.context.*;
027    import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
028    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
029    import org.jetbrains.jet.lang.types.JetType;
030    
031    import java.util.Collection;
032    import java.util.Set;
033    
034    /**
035     * Stores candidates for call resolution.
036     */
037    public 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    }