From 990903e4e27ae61eefb903038480873d6157b918 Mon Sep 17 00:00:00 2001 From: Norbert Nogacki Date: Thu, 25 Jun 2020 14:41:28 +0200 Subject: [PATCH] Show documentation for a class if the constructor has no docs #KT-17926 Fixed --- .../idea/KotlinDocumentationProvider.kt | 33 ++++++++++++------- .../quickDoc/OnEmptySecondaryConstructor.kt | 17 ++++++++++ .../QuickDocProviderTestGenerated.java | 5 +++ 3 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 idea/testData/editor/quickDoc/OnEmptySecondaryConstructor.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt b/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt index 58547a75153..d6fb301b034 100644 --- a/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/KotlinDocumentationProvider.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.idea import com.google.common.html.HtmlEscapers -import com.intellij.codeInsight.documentation.DocumentationManager import com.intellij.codeInsight.documentation.DocumentationManagerUtil import com.intellij.codeInsight.javadoc.JavaDocInfoGeneratorFactory import com.intellij.lang.documentation.AbstractDocumentationProvider @@ -33,7 +32,6 @@ import org.jetbrains.kotlin.idea.kdoc.* import org.jetbrains.kotlin.idea.kdoc.KDocRenderer.appendKDocContent import org.jetbrains.kotlin.idea.kdoc.KDocRenderer.appendKDocSections import org.jetbrains.kotlin.idea.kdoc.KDocTemplate.DescriptionBodyTemplate -import org.jetbrains.kotlin.idea.references.KtDescriptorsBasedReference import org.jetbrains.kotlin.idea.references.resolveToDescriptors import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.resolve.ResolutionFacade @@ -182,7 +180,10 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider defaultParameterValueRenderer = { (it.source.getPsi() as? KtParameter)?.defaultValue?.text ?: "..." } } - fun StringBuilder.renderKDoc(contentTag: KDocTag, sections: List) { + private fun StringBuilder.renderKDoc( + contentTag: KDocTag, + sections: List = if (contentTag is KDocSection) listOf(contentTag) else emptyList() + ) { insert(DescriptionBodyTemplate.Kotlin()) { content { appendKDocContent(contentTag) @@ -215,7 +216,7 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider } if (!quickNavigation && kdoc != null) { description { - renderKDoc(kdoc.getDefaultSection(), listOf(kdoc.getDefaultSection())) + renderKDoc(kdoc.getDefaultSection()) } } } @@ -312,10 +313,9 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider return mixKotlinToJava(declarationDescriptor, element, originalElement) } } - } else { - // This element was resolved to non-kotlin element, it will be rendered with own provider } + // This element was resolved to non-kotlin element, it will be rendered with own provider return null } @@ -384,11 +384,22 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider if (!quickNavigation) { description { - val comment = declarationDescriptor.findKDoc { DescriptorToSourceUtilsIde.getAnyDeclaration(ktElement.project, it) } - if (comment != null) { - val sectionList = if (comment is KDocSection) listOf(comment) else emptyList() - renderKDoc(comment, sectionList) - } else if (declarationDescriptor is CallableDescriptor) { // If we couldn't find KDoc, try to find javadoc in one of super's + declarationDescriptor.findKDoc { DescriptorToSourceUtilsIde.getAnyDeclaration(ktElement.project, it) }?.let { + renderKDoc(it) + return@description + } + if (declarationDescriptor is ClassConstructorDescriptor && !declarationDescriptor.isPrimary) { + declarationDescriptor.constructedClass.findKDoc { + DescriptorToSourceUtilsIde.getAnyDeclaration( + ktElement.project, + it + ) + }?.let { + renderKDoc(it) + return@description + } + } + if (declarationDescriptor is CallableDescriptor) { // If we couldn't find KDoc, try to find javadoc in one of super's insert(DescriptionBodyTemplate.FromJava()) { body = extractJavaDescription(declarationDescriptor) } diff --git a/idea/testData/editor/quickDoc/OnEmptySecondaryConstructor.kt b/idea/testData/editor/quickDoc/OnEmptySecondaryConstructor.kt new file mode 100644 index 00000000000..f957bca0579 --- /dev/null +++ b/idea/testData/editor/quickDoc/OnEmptySecondaryConstructor.kt @@ -0,0 +1,17 @@ +/** +Documentation is here. + */ +class Foo { + private var x: Int = 0 + + constructor(x: Int) { + this.x = x + } //secondary constructor without documentation +} + +fun test() { + val f = Foo(10) +} +//INFO:
Foo
public constructor Foo( +//INFO: x: Int +//INFO: )

Documentation is here.

diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java index acc30f72095..644745482b1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java @@ -158,6 +158,11 @@ public class QuickDocProviderTestGenerated extends AbstractQuickDocProviderTest runTest("idea/testData/editor/quickDoc/OnClassDeclarationWithNoPackage.kt"); } + @TestMetadata("OnEmptySecondaryConstructor.kt") + public void testOnEmptySecondaryConstructor() throws Exception { + runTest("idea/testData/editor/quickDoc/OnEmptySecondaryConstructor.kt"); + } + @TestMetadata("OnEnumClassReference.kt") public void testOnEnumClassReference() throws Exception { runTest("idea/testData/editor/quickDoc/OnEnumClassReference.kt");