From 7ec8716d65aa3db7b9d4bf7b1aeab6d52eec9067 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Mon, 1 Jun 2020 10:00:48 +0300 Subject: [PATCH] Introduce HTML redenred version for compatibility warning --- .../org/jetbrains/kotlin/diagnostics/Errors.java | 2 +- .../rendering/DefaultErrorMessages.java | 4 ++-- .../kotlin/diagnostics/rendering/Renderers.kt | 5 +++++ .../calls/DiagnosticReporterByTrackingStrategy.kt | 14 ++++++++++++-- .../components/CallableReferenceResolution.kt | 4 ++-- .../calls/components/CallableReferenceResolver.kt | 2 +- .../resolve/calls/model/KotlinCallDiagnostics.kt | 7 +++++-- .../resolve/calls/model/ResolutionCandidate.kt | 4 ++-- .../messages/KotlinIdeaAnalysisBundle.properties | 1 + .../kotlin/idea/highlighter/IdeErrorMessages.java | 4 ++++ .../kotlin/idea/highlighter/IdeRenderers.kt | 5 +++++ 11 files changed, 40 insertions(+), 12 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 09f3590390b..e904d351bca 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -761,7 +761,7 @@ public interface Errors { DiagnosticFactory1 REIFIED_TYPE_UNSAFE_SUBSTITUTION = DiagnosticFactory1.create(WARNING); DiagnosticFactory0 CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION = DiagnosticFactory0.create(WARNING); - DiagnosticFactory0 COMPATIBILITY_WARNING = DiagnosticFactory0.create(WARNING); + DiagnosticFactory1 COMPATIBILITY_WARNING = DiagnosticFactory1.create(WARNING); DiagnosticFactory3 RESOLUTION_TO_CLASSIFIER = DiagnosticFactory3.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 7a08f6d9c0a..b9379796074 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -896,9 +896,9 @@ public class DefaultErrorMessages { MAP.put(REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, "Cannot use ''{0}'' as reified type parameter", RENDER_TYPE); MAP.put(REIFIED_TYPE_UNSAFE_SUBSTITUTION, "It may be not safe to use ''{0}'' as an argument for a reified type parameter. Use a non-generic type or * if possible", RENDER_TYPE); MAP.put(TYPE_PARAMETERS_NOT_ALLOWED, "Type parameters are not allowed here"); - MAP.put(CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION, "Candidate was choosen only by @OverloadResolutionByLambdaReturnType annotation"); + MAP.put(CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION, "Candidate was chosen only by @OverloadResolutionByLambdaReturnType annotation"); - MAP.put(COMPATIBILITY_WARNING, "Candidate was chosen to preserve compatibility"); + MAP.put(COMPATIBILITY_WARNING, "Candidate resolution will be changed, please invoke explicitly ''{0}''", COMPATIBILITY_CANDIDATE); MAP.put(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER, "Type parameter of a property must be used in its receiver type"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt index b9cdb6c1f32..44643f094dd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/Renderers.kt @@ -197,6 +197,11 @@ object Renderers { renderAmbiguousDescriptors(descriptors) } + @JvmField + val COMPATIBILITY_CANDIDATE = Renderer { call: CallableDescriptor -> + renderAmbiguousDescriptors(listOf(call)) + } + @JvmField val AMBIGUOUS_CALLABLE_REFERENCES = Renderer { references: Collection -> renderAmbiguousDescriptors(references) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index b0069563864..0d55f89b9ee 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -81,7 +81,12 @@ class DiagnosticReporterByTrackingStrategy( trace.report(CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION.on(psiKotlinCall.psiCall.callElement)) } CompatibilityWarning::class.java -> { - trace.report(COMPATIBILITY_WARNING.on(psiKotlinCall.psiCall.callElement)) + trace.report( + COMPATIBILITY_WARNING.on( + psiKotlinCall.psiCall.callElement, + (diagnostic as CompatibilityWarning).candidate + ) + ) } } } @@ -220,7 +225,12 @@ class DiagnosticReporterByTrackingStrategy( } CompatibilityWarningOnArgument::class.java -> { - trace.report(COMPATIBILITY_WARNING.on(callArgument.psiCallArgument.valueArgument.asElement())) + trace.report( + COMPATIBILITY_WARNING.on( + callArgument.psiCallArgument.valueArgument.asElement(), + (diagnostic as CompatibilityWarningOnArgument).candidate + ) + ) } } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt index 27937f708c4..8a37f6012e0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt @@ -69,8 +69,8 @@ class CallableReferenceCandidate( override val resultingApplicability = getResultApplicability(diagnostics) override fun addCompatibilityWarning(other: Candidate) { - if (this !== other) { - mutableDiagnostics.add(CompatibilityWarning()) + if (this !== other && other is CallableReferenceCandidate) { + mutableDiagnostics.add(CompatibilityWarning(other.candidate)) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt index 3f465f9b5ea..ab16ed548da 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt @@ -109,7 +109,7 @@ class CallableReferenceResolver( diagnosticsHolder.addDiagnosticIfNotNull(diagnostic) chosenCandidate.diagnostics.forEach { val transformedDiagnostic = when (it) { - is CompatibilityWarning -> CompatibilityWarningOnArgument(argument) + is CompatibilityWarning -> CompatibilityWarningOnArgument(argument, it.candidate) is LowerPriorityToPreserveCompatibility -> return@forEach else -> it } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt index b1efe3ebc94..c737133a9ad 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt @@ -250,13 +250,16 @@ class CandidateChosenUsingOverloadResolutionByLambdaAnnotation : KotlinCallDiagn } } -class CompatibilityWarning : KotlinCallDiagnostic(RESOLVED) { +class CompatibilityWarning(val candidate: CallableDescriptor) : KotlinCallDiagnostic(RESOLVED) { override fun report(reporter: DiagnosticReporter) { reporter.onCall(this) } } -class CompatibilityWarningOnArgument(val argument: CallableReferenceKotlinCallArgument) : KotlinCallDiagnostic(RESOLVED) { +class CompatibilityWarningOnArgument( + val argument: CallableReferenceKotlinCallArgument, + val candidate: CallableDescriptor +) : KotlinCallDiagnostic(RESOLVED) { override fun report(reporter: DiagnosticReporter) { reporter.onCallArgument(argument, this) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt index 49575725bd4..31ee44b360a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt @@ -166,8 +166,8 @@ class KotlinResolutionCandidate( } override fun addCompatibilityWarning(other: Candidate) { - if (this !== other) { - addDiagnostic(CompatibilityWarning()) + if (this !== other && other is KotlinResolutionCandidate) { + addDiagnostic(CompatibilityWarning(other.resolvedCall.candidateDescriptor)) } } diff --git a/idea/idea-analysis/resources/messages/KotlinIdeaAnalysisBundle.properties b/idea/idea-analysis/resources/messages/KotlinIdeaAnalysisBundle.properties index 526c3442309..e565b70f818 100644 --- a/idea/idea-analysis/resources/messages/KotlinIdeaAnalysisBundle.properties +++ b/idea/idea-analysis/resources/messages/KotlinIdeaAnalysisBundle.properties @@ -3,6 +3,7 @@ html.0.has.no.corresponding.expected.declaration.1.html={0} has no corresponding html.0.is.not.abstract.and.does.not.implement.abstract.base.class.member.br.1.html={0} is not abstract and does not implement abstract base class member
{1} html.0.is.not.abstract.and.does.not.implement.abstract.member.br.1.html={0} is not abstract and does not implement abstract member
{1} html.0.method.may.be.missing.none.of.the.following.functions.will.be.called.ul.1.ul.html=''{0}'' method may be missing. None of the following functions will be called:
    {1}
+html.candidate.resolution.will.be.changed.please.invoke.explicitly.ul.0.ul.html=Candidate resolution will be changed, please invoke explicitly:
    {0}
html.expected.0.has.no.actual.declaration.in.module.1.2.html=Expected {0} has no actual declaration in module {1}{2} html.accidental.override.0.html=Accidental override: {0} html.method.contains.from.concurrenthashmap.may.have.unexpected.semantics.it.calls.containsvalue.instead.of.containskey.br.use.explicit.form.of.the.call.to.containskey.containsvalue.contains.or.cast.the.value.to.kotlin.collections.map.instead.br.see.https.youtrack.jetbrains.com.issue.kt.18053.for.more.details.html=Method ''contains'' from ConcurrentHashMap may have unexpected semantics: it calls ''containsValue'' instead of ''containsKey''.
Use explicit form of the call to ''containsKey''/''containsValue''/''contains'' or cast the value to kotlin.collections.Map instead.
See https://youtrack.jetbrains.com/issue/KT-18053 for more details diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeErrorMessages.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeErrorMessages.java index 7209d13623f..8c1bbc2ce05 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeErrorMessages.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeErrorMessages.java @@ -170,6 +170,10 @@ public class IdeErrorMessages { KotlinIdeaAnalysisBundle.htmlMessage("html.0.method.may.be.missing.none.of.the.following.functions.will.be.called.ul.1.ul.html"), STRING, HTML_NONE_APPLICABLE_CALLS); + MAP.put(COMPATIBILITY_WARNING, + KotlinIdeaAnalysisBundle.htmlMessage("html.candidate.resolution.will.be.changed.please.invoke.explicitly.ul.0.ul.html"), + HTML_COMPATIBILITY_CANDIDATE); + MAP.put(CONFLICTING_JVM_DECLARATIONS, KotlinIdeaAnalysisBundle.htmlMessage("html.platform.declaration.clash.0.html"), HTML_CONFLICTING_JVM_DECLARATIONS_DATA); MAP.put(ACCIDENTAL_OVERRIDE, KotlinIdeaAnalysisBundle.htmlMessage("html.accidental.override.0.html"), HTML_CONFLICTING_JVM_DECLARATIONS_DATA); diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeRenderers.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeRenderers.kt index ff535df431f..459b038bf31 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeRenderers.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/IdeRenderers.kt @@ -24,6 +24,11 @@ object IdeRenderers { renderAmbiguousDescriptors(calls.map { it.resultingDescriptor }) } + @JvmField + val HTML_COMPATIBILITY_CANDIDATE = Renderer { call: CallableDescriptor -> + renderAmbiguousDescriptors(listOf(call)) + } + @JvmField val HTML_AMBIGUOUS_REFERENCES = Renderer { descriptors: Collection -> renderAmbiguousDescriptors(descriptors)