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.results;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.kotlin.descriptors.CallableDescriptor;
022 import org.jetbrains.kotlin.resolve.DelegatingBindingTrace;
023 import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall;
024 import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
025
026 import java.util.Collection;
027 import java.util.Collections;
028
029 public class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
030
031 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull MutableResolvedCall<D> candidate) {
032 return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(candidate));
033 }
034
035 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> nameNotFound() {
036 OverloadResolutionResultsImpl<D> results = new OverloadResolutionResultsImpl<D>(
037 Code.NAME_NOT_FOUND, Collections.<MutableResolvedCall<D>>emptyList());
038 results.setAllCandidates(Collections.<ResolvedCall<D>>emptyList());
039 return results;
040 }
041
042 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> singleFailedCandidate(MutableResolvedCall<D> candidate) {
043 return new OverloadResolutionResultsImpl<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
044 }
045 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> manyFailedCandidates(Collection<MutableResolvedCall<D>> failedCandidates) {
046 return new OverloadResolutionResultsImpl<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
047 }
048
049 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> candidatesWithWrongReceiver(Collection<MutableResolvedCall<D>> failedCandidates) {
050 return new OverloadResolutionResultsImpl<D>(Code.CANDIDATES_WITH_WRONG_RECEIVER, failedCandidates);
051 }
052
053 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<MutableResolvedCall<D>> candidates) {
054 return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, candidates);
055 }
056
057 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(Collection<MutableResolvedCall<D>> candidates) {
058 return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, candidates);
059 }
060
061 public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(MutableResolvedCall<D> candidate) {
062 return incompleteTypeInference(Collections.singleton(candidate));
063 }
064
065 private final Collection<MutableResolvedCall<D>> results;
066 private final Code resultCode;
067 private DelegatingBindingTrace trace;
068 private Collection<ResolvedCall<D>> allCandidates;
069
070 private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection<MutableResolvedCall<D>> results) {
071 this.results = results;
072 this.resultCode = resultCode;
073 }
074
075 @Override
076 @NotNull
077 public Collection<MutableResolvedCall<D>> getResultingCalls() {
078 return results;
079 }
080
081 @Override
082 @NotNull
083 public MutableResolvedCall<D> getResultingCall() {
084 assert isSingleResult();
085 return results.iterator().next();
086 }
087
088 @NotNull
089 @Override
090 public D getResultingDescriptor() {
091 return getResultingCall().getResultingDescriptor();
092 }
093
094 @Override
095 @NotNull
096 public Code getResultCode() {
097 return resultCode;
098 }
099
100 @Override
101 public boolean isSuccess() {
102 return resultCode.isSuccess();
103 }
104
105 @Override
106 public boolean isSingleResult() {
107 return results.size() == 1 && getResultCode() != Code.CANDIDATES_WITH_WRONG_RECEIVER;
108 }
109
110 @Override
111 public boolean isNothing() {
112 return resultCode == Code.NAME_NOT_FOUND;
113 }
114
115 @Override
116 public boolean isAmbiguity() {
117 return resultCode == Code.AMBIGUITY;
118 }
119
120 @Override
121 public boolean isIncomplete() {
122 return resultCode == Code.INCOMPLETE_TYPE_INFERENCE;
123 }
124
125 public DelegatingBindingTrace getTrace() {
126 return trace;
127 }
128
129 public OverloadResolutionResultsImpl<D> setTrace(DelegatingBindingTrace trace) {
130 this.trace = trace;
131 return this;
132 }
133
134 public void setAllCandidates(@Nullable Collection<ResolvedCall<D>> allCandidates) {
135 this.allCandidates = allCandidates;
136 }
137
138 @Nullable
139 @Override
140 public Collection<ResolvedCall<D>> getAllCandidates() {
141 return allCandidates;
142 }
143
144 @NotNull
145 public OverloadResolutionResultsImpl<D> changeStatusToSuccess() {
146 if (getResultCode() == Code.SUCCESS) return this;
147
148 assert isSingleResult() && getResultCode() == Code.INCOMPLETE_TYPE_INFERENCE :
149 "Only incomplete type inference status with one candidate can be changed to success: " +
150 getResultCode() + "\n" + getResultingCalls();
151 OverloadResolutionResultsImpl<D> newResults = new OverloadResolutionResultsImpl<D>(Code.SUCCESS, getResultingCalls());
152 newResults.setAllCandidates(getAllCandidates());
153 return newResults;
154 }
155 }