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