Improve NONE_APPLICABLE ide renderer

This commit is contained in:
Pavel V. Talanov
2016-02-25 11:35:36 +03:00
parent 8cbc9eee3e
commit e397544aee
7 changed files with 86 additions and 13 deletions
@@ -39,12 +39,13 @@ object IdeRenderers {
@JvmField val HTML_RENDER_TYPE = SmartTypeRenderer(DescriptorRenderer.HTML)
@JvmField val HTML_NONE_APPLICABLE_CALLS= Renderer {
@JvmField val HTML_NONE_APPLICABLE_CALLS = Renderer {
calls: Collection<ResolvedCall<*>> ->
val comparator = compareBy(MemberComparator.INSTANCE) { c: ResolvedCall<*> -> c.resultingDescriptor }
calls
val context = RenderingContext.Impl(calls.map { it.resultingDescriptor })
val comparator = compareBy(MemberComparator.INSTANCE) { c: ResolvedCall<*> -> c.resultingDescriptor }
calls
.sortedWith(comparator)
.joinToString("") { "<li>${renderResolvedCall(it)}</li>" }
.joinToString("") { "<li>${renderResolvedCall(it, context)}</li>" }
}
@JvmField val HTML_TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER = Renderer<InferenceErrorData> {
@@ -17,11 +17,13 @@
package org.jetbrains.kotlin.idea.highlighter.renderersUtil
import com.google.common.html.HtmlEscapers
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
import org.jetbrains.kotlin.diagnostics.rendering.SmartTypeRenderer
import org.jetbrains.kotlin.diagnostics.rendering.asRenderer
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.renderer.RenderingFormat
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.hasTypeMismatchErrorOnParameter
@@ -46,8 +48,9 @@ private val HTML_FOR_UNINFERRED_TYPE_PARAMS: DescriptorRenderer = DescriptorRend
textFormat = RenderingFormat.HTML
}
fun <D : CallableDescriptor> renderResolvedCall(resolvedCall: ResolvedCall<D>): String {
val htmlRenderer = HTML_FOR_UNINFERRED_TYPE_PARAMS
fun renderResolvedCall(resolvedCall: ResolvedCall<*>, context: RenderingContext): String {
val typeRenderer = SmartTypeRenderer(HTML_FOR_UNINFERRED_TYPE_PARAMS)
val descriptorRenderer = HTML_FOR_UNINFERRED_TYPE_PARAMS.asRenderer()
val stringBuilder = StringBuilder("")
val indent = "&nbsp;&nbsp;"
@@ -58,7 +61,7 @@ fun <D : CallableDescriptor> renderResolvedCall(resolvedCall: ResolvedCall<D>):
val parameterType = varargElementType ?: parameter.type
val renderedParameter =
(if (varargElementType != null) "<b>vararg</b> " else "") +
htmlRenderer.renderType(parameterType) +
typeRenderer.render(parameterType, context) +
if (parameter.hasDefaultValue()) " = ..." else ""
if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter)) {
return renderError(renderedParameter)
@@ -89,15 +92,15 @@ fun <D : CallableDescriptor> renderResolvedCall(resolvedCall: ResolvedCall<D>):
val typeParameterToTypeArgumentMap = resolvedCall.typeArguments
if (!inferredTypeParameters.isEmpty()) {
append(inferredTypeParameters.map { typeParameter ->
"${typeParameter.name} = ${htmlRenderer.renderType(typeParameterToTypeArgumentMap[typeParameter]!!)}"
}.joinToString())
"${typeParameter.name} = ${typeRenderer.render(typeParameterToTypeArgumentMap[typeParameter]!!, context)}"
}.joinToString())
}
}
val resultingDescriptor = resolvedCall.resultingDescriptor
val receiverParameter = resultingDescriptor.extensionReceiverParameter
if (receiverParameter != null) {
append(htmlRenderer.renderType(receiverParameter.type)).append(".")
append(typeRenderer.render(receiverParameter.type, context)).append(".")
}
append(HtmlEscapers.htmlEscaper().escape(resultingDescriptor.name.asString())).append("(")
append(resultingDescriptor.valueParameters.map { parameter -> renderParameter(parameter) }.joinToString())
@@ -106,7 +109,8 @@ fun <D : CallableDescriptor> renderResolvedCall(resolvedCall: ResolvedCall<D>):
if (!resolvedCall.candidateDescriptor.typeParameters.isEmpty()) {
appendTypeParametersSubstitution()
append("<i> for </i><br/>$indent")
append(htmlRenderer.render(resolvedCall.candidateDescriptor))
// candidate descriptor is not in context of the rest of the message
append(descriptorRenderer.render(resolvedCall.candidateDescriptor, RenderingContext.of(resolvedCall.candidateDescriptor)))
}
else {
append(" <i>defined in</i> ")
+21
View File
@@ -0,0 +1,21 @@
// !DIAGNOSTICS_NUMBER: 1
// !DIAGNOSTICS: NONE_APPLICABLE
// !MESSAGE_TYPE: HTML
package a.b
fun foo(a: kotlin.String) {
}
fun foo(b: String) {
}
fun foo(i: Int) {
}
class String
val c = foo(1, 2)
@@ -0,0 +1,9 @@
<!-- noneApplicableHtml1 -->
<html>
None of the following functions can be called with the arguments supplied.
<ul>
<li>foo(<font color=red><b>a.b.String</b></font><font color=red><b>)</b></font> <i>defined in</i> a.b</li>
<li>foo(Int<font color=red><b>)</b></font> <i>defined in</i> a.b</li>
<li>foo(<font color=red><b>kotlin.String</b></font><font color=red><b>)</b></font> <i>defined in</i> a.b</li>
</ul>
</html>
+21
View File
@@ -0,0 +1,21 @@
// !DIAGNOSTICS_NUMBER: 1
// !DIAGNOSTICS: NONE_APPLICABLE
// !MESSAGE_TYPE: TEXT
package a.b
fun foo(a: kotlin.String) {
}
fun foo(b: String) {
}
fun foo(i: Int) {
}
class String
val c = foo(1, 2)
@@ -0,0 +1,5 @@
<!-- noneApplicableTxt1 -->
None of the following functions can be called with the arguments supplied:
public fun foo(b: a.b.String): Unit defined in a.b
public fun foo(i: Int): Unit defined in a.b
public fun foo(a: kotlin.String): Unit defined in a.b
@@ -173,6 +173,18 @@ public class DiagnosticMessageTestGenerated extends AbstractDiagnosticMessageTes
doTest(fileName);
}
@TestMetadata("noneApplicableHtml.kt")
public void testNoneApplicableHtml() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/noneApplicableHtml.kt");
doTest(fileName);
}
@TestMetadata("noneApplicableTxt.kt")
public void testNoneApplicableTxt() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/noneApplicableTxt.kt");
doTest(fileName);
}
@TestMetadata("numberValueTypes.kt")
public void testNumberValueTypes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/diagnosticMessage/numberValueTypes.kt");