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.Lists;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
023    import org.jetbrains.jet.lang.psi.Call;
024    import org.jetbrains.jet.lang.psi.JetReferenceExpression;
025    import org.jetbrains.jet.lang.resolve.BindingTrace;
026    import org.jetbrains.jet.lang.resolve.calls.CallResolverExtension;
027    import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
028    import org.jetbrains.jet.lang.resolve.calls.context.*;
029    import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments;
030    import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall;
031    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
032    import org.jetbrains.jet.lang.types.JetType;
033    import org.jetbrains.jet.lang.types.expressions.LabelResolver;
034    
035    import java.util.Collection;
036    
037    /**
038     * Stores candidates for call resolution.
039     */
040    public class ResolutionTask<D extends CallableDescriptor, F extends D> extends CallResolutionContext<ResolutionTask<D, F>> {
041        private final Collection<ResolutionCandidate<D>> candidates;
042        private final Collection<MutableResolvedCall<F>> resolvedCalls;
043        private DescriptorCheckStrategy checkingStrategy;
044        public final TracingStrategy tracing;
045    
046        private ResolutionTask(
047                @NotNull Collection<ResolutionCandidate<D>> candidates,
048                @NotNull TracingStrategy tracing,
049                @NotNull BindingTrace trace,
050                @NotNull JetScope scope,
051                @NotNull Call call,
052                @NotNull JetType expectedType,
053                @NotNull DataFlowInfo dataFlowInfo,
054                @NotNull ContextDependency contextDependency,
055                @NotNull CheckValueArgumentsMode checkArguments,
056                @NotNull ResolutionResultsCache resolutionResultsCache,
057                @NotNull LabelResolver labelResolver,
058                @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
059                @NotNull CallResolverExtension callResolverExtension,
060                @NotNull Collection<MutableResolvedCall<F>> resolvedCalls,
061                boolean isAnnotationContext,
062                boolean collectAllCandidates
063        ) {
064            super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
065                  labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext, collectAllCandidates);
066            this.candidates = candidates;
067            this.resolvedCalls = resolvedCalls;
068            this.tracing = tracing;
069        }
070    
071        public ResolutionTask(
072                @NotNull Collection<ResolutionCandidate<D>> candidates,
073                @NotNull BasicCallResolutionContext context,
074                @NotNull TracingStrategy tracing
075        ) {
076            this(candidates, tracing,
077                 context.trace, context.scope, context.call,
078                 context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments,
079                 context.resolutionResultsCache, context.labelResolver, context.dataFlowInfoForArguments,
080                 context.callResolverExtension, Lists.<MutableResolvedCall<F>>newArrayList(), context.isAnnotationContext, context.collectAllCandidates);
081        }
082    
083        public ResolutionTask(
084                @NotNull Collection<ResolutionCandidate<D>> candidates,
085                @NotNull JetReferenceExpression reference,
086                @NotNull BasicCallResolutionContext context
087        ) {
088            this(candidates, context, TracingStrategyImpl.create(reference, context.call));
089        }
090    
091        @NotNull
092        public Collection<ResolutionCandidate<D>> getCandidates() {
093            return candidates;
094        }
095    
096        public void addResolvedCall(@NotNull MutableResolvedCall<F> resolvedCall) {
097            resolvedCalls.add(resolvedCall);
098        }
099    
100        @NotNull
101        public Collection<MutableResolvedCall<F>> getResolvedCalls() {
102            return resolvedCalls;
103        }
104    
105        public void setCheckingStrategy(DescriptorCheckStrategy strategy) {
106            checkingStrategy = strategy;
107        }
108    
109        public boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
110            if (checkingStrategy != null && !checkingStrategy.performAdvancedChecks(descriptor, trace, tracing)) {
111                return false;
112            }
113            return true;
114        }
115    
116        @Override
117        protected ResolutionTask<D, F> create(
118                @NotNull BindingTrace trace,
119                @NotNull JetScope scope,
120                @NotNull DataFlowInfo dataFlowInfo,
121                @NotNull JetType expectedType,
122                @NotNull ContextDependency contextDependency,
123                @NotNull ResolutionResultsCache resolutionResultsCache,
124                @NotNull LabelResolver labelResolver,
125                boolean collectAllCandidates
126        ) {
127            ResolutionTask<D, F> newTask = new ResolutionTask<D, F>(
128                    candidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
129                    resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, resolvedCalls, isAnnotationContext,
130                    collectAllCandidates);
131            newTask.setCheckingStrategy(checkingStrategy);
132            return newTask;
133        }
134    
135        public ResolutionTask<D, F> replaceCall(@NotNull Call newCall) {
136            return new ResolutionTask<D, F>(
137                    candidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments,
138                    resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, resolvedCalls,
139                    isAnnotationContext, collectAllCandidates);
140        }
141    
142        public interface DescriptorCheckStrategy {
143            <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing);
144        }
145    
146        @Override
147        public String toString() {
148            return candidates.toString();
149        }
150    }