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