Report diagnostics about callable reference resolution ambiguity

Found diagnostics were not reported before.
#KT-32862 In Progress
This commit is contained in:
Pavel Kirpichenkov
2019-10-17 18:41:41 +03:00
parent 138d558f6a
commit 02fc921eed
11 changed files with 59 additions and 8 deletions
@@ -10760,6 +10760,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt3174.kt");
}
@TestMetadata("kt32862_both.kt")
public void testKt32862_both() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.kt");
}
@TestMetadata("kt32862_none.kt")
public void testKt32862_none() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt32862_none.kt");
}
@TestMetadata("kt3301.kt")
public void testKt3301() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt3301.kt");
@@ -730,6 +730,7 @@ public interface Errors {
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);
DiagnosticFactory1<PsiElement, Collection<? extends CallableDescriptor>> CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, TypeParameterDescriptor> TYPE_PARAMETER_AS_REIFIED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_FORBIDDEN_SUBSTITUTION = DiagnosticFactory1.create(ERROR);
@@ -828,6 +828,7 @@ public class DefaultErrorMessages {
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(CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, "Callable reference resolution ambiguity: {0}", AMBIGUOUS_CALLABLE_REFERENCES);
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);
@@ -190,10 +190,21 @@ object Renderers {
@JvmField
val AMBIGUOUS_CALLS = Renderer { calls: Collection<ResolvedCall<*>> ->
val descriptors = calls.map { it.resultingDescriptor }
renderAmbiguousDescriptors(descriptors)
}
@JvmField
val AMBIGUOUS_CALLABLE_REFERENCES = Renderer { references: Collection<CallableDescriptor> ->
renderAmbiguousDescriptors(references)
}
private fun renderAmbiguousDescriptors(descriptors: Collection<CallableDescriptor>): String {
val context = RenderingContext.Impl(descriptors)
descriptors
return descriptors
.sortedWith(MemberComparator.INSTANCE)
.joinToString(separator = "\n", prefix = "\n") { FQ_NAMES_IN_TYPES.render(it, context) }
.joinToString(separator = "\n", prefix = "\n") {
FQ_NAMES_IN_TYPES.render(it, context)
}
}
@JvmStatic
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.unCapture
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class DiagnosticReporterByTrackingStrategy(
@@ -140,6 +139,15 @@ class DiagnosticReporterByTrackingStrategy(
}
}
CallableReferenceCandidatesAmbiguity::class.java -> {
val ambiguityDiagnostic = diagnostic as CallableReferenceCandidatesAmbiguity
val expression = ambiguityDiagnostic.argument.psiExpression.safeAs<KtCallableReferenceExpression>()
val candidates = ambiguityDiagnostic.candidates.map { it.candidate }
reportIfNonNull(expression) {
trace.report(CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY.on(it.callableReference, candidates))
}
}
ArgumentTypeMismatchDiagnostic::class.java -> {
require(diagnostic is ArgumentTypeMismatchDiagnostic)
reportIfNonNull(callArgument.safeAs<PSIKotlinCallArgument>()?.valueArgument?.getArgumentExpression()) {
@@ -7,5 +7,5 @@ fun foo(y: String) {}
fun <T> bar(f: (T) -> Unit) {}
fun test() {
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!>(::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>)
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!>(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>)
}
@@ -31,7 +31,7 @@ fun test() {
val t3 = bar(::baz)
<!DEBUG_INFO_EXPRESSION_TYPE("B")!>t3<!>
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!>(::<!DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>)
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!>(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, DEBUG_INFO_MISSING_UNRESOLVED!>foo<!>)
}
}
}
@@ -31,5 +31,5 @@ fun test() {
val a6 = foo(::singleA, ::singleB)
<!DEBUG_INFO_EXPRESSION_TYPE("{A & B}")!>a6<!>
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(::<!DEBUG_INFO_MISSING_UNRESOLVED!>multiple<!>, ::<!DEBUG_INFO_MISSING_UNRESOLVED!>multiple<!>)
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, DEBUG_INFO_MISSING_UNRESOLVED!>multiple<!>, ::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, DEBUG_INFO_MISSING_UNRESOLVED!>multiple<!>)
}
@@ -6,8 +6,8 @@ class Impl : Inv
class Scope<InterfaceT, ImplementationT : InterfaceT>(private val implClass: <!UNRESOLVED_REFERENCE!>j<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>Class<!><ImplementationT>) {
fun foo(c: Collection<InterfaceT>) {
val <!UNUSED_VARIABLE!>hm<!> = c.asSequence()
.filter(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>implClass<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>isInstance<!>)
.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>map<!>(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>implClass<!>::<!DEBUG_INFO_MISSING_UNRESOLVED!>cast<!>)
.filter(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>implClass<!>::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, DEBUG_INFO_MISSING_UNRESOLVED!>isInstance<!>)
.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>map<!>(<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>implClass<!>::<!CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, DEBUG_INFO_MISSING_UNRESOLVED!>cast<!>)
.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>toSet<!>()
}
}
@@ -10767,6 +10767,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt3174.kt");
}
@TestMetadata("kt32862_both.kt")
public void testKt32862_both() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.kt");
}
@TestMetadata("kt32862_none.kt")
public void testKt32862_none() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt32862_none.kt");
}
@TestMetadata("kt3301.kt")
public void testKt3301() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt3301.kt");
@@ -10762,6 +10762,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt3174.kt");
}
@TestMetadata("kt32862_both.kt")
public void testKt32862_both() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.kt");
}
@TestMetadata("kt32862_none.kt")
public void testKt32862_none() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt32862_none.kt");
}
@TestMetadata("kt3301.kt")
public void testKt3301() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt3301.kt");