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 8762e3bd219..7c05170dcdd 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 @@ -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> -> - 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("") { "
  • ${renderResolvedCall(it)}
  • " } + .joinToString("") { "
  • ${renderResolvedCall(it, context)}
  • " } } @JvmField val HTML_TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS_RENDERER = Renderer { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/renderersUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/renderersUtil.kt index 0fd72e63a93..b14db3c8656 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/renderersUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/renderersUtil.kt @@ -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 renderResolvedCall(resolvedCall: ResolvedCall): 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 = "  " @@ -58,7 +61,7 @@ fun renderResolvedCall(resolvedCall: ResolvedCall): val parameterType = varargElementType ?: parameter.type val renderedParameter = (if (varargElementType != null) "vararg " else "") + - htmlRenderer.renderType(parameterType) + + typeRenderer.render(parameterType, context) + if (parameter.hasDefaultValue()) " = ..." else "" if (resolvedCall.hasTypeMismatchErrorOnParameter(parameter)) { return renderError(renderedParameter) @@ -89,15 +92,15 @@ fun renderResolvedCall(resolvedCall: ResolvedCall): 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 renderResolvedCall(resolvedCall: ResolvedCall): if (!resolvedCall.candidateDescriptor.typeParameters.isEmpty()) { appendTypeParametersSubstitution() append(" for
    $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(" defined in ") diff --git a/idea/testData/diagnosticMessage/noneApplicableHtml.kt b/idea/testData/diagnosticMessage/noneApplicableHtml.kt new file mode 100644 index 00000000000..a332073813e --- /dev/null +++ b/idea/testData/diagnosticMessage/noneApplicableHtml.kt @@ -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) \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/noneApplicableHtml1.html b/idea/testData/diagnosticMessage/noneApplicableHtml1.html new file mode 100644 index 00000000000..c6414af2b56 --- /dev/null +++ b/idea/testData/diagnosticMessage/noneApplicableHtml1.html @@ -0,0 +1,9 @@ + + +None of the following functions can be called with the arguments supplied. +
      +
    • foo(a.b.String) defined in a.b
    • +
    • foo(Int) defined in a.b
    • +
    • foo(kotlin.String) defined in a.b
    • +
    + \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/noneApplicableTxt.kt b/idea/testData/diagnosticMessage/noneApplicableTxt.kt new file mode 100644 index 00000000000..ba4b68eb313 --- /dev/null +++ b/idea/testData/diagnosticMessage/noneApplicableTxt.kt @@ -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) \ No newline at end of file diff --git a/idea/testData/diagnosticMessage/noneApplicableTxt1.txt b/idea/testData/diagnosticMessage/noneApplicableTxt1.txt new file mode 100644 index 00000000000..3ceb80f3e78 --- /dev/null +++ b/idea/testData/diagnosticMessage/noneApplicableTxt1.txt @@ -0,0 +1,5 @@ + +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 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java index 815f211dfa6..a55c985c5dc 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/highlighter/DiagnosticMessageTestGenerated.java @@ -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");