/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.calls.results;
import org.jetbrains.annotations.
NotNull;
import org.jetbrains.annotations.
Nullable;
import org.jetbrains.kotlin.descriptors.
CallableDescriptor;
import org.jetbrains.kotlin.resolve.
DelegatingBindingTrace;
import org.jetbrains.kotlin.resolve.calls.model.
MutableResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.
ResolvedCall;
import java.util.
Collection;
import java.util.
Collections;
public class
OverloadResolutionResultsImpl<D extends
CallableDescriptor> implements
OverloadResolutionResults<D> {
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
success(@
NotNull MutableResolvedCall<D>
candidate) {
return new
OverloadResolutionResultsImpl<>(
Code.
SUCCESS,
Collections.
singleton(
candidate));
}
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
nameNotFound() {
OverloadResolutionResultsImpl<D>
results = new
OverloadResolutionResultsImpl<>(
Code.
NAME_NOT_FOUND,
Collections.<
MutableResolvedCall<D>>
emptyList());
results.
setAllCandidates(
Collections.
emptyList());
return
results;
}
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
singleFailedCandidate(
MutableResolvedCall<D>
candidate) {
return new
OverloadResolutionResultsImpl<>(
Code.
SINGLE_CANDIDATE_ARGUMENT_MISMATCH,
Collections.
singleton(
candidate));
}
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
manyFailedCandidates(
Collection<
MutableResolvedCall<D>>
failedCandidates) {
return new
OverloadResolutionResultsImpl<>(
Code.
MANY_FAILED_CANDIDATES,
failedCandidates);
}
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
candidatesWithWrongReceiver(
Collection<
MutableResolvedCall<D>>
failedCandidates) {
return new
OverloadResolutionResultsImpl<>(
Code.
CANDIDATES_WITH_WRONG_RECEIVER,
failedCandidates);
}
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
ambiguity(
Collection<
MutableResolvedCall<D>>
candidates) {
return new
OverloadResolutionResultsImpl<>(
Code.
AMBIGUITY,
candidates);
}
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
incompleteTypeInference(
Collection<
MutableResolvedCall<D>>
candidates) {
return new
OverloadResolutionResultsImpl<>(
Code.
INCOMPLETE_TYPE_INFERENCE,
candidates);
}
public static <D extends
CallableDescriptor>
OverloadResolutionResultsImpl<D>
incompleteTypeInference(
MutableResolvedCall<D>
candidate) {
return
incompleteTypeInference(
Collections.
singleton(
candidate));
}
private final
Collection<
MutableResolvedCall<D>>
results;
private final
Code resultCode;
private
DelegatingBindingTrace trace;
private
Collection<
ResolvedCall<D>>
allCandidates;
private
OverloadResolutionResultsImpl(@
NotNull Code resultCode, @
NotNull Collection<
MutableResolvedCall<D>>
results) {
this.
results =
results;
this.
resultCode =
resultCode;
}
@
Override
@
NotNull
public
Collection<
MutableResolvedCall<D>>
getResultingCalls() {
return
results;
}
@
Override
@
NotNull
public
MutableResolvedCall<D>
getResultingCall() {
assert
isSingleResult();
return
results.
iterator().
next();
}
@
NotNull
@
Override
public D
getResultingDescriptor() {
return
getResultingCall().
getResultingDescriptor();
}
@
Override
@
NotNull
public
Code getResultCode() {
return
resultCode;
}
@
Override
public boolean
isSuccess() {
return
resultCode.
isSuccess();
}
@
Override
public boolean
isSingleResult() {
return
results.
size() == 1 &&
getResultCode() !=
Code.
CANDIDATES_WITH_WRONG_RECEIVER;
}
@
Override
public boolean
isNothing() {
return
resultCode ==
Code.
NAME_NOT_FOUND;
}
@
Override
public boolean
isAmbiguity() {
return
resultCode ==
Code.
AMBIGUITY;
}
@
Override
public boolean
isIncomplete() {
return
resultCode ==
Code.
INCOMPLETE_TYPE_INFERENCE;
}
public
DelegatingBindingTrace getTrace() {
return
trace;
}
public
OverloadResolutionResultsImpl<D>
setTrace(
DelegatingBindingTrace trace) {
this.
trace =
trace;
return this;
}
public void
setAllCandidates(@
Nullable Collection<
ResolvedCall<D>>
allCandidates) {
this.
allCandidates =
allCandidates;
}
@
Nullable
@
Override
public
Collection<
ResolvedCall<D>>
getAllCandidates() {
return
allCandidates;
}
@
NotNull
public
OverloadResolutionResultsImpl<D>
changeStatusToSuccess() {
if (
getResultCode() ==
Code.
SUCCESS) return this;
assert
isSingleResult() &&
getResultCode() ==
Code.
INCOMPLETE_TYPE_INFERENCE :
"Only incomplete type inference status with one candidate can be changed to success: " +
getResultCode() + "\n" +
getResultingCalls();
OverloadResolutionResultsImpl<D>
newResults = new
OverloadResolutionResultsImpl<>(
Code.
SUCCESS,
getResultingCalls());
newResults.
setAllCandidates(
getAllCandidates());
return
newResults;
}
}