Repository: Kotlin/dokka (kotlin)

Issue:
[K2] Missing param tag for type parameter on implicit primary constructor
```
/** @param T a type */
class Foo<T>
```

With K1, the `documentation` on the `DFunction` for the implicit primary constructor of `Foo` is
`DocumentationNode(children=[Param(root=CustomDocTag(children=[P(children=[Text(body=a type, children=[], params={})], params={})], params={}, name=MARKDOWN_FILE), name=T)])`.

With K2, the `documentation` for the constructor `DFunction` is empty.

Possibly related to #3348?

Pull request description:
fix #4145

Patch:
diff --git a/dokka-subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt b/dokka-subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt
index f5ed2132e8..47984e5e31 100644
--- a/dokka-subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt
+++ b/dokka-subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/kdoc/KDocProvider.kt
@@ -89,6 +89,8 @@ internal fun KaSession.findKDoc(symbol: KaSymbol): KDocContent? {
         val containingClass = symbol.fakeOverrideOriginal.containingSymbol as? KaClassSymbol
         if (containingClass?.origin != KaSymbolOrigin.SOURCE) return null
         val kdoc = (containingClass.psi as? KtDeclaration)?.docComment ?: return null
+
+        // duplicates the logic of IDE's `lookupOwnedKDoc`
         val constructorSection = kdoc.findSectionByTag(KDocKnownTag.CONSTRUCTOR)
         if (constructorSection != null) {
             // if annotated with @constructor tag and the caret is on constructor definition,
@@ -98,6 +100,7 @@ internal fun KaSession.findKDoc(symbol: KaSymbol): KDocContent? {
             val paramSections = kdoc.findSectionsContainingTag(KDocKnownTag.PARAM)
             return KDocContent(constructorSection, paramSections)
         }
+        return KDocContent(kdoc.getDefaultSection(), kdoc.getAllSections())
     }
 
     // for generated function (e.g. `copy`) [KtSymbol.psi] is undefined (although actually returns a class psi), see test `data class kdocs over generated methods`


Test patch:
diff --git a/dokka-subprojects/plugin-base/src/test/kotlin/model/ConstructorsTest.kt b/dokka-subprojects/plugin-base/src/test/kotlin/model/ConstructorsTest.kt
index 22d40ae666..75ceba55b4 100644
--- a/dokka-subprojects/plugin-base/src/test/kotlin/model/ConstructorsTest.kt
+++ b/dokka-subprojects/plugin-base/src/test/kotlin/model/ConstructorsTest.kt
@@ -14,6 +14,46 @@ import utils.*
 
 class ConstructorsTest : AbstractModelTest("/src/main/kotlin/constructors/Test.kt", "constructors") {
 
+    @Test
+    fun `should have documentation for @param of type parameter on implicit primary constructor`() {
+        val expectedRootDescription = Description(
+            CustomDocTag(
+                emptyList(),
+                params = emptyMap(),
+                name = MARKDOWN_ELEMENT_FILE_NAME
+            )
+        )
+
+        val expectedParamTag = Param(
+            CustomDocTag(
+                listOf(
+                    P(
+                        listOf(
+                            Text("some doc"),
+                        )
+                    )
+                ),
+                params = emptyMap(),
+                name = MARKDOWN_ELEMENT_FILE_NAME
+            ),
+            name = "T"
+        )
+        inlineModelTest(
+            """
+               |/** 
+               |* @param T some doc 
+               |*/
+               |class Foo<T>
+            """.trimMargin()
+        ) {
+            val classlike = packages.flatMap { it.classlikes }.first() as DClass
+            classlike.name equals "Foo"
+            classlike.documentation.values.single() equals DocumentationNode(listOf(expectedRootDescription, expectedParamTag))
+            val constructor = classlike.constructors.single()
+            constructor.documentation.values.single() equals DocumentationNode(listOf(expectedParamTag))
+        }
+    }
+
     @Test
     fun `should have documentation for @constructor tag without parameters`() {
         val expectedRootDescription = Description(