report UNRESOLVED_REFERENCE_WRONG_RECEIVER
mentioning candidates with wrong receiver
This commit is contained in:
@@ -337,6 +337,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> OVERLOAD_RESOLUTION_AMBIGUITY = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> NONE_APPLICABLE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> CANNOT_COMPLETE_RESOLVE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, Collection<? extends ResolvedCall<?>>> UNRESOLVED_REFERENCE_WRONG_RECEIVER = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<JetExpression> DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
@@ -548,7 +549,7 @@ public interface Errors {
|
||||
|
||||
// Error sets
|
||||
ImmutableSet<? extends AbstractDiagnosticFactory> UNRESOLVED_REFERENCE_DIAGNOSTICS = ImmutableSet.of(
|
||||
UNRESOLVED_REFERENCE, NAMED_PARAMETER_NOT_FOUND);
|
||||
UNRESOLVED_REFERENCE, NAMED_PARAMETER_NOT_FOUND, UNRESOLVED_REFERENCE_WRONG_RECEIVER);
|
||||
ImmutableSet<? extends AbstractDiagnosticFactory> UNUSED_ELEMENT_DIAGNOSTICS = ImmutableSet.of(
|
||||
UNUSED_VARIABLE, UNUSED_PARAMETER, ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE);
|
||||
ImmutableSet<? extends AbstractDiagnosticFactory> REDECLARATION_DIAGNOSTICS = ImmutableSet.of(
|
||||
|
||||
+1
@@ -410,6 +410,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(OVERLOAD_RESOLUTION_AMBIGUITY, "Overload resolution ambiguity: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(CANNOT_COMPLETE_RESOLVE, "Cannot choose among the following candidates without completing type inference: {0}", AMBIGUOUS_CALLS);
|
||||
MAP.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, "Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: {0}", AMBIGUOUS_CALLS);
|
||||
|
||||
MAP.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter {0}", NAME);
|
||||
MAP.put(MISSING_RECEIVER, "A receiver of type {0} is required", RENDER_TYPE);
|
||||
|
||||
+2
-4
@@ -56,8 +56,6 @@ import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgum
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
|
||||
public class ArgumentTypeResolver {
|
||||
@NotNull
|
||||
private final JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
|
||||
|
||||
@NotNull
|
||||
private TypeResolver typeResolver;
|
||||
@@ -74,14 +72,14 @@ public class ArgumentTypeResolver {
|
||||
this.expressionTypingServices = expressionTypingServices;
|
||||
}
|
||||
|
||||
public boolean isSubtypeOfForArgumentType(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
public static boolean isSubtypeOfForArgumentType(@NotNull JetType subtype, @NotNull JetType supertype) {
|
||||
if (subtype == PLACEHOLDER_FUNCTION_TYPE) {
|
||||
return isFunctionOrErrorType(supertype) || KotlinBuiltIns.getInstance().isAny(supertype); //todo function type extends
|
||||
}
|
||||
if (supertype == PLACEHOLDER_FUNCTION_TYPE) {
|
||||
return isFunctionOrErrorType(subtype); //todo extends function type
|
||||
}
|
||||
return typeChecker.isSubtypeOf(subtype, supertype);
|
||||
return JetTypeChecker.INSTANCE.isSubtypeOf(subtype, supertype);
|
||||
}
|
||||
|
||||
private static boolean isFunctionOrErrorType(@NotNull JetType supertype) {
|
||||
|
||||
@@ -31,10 +31,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.context.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler;
|
||||
import org.jetbrains.jet.lang.resolve.calls.results.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.tasks.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
|
||||
@@ -59,6 +56,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLUTION_SCOPE;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code.*;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
|
||||
@@ -274,8 +272,8 @@ public class CallResolver {
|
||||
|
||||
private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCallOrGetCachedResults(
|
||||
@NotNull ResolutionResultsCache.MemberType<F> memberType,
|
||||
@NotNull final BasicCallResolutionContext context,
|
||||
@NotNull final List<ResolutionTask<D, F>> prioritizedTasks,
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull List<ResolutionTask<D, F>> prioritizedTasks,
|
||||
@NotNull CallTransformer<D, F> callTransformer,
|
||||
@NotNull JetReferenceExpression reference
|
||||
) {
|
||||
@@ -323,7 +321,7 @@ public class CallResolver {
|
||||
@NotNull TracingStrategy tracing
|
||||
) {
|
||||
if (!results.isSingleResult()) {
|
||||
if (results.getResultCode() == OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
|
||||
if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) {
|
||||
argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS);
|
||||
}
|
||||
return;
|
||||
@@ -427,11 +425,14 @@ public class CallResolver {
|
||||
resolveFunctionArguments(context, results);
|
||||
return results;
|
||||
}
|
||||
if (results.getResultCode() == OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) {
|
||||
if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) {
|
||||
results.setTrace(taskTrace);
|
||||
return results;
|
||||
}
|
||||
if (traceForFirstNonemptyCandidateSet == null && !task.getCandidates().isEmpty() && !results.isNothing()) {
|
||||
boolean updateResults = traceForFirstNonemptyCandidateSet == null
|
||||
|| (resultsForFirstNonemptyCandidateSet.getResultCode() == CANDIDATES_WITH_WRONG_RECEIVER &&
|
||||
results.getResultCode() != CANDIDATES_WITH_WRONG_RECEIVER);
|
||||
if (!task.getCandidates().isEmpty() && !results.isNothing() && updateResults) {
|
||||
traceForFirstNonemptyCandidateSet = taskTrace;
|
||||
resultsForFirstNonemptyCandidateSet = results;
|
||||
}
|
||||
@@ -488,8 +489,8 @@ public class CallResolver {
|
||||
// {...} // intended to be a returned from the outer literal
|
||||
// }
|
||||
// }
|
||||
ImmutableSet<OverloadResolutionResults.Code> someFailed = ImmutableSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES,
|
||||
OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
|
||||
ImmutableSet<OverloadResolutionResults.Code> someFailed = ImmutableSet.of(MANY_FAILED_CANDIDATES,
|
||||
SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
|
||||
if (someFailed.contains(results.getResultCode()) && !task.call.getFunctionLiteralArguments().isEmpty()
|
||||
&& task.resolveMode == ResolveMode.TOP_LEVEL_CALL) { //For nested calls there are no such cases
|
||||
// We have some candidates that failed for some reason
|
||||
|
||||
@@ -83,6 +83,8 @@ public class CandidateResolver {
|
||||
ResolvedCallImpl<D> candidateCall = context.candidateCall;
|
||||
D candidate = candidateCall.getCandidateDescriptor();
|
||||
|
||||
candidateCall.addStatus(checkReceiver(context, context.trace, /*checkOnlyReceiverTypeError=*/true));
|
||||
|
||||
if (ErrorUtils.isError(candidate)) {
|
||||
candidateCall.addStatus(SUCCESS);
|
||||
argumentTypeResolver.checkTypesWithNoCallee(context.toBasic());
|
||||
@@ -110,7 +112,7 @@ public class CandidateResolver {
|
||||
candidateCall, unmappedArguments);
|
||||
if (!argumentMappingStatus.isSuccess()) {
|
||||
if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) {
|
||||
candidateCall.addStatus(STRONG_ERROR);
|
||||
candidateCall.addStatus(RECEIVER_PRESENCE_ERROR);
|
||||
}
|
||||
else {
|
||||
candidateCall.addStatus(OTHER_ERROR);
|
||||
@@ -563,6 +565,17 @@ public class CandidateResolver {
|
||||
ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes(
|
||||
context, context.candidateCall, trace, resolveFunctionArgumentBodies);
|
||||
ResolutionStatus resultStatus = checkingResult.status;
|
||||
resultStatus = resultStatus.combine(checkReceiver(context, trace, false));
|
||||
|
||||
return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> ResolutionStatus checkReceiver(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@NotNull BindingTrace trace,
|
||||
boolean checkOnlyReceiverTypeError
|
||||
) {
|
||||
ResolutionStatus resultStatus = SUCCESS;
|
||||
ResolvedCall<D> candidateCall = context.candidateCall;
|
||||
|
||||
// Comment about a very special case.
|
||||
@@ -573,15 +586,15 @@ public class CandidateResolver {
|
||||
resultStatus = resultStatus.combine(checkReceiver(
|
||||
context, candidateCall, trace,
|
||||
candidateCall.getResultingDescriptor().getReceiverParameter(),
|
||||
candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false));
|
||||
candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false, checkOnlyReceiverTypeError));
|
||||
|
||||
resultStatus = resultStatus.combine(checkReceiver(
|
||||
context, candidateCall, trace,
|
||||
candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(),
|
||||
candidateCall.getExplicitReceiverKind().isThisObject(),
|
||||
// for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error
|
||||
context.call instanceof CallForImplicitInvoke));
|
||||
return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes);
|
||||
context.call instanceof CallForImplicitInvoke, checkOnlyReceiverTypeError));
|
||||
return resultStatus;
|
||||
}
|
||||
|
||||
public <D extends CallableDescriptor> ValueArgumentsCheckingResult checkValueArgumentTypes(
|
||||
@@ -623,7 +636,7 @@ public class CandidateResolver {
|
||||
}
|
||||
else {
|
||||
JetType resultingType;
|
||||
if (expectedType == NO_EXPECTED_TYPE || argumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) {
|
||||
if (expectedType == NO_EXPECTED_TYPE || ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) {
|
||||
resultingType = type;
|
||||
}
|
||||
else {
|
||||
@@ -642,7 +655,7 @@ public class CandidateResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType autocastValueArgumentTypeIfPossible(
|
||||
private static JetType autocastValueArgumentTypeIfPossible(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull JetType expectedType,
|
||||
@NotNull JetType actualType,
|
||||
@@ -653,38 +666,43 @@ public class CandidateResolver {
|
||||
List<ReceiverValue> variants = AutoCastUtils.getAutoCastVariants(trace.getBindingContext(), dataFlowInfo, receiverToCast);
|
||||
for (ReceiverValue receiverValue : variants) {
|
||||
JetType possibleType = receiverValue.getType();
|
||||
if (argumentTypeResolver.isSubtypeOfForArgumentType(possibleType, expectedType)) {
|
||||
if (ArgumentTypeResolver.isSubtypeOfForArgumentType(possibleType, expectedType)) {
|
||||
return possibleType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> ResolutionStatus checkReceiver(
|
||||
private static <D extends CallableDescriptor> ResolutionStatus checkReceiver(
|
||||
@NotNull CallCandidateResolutionContext<D> context,
|
||||
@NotNull ResolvedCall<D> candidateCall,
|
||||
@NotNull BindingTrace trace,
|
||||
@Nullable ReceiverParameterDescriptor receiverParameter,
|
||||
@NotNull ReceiverValue receiverArgument,
|
||||
boolean isExplicitReceiver,
|
||||
boolean implicitInvokeCheck
|
||||
boolean implicitInvokeCheck,
|
||||
boolean checkOnlyReceiverTypeError
|
||||
) {
|
||||
if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS;
|
||||
|
||||
JetType receiverArgumentType = receiverArgument.getType();
|
||||
JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType);
|
||||
D candidateDescriptor = candidateCall.getCandidateDescriptor();
|
||||
if (!argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) {
|
||||
if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) {
|
||||
|
||||
if (CallResolverUtil.checkArgumentCannotBeReceiver(effectiveReceiverArgumentType, candidateDescriptor)
|
||||
&& !(candidateDescriptor instanceof ExpressionAsFunctionDescriptor)) {
|
||||
return STRONG_ERROR;
|
||||
return RECEIVER_TYPE_ERROR;
|
||||
}
|
||||
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) {
|
||||
//todo
|
||||
if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())
|
||||
&& !checkOnlyReceiverTypeError) {
|
||||
context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument);
|
||||
return OTHER_ERROR;
|
||||
}
|
||||
}
|
||||
if (checkOnlyReceiverTypeError) return SUCCESS;
|
||||
|
||||
BindingContext bindingContext = trace.getBindingContext();
|
||||
boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall();
|
||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext);
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
|
||||
SINGLE_CANDIDATE_ARGUMENT_MISMATCH(false),
|
||||
AMBIGUITY(false),
|
||||
MANY_FAILED_CANDIDATES(false),
|
||||
CANDIDATES_WITH_WRONG_RECEIVER(false),
|
||||
INCOMPLETE_TYPE_INFERENCE(false);
|
||||
|
||||
private final boolean success;
|
||||
|
||||
+5
-1
@@ -41,6 +41,10 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
|
||||
return new OverloadResolutionResultsImpl<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> candidatesWithWrongReceiver(Collection<ResolvedCallWithTrace<D>> failedCandidates) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.CANDIDATES_WITH_WRONG_RECEIVER, failedCandidates);
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, candidates);
|
||||
}
|
||||
@@ -94,7 +98,7 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
|
||||
|
||||
@Override
|
||||
public boolean isSingleResult() {
|
||||
return results.size() == 1;
|
||||
return results.size() == 1 && getResultCode() != Code.CANDIDATES_WITH_WRONG_RECEIVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-4
@@ -44,6 +44,7 @@ public class ResolutionResultsHandler {
|
||||
Set<ResolvedCallWithTrace<D>> successfulCandidates = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallWithTrace<D>> failedCandidates = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallWithTrace<D>> incompleteCandidates = Sets.newLinkedHashSet();
|
||||
Set<ResolvedCallWithTrace<D>> candidatesWithWrongReceiver = Sets.newLinkedHashSet();
|
||||
for (ResolvedCallWithTrace<D> candidateCall : candidates) {
|
||||
ResolutionStatus status = candidateCall.getStatus();
|
||||
assert status != UNKNOWN_STATUS : "No resolution for " + candidateCall.getCandidateDescriptor();
|
||||
@@ -53,7 +54,10 @@ public class ResolutionResultsHandler {
|
||||
else if (status == INCOMPLETE_TYPE_INFERENCE) {
|
||||
incompleteCandidates.add(candidateCall);
|
||||
}
|
||||
else if (candidateCall.getStatus() != STRONG_ERROR) {
|
||||
else if (candidateCall.getStatus() == RECEIVER_TYPE_ERROR) {
|
||||
candidatesWithWrongReceiver.add(candidateCall);
|
||||
}
|
||||
else if (candidateCall.getStatus() != RECEIVER_PRESENCE_ERROR) {
|
||||
failedCandidates.add(candidateCall);
|
||||
}
|
||||
}
|
||||
@@ -65,10 +69,12 @@ public class ResolutionResultsHandler {
|
||||
else if (!failedCandidates.isEmpty()) {
|
||||
return computeFailedResult(trace, tracing, failedCandidates);
|
||||
}
|
||||
else {
|
||||
tracing.unresolvedReference(trace);
|
||||
return OverloadResolutionResultsImpl.nameNotFound();
|
||||
if (!candidatesWithWrongReceiver.isEmpty()) {
|
||||
tracing.unresolvedReferenceWrongReceiver(trace, candidatesWithWrongReceiver);
|
||||
return OverloadResolutionResultsImpl.candidatesWithWrongReceiver(candidatesWithWrongReceiver);
|
||||
}
|
||||
tracing.unresolvedReference(trace);
|
||||
return OverloadResolutionResultsImpl.nameNotFound();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+9
-2
@@ -22,7 +22,13 @@ public enum ResolutionStatus {
|
||||
UNKNOWN_STATUS,
|
||||
UNSAFE_CALL_ERROR,
|
||||
OTHER_ERROR,
|
||||
STRONG_ERROR,
|
||||
// '1.foo()' shouldn't be resolved to 'fun String.foo()'
|
||||
// candidates with such error are treated specially
|
||||
// (are mentioned in 'unresolved' error, if there are no other options)
|
||||
RECEIVER_TYPE_ERROR,
|
||||
// 'a.foo()' shouldn't be resolved to package level non-extension 'fun foo()'
|
||||
// candidates with such error are thrown away completely
|
||||
RECEIVER_PRESENCE_ERROR,
|
||||
INCOMPLETE_TYPE_INFERENCE,
|
||||
SUCCESS(true);
|
||||
|
||||
@@ -30,7 +36,8 @@ public enum ResolutionStatus {
|
||||
public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] {
|
||||
EnumSet.of(UNSAFE_CALL_ERROR), // weakest
|
||||
EnumSet.of(OTHER_ERROR),
|
||||
EnumSet.of(STRONG_ERROR), // most severe
|
||||
EnumSet.of(RECEIVER_TYPE_ERROR),
|
||||
EnumSet.of(RECEIVER_PRESENCE_ERROR), // most severe
|
||||
};
|
||||
|
||||
private final boolean success;
|
||||
|
||||
+7
-3
@@ -23,7 +23,6 @@ import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
|
||||
@@ -47,7 +46,10 @@ public interface TracingStrategy {
|
||||
public void unresolvedReference(@NotNull BindingTrace trace) {}
|
||||
|
||||
@Override
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<ResolvedCallWithTrace<D>> candidates) {}
|
||||
public <D extends CallableDescriptor> void unresolvedReferenceWrongReceiver(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallWithTrace<D>> candidates) {}
|
||||
|
||||
@Override
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallWithTrace<D>> candidates) {}
|
||||
|
||||
@Override
|
||||
public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverParameterDescriptor expectedReceiver) {}
|
||||
@@ -104,7 +106,9 @@ public interface TracingStrategy {
|
||||
|
||||
void unresolvedReference(@NotNull BindingTrace trace);
|
||||
|
||||
<D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<ResolvedCallWithTrace<D>> candidates);
|
||||
<D extends CallableDescriptor> void unresolvedReferenceWrongReceiver(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallWithTrace<D>> candidates);
|
||||
|
||||
<D extends CallableDescriptor> void recordAmbiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallWithTrace<D>> candidates);
|
||||
|
||||
void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverParameterDescriptor expectedReceiver);
|
||||
|
||||
|
||||
+6
-1
@@ -78,7 +78,7 @@ public class TracingStrategyImpl implements TracingStrategy {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(BindingTrace trace, Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||
public <D extends CallableDescriptor> void recordAmbiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||
Collection<D> descriptors = Sets.newHashSet();
|
||||
for (ResolvedCallWithTrace<D> candidate : candidates) {
|
||||
descriptors.add(candidate.getCandidateDescriptor());
|
||||
@@ -91,6 +91,11 @@ public class TracingStrategyImpl implements TracingStrategy {
|
||||
trace.report(UNRESOLVED_REFERENCE.on(reference, reference));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D extends CallableDescriptor> void unresolvedReferenceWrongReceiver(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||
trace.report(UNRESOLVED_REFERENCE_WRONG_RECEIVER.on(reference, candidates));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter) {
|
||||
JetElement reportOn;
|
||||
|
||||
@@ -9,9 +9,9 @@ class Customer(name: String)
|
||||
fun foo(f: File, c: Customer) {
|
||||
f.name
|
||||
|
||||
c.<!UNRESOLVED_REFERENCE!>name<!> // name should be unresolved here
|
||||
c.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>name<!> // name should be unresolved here
|
||||
}
|
||||
|
||||
//from standard library
|
||||
val File.name: String
|
||||
get() = getName()
|
||||
get() = getName()
|
||||
@@ -6,26 +6,28 @@ package bar
|
||||
fun <R> List<R>.a() {}
|
||||
|
||||
fun test1(i: Int?) {
|
||||
1.<!UNRESOLVED_REFERENCE!>a<!>()
|
||||
i.<!UNRESOLVED_REFERENCE!>a<!>()
|
||||
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>a<!>()
|
||||
i.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>a<!>()
|
||||
}
|
||||
|
||||
fun <R> test2(c: Collection<R>) {
|
||||
c.<!UNRESOLVED_REFERENCE!>a<!>()
|
||||
c.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>a<!>()
|
||||
}
|
||||
|
||||
fun Int.foo() {}
|
||||
|
||||
fun test3(s: String?) {
|
||||
"".<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||
s.<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||
"".<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>foo<!>()
|
||||
s.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>foo<!>()
|
||||
"".<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>foo<!>(1)
|
||||
s.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>foo<!>("a")
|
||||
}
|
||||
|
||||
trait A
|
||||
fun <T: A> T.c() {}
|
||||
|
||||
fun test4() {
|
||||
1.<!UNRESOLVED_REFERENCE!>c<!>()
|
||||
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>c<!>()
|
||||
}
|
||||
|
||||
|
||||
@@ -46,4 +48,8 @@ fun List<String>.b() {}
|
||||
|
||||
fun test7(l: List<String?>) {
|
||||
<!TYPE_MISMATCH!>l<!>.b()
|
||||
}
|
||||
|
||||
fun test8(l: List<Any>?) {
|
||||
<!TYPE_MISMATCH!>l<!>.b()
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package a
|
||||
|
||||
class A {}
|
||||
|
||||
fun test(a1: A, a2: A) {
|
||||
val <!UNUSED_VARIABLE!>range<!> = "island".."isle"
|
||||
|
||||
a1<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>..<!>a2
|
||||
}
|
||||
|
||||
|
||||
public fun <T: Comparable<T>> T.rangeTo(<!UNUSED_PARAMETER!>that<!>: T): Range<T> {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
@@ -9,4 +9,4 @@ fun <T, Q> List<T>.map1(f: (T)-> Q): List<T>? = tail!!.map1(f)
|
||||
|
||||
fun <T, Q> List<T>.map2(f: (T)-> Q): List<T>? = tail.sure().map2(f)
|
||||
|
||||
fun <T, Q> List<T>.map3(f: (T)-> Q): List<T>? = <!TYPE_MISMATCH!>tail<!>.sure<T>().<!UNRESOLVED_REFERENCE!>map3<!>(f)
|
||||
fun <T, Q> List<T>.map3(f: (T)-> Q): List<T>? = <!TYPE_MISMATCH!>tail<!>.sure<T>().<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>map3<!>(f)
|
||||
@@ -0,0 +1,17 @@
|
||||
fun Int.foo() {}
|
||||
|
||||
open class A {
|
||||
~A.foo~fun foo(i: Int) {}
|
||||
}
|
||||
open class B {}
|
||||
|
||||
fun test(a: A, b: B) {
|
||||
with (a) {
|
||||
with (b) {
|
||||
// at first we try b.foo, so 'Int.foo' should have less priority to be thrown away
|
||||
`A.foo`foo(1.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||
@@ -2297,6 +2297,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("throwOutCandidatesByReceiver2.kt")
|
||||
public void testThrowOutCandidatesByReceiver2() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver2.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/functionLiterals")
|
||||
|
||||
@@ -238,6 +238,11 @@ public class JetResolveTestGenerated extends AbstractResolveTest {
|
||||
doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve");
|
||||
}
|
||||
|
||||
@TestMetadata("wrongReceiverVsOtherError.resolve")
|
||||
public void testWrongReceiverVsOtherError() throws Exception {
|
||||
doTest("compiler/testData/resolve/candidatesPriority/wrongReceiverVsOtherError.resolve");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/resolve/delegatedProperty")
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.jet.lang.diagnostics.rendering.*;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.NAME;
|
||||
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.RENDER_CLASS_OR_OBJECT;
|
||||
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.TO_STRING;
|
||||
import static org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TextElementType;
|
||||
@@ -93,6 +92,7 @@ public class IdeErrorMessages {
|
||||
MAP.put(NONE_APPLICABLE, "<html>None of the following functions can be called with the arguments supplied. <ul>{0}</ul></html>",
|
||||
HTML_NONE_APPLICABLE_CALLS);
|
||||
MAP.put(CANNOT_COMPLETE_RESOLVE, "<html>Cannot choose among the following candidates without completing type inference: <ul>{0}</ul></html>", HTML_AMBIGUOUS_CALLS);
|
||||
MAP.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, "<html>Unresolved reference. <br/> None of the following candidates is applicable because of receiver type mismatch: <ul>{0}</ul></html>", HTML_AMBIGUOUS_CALLS);
|
||||
|
||||
MAP.put(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY, "<html>Overload resolution ambiguity on method ''{0}''. All these functions match. <ul>{1}</ul></html>", TO_STRING, HTML_AMBIGUOUS_CALLS);
|
||||
MAP.put(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, "<html>Property delegate must have a ''{0}'' method. None of the following functions is suitable. <ul>{1}</ul></html>",
|
||||
|
||||
Reference in New Issue
Block a user