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    }