Show documentation for a class if the constructor has no docs

#KT-17926 Fixed
This commit is contained in:
Norbert Nogacki
2020-06-25 14:41:28 +02:00
committed by Vladimir Dolzhenko
parent 699829ccb3
commit 990903e4e2
3 changed files with 44 additions and 11 deletions
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.idea package org.jetbrains.kotlin.idea
import com.google.common.html.HtmlEscapers import com.google.common.html.HtmlEscapers
import com.intellij.codeInsight.documentation.DocumentationManager
import com.intellij.codeInsight.documentation.DocumentationManagerUtil import com.intellij.codeInsight.documentation.DocumentationManagerUtil
import com.intellij.codeInsight.javadoc.JavaDocInfoGeneratorFactory import com.intellij.codeInsight.javadoc.JavaDocInfoGeneratorFactory
import com.intellij.lang.documentation.AbstractDocumentationProvider 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.appendKDocContent
import org.jetbrains.kotlin.idea.kdoc.KDocRenderer.appendKDocSections import org.jetbrains.kotlin.idea.kdoc.KDocRenderer.appendKDocSections
import org.jetbrains.kotlin.idea.kdoc.KDocTemplate.DescriptionBodyTemplate 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.resolveToDescriptors
import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
@@ -182,7 +180,10 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
defaultParameterValueRenderer = { (it.source.getPsi() as? KtParameter)?.defaultValue?.text ?: "..." } defaultParameterValueRenderer = { (it.source.getPsi() as? KtParameter)?.defaultValue?.text ?: "..." }
} }
fun StringBuilder.renderKDoc(contentTag: KDocTag, sections: List<KDocSection>) { private fun StringBuilder.renderKDoc(
contentTag: KDocTag,
sections: List<KDocSection> = if (contentTag is KDocSection) listOf(contentTag) else emptyList()
) {
insert(DescriptionBodyTemplate.Kotlin()) { insert(DescriptionBodyTemplate.Kotlin()) {
content { content {
appendKDocContent(contentTag) appendKDocContent(contentTag)
@@ -215,7 +216,7 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
} }
if (!quickNavigation && kdoc != null) { if (!quickNavigation && kdoc != null) {
description { description {
renderKDoc(kdoc.getDefaultSection(), listOf(kdoc.getDefaultSection())) renderKDoc(kdoc.getDefaultSection())
} }
} }
} }
@@ -312,10 +313,9 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
return mixKotlinToJava(declarationDescriptor, element, originalElement) 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 return null
} }
@@ -384,11 +384,22 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
if (!quickNavigation) { if (!quickNavigation) {
description { description {
val comment = declarationDescriptor.findKDoc { DescriptorToSourceUtilsIde.getAnyDeclaration(ktElement.project, it) } declarationDescriptor.findKDoc { DescriptorToSourceUtilsIde.getAnyDeclaration(ktElement.project, it) }?.let {
if (comment != null) { renderKDoc(it)
val sectionList = if (comment is KDocSection) listOf(comment) else emptyList() return@description
renderKDoc(comment, sectionList) }
} else if (declarationDescriptor is CallableDescriptor) { // If we couldn't find KDoc, try to find javadoc in one of super's 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()) { insert(DescriptionBodyTemplate.FromJava()) {
body = extractJavaDescription(declarationDescriptor) body = extractJavaDescription(declarationDescriptor)
} }
@@ -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<caret>(10)
}
//INFO: <div class='definition'><pre><a href="psi_element://Foo"><code>Foo</code></a><br>public constructor <b>Foo</b>(
//INFO: x: Int
//INFO: )</pre></div><div class='content'><p>Documentation is here.</p></div><table class='sections'></table>
@@ -158,6 +158,11 @@ public class QuickDocProviderTestGenerated extends AbstractQuickDocProviderTest
runTest("idea/testData/editor/quickDoc/OnClassDeclarationWithNoPackage.kt"); 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") @TestMetadata("OnEnumClassReference.kt")
public void testOnEnumClassReference() throws Exception { public void testOnEnumClassReference() throws Exception {
runTest("idea/testData/editor/quickDoc/OnEnumClassReference.kt"); runTest("idea/testData/editor/quickDoc/OnEnumClassReference.kt");