OverloadResolutionResult is returned from CallResolver instead of descriptors. This makes more information availbale to the caller (useful for better diagnostics).

This commit is contained in:
Andrey Breslav
2011-12-14 16:51:25 +04:00
parent 4357309efe
commit 5f2afb38a8
13 changed files with 132 additions and 123 deletions
@@ -1,8 +1,8 @@
package org.jetbrains.jet.lang.diagnostics; package org.jetbrains.jet.lang.diagnostics;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.Collection; import java.util.Collection;
@@ -10,7 +10,7 @@ import java.util.Collection;
/** /**
* @author abreslav * @author abreslav
*/ */
public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1<Collection<? extends ResolvedCallImpl<? extends DeclarationDescriptor>>> { public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosticFactory1<Collection<? extends ResolvedCall<? extends CallableDescriptor>>> {
public static AmbiguousDescriptorDiagnosticFactory create(String messageTemplate) { public static AmbiguousDescriptorDiagnosticFactory create(String messageTemplate) {
return new AmbiguousDescriptorDiagnosticFactory(messageTemplate); return new AmbiguousDescriptorDiagnosticFactory(messageTemplate);
} }
@@ -20,9 +20,9 @@ public class AmbiguousDescriptorDiagnosticFactory extends ParameterizedDiagnosti
} }
@Override @Override
protected String makeMessageFor(@NotNull Collection<? extends ResolvedCallImpl<? extends DeclarationDescriptor>> argument) { protected String makeMessageFor(@NotNull Collection<? extends ResolvedCall<? extends CallableDescriptor>> argument) {
StringBuilder stringBuilder = new StringBuilder("\n"); StringBuilder stringBuilder = new StringBuilder("\n");
for (ResolvedCallImpl<? extends DeclarationDescriptor> call : argument) { for (ResolvedCall<? extends CallableDescriptor> call : argument) {
stringBuilder.append(DescriptorRenderer.TEXT.render(call.getResultingDescriptor())).append("\n"); stringBuilder.append(DescriptorRenderer.TEXT.render(call.getResultingDescriptor())).append("\n");
} }
return stringBuilder.toString(); return stringBuilder.toString();
@@ -4,12 +4,14 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetAnnotationEntry; import org.jetbrains.jet.lang.psi.JetAnnotationEntry;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetModifierList; import org.jetbrains.jet.lang.psi.JetModifierList;
import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -52,8 +54,13 @@ public class AnnotationResolver {
} }
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) { public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) {
JetType jetType = callResolver.resolveCall(trace, scope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement), NO_EXPECTED_TYPE); OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCall(trace, scope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement), NO_EXPECTED_TYPE);
descriptor.setAnnotationType(jetType == null ? ErrorUtils.createErrorType("Unresolved annotation type") : jetType); if (results.isSuccess()) {
descriptor.setAnnotationType(results.getResultingDescriptor().getReturnType());
}
else {
descriptor.setAnnotationType(ErrorUtils.createErrorType("Unresolved annotation type"));
}
} }
@NotNull @NotNull
@@ -3,7 +3,6 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.Queue; import com.intellij.util.containers.Queue;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -11,6 +10,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
@@ -122,10 +122,11 @@ public class BodyResolver {
JetTypeReference typeReference = call.getTypeReference(); JetTypeReference typeReference = call.getTypeReference();
if (typeReference != null) { if (typeReference != null) {
if (descriptor.getUnsubstitutedPrimaryConstructor() != null) { if (descriptor.getUnsubstitutedPrimaryConstructor() != null) {
JetType supertype = new CallResolver(context.getSemanticServices(), DataFlowInfo.EMPTY).resolveCall( OverloadResolutionResults<FunctionDescriptor> results = new CallResolver(context.getSemanticServices(), DataFlowInfo.EMPTY).resolveCall(
context.getTrace(), scopeForConstructor, context.getTrace(), scopeForConstructor,
CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE); CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE);
if (supertype != null) { if (results.isSuccess()) {
JetType supertype = results.getResultingDescriptor().getReturnType();
recordSupertype(typeReference, supertype); recordSupertype(typeReference, supertype);
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype); ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) { if (classDescriptor != null) {
@@ -6,7 +6,6 @@ import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
@@ -29,9 +28,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.*; import static org.jetbrains.jet.lang.resolve.calls.ResolutionStatus.*;
import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_CANDIDATE; import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_CANDIDATE;
import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_RESULT; import static org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl.MAP_TO_RESULT;
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.EXPECTED_TYPE; import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.*;
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER;
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.VALUE_ARGUMENT;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
@@ -51,8 +48,8 @@ public class CallResolver {
this.dataFlowInfo = dataFlowInfo; this.dataFlowInfo = dataFlowInfo;
} }
@Nullable @NotNull
public VariableDescriptor resolveSimpleProperty( public OverloadResolutionResults<VariableDescriptor> resolveSimpleProperty(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull Call call, @NotNull Call call,
@@ -76,19 +73,18 @@ public class CallResolver {
return resolveCallToDescriptor(trace, scope, call, expectedType, prioritizedTasks, nameExpression); return resolveCallToDescriptor(trace, scope, call, expectedType, prioritizedTasks, nameExpression);
} }
@Nullable @NotNull
public JetType resolveCall( public OverloadResolutionResults<FunctionDescriptor> resolveCall(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull Call call, @NotNull Call call,
@NotNull JetType expectedType @NotNull JetType expectedType
) { ) {
FunctionDescriptor functionDescriptor = resolveSimpleCallToFunctionDescriptor(trace, scope, call, expectedType); return resolveSimpleCallToFunctionDescriptor(trace, scope, call, expectedType);
return functionDescriptor == null ? null : functionDescriptor.getReturnType();
} }
@Nullable @NotNull
public ResolvedCall<FunctionDescriptor> resolveCallWithGivenName( public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull final Call call, @NotNull final Call call,
@@ -100,8 +96,8 @@ public class CallResolver {
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference); return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
} }
@Nullable @NotNull
private FunctionDescriptor resolveSimpleCallToFunctionDescriptor( private OverloadResolutionResults<FunctionDescriptor> resolveSimpleCallToFunctionDescriptor(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull final Call call, @NotNull final Call call,
@@ -189,11 +185,11 @@ public class CallResolver {
JetType calleeType = typingServices.safeGetType(scope, calleeExpression, NO_EXPECTED_TYPE); // We are actually expecting a function, but there seems to be no easy way of expressing this JetType calleeType = typingServices.safeGetType(scope, calleeExpression, NO_EXPECTED_TYPE); // We are actually expecting a function, but there seems to be no easy way of expressing this
if (!JetStandardClasses.isFunctionType(calleeType)) { if (!JetStandardClasses.isFunctionType(calleeType)) {
checkTypesWithNoCallee(trace, scope, call); // checkTypesWithNoCallee(trace, scope, call);
if (!ErrorUtils.isErrorType(calleeType)) { if (!ErrorUtils.isErrorType(calleeType)) {
trace.report(CALLEE_NOT_A_FUNCTION.on(calleeExpression, calleeType)); trace.report(CALLEE_NOT_A_FUNCTION.on(calleeExpression, calleeType));
} }
return null; return checkArgumentTypesAndFail(trace, scope, call);
} }
FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(scope.getContainingDeclaration(), "[for expression " + calleeExpression.getText() + "]"); FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(scope.getContainingDeclaration(), "[for expression " + calleeExpression.getText() + "]");
@@ -209,33 +205,32 @@ public class CallResolver {
functionReference = new JetFakeReference(calleeExpression); functionReference = new JetFakeReference(calleeExpression);
} }
else { else {
checkTypesWithNoCallee(trace, scope, call); // checkTypesWithNoCallee(trace, scope, call);
return null; return checkArgumentTypesAndFail(trace, scope, call);
} }
} }
return resolveCallToDescriptor(trace, scope, call, expectedType, prioritizedTasks, functionReference); return resolveCallToDescriptor(trace, scope, call, expectedType, prioritizedTasks, functionReference);
} }
private FunctionDescriptor checkArgumentTypesAndFail(BindingTrace trace, JetScope scope, Call call) { private <D extends CallableDescriptor> OverloadResolutionResults<D> checkArgumentTypesAndFail(BindingTrace trace, JetScope scope, Call call) {
checkTypesWithNoCallee(trace, scope, call); checkTypesWithNoCallee(trace, scope, call);
return null; return OverloadResolutionResultsImpl.nameNotFound();
} }
@Nullable @NotNull
private <D extends CallableDescriptor> D resolveCallToDescriptor( private <D extends CallableDescriptor> OverloadResolutionResults<D> resolveCallToDescriptor(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull final Call call, @NotNull final Call call,
@NotNull JetType expectedType, @NotNull JetType expectedType,
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority @NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
@NotNull final JetReferenceExpression reference) { @NotNull final JetReferenceExpression reference) {
ResolvedCallImpl<D> resolvedCall = doResolveCall(trace, scope, call, expectedType, prioritizedTasks, reference); return doResolveCall(trace, scope, call, expectedType, prioritizedTasks, reference);
return resolvedCall == null ? null : resolvedCall.getResultingDescriptor();
} }
@Nullable @NotNull
private <D extends CallableDescriptor> ResolvedCallImpl<D> doResolveCall( private <D extends CallableDescriptor> OverloadResolutionResults<D> doResolveCall(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull final Call call, @NotNull final Call call,
@@ -379,9 +374,9 @@ public class CallResolver {
if (results.isSuccess()) { if (results.isSuccess()) {
temporaryTrace.commit(); temporaryTrace.commit();
debugInfo.set(ResolutionDebugInfo.RESULT, results.getResult()); debugInfo.set(ResolutionDebugInfo.RESULT, results.getResultingCall());
return results.getResult(); return results;
} }
if (traceForFirstNonemptyCandidateSet == null && !task.getCandidates().isEmpty()) { if (traceForFirstNonemptyCandidateSet == null && !task.getCandidates().isEmpty()) {
traceForFirstNonemptyCandidateSet = temporaryTrace; traceForFirstNonemptyCandidateSet = temporaryTrace;
@@ -390,18 +385,16 @@ public class CallResolver {
} }
if (traceForFirstNonemptyCandidateSet != null) { if (traceForFirstNonemptyCandidateSet != null) {
traceForFirstNonemptyCandidateSet.commit(); traceForFirstNonemptyCandidateSet.commit();
if (resultsForFirstNonemptyCandidateSet.singleDescriptor()) { if (resultsForFirstNonemptyCandidateSet.singleResult()) {
debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResult()); debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResultingCall());
return resultsForFirstNonemptyCandidateSet.getResult();
} }
} }
else { else {
trace.report(UNRESOLVED_REFERENCE.on(reference)); trace.report(UNRESOLVED_REFERENCE.on(reference));
checkTypesWithNoCallee(trace, scope, call); checkTypesWithNoCallee(trace, scope, call);
} }
return null; return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<D>nameNotFound();
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -594,7 +587,7 @@ public class CallResolver {
} }
OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates); OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates);
if (!results.singleDescriptor()) { if (!results.singleResult()) {
checkTypesWithNoCallee(trace, scope, task.getCall()); checkTypesWithNoCallee(trace, scope, task.getCall());
} }
return results; return results;
@@ -752,10 +745,10 @@ public class CallResolver {
if (results.isAmbiguity()) { if (results.isAmbiguity()) {
// This check is needed for the following case: // This check is needed for the following case:
// x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here // x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here
if (allClean(results.getResults())) { if (allClean(results.getResultingCalls())) {
tracing.ambiguity(trace, results.getResults()); tracing.ambiguity(trace, results.getResultingCalls());
} }
tracing.recordAmbiguity(trace, results.getResults()); tracing.recordAmbiguity(trace, results.getResultingCalls());
} }
return results; return results;
} }
@@ -774,13 +767,13 @@ public class CallResolver {
if (!thisLevel.isEmpty()) { if (!thisLevel.isEmpty()) {
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false); OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
if (results.isSuccess()) { if (results.isSuccess()) {
results.getResult().getTrace().commit(); results.getResultingCall().getTrace().commit();
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResult()); return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
} }
tracing.noneApplicable(trace, results.getResults()); tracing.noneApplicable(trace, results.getResultingCalls());
tracing.recordAmbiguity(trace, results.getResults()); tracing.recordAmbiguity(trace, results.getResultingCalls());
return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResults()); return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls());
} }
} }
assert false : "Should not be reachable, cause every status must belong to some level"; assert false : "Should not be reachable, cause every status must belong to some level";
@@ -848,7 +841,7 @@ public class CallResolver {
} }
} }
public void checkGenericBoundsInAFunctionCall(List<JetTypeProjection> jetTypeArguments, List<JetType> typeArguments, CallableDescriptor functionDescriptor, BindingTrace trace) { private void checkGenericBoundsInAFunctionCall(List<JetTypeProjection> jetTypeArguments, List<JetType> typeArguments, CallableDescriptor functionDescriptor, BindingTrace trace) {
Map<TypeConstructor, TypeProjection> context = Maps.newHashMap(); Map<TypeConstructor, TypeProjection> context = Maps.newHashMap();
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters(); List<TypeParameterDescriptor> typeParameters = functionDescriptor.getOriginal().getTypeParameters();
@@ -868,7 +861,7 @@ public class CallResolver {
} }
@NotNull @NotNull
public OverloadResolutionResultsImpl<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) { public OverloadResolutionResults<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
List<ResolvedCallImpl<FunctionDescriptor>> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes); List<ResolvedCallImpl<FunctionDescriptor>> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
BindingTraceContext trace = new BindingTraceContext(); BindingTraceContext trace = new BindingTraceContext();
@@ -28,17 +28,20 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
} }
@NotNull @NotNull
Collection<? extends ResolvedCall<? extends D>> getResults(); Collection<? extends ResolvedCall<? extends D>> getResultingCalls();
@NotNull @NotNull
ResolvedCall<? extends D> getResult(); ResolvedCall<D> getResultingCall();
@NotNull
D getResultingDescriptor();
@NotNull @NotNull
Code getResultCode(); Code getResultCode();
boolean isSuccess(); boolean isSuccess();
boolean singleDescriptor(); boolean singleResult();
boolean isNothing(); boolean isNothing();
@@ -9,7 +9,7 @@ import java.util.Collections;
/** /**
* @author abreslav * @author abreslav
*/ */
public class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> { /*package*/ class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallImpl<D> descriptor) { public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallImpl<D> descriptor) {
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(descriptor)); return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(descriptor));
@@ -40,17 +40,23 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
@Override @Override
@NotNull @NotNull
public Collection<ResolvedCallImpl<D>> getResults() { public Collection<ResolvedCallImpl<D>> getResultingCalls() {
return results; return results;
} }
@Override @Override
@NotNull @NotNull
public ResolvedCallImpl<D> getResult() { public ResolvedCallImpl<D> getResultingCall() {
assert singleDescriptor(); assert singleResult();
return results.iterator().next(); return results.iterator().next();
} }
@NotNull
@Override
public D getResultingDescriptor() {
return getResultingCall().getResultingDescriptor();
}
@Override @Override
@NotNull @NotNull
public Code getResultCode() { public Code getResultCode() {
@@ -63,7 +69,7 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
} }
@Override @Override
public boolean singleDescriptor() { public boolean singleResult() {
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH; return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
} }
@@ -13,10 +13,10 @@ import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
@@ -30,7 +30,8 @@ import org.jetbrains.jet.lexer.JetTokens;
import java.util.*; import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_GET;
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*; import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*;
@@ -584,10 +585,10 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression; JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression;
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace);
VariableDescriptor variableDescriptor = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression); OverloadResolutionResults<VariableDescriptor> variableDescriptor = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression);
if (variableDescriptor != null) { if (variableDescriptor.isSuccess()) {
temporaryTrace.commit(); temporaryTrace.commit();
return variableDescriptor.getOutType(); return variableDescriptor.getResultingDescriptor().getOutType();
} }
ExpressionTypingContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context; ExpressionTypingContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context;
JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext); JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext);
@@ -645,13 +646,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionReceiver receiver = getExpressionReceiver(facade, baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope)); ExpressionReceiver receiver = getExpressionReceiver(facade, baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope));
if (receiver == null) return null; if (receiver == null) return null;
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor( OverloadResolutionResults<FunctionDescriptor> functionDescriptor = context.resolveCallWithGivenNameToDescriptor(
CallMaker.makeCall(receiver, expression), CallMaker.makeCall(receiver, expression),
expression.getOperationReference(), expression.getOperationReference(),
name); name);
if (functionDescriptor == null) return null; if (!functionDescriptor.isSuccess()) return null;
JetType returnType = functionDescriptor.getReturnType(); JetType returnType = functionDescriptor.getResultingDescriptor().getReturnType();
JetType result; JetType result;
if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) {
if (context.semanticServices.getTypeChecker().isSubtypeOf(returnType, JetStandardClasses.getUnitType())) { if (context.semanticServices.getTypeChecker().isSubtypeOf(returnType, JetStandardClasses.getUnitType())) {
@@ -740,11 +741,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
String name = "equals"; String name = "equals";
if (right != null) { if (right != null) {
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context.replaceScope(context.scope)); ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context.replaceScope(context.scope));
OverloadResolutionResultsImpl<FunctionDescriptor> resolutionResults = context.resolveExactSignature( OverloadResolutionResults<FunctionDescriptor> resolutionResults = context.resolveExactSignature(
receiver, "equals", receiver, "equals",
Collections.singletonList(JetStandardClasses.getNullableAnyType())); Collections.singletonList(JetStandardClasses.getNullableAnyType()));
if (resolutionResults.isSuccess()) { if (resolutionResults.isSuccess()) {
FunctionDescriptor equals = resolutionResults.getResult().getResultingDescriptor(); FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
context.trace.record(REFERENCE_TARGET, operationSign, equals); context.trace.record(REFERENCE_TARGET, operationSign, equals);
if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) { if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) {
ensureNonemptyIntersectionOfOperandTypes(expression, context); ensureNonemptyIntersectionOfOperandTypes(expression, context);
@@ -752,7 +753,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
} }
else { else {
if (resolutionResults.isAmbiguity()) { if (resolutionResults.isAmbiguity()) {
context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResults())); context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResultingCalls()));
} }
else { else {
context.trace.report(EQUALS_MISSING.on(operationSign)); context.trace.report(EQUALS_MISSING.on(operationSign));
@@ -812,11 +813,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) {
String name = "contains"; String name = "contains";
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE)); ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE));
FunctionDescriptor functionDescriptor = context.resolveCallWithGivenNameToDescriptor( OverloadResolutionResults<FunctionDescriptor> functionDescriptor = context.resolveCallWithGivenNameToDescriptor(
CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)),
operationSign, operationSign,
name); name);
JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null; JetType containsType = functionDescriptor.isSuccess() ? functionDescriptor.getResultingDescriptor().getReturnType() : null;
ensureBooleanResult(operationSign, name, containsType, context); ensureBooleanResult(operationSign, name, containsType, context);
} }
@@ -860,14 +861,14 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionReceiver receiver = getExpressionReceiver(facade, arrayExpression, context.replaceScope(context.scope)); ExpressionReceiver receiver = getExpressionReceiver(facade, arrayExpression, context.replaceScope(context.scope));
if (receiver != null) { if (receiver != null) {
ResolvedCall<FunctionDescriptor> resolvedCall = context.resolveCallWithGivenName( OverloadResolutionResults<FunctionDescriptor> results = context.resolveCallWithGivenName(
CallMaker.makeCallWithExpressions(expression, receiver, null, expression, expression.getIndexExpressions()), CallMaker.makeCallWithExpressions(expression, receiver, null, expression, expression.getIndexExpressions()),
expression, expression,
"get" "get"
); );
if (resolvedCall != null) { if (results.isSuccess()) {
context.trace.record(INDEXED_LVALUE_GET, expression, resolvedCall); context.trace.record(INDEXED_LVALUE_GET, expression, results.getResultingCall());
return DataFlowUtils.checkType(resolvedCall.getResultingDescriptor().getReturnType(), expression, contextWithExpectedType); return DataFlowUtils.checkType(results.getResultingDescriptor().getReturnType(), expression, contextWithExpectedType);
} }
} }
return null; return null;
@@ -876,13 +877,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Nullable @Nullable
public JetType getTypeForBinaryCall(JetScope scope, String name, ExpressionTypingContext context, JetBinaryExpression binaryExpression) { public JetType getTypeForBinaryCall(JetScope scope, String name, ExpressionTypingContext context, JetBinaryExpression binaryExpression) {
ExpressionReceiver receiver = safeGetExpressionReceiver(facade, binaryExpression.getLeft(), context.replaceScope(scope)); ExpressionReceiver receiver = safeGetExpressionReceiver(facade, binaryExpression.getLeft(), context.replaceScope(scope));
FunctionDescriptor functionDescriptor = context.replaceScope(scope).resolveCallWithGivenNameToDescriptor( OverloadResolutionResults<FunctionDescriptor> results = context.replaceScope(scope).resolveCallWithGivenNameToDescriptor(
CallMaker.makeCall(receiver, binaryExpression), CallMaker.makeCall(receiver, binaryExpression),
binaryExpression.getOperationReference(), binaryExpression.getOperationReference(),
name name
); );
if (functionDescriptor != null) { if (results.isSuccess()) {
return functionDescriptor.getReturnType(); return results.getResultingDescriptor().getReturnType();
} }
return null; return null;
} }
@@ -10,8 +10,8 @@ import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
@@ -258,9 +258,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
@Nullable @Nullable
private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) {
JetExpression loopRangeExpression = loopRange.getExpression(); JetExpression loopRangeExpression = loopRange.getExpression();
OverloadResolutionResultsImpl<FunctionDescriptor> iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.<JetType>emptyList()); OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.<JetType>emptyList());
if (iteratorResolutionResults.isSuccess()) { if (iteratorResolutionResults.isSuccess()) {
FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResult().getResultingDescriptor(); FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResultingCall().getResultingDescriptor();
context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction); context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction);
@@ -280,13 +280,13 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty); context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty);
} }
OverloadResolutionResultsImpl<FunctionDescriptor> nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.<JetType>emptyList()); OverloadResolutionResults<FunctionDescriptor> nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.<JetType>emptyList());
if (nextResolutionResults.isAmbiguity()) { if (nextResolutionResults.isAmbiguity()) {
context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression)); context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression));
} else if (nextResolutionResults.isNothing()) { } else if (nextResolutionResults.isNothing()) {
context.trace.report(NEXT_MISSING.on(loopRangeExpression)); context.trace.report(NEXT_MISSING.on(loopRangeExpression));
} else { } else {
FunctionDescriptor nextFunction = nextResolutionResults.getResult().getResultingDescriptor(); FunctionDescriptor nextFunction = nextResolutionResults.getResultingCall().getResultingDescriptor();
context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction); context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction);
return nextFunction.getReturnType(); return nextFunction.getReturnType();
} }
@@ -294,11 +294,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
else { else {
if (iteratorResolutionResults.isAmbiguity()) { if (iteratorResolutionResults.isAmbiguity()) {
// StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); // StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: ");
// for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResults()) { // for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResultingCalls()) {
// stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); // stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" ");
// } // }
// errorMessage = stringBuffer.toString(); // errorMessage = stringBuffer.toString();
context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResults())); context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResultingCalls()));
} }
else { else {
context.trace.report(ITERATOR_MISSING.on(loopRangeExpression)); context.trace.report(ITERATOR_MISSING.on(loopRangeExpression));
@@ -309,19 +309,19 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
@Nullable @Nullable
private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
OverloadResolutionResultsImpl<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList()); OverloadResolutionResults<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
if (hasNextResolutionResults.isAmbiguity()) { if (hasNextResolutionResults.isAmbiguity()) {
context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange)); context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange));
} else if (hasNextResolutionResults.isNothing()) { } else if (hasNextResolutionResults.isNothing()) {
return null; return null;
} else { } else {
assert hasNextResolutionResults.isSuccess(); assert hasNextResolutionResults.isSuccess();
JetType hasNextReturnType = hasNextResolutionResults.getResult().getResultingDescriptor().getReturnType(); JetType hasNextReturnType = hasNextResolutionResults.getResultingDescriptor().getReturnType();
if (!isBoolean(context.semanticServices, hasNextReturnType)) { if (!isBoolean(context.semanticServices, hasNextReturnType)) {
context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRange, hasNextReturnType));
} }
} }
return hasNextResolutionResults.getResult().getResultingDescriptor(); return hasNextResolutionResults.getResultingCall().getResultingDescriptor();
} }
@Nullable @Nullable
@@ -10,10 +10,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver; import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -173,30 +170,31 @@ import java.util.Map;
////////// Call resolution utilities ////////// Call resolution utilities
@Nullable @NotNull
public ResolvedCall<FunctionDescriptor> resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) { public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) {
return getCallResolver().resolveCallWithGivenName(trace, scope, call, functionReference, name, expectedType); return getCallResolver().resolveCallWithGivenName(trace, scope, call, functionReference, name, expectedType);
} }
@Nullable @NotNull
public FunctionDescriptor resolveCallWithGivenNameToDescriptor(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) { public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenNameToDescriptor(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name) {
ResolvedCall<FunctionDescriptor> resolvedCall = resolveCallWithGivenName(call, functionReference, name); return resolveCallWithGivenName(call, functionReference, name);
return resolvedCall == null ? null : resolvedCall.getResultingDescriptor(); // return results == null ? null : results.getResultingDescriptor();
} }
@Nullable @Nullable
public JetType resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) { public JetType resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) {
return getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType); OverloadResolutionResults<FunctionDescriptor> results = getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType);
return results.singleResult() ? results.getResultingDescriptor().getReturnType() : null;
} }
@Nullable @NotNull
public VariableDescriptor resolveSimpleProperty(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) { public OverloadResolutionResults<VariableDescriptor> resolveSimpleProperty(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) {
Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression); Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression);
return getCallResolver().resolveSimpleProperty(trace, scope, call, expectedType); return getCallResolver().resolveSimpleProperty(trace, scope, call, expectedType);
} }
@NotNull @NotNull
public OverloadResolutionResultsImpl<FunctionDescriptor> resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) { public OverloadResolutionResults<FunctionDescriptor> resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes); return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes);
} }
} }
@@ -11,7 +11,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace; import org.jetbrains.jet.lang.resolve.TemporaryBindingTrace;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer; import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
@@ -223,14 +223,14 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
if (receiver == null) return null; if (receiver == null) return null;
Call call = CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide); Call call = CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide);
ResolvedCall<FunctionDescriptor> setFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName( OverloadResolutionResults<FunctionDescriptor> setFunctionResults = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
call, call,
arrayAccessExpression, arrayAccessExpression,
"set"); "set");
if (setFunctionCall == null) return null; if (!setFunctionResults.isSuccess()) return null;
FunctionDescriptor setFunctionDescriptor = setFunctionCall.getResultingDescriptor(); FunctionDescriptor setFunctionDescriptor = setFunctionResults.getResultingDescriptor();
context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunctionCall); context.trace.record(INDEXED_LVALUE_SET, arrayAccessExpression, setFunctionResults.getResultingCall());
// if (getterNeeded) { // if (getterNeeded) {
// ResolvedCall<FunctionDescriptor> getFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName( // ResolvedCall<FunctionDescriptor> getFunctionCall = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName(
@@ -42,7 +42,7 @@ fun main(args : Array<String>) {
val b = fooT2<Int>()(1) val b = fooT2<Int>()(1)
b : Int b : Int
<!TYPE_INFERENCE_FAILED!>fooT2()<!>(1) // : Any? <!TYPE_INFERENCE_FAILED!>fooT2()<!>(<!ERROR_COMPILE_TIME_VALUE!>1<!>) // : Any?
<!CALLEE_NOT_A_FUNCTION!>1<!>() <!CALLEE_NOT_A_FUNCTION!>1<!>()
<!CALLEE_NOT_A_FUNCTION!>1<!>{} <!CALLEE_NOT_A_FUNCTION!>1<!>{}
@@ -1,9 +1,9 @@
fun fooT2<T>() : fun(t : T) : T { fun fooT22<T>() : T? {
return {it} return null
}
fun foo1() {
<!TYPE_INFERENCE_FAILED!>fooT22()<!>
} }
val n : Nothing = null.sure() val n : Nothing = null.sure()
fun test() {
<!TYPE_INFERENCE_FAILED!>fooT2()<!>(1)
}
@@ -16,8 +16,8 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetStandardLibrary;
@@ -113,9 +113,9 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
// JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext()); // JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext());
CallResolver callResolver = new CallResolver(JetSemanticServices.createSemanticServices(getProject()), DataFlowInfo.EMPTY); CallResolver callResolver = new CallResolver(JetSemanticServices.createSemanticServices(getProject()), DataFlowInfo.EMPTY);
OverloadResolutionResultsImpl<FunctionDescriptor> functions = callResolver.resolveExactSignature( OverloadResolutionResults<FunctionDescriptor> functions = callResolver.resolveExactSignature(
classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList); classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList);
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : functions.getResults()) { for (ResolvedCall<? extends FunctionDescriptor> resolvedCall : functions.getResultingCalls()) {
List<ValueParameterDescriptor> unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters(); List<ValueParameterDescriptor> unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters();
for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) {
ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i);