report UNRESOLVED_REFERENCE_WRONG_RECEIVER

mentioning candidates with wrong receiver
This commit is contained in:
Svetlana Isakova
2013-06-17 19:05:54 +04:00
parent 3340b94bd8
commit 041505f5b8
19 changed files with 142 additions and 49 deletions
@@ -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(
@@ -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);
@@ -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);
@@ -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;
@@ -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
@@ -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
@@ -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;
@@ -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);
@@ -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>",