001 /*
002 * Copyright 2010-2015 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.kotlin.resolve.calls.tasks;
018
019 import com.google.common.collect.Lists;
020 import kotlin.jvm.functions.Function0;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.descriptors.CallableDescriptor;
024 import org.jetbrains.kotlin.psi.Call;
025 import org.jetbrains.kotlin.psi.JetReferenceExpression;
026 import org.jetbrains.kotlin.resolve.BindingTrace;
027 import org.jetbrains.kotlin.resolve.StatementFilter;
028 import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker;
029 import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
030 import org.jetbrains.kotlin.resolve.calls.context.*;
031 import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments;
032 import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
033 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
034 import org.jetbrains.kotlin.resolve.scopes.JetScope;
035 import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
036 import org.jetbrains.kotlin.types.JetType;
037
038 import java.util.Collection;
039
040 /**
041 * Stores candidates for call resolution.
042 */
043 public class ResolutionTask<D extends CallableDescriptor, F extends D> extends CallResolutionContext<ResolutionTask<D, F>> {
044 private final Function0<Collection<ResolutionCandidate<D>>> lazyCandidates;
045 private final Collection<MutableResolvedCall<F>> resolvedCalls;
046 public final TracingStrategy tracing;
047
048 private ResolutionTask(
049 @NotNull Function0<Collection<ResolutionCandidate<D>>> lazyCandidates,
050 @NotNull TracingStrategy tracing,
051 @NotNull BindingTrace trace,
052 @NotNull JetScope scope,
053 @NotNull Call call,
054 @NotNull JetType expectedType,
055 @NotNull DataFlowInfo dataFlowInfo,
056 @NotNull ContextDependency contextDependency,
057 @NotNull CheckValueArgumentsMode checkArguments,
058 @NotNull ResolutionResultsCache resolutionResultsCache,
059 @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
060 @NotNull CallChecker callChecker,
061 @NotNull SymbolUsageValidator symbolUsageValidator,
062 @NotNull AdditionalTypeChecker additionalTypeChecker,
063 @NotNull StatementFilter statementFilter,
064 @NotNull Collection<MutableResolvedCall<F>> resolvedCalls,
065 boolean isAnnotationContext,
066 boolean collectAllCandidates,
067 boolean insideSafeCallChain
068 ) {
069 super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
070 dataFlowInfoForArguments, callChecker, symbolUsageValidator, additionalTypeChecker, statementFilter, isAnnotationContext, collectAllCandidates, insideSafeCallChain);
071 this.lazyCandidates = lazyCandidates;
072 this.resolvedCalls = resolvedCalls;
073 this.tracing = tracing;
074 }
075
076 public ResolutionTask(
077 @NotNull BasicCallResolutionContext context,
078 @NotNull TracingStrategy tracing,
079 @NotNull Function0<Collection<ResolutionCandidate<D>>> lazyCandidates
080 ) {
081 this(lazyCandidates, tracing,
082 context.trace, context.scope, context.call,
083 context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments,
084 context.resolutionResultsCache, context.dataFlowInfoForArguments,
085 context.callChecker, context.symbolUsageValidator, context.additionalTypeChecker,
086 context.statementFilter, Lists.<MutableResolvedCall<F>>newArrayList(),
087 context.isAnnotationContext, context.collectAllCandidates, context.insideCallChain);
088 }
089
090 public ResolutionTask(
091 @NotNull final Collection<ResolutionCandidate<D>> candidates,
092 @NotNull JetReferenceExpression reference,
093 @NotNull BasicCallResolutionContext context
094 ) {
095 this(context, TracingStrategyImpl.create(reference, context.call), new Function0<Collection<ResolutionCandidate<D>>>() {
096 @Override
097 public Collection<ResolutionCandidate<D>> invoke() {
098 return candidates;
099 }
100 });
101 }
102
103 @NotNull
104 public Collection<ResolutionCandidate<D>> getCandidates() {
105 return lazyCandidates.invoke();
106 }
107
108 public void addResolvedCall(@NotNull MutableResolvedCall<F> resolvedCall) {
109 resolvedCalls.add(resolvedCall);
110 }
111
112 @NotNull
113 public Collection<MutableResolvedCall<F>> getResolvedCalls() {
114 return resolvedCalls;
115 }
116
117 @Override
118 protected ResolutionTask<D, F> create(
119 @NotNull BindingTrace trace,
120 @NotNull JetScope scope,
121 @NotNull DataFlowInfo dataFlowInfo,
122 @NotNull JetType expectedType,
123 @NotNull ContextDependency contextDependency,
124 @NotNull ResolutionResultsCache resolutionResultsCache,
125 @NotNull StatementFilter statementFilter,
126 boolean collectAllCandidates,
127 boolean insideSafeCallChain
128 ) {
129 return new ResolutionTask<D, F>(
130 lazyCandidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
131 resolutionResultsCache, dataFlowInfoForArguments,
132 callChecker, symbolUsageValidator, additionalTypeChecker,
133 statementFilter, resolvedCalls,
134 isAnnotationContext, collectAllCandidates, insideSafeCallChain);
135 }
136
137 public ResolutionTask<D, F> replaceContext(@NotNull BasicCallResolutionContext newContext) {
138 return new ResolutionTask<D, F>(newContext, tracing, lazyCandidates);
139 }
140
141 public ResolutionTask<D, F> replaceCall(@NotNull Call newCall) {
142 return new ResolutionTask<D, F>(
143 lazyCandidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments,
144 resolutionResultsCache, dataFlowInfoForArguments,
145 callChecker, symbolUsageValidator, additionalTypeChecker,
146 statementFilter, resolvedCalls,
147 isAnnotationContext, collectAllCandidates, insideCallChain);
148 }
149
150 public interface DescriptorCheckStrategy {
151 <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing);
152 }
153
154 @Override
155 public String toString() {
156 return lazyCandidates.toString();
157 }
158 }