Improved error reporting for candidates with wrong parameter count

This commit is contained in:
Stanislav Erokhin
2015-08-31 20:32:59 +03:00
parent 8ea6f36903
commit 5ded315cbb
23 changed files with 82 additions and 52 deletions
@@ -160,7 +160,7 @@ public class CandidateResolver(
val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
call, tracing, candidateCall, Sets.newLinkedHashSet<ValueArgument>())
if (!argumentMappingStatus.isSuccess()) {
candidateCall.addStatus(OTHER_ERROR)
candidateCall.addStatus(ARGUMENTS_MAPPING_ERROR)
}
}
@@ -136,33 +136,36 @@ public class ResolutionResultsHandler {
}
}
if (!thisLevel.isEmpty()) {
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
if (results.isSingleResult()) {
results.getResultingCall().getTrace().moveAllMyDataTo(task.trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
if (severityLevel.contains(ARGUMENTS_MAPPING_ERROR)) {
return recordFailedInfo(task, thisLevel);
}
task.tracing.noneApplicable(task.trace, results.getResultingCalls());
task.tracing.recordAmbiguity(task.trace, results.getResultingCalls());
return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls());
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
return recordFailedInfo(task, results.getResultingCalls());
}
}
assert false : "Should not be reachable, cause every status must belong to some level";
Set<MutableResolvedCall<D>> noOverrides = OverrideResolver.filterOutOverridden(failedCandidates, MAP_TO_CANDIDATE);
if (noOverrides.size() != 1) {
task.tracing.noneApplicable(task.trace, noOverrides);
task.tracing.recordAmbiguity(task.trace, noOverrides);
return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides);
}
failedCandidates = noOverrides;
return recordFailedInfo(task, noOverrides);
}
MutableResolvedCall<D> failed = failedCandidates.iterator().next();
failed.getTrace().moveAllMyDataTo(task.trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
return recordFailedInfo(task, failedCandidates);
}
@NotNull
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> recordFailedInfo(
@NotNull ResolutionTask task,
@NotNull Collection<MutableResolvedCall<D>> candidates
) {
if (candidates.size() == 1) {
MutableResolvedCall<D> failed = candidates.iterator().next();
failed.getTrace().moveAllMyDataTo(task.trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
}
task.tracing.noneApplicable(task.trace, candidates);
task.tracing.recordAmbiguity(task.trace, candidates);
return OverloadResolutionResultsImpl.manyFailedCandidates(candidates);
}
private static <D extends CallableDescriptor> boolean allIncomplete(@NotNull Collection<MutableResolvedCall<D>> results) {
@@ -31,6 +31,7 @@ public enum ResolutionStatus {
// 'a.foo()' shouldn't be resolved to package level non-extension 'fun foo()'
// candidates with such error are thrown away completely
RECEIVER_PRESENCE_ERROR,
ARGUMENTS_MAPPING_ERROR,
INCOMPLETE_TYPE_INFERENCE,
SUCCESS(true);
@@ -38,6 +39,7 @@ public enum ResolutionStatus {
public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] {
EnumSet.of(UNSAFE_CALL_ERROR), // weakest
EnumSet.of(OTHER_ERROR),
EnumSet.of(ARGUMENTS_MAPPING_ERROR),
EnumSet.of(RECEIVER_TYPE_ERROR),
EnumSet.of(RECEIVER_PRESENCE_ERROR), // most severe
};
@@ -0,0 +1,16 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
fun foo() {}
fun foo(s: Int) {}
fun bar(a: Any) {}
fun bar(a: Int) {}
fun test() {
<!NONE_APPLICABLE!>foo<!>(1, 2)
foo(<!TYPE_MISMATCH!>""<!>)
<!NONE_APPLICABLE!>bar<!>(1, 2)
<!NONE_APPLICABLE!>bar<!>()
}
@@ -0,0 +1,7 @@
package
internal fun bar(/*0*/ a: kotlin.Any): kotlin.Unit
internal fun bar(/*0*/ a: kotlin.Int): kotlin.Unit
internal fun foo(): kotlin.Unit
internal fun foo(/*0*/ s: kotlin.Int): kotlin.Unit
internal fun test(): kotlin.Unit
@@ -6,12 +6,11 @@ fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Int, vararg <!UNUSED_PARAMETER!>a<!
return null
}
fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Any, <!UNUSED_PARAMETER!>y<!>: T): T? {
fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Comparable<*>, <!UNUSED_PARAMETER!>y<!>: T): T? {
return null
}
fun test() {
val x2 = joinT(<!NON_VARARG_SPREAD!>*<!>1, "2")
val x2 = <!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>joinT<!>(<!TYPE_MISMATCH!>Unit<!>, "2")
checkSubtype<String?>(x2)
}
}
@@ -1,7 +1,7 @@
package
package d {
internal fun </*0*/ T : kotlin.Any> joinT(/*0*/ x: kotlin.Any, /*1*/ y: T): T?
internal fun </*0*/ T : kotlin.Any> joinT(/*0*/ x: kotlin.Comparable<*>, /*1*/ y: T): T?
internal fun </*0*/ T : kotlin.Any> joinT(/*0*/ x: kotlin.Int, /*1*/ vararg a: T /*kotlin.Array<out T>*/): T?
internal fun test(): kotlin.Unit
}
@@ -83,7 +83,7 @@ fun test(n: J?, nn: J) {
J(nn, nn, nn)
J(platformNN, platformNN, platformNN)
<!NONE_APPLICABLE!>J<!>(n, n, n)
<!NONE_APPLICABLE!>J<!>(platformN, platformN, platformN)
J(<!TYPE_MISMATCH!>n<!>, n, n)
J(<!TYPE_MISMATCH!>platformN<!>, platformN, platformN)
J(platformJ, platformJ, platformJ)
}
@@ -11,7 +11,6 @@ public class ResolutionTaskHolder<F, G : F> {
//todo the problem is the type of ResolutionTask is inferred as ResolutionTask<F, F> too early
tasks.<!TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS!>bar<!>(ResolutionTask(candidate))
tasks.<!NONE_APPLICABLE!>add<!>(ResolutionTask(candidate))
tasks.add(ResolutionTask(candidate))
}
}
}
@@ -1,4 +1,4 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class X<T>(val t: T) {
constructor(t: T, i: Int) : <!NONE_APPLICABLE!>this<!>(i)
}
constructor(t: T, i: Int) : this(<!TYPE_MISMATCH!>i<!>)
}
@@ -5,8 +5,8 @@ fun bar(): String? = null
fun foo() {
var x = ArrayList<String>()
x.<!NONE_APPLICABLE!>add<!>(null)
x.<!NONE_APPLICABLE!>add<!>(bar())
x.add(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.add(<!TYPE_MISMATCH!>bar()<!>)
x.add("")
x[0] = <!NULL_FOR_NONNULL_TYPE!>null<!>
@@ -19,4 +19,4 @@ fun foo() {
val b4: Collection<String?> = x
val b6: MutableCollection<String?> = <!TYPE_MISMATCH!>x<!>
}
}
@@ -22,8 +22,8 @@ fun bar(): String? = null
fun foo() {
var x = A<String>()
x.<!NONE_APPLICABLE!>add<!>(null)
x.<!NONE_APPLICABLE!>add<!>(bar())
x.add(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.add(<!TYPE_MISMATCH!>bar()<!>)
x.add("")
x[0] = <!NULL_FOR_NONNULL_TYPE!>null<!>
@@ -36,4 +36,4 @@ fun foo() {
val b4: Collection<String?> = x
val b6: MutableCollection<String?> = <!TYPE_MISMATCH!>x<!>
}
}
@@ -60,7 +60,7 @@ fun <T> tt(t : T) : T {
val x : ArrayList<Int> = 0
x`java::java.util.ArrayList.get()`[1]
val foo = `Bar`Bar()
foo`!!`[null, 1]
foo`get2`[null, 1]
foo`get2`[1, 1]
foo`get1`[1]
foo`set1`[1] = ""
@@ -2370,6 +2370,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("overloadedFunction.kt")
public void testOverloadedFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/checkArguments/overloadedFunction.kt");
doTest(fileName);
}
@TestMetadata("SpreadVarargs.kt")
public void testSpreadVarargs() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/checkArguments/SpreadVarargs.kt");
@@ -11,10 +11,10 @@ fun other() {
}
// EXIST: { lookupString:"nFirst", itemText:"nFirst =" }
// EXIST: { lookupString:"nSecond", itemText:"nSecond =" }
// EXIST: { lookupString:"nThird", itemText:"nThird =" }
// EXIST: nLocal
// todo - should exist
// ABSENT: nClassParam
// ABSENT: nSecond
// ABSENT: nThird
// ABSENT: nClassField
+1
View File
@@ -3,6 +3,7 @@
// !MESSAGE_TYPE: HTML
fun foo(i: Int, s: String, b: Boolean) {}
fun foo(i: Int, s: Int) {}
fun foo(b: Boolean, s: String) {}
fun foo(i: Int) {}
+1 -2
View File
@@ -3,7 +3,6 @@
None of the following functions can be called with the arguments supplied.
<ul>
<li>foo(<font color=red><b>Boolean</b></font>, String) <i>defined in</i> root package</li>
<li>foo(Int<font color=red><b>)</b></font> <i>defined in</i> root package</li>
<li>foo(Int, String, <font color=red><b>Boolean</b></font>) <i>defined in</i> root package</li>
<li>foo(Int, <font color=red><b>Int</b></font>) <i>defined in</i> root package</li>
</ul>
</html>
@@ -8,8 +8,5 @@ None of the following functions can be called with the arguments supplied.
<li>foo(Int, <font color=red><b>R</b></font>, MutableList<`Int>, MutableList<`<font color=red><b>R</b></font>>)<br/>
<i>where</i> <font color=red><b>R</b></font><i> cannot be inferred</i>; T = Int<i> for </i><br/>
<b>fun</b> <`T, R> foo(t: T, r: R, lt: MutableList<`T>, lr: MutableList<`R>): Int <i>defined in</i> p</li>
<li>foo(Int, Any, List<`Int><font color=red><b>)</b></font><br/>
<i>where</i> T = Int<i> for </i><br/>
<b>fun</b> <`T> foo(t: T, a: Any, l: List<`T>): Int <i>defined in</i> p</li>
</ul>
</html>
@@ -1,6 +1,7 @@
// IS_APPLICABLE: false
// WITH_RUNTIME
// ERROR: No value passed for parameter value
// ERROR: <html>None of the following functions can be called with the arguments supplied. <ul><li>assert(<font color=red><b>Boolean</b></font>, () &rarr; Any) <i>defined in</i> kotlin</li><li>assert(<font color=red><b>Boolean</b></font>, Any = ...) <i>defined in</i> kotlin</li></ul></html>
fun foo() {
<caret>assert { "text" }
}
+1 -1
View File
@@ -1,4 +1,4 @@
// ERROR: None of the following functions can be called with the arguments supplied: public open fun valueOf(p0: kotlin.Short): kotlin.Short! defined in java.lang.Short public open fun valueOf(p0: kotlin.String!): kotlin.Short! defined in java.lang.Short public open fun valueOf(p0: kotlin.String!, p1: kotlin.Int): kotlin.Short! defined in java.lang.Short
// ERROR: None of the following functions can be called with the arguments supplied: public open fun valueOf(p0: kotlin.Short): kotlin.Short! defined in java.lang.Short public open fun valueOf(p0: kotlin.String!): kotlin.Short! defined in java.lang.Short
package demo
class Test {
+1 -1
View File
@@ -1,5 +1,5 @@
// ERROR: None of the following functions can be called with the arguments supplied: public constructor FileInputStream(p0: [ERROR : Unresolved java classifier: FileDescriptor]!) defined in java.io.FileInputStream public constructor FileInputStream(p0: java.io.File!) defined in java.io.FileInputStream public constructor FileInputStream(p0: kotlin.String!) defined in java.io.FileInputStream
// ERROR: None of the following functions can be called with the arguments supplied: public constructor InputStreamReader(p0: java.io.InputStream!) defined in java.io.InputStreamReader public constructor InputStreamReader(p0: java.io.InputStream!, p1: [ERROR : Unresolved java classifier: CharsetDecoder]!) defined in java.io.InputStreamReader public constructor InputStreamReader(p0: java.io.InputStream!, p1: java.nio.charset.Charset!) defined in java.io.InputStreamReader public constructor InputStreamReader(p0: java.io.InputStream!, p1: kotlin.String!) defined in java.io.InputStreamReader
// ERROR: Type mismatch: inferred type is java.io.DataInputStream but java.io.InputStream! was expected
// ERROR: Assignments are not expressions, and only expressions are allowed in this context
// ERROR: Unresolved reference: close
import java.io.*
+2 -2
View File
@@ -1,6 +1,6 @@
// ERROR: Unresolved reference: LinkedList
// ERROR: None of the following functions can be called with the arguments supplied: public open fun add(e: kotlin.Any): kotlin.Boolean defined in java.util.ArrayList public open fun add(index: kotlin.Int, element: kotlin.Any): kotlin.Unit defined in java.util.ArrayList
// ERROR: None of the following functions can be called with the arguments supplied: public open fun add(e: kotlin.Any): kotlin.Boolean defined in java.util.ArrayList public open fun add(index: kotlin.Int, element: kotlin.Any): kotlin.Unit defined in java.util.ArrayList
// ERROR: Null can not be a value of a non-null type kotlin.Any
// ERROR: Null can not be a value of a non-null type kotlin.Any
import java.util.*
public class Lists {
@@ -1,5 +1,5 @@
// ERROR: None of the following functions can be called with the arguments supplied: public fun <T> listOf(): kotlin.List<kotlin.String> defined in kotlin public fun <T> listOf(vararg values: kotlin.String): kotlin.List<kotlin.String> defined in kotlin public fun <T> listOf(value: kotlin.String): kotlin.List<kotlin.String> defined in kotlin
// ERROR: None of the following functions can be called with the arguments supplied: public fun <T> setOf(): kotlin.Set<kotlin.String> defined in kotlin public fun <T> setOf(vararg values: kotlin.String): kotlin.Set<kotlin.String> defined in kotlin public fun <T> setOf(value: kotlin.String): kotlin.Set<kotlin.String> defined in kotlin
// ERROR: Null can not be a value of a non-null type kotlin.String
// ERROR: Null can not be a value of a non-null type kotlin.String
import java.util.*
class A {