aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Aman <maman@virtuslab.com>2020-05-07 17:10:10 +0200
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-05-19 13:47:03 +0200
commit3aeb65472be150a6098f2fac17dbdf0bb2a40013 (patch)
tree03540fe12ce6b139fbb7658a2d57d0e97023721c
parente9d7fc75b46bb44f2c946b8cbb0636deb71e20dc (diff)
downloaddokka-3aeb65472be150a6098f2fac17dbdf0bb2a40013.tar.gz
dokka-3aeb65472be150a6098f2fac17dbdf0bb2a40013.tar.bz2
dokka-3aeb65472be150a6098f2fac17dbdf0bb2a40013.zip
Missing generics on class. Add generics to annotation #834
-rw-r--r--core/src/main/kotlin/links/DRI.kt71
-rw-r--r--core/src/main/kotlin/model/Documentable.kt5
-rw-r--r--plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt16
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt3
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt1
-rw-r--r--plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt21
-rw-r--r--plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt10
-rw-r--r--plugins/base/src/test/kotlin/basic/DRITest.kt118
-rw-r--r--plugins/base/src/test/kotlin/markdown/LinkTest.kt36
-rw-r--r--plugins/base/src/test/kotlin/model/ClassesTest.kt27
-rw-r--r--plugins/base/src/test/kotlin/model/JavaTest.kt1
-rw-r--r--plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt7
-rw-r--r--plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt2
13 files changed, 271 insertions, 47 deletions
diff --git a/core/src/main/kotlin/links/DRI.kt b/core/src/main/kotlin/links/DRI.kt
index 3d9012ec..1c823d92 100644
--- a/core/src/main/kotlin/links/DRI.kt
+++ b/core/src/main/kotlin/links/DRI.kt
@@ -1,9 +1,6 @@
package org.jetbrains.dokka.links
-import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiMethod
-import com.intellij.psi.PsiParameter
+import com.intellij.psi.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -20,17 +17,15 @@ data class DRI(
val packageName: String? = null,
val classNames: String? = null,
val callable: Callable? = null,
- val target: Int? = null,
- val genericTarget: Int? = null,
+ val target: DriTarget = PointingToDeclaration,
val extra: String? = null
) {
override fun toString(): String =
- "${packageName.orEmpty()}/${classNames.orEmpty()}/${callable?.name.orEmpty()}/${callable?.signature().orEmpty()}/${target?.toString().orEmpty()}/${extra.orEmpty()}"
+ "${packageName.orEmpty()}/${classNames.orEmpty()}/${callable?.name.orEmpty()}/${callable?.signature().orEmpty()}/$target/${extra.orEmpty()}"
companion object {
fun from(descriptor: DeclarationDescriptor) = descriptor.parentsWithSelf.run {
val callable = firstIsInstanceOrNull<CallableDescriptor>()
- val params = callable?.let { listOfNotNull(it.extensionReceiverParameter) + it.valueParameters }.orEmpty()
DRI(
firstIsInstanceOrNull<PackageFragmentDescriptor>()?.fqName?.asString(),
(filterIsInstance<ClassDescriptor>() + filterIsInstance<TypeAliasDescriptor>()).toList()
@@ -38,20 +33,18 @@ data class DRI(
?.asReversed()
?.joinToString(separator = ".") { it.name.asString() },
callable?.let { Callable.from(it) },
- firstIsInstanceOrNull<ParameterDescriptor>()?.let { params.indexOf(it) },
- null
+ DriTarget.from(descriptor)
)
}
fun from(psi: PsiElement) = psi.parentsWithSelf.run {
val callable = firstIsInstanceOrNull<PsiMethod>()
- val params = (callable?.parameterList?.parameters).orEmpty()
val classes = filterIsInstance<PsiClass>().toList()
DRI(
classes.lastOrNull()?.qualifiedName?.substringBeforeLast('.', ""),
classes.toList().takeIf { it.isNotEmpty() }?.asReversed()?.mapNotNull { it.name }?.joinToString("."),
callable?.let { Callable.from(it) },
- firstIsInstanceOrNull<PsiParameter>()?.let { params.indexOf(it) }
+ DriTarget.from(psi)
)
}
val topLevel = DRI()
@@ -63,11 +56,12 @@ val DriOfAny = DRI("kotlin", "Any")
fun DRI.withClass(name: String) = copy(classNames = if (classNames.isNullOrBlank()) name else "$classNames.$name")
+fun DRI.withTargetToDeclaration() = copy(target = PointingToDeclaration)
+
val DRI.parent: DRI
get() = when {
extra != null -> copy(extra = null)
- genericTarget != null -> copy(genericTarget = null)
- target != null -> copy(target = null)
+ target != PointingToDeclaration -> copy(target = PointingToDeclaration)
callable != null -> copy(callable = null)
classNames != null -> copy(classNames = classNames.substringBeforeLast(".", "").takeIf { it.isNotBlank() })
else -> DRI.topLevel
@@ -167,8 +161,53 @@ object StarProjection : TypeReference() {
override fun toString() = "*"
}
-private operator fun <T> List<T>.component6(): T = get(5)
-
private val KotlinType.constructorName
get() = constructor.declarationDescriptor?.fqNameSafe?.asString()
+sealed class DriTarget {
+ override fun toString(): String = this.javaClass.simpleName
+
+ companion object {
+ fun from(descriptor: DeclarationDescriptor): DriTarget = descriptor.parentsWithSelf.run {
+ return when(descriptor){
+ is TypeParameterDescriptor -> PointingToGenericParameters(descriptor.index)
+ else -> {
+ val callable = firstIsInstanceOrNull<CallableDescriptor>()
+ val params = callable?.let { listOfNotNull(it.extensionReceiverParameter) + it.valueParameters }.orEmpty()
+ val parameterDescriptor = firstIsInstanceOrNull<ParameterDescriptor>()
+
+ parameterDescriptor?.let { PointingToCallableParameters(params.indexOf(it)) }
+ ?: PointingToDeclaration
+ }
+ }
+ }
+
+ fun from(psi: PsiElement): DriTarget = psi.parentsWithSelf.run {
+ return when(psi) {
+ is PsiTypeParameter -> PointingToGenericParameters(psi.index)
+ else -> firstIsInstanceOrNull<PsiParameter>()?.let {
+ val callable = firstIsInstanceOrNull<PsiMethod>()
+ val params = (callable?.parameterList?.parameters).orEmpty()
+ PointingToCallableParameters(params.indexOf(it))
+ } ?: PointingToDeclaration
+ }
+ }
+ }
+}
+
+data class PointingToGenericParameters(val parameterIndex: Int) : DriTarget() {
+ override fun toString(): String = "PointingToGenericParameters($parameterIndex)"
+}
+
+object PointingToDeclaration: DriTarget()
+
+data class PointingToCallableParameters(val parameterIndex: Int): DriTarget(){
+ override fun toString(): String = "PointingToCallableParameters($parameterIndex)"
+}
+
+fun DriTarget.nextTarget(): DriTarget = when(this){
+ is PointingToGenericParameters -> PointingToGenericParameters(this.parameterIndex+1)
+ is PointingToCallableParameters -> PointingToCallableParameters(this.parameterIndex+1)
+ else -> this
+ }
+
diff --git a/core/src/main/kotlin/model/Documentable.kt b/core/src/main/kotlin/model/Documentable.kt
index 85487725..9f17638c 100644
--- a/core/src/main/kotlin/model/Documentable.kt
+++ b/core/src/main/kotlin/model/Documentable.kt
@@ -263,9 +263,10 @@ data class DAnnotation(
override val visibility: SourceSetDependent<Visibility>,
override val companion: DObject?,
override val constructors: List<DFunction>,
+ override val generics: List<DTypeParameter>,
override val sourceSets: List<SourceSetData>,
override val extra: PropertyContainer<DAnnotation> = PropertyContainer.empty()
-) : DClasslike(), WithCompanion, WithConstructors, WithExtraProperties<DAnnotation> {
+) : DClasslike(), WithCompanion, WithConstructors, WithExtraProperties<DAnnotation>, WithGenerics {
override val children: List<Documentable>
get() = (functions + properties + classlikes + constructors) as List<Documentable>
@@ -344,7 +345,7 @@ data class DTypeAlias(
sealed class Projection
sealed class Bound : Projection()
-data class OtherParameter(val name: String) : Bound()
+data class OtherParameter(val declarationDRI: DRI, val name: String) : Bound()
object Star : Projection()
data class TypeConstructor(
val dri: DRI,
diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
index 3836f45d..617af959 100644
--- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
+++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
@@ -2,11 +2,10 @@ package org.jetbrains.dokka.base.signatures
import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.links.DriOfAny
-import org.jetbrains.dokka.links.DriOfUnit
-import org.jetbrains.dokka.links.sureClassNames
+import org.jetbrains.dokka.links.*
import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.Nullable
+import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.pages.ContentKind
import org.jetbrains.dokka.pages.ContentNode
@@ -71,6 +70,11 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
is DAnnotation -> text("annotation class ")
}
link(c.name!!, c.dri)
+ if(c is WithGenerics){
+ list(c.generics, prefix = "<", suffix = "> ") {
+ +buildSignature(it)
+ }
+ }
if (c is DClass) {
val pConstructor = c.constructors.singleOrNull { it.extra[PrimaryConstructorExtra] != null }
list(pConstructor?.parameters.orEmpty(), "(", ")", ",", pConstructor?.sourceSets.orEmpty().toSet()) {
@@ -158,7 +162,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
}
private fun signature(t: DTypeParameter) = contentBuilder.contentFor(t) {
- link(t.name, t.dri)
+ link(t.name, t.dri.withTargetToDeclaration())
list(t.bounds, prefix = " : ") {
signatureForProjection(it)
}
@@ -166,7 +170,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
private fun PageContentBuilder.DocumentableContentBuilder.signatureForProjection(p: Projection): Unit =
when (p) {
- is OtherParameter -> text(p.name)
+ is OtherParameter -> link(p.name, p.declarationDRI)
is TypeConstructor -> if (p.function)
+funType(mainDRI.single(), mainPlatformData, p)
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
index 862f9240..1b8fa299 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DefaultDocumentableMerger.kt
@@ -175,7 +175,8 @@ fun DAnnotation.mergeWith(other: DAnnotation): DAnnotation = copy(
expectPresentInSet = expectPresentInSet ?: other.expectPresentInSet,
sources = sources+ other.sources,
visibility = visibility + other.visibility,
- sourceSets = sourceSets + other.sourceSets
+ sourceSets = sourceSets + other.sourceSets,
+ generics = merge(generics + other.generics, DTypeParameter::mergeWith)
).mergeExtras(this, other)
fun DParameter.mergeWith(other: DParameter): DParameter = copy(
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt
index 6fdce3a8..d15ec791 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/DocumentableVisibilityFilter.kt
@@ -265,6 +265,7 @@ internal class DocumentableVisibilityFilter(val context: DokkaContext) : PreMerg
visibility.filtered(filteredPlatforms),
companion,
constructors,
+ generics,
filteredPlatforms,
extra
)
diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
index 7cc96a24..a62d9a0b 100644
--- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
@@ -1,10 +1,11 @@
package org.jetbrains.dokka.base.translators.descriptors
import org.jetbrains.dokka.analysis.DokkaResolutionFacade
+import org.jetbrains.dokka.links.*
import org.jetbrains.dokka.links.Callable
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.links.withClass
import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.Nullable
+import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.doc.*
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.parsers.MarkdownParser
@@ -127,7 +128,7 @@ private class DokkaDescriptorVisitor(
visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(),
supertypes = info.supertypes.toSourceSetDependent(),
documentation = info.docs,
- generics = descriptor.typeConstructor.parameters.map { it.toTypeParameter() },
+ generics = descriptor.declaredTypeParameters.map { it.toTypeParameter() },
companion = descriptor.companion(driWithPlatform),
sourceSets = listOf(sourceSet),
extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations())
@@ -216,6 +217,7 @@ private class DokkaDescriptorVisitor(
extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()),
companion = descriptor.companionObjectDescriptor?.let { objectDescriptor(it, driWithPlatform) },
visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(),
+ generics = descriptor.declaredTypeParameters.map { it.toTypeParameter() },
constructors = descriptor.constructors.map { visitConstructorDescriptor(it, driWithPlatform) },
sources = descriptor.createSources()
)
@@ -245,7 +247,7 @@ private class DokkaDescriptorVisitor(
expectPresentInSet = sourceSet.takeIf { isExpect },
visibility = descriptor.visibility.toDokkaVisibility().toSourceSetDependent(),
supertypes = info.supertypes.toSourceSetDependent(),
- generics = descriptor.typeConstructor.parameters.map { it.toTypeParameter() },
+ generics = descriptor.declaredTypeParameters.map { it.toTypeParameter() },
documentation = info.docs,
modifier = descriptor.modifier().toSourceSetDependent(),
companion = descriptor.companion(driWithPlatform),
@@ -364,7 +366,7 @@ private class DokkaDescriptorVisitor(
descriptor: ReceiverParameterDescriptor,
parent: DRIWithPlatformInfo
) = DParameter(
- dri = parent.dri.copy(target = 0),
+ dri = parent.dri.copy(target = PointingToDeclaration),
name = null,
type = descriptor.type.toBound(),
expectPresentInSet = null,
@@ -383,7 +385,7 @@ private class DokkaDescriptorVisitor(
fun PropertyDescriptor.asParameter(parent: DRI) =
DParameter(
- parent.copy(target = 1),
+ parent.copy(target = PointingToCallableParameters(parameterIndex = 1)),
this.name.asString(),
type = this.type.toBound(),
expectPresentInSet = sourceSet.takeIf { isExpect },
@@ -444,7 +446,7 @@ private class DokkaDescriptorVisitor(
private fun parameter(index: Int, descriptor: ValueParameterDescriptor, parent: DRIWithPlatformInfo) =
DParameter(
- dri = parent.dri.copy(target = index + 1),
+ dri = parent.dri.copy(target = PointingToCallableParameters(index)),
name = descriptor.name.asString(),
type = descriptor.type.toBound(),
expectPresentInSet = null,
@@ -518,7 +520,10 @@ private class DokkaDescriptorVisitor(
)
private fun KotlinType.toBound(): Bound = when (val ctor = constructor.declarationDescriptor) {
- is TypeParameterDescriptor -> OtherParameter(ctor.name.asString()).let {
+ is TypeParameterDescriptor -> OtherParameter(
+ declarationDRI = DRI.from(ctor.containingDeclaration),
+ name = ctor.name.asString()
+ ).let {
if (isMarkedNullable) Nullable(it) else it
}
else -> TypeConstructor(
diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
index ca8055c8..ab4a84f6 100644
--- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
@@ -6,6 +6,7 @@ import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiClassReferenceType
import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.links.nextTarget
import org.jetbrains.dokka.links.withClass
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.properties.PropertyContainer
@@ -159,6 +160,7 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
visibility,
null,
constructors.map { parseFunction(it, true) },
+ mapTypeParameters(dri),
listOf(sourceSetData),
PropertyContainer.empty<DAnnotation>() + annotations.toList().toExtra()
)
@@ -238,9 +240,9 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
dri,
if (isConstructor) "<init>" else psi.name,
isConstructor,
- psi.parameterList.parameters.mapIndexed { index, psiParameter ->
+ psi.parameterList.parameters.map { psiParameter ->
DParameter(
- dri.copy(target = index + 1),
+ dri.copy(target = dri.target.nextTarget()),
psiParameter.name,
javadocParser.parseDocumentation(psiParameter).toPlatformDependant(),
null,
@@ -321,9 +323,9 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
if (bounds.isEmpty()) emptyList() else bounds.mapNotNull {
(it as? PsiClassType)?.let { classType -> Nullable(getBound(classType)) }
}
- return typeParameters.mapIndexed { index, type ->
+ return typeParameters.map { type ->
DTypeParameter(
- dri.copy(genericTarget = index),
+ dri.copy(target = dri.target.nextTarget()),
type.name.orEmpty(),
javadocParser.parseDocumentation(type).toPlatformDependant(),
null,
diff --git a/plugins/base/src/test/kotlin/basic/DRITest.kt b/plugins/base/src/test/kotlin/basic/DRITest.kt
index e85ca30e..1ac05177 100644
--- a/plugins/base/src/test/kotlin/basic/DRITest.kt
+++ b/plugins/base/src/test/kotlin/basic/DRITest.kt
@@ -1,8 +1,10 @@
package basic
import org.jetbrains.dokka.links.*
-import org.jetbrains.dokka.pages.ContentPage
-import org.jetbrains.dokka.pages.asSequence
+import org.jetbrains.dokka.model.DClass
+import org.jetbrains.dokka.model.DFunction
+import org.jetbrains.dokka.model.DParameter
+import org.jetbrains.dokka.pages.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
@@ -131,7 +133,7 @@ class DRITest : AbstractCoreTest() {
configuration
) {
pagesGenerationStage = { module ->
- // DRI(//qux/Foo[TypeParam(bounds=[kotlin.Comparable[kotlin.Any?]]),*]#//)
+ // DRI(//qux/Foo[TypeParam(bounds=[kotlin.Comparable[kotlin.Any?]]),*]#/PointingToFunctionOrClasslike/)
val expectedDRI = DRI(
"",
null,
@@ -163,4 +165,114 @@ class DRITest : AbstractCoreTest() {
}
}
}
+
+ @Test
+ fun driForGenericClass(){
+ val configuration = dokkaConfiguration {
+ passes {
+ pass {
+ sourceRoots = listOf("src/")
+ }
+ }
+ }
+ testInline(
+ """
+ |/src/main/kotlin/Test.kt
+ |package example
+ |
+ |class Sample<S>(first: S){ }
+ |
+ |
+ """.trimMargin(),
+ configuration
+ ) {
+ pagesGenerationStage = { module ->
+ val sampleClass = module.dfs { it.name == "Sample" } as ClasslikePageNode
+ val classDocumentable = sampleClass.documentable as DClass
+
+ assertEquals( "example/Sample///PointingToDeclaration/", sampleClass.dri.first().toString())
+ assertEquals("example/Sample///PointingToGenericParameters(0)/", classDocumentable.generics.first().dri.toString())
+ }
+ }
+ }
+
+ @Test
+ fun driForGenericFunction(){
+ val configuration = dokkaConfiguration {
+ passes {
+ pass {
+ sourceRoots = listOf("src/")
+ classpath = listOfNotNull(jvmStdlibPath)
+ }
+ }
+ }
+ testInline(
+ """
+ |/src/main/kotlin/Test.kt
+ |package example
+ |
+ |class Sample<S>(first: S){
+ | fun <T> genericFun(param1: String): Triple<S,T> = TODO()
+ |}
+ |
+ |
+ """.trimMargin(),
+ configuration
+ ) {
+ pagesGenerationStage = { module ->
+ val sampleClass = module.dfs { it.name == "Sample" } as ClasslikePageNode
+ val functionNode = sampleClass.children.first { it.name == "genericFun" } as MemberPageNode
+ val functionDocumentable = functionNode.documentable as DFunction
+ val parameter = functionDocumentable.parameters.first()
+
+ assertEquals("example/Sample/genericFun/#kotlin.String/PointingToDeclaration/", functionNode.dri.first().toString())
+
+ assertEquals(1, functionDocumentable.parameters.size)
+ assertEquals("example/Sample/genericFun/#kotlin.String/PointingToCallableParameters(0)/", parameter.dri.toString())
+ //1 since from the function's perspective there is only 1 new generic declared
+ //The other one is 'inherited' from class
+ assertEquals( 1, functionDocumentable.generics.size)
+ assertEquals( "T", functionDocumentable.generics.first().name)
+ assertEquals( "example/Sample/genericFun/#kotlin.String/PointingToGenericParameters(0)/", functionDocumentable.generics.first().dri.toString())
+ }
+ }
+ }
+
+ @Test
+ fun driForGenericExtensionFunction(){
+ val configuration = dokkaConfiguration {
+ passes {
+ pass {
+ sourceRoots = listOf("src/")
+ }
+ }
+ }
+ testInline(
+ """
+ |/src/main/kotlin/Test.kt
+ |package example
+ |
+ | fun <T> List<T>.extensionFunction(): String = ""
+ |
+ """.trimMargin(),
+ configuration
+ ) {
+ pagesGenerationStage = { module ->
+ val extensionFunction = module.dfs { it.name == "extensionFunction" } as MemberPageNode
+ val documentable = extensionFunction.documentable as DFunction
+
+ assertEquals(
+ "example//extensionFunction/kotlin.collections.List[TypeParam(bounds=[kotlin.Any?])]#/PointingToDeclaration/",
+ extensionFunction.dri.first().toString()
+ )
+ assertEquals(1, documentable.generics.size)
+ assertEquals("T", documentable.generics.first().name)
+ assertEquals(
+ "example//extensionFunction/kotlin.collections.List[TypeParam(bounds=[kotlin.Any?])]#/PointingToGenericParameters(0)/",
+ documentable.generics.first().dri.toString()
+ )
+
+ }
+ }
+ }
}
diff --git a/plugins/base/src/test/kotlin/markdown/LinkTest.kt b/plugins/base/src/test/kotlin/markdown/LinkTest.kt
index d38486b5..bf234b6b 100644
--- a/plugins/base/src/test/kotlin/markdown/LinkTest.kt
+++ b/plugins/base/src/test/kotlin/markdown/LinkTest.kt
@@ -1,10 +1,12 @@
package markdown
+import org.jetbrains.dokka.pages.ClasslikePageNode
import org.jetbrains.dokka.pages.ContentDRILink
import org.jetbrains.dokka.pages.MemberPageNode
import org.jetbrains.dokka.pages.dfs
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
class LinkTest : AbstractCoreTest() {
@@ -36,11 +38,43 @@ class LinkTest : AbstractCoreTest() {
.dfs { node -> node is ContentDRILink }
.let {
assertEquals(
- "parser//test/#java.lang.ClassLoader//",
+ "parser//test/#java.lang.ClassLoader/PointingToDeclaration/",
(it as ContentDRILink).address.toString()
)
}
}
}
}
+
+ @Test
+ fun returnTypeShouldHaveLinkToOuterClassFromInner() {
+ val configuration = dokkaConfiguration {
+ passes {
+ pass {
+ sourceRoots = listOf("src/main/kotlin/parser")
+ }
+ }
+ }
+ testInline(
+ """
+ |/src/main/kotlin/parser/Test.kt
+ |package parser
+ |
+ |class Outer<OUTER> {
+ | inner class Inner<INNER> {
+ | fun foo(): OUTER = TODO()
+ | }
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ renderingStage = { rootPageNode, _ ->
+ val root = rootPageNode.children.single().children.single() as ClasslikePageNode
+ val innerClass = root.children.first { it is ClasslikePageNode }
+ val foo = innerClass.children.first { it.name == "foo" } as MemberPageNode
+
+ assertNotNull(foo.content.dfs { it is ContentDRILink && it.address.toString() == "parser/Outer///PointingToDeclaration/" } )
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/base/src/test/kotlin/model/ClassesTest.kt b/plugins/base/src/test/kotlin/model/ClassesTest.kt
index a349e54a..ea0d93ed 100644
--- a/plugins/base/src/test/kotlin/model/ClassesTest.kt
+++ b/plugins/base/src/test/kotlin/model/ClassesTest.kt
@@ -425,7 +425,7 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
) {
with((this / "classes" / "Foo").cast<DClass>()) {
with(extra[Annotations]?.content?.firstOrNull().assertNotNull("annotations")) {
- dri.toString() equals "kotlin/Suppress////"
+ dri.toString() equals "kotlin/Suppress///PointingToDeclaration/"
with(params["names"].assertNotNull("param")) {
this equals "[\"abc\"]"
}
@@ -459,4 +459,29 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
}
}
}
+
+ @Test fun genericAnnotationClass() {
+ inlineModelTest(
+ """annotation class Foo<A,B,C,D:Number>() {}"""
+ ) {
+ with((this / "classes" / "Foo").cast<DAnnotation>()){
+ generics.map { it.name to it.bounds.first().name } equals listOf("A" to "Any", "B" to "Any", "C" to "Any", "D" to "Number")
+ }
+ }
+ }
+
+ @Test fun nestedGenericClasses(){
+ inlineModelTest(
+ """
+ |class Outer<OUTER> {
+ | inner class Inner<INNER, T : OUTER> { }
+ |}
+ """.trimMargin()
+ ){
+ with((this / "classes" / "Outer").cast<DClass>()){
+ val inner = classlikes.single().cast<DClass>()
+ inner.generics.map { it.name to it.bounds.first().name } equals listOf("INNER" to "Any", "T" to "OUTER")
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/base/src/test/kotlin/model/JavaTest.kt b/plugins/base/src/test/kotlin/model/JavaTest.kt
index a58b380c..76924f0f 100644
--- a/plugins/base/src/test/kotlin/model/JavaTest.kt
+++ b/plugins/base/src/test/kotlin/model/JavaTest.kt
@@ -394,7 +394,6 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") {
}
}
- @Disabled("reenable after fixing subtypes")
@Test
fun inheritorLinks() {
inlineModelTest(
diff --git a/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt b/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt
index 5a77016d..8d9ac20d 100644
--- a/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt
+++ b/plugins/kotlin-as-java/src/main/kotlin/converters/KotlinToJavaConverter.kt
@@ -1,12 +1,13 @@
package org.jetbrains.dokka.kotlinAsJava.converters
+import org.jetbrains.dokka.links.*
import org.jetbrains.dokka.links.Callable
-import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.links.withClass
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.DAnnotation
import org.jetbrains.dokka.model.DEnum
import org.jetbrains.dokka.model.DFunction
+import org.jetbrains.dokka.model.Nullable
+import org.jetbrains.dokka.model.TypeConstructor
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.name.ClassId
@@ -243,7 +244,7 @@ internal fun ClassId.toDRI(dri: DRI?): DRI = DRI(
classNames = classNames(),
callable = dri?.callable,//?.asJava(), TODO: check this
extra = null,
- target = null
+ target = PointingToDeclaration
)
private fun PropertyContainer<out Documentable>.mergeAdditionalModifiers(second: Set<ExtraModifiers>) =
diff --git a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt
index d737cedb..9135d36e 100644
--- a/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt
+++ b/plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt
@@ -92,7 +92,7 @@ class JavaSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogge
private fun PageContentBuilder.DocumentableContentBuilder.signatureForProjection(p: Projection): Unit = when (p) {
- is OtherParameter -> text(p.name)
+ is OtherParameter -> link(p.name, p.declarationDRI)
is TypeConstructor -> group {
link(p.dri.classNames.orEmpty(), p.dri)