Introduce HTML redenred version for compatibility warning

This commit is contained in:
Mikhail Zarechenskiy
2020-06-01 10:00:48 +03:00
parent 569b6eaff2
commit 7ec8716d65
11 changed files with 40 additions and 12 deletions
@@ -761,7 +761,7 @@ public interface Errors {
DiagnosticFactory1<PsiElement, KotlinType> REIFIED_TYPE_UNSAFE_SUBSTITUTION = DiagnosticFactory1.create(WARNING);
DiagnosticFactory0<KtElement> CANDIDATE_CHOSEN_USING_OVERLOAD_RESOLUTION_BY_LAMBDA_ANNOTATION = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<KtElement> COMPATIBILITY_WARNING = DiagnosticFactory0.create(WARNING);
DiagnosticFactory1<KtElement, CallableDescriptor> COMPATIBILITY_WARNING = DiagnosticFactory1.create(WARNING);
DiagnosticFactory3<KtReferenceExpression, ClassifierDescriptor, WrongResolutionToClassifier, String> RESOLUTION_TO_CLASSIFIER =
DiagnosticFactory3.create(ERROR);
@@ -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");
@@ -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<CallableDescriptor> ->
renderAmbiguousDescriptors(references)
@@ -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
)
)
}
}
}
@@ -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))
}
}
@@ -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
}
@@ -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)
}
@@ -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))
}
}
@@ -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<br/>{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<br/>{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: <ul>{1}</ul>
html.candidate.resolution.will.be.changed.please.invoke.explicitly.ul.0.ul.html=Candidate resolution will be changed, please invoke explicitly: <ul>{0}</ul>
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''.<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
@@ -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);
@@ -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<CallableDescriptor> ->
renderAmbiguousDescriptors(descriptors)