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.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.context.*; 029 import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker; 030 import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments; 031 import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall; 032 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; 033 import org.jetbrains.kotlin.resolve.scopes.JetScope; 034 import org.jetbrains.kotlin.types.JetType; 035 036 import java.util.Collection; 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 Function0<Collection<ResolutionCandidate<D>>> lazyCandidates; 043 private final Collection<MutableResolvedCall<F>> resolvedCalls; 044 public final TracingStrategy tracing; 045 046 private ResolutionTask( 047 @NotNull Function0<Collection<ResolutionCandidate<D>>> lazyCandidates, 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 @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments, 058 @NotNull CallChecker callChecker, 059 @NotNull StatementFilter statementFilter, 060 @NotNull Collection<MutableResolvedCall<F>> resolvedCalls, 061 boolean isAnnotationContext, 062 boolean collectAllCandidates 063 ) { 064 super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache, 065 dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates); 066 this.lazyCandidates = lazyCandidates; 067 this.resolvedCalls = resolvedCalls; 068 this.tracing = tracing; 069 } 070 071 public ResolutionTask( 072 @NotNull BasicCallResolutionContext context, 073 @NotNull TracingStrategy tracing, 074 @NotNull Function0<Collection<ResolutionCandidate<D>>> lazyCandidates 075 ) { 076 this(lazyCandidates, tracing, 077 context.trace, context.scope, context.call, 078 context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments, 079 context.resolutionResultsCache, context.dataFlowInfoForArguments, 080 context.callChecker, context.statementFilter, Lists.<MutableResolvedCall<F>>newArrayList(), 081 context.isAnnotationContext, context.collectAllCandidates); 082 } 083 084 public ResolutionTask( 085 @NotNull final Collection<ResolutionCandidate<D>> candidates, 086 @NotNull JetReferenceExpression reference, 087 @NotNull BasicCallResolutionContext context 088 ) { 089 this(context, TracingStrategyImpl.create(reference, context.call), new Function0<Collection<ResolutionCandidate<D>>>() { 090 @Override 091 public Collection<ResolutionCandidate<D>> invoke() { 092 return candidates; 093 } 094 }); 095 } 096 097 @NotNull 098 public Collection<ResolutionCandidate<D>> getCandidates() { 099 return lazyCandidates.invoke(); 100 } 101 102 public void addResolvedCall(@NotNull MutableResolvedCall<F> resolvedCall) { 103 resolvedCalls.add(resolvedCall); 104 } 105 106 @NotNull 107 public Collection<MutableResolvedCall<F>> getResolvedCalls() { 108 return resolvedCalls; 109 } 110 111 @Override 112 protected ResolutionTask<D, F> create( 113 @NotNull BindingTrace trace, 114 @NotNull JetScope scope, 115 @NotNull DataFlowInfo dataFlowInfo, 116 @NotNull JetType expectedType, 117 @NotNull ContextDependency contextDependency, 118 @NotNull ResolutionResultsCache resolutionResultsCache, 119 @NotNull StatementFilter statementFilter, 120 boolean collectAllCandidates 121 ) { 122 return new ResolutionTask<D, F>( 123 lazyCandidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, 124 resolutionResultsCache, dataFlowInfoForArguments, callChecker, statementFilter, resolvedCalls, 125 isAnnotationContext, collectAllCandidates); 126 } 127 128 public ResolutionTask<D, F> replaceContext(@NotNull BasicCallResolutionContext newContext) { 129 return new ResolutionTask<D, F>(newContext, tracing, lazyCandidates); 130 } 131 132 public ResolutionTask<D, F> replaceCall(@NotNull Call newCall) { 133 return new ResolutionTask<D, F>( 134 lazyCandidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, 135 resolutionResultsCache, dataFlowInfoForArguments, callChecker, statementFilter, 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 lazyCandidates.toString(); 146 } 147 }