aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorMarcin Aman <marcin.aman@gmail.com>2020-06-18 12:00:46 +0200
committerBłażej Kardyś <bkardys@virtuslab.com>2020-06-23 02:57:40 +0200
commit0206be47827e5b072dac3deb9ccc1792ba95b13c (patch)
treee00704bbb2a872e64b575c5f11ade21551a86535 /plugins
parentef2db3b74d2653c2f84eda4d7058ffcb546dae1d (diff)
downloaddokka-0206be47827e5b072dac3deb9ccc1792ba95b13c.tar.gz
dokka-0206be47827e5b072dac3deb9ccc1792ba95b13c.tar.bz2
dokka-0206be47827e5b072dac3deb9ccc1792ba95b13c.zip
Javadoc classlikes and function pages
All implemented interfaces, first attempt at inherited methods
Diffstat (limited to 'plugins')
-rw-r--r--plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt43
-rw-r--r--plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt63
-rw-r--r--plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt51
-rw-r--r--plugins/base/src/test/kotlin/model/ClassesTest.kt19
-rw-r--r--plugins/base/src/test/kotlin/model/JavaTest.kt25
-rw-r--r--plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt2
-rw-r--r--plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt81
-rw-r--r--plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt114
-rw-r--r--plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocContentNodes.kt23
-rw-r--r--plugins/javadoc/src/main/kotlin/javadoc/pages/JavadocPageNodes.kt112
-rw-r--r--plugins/javadoc/src/main/kotlin/javadoc/pages/OverviewSummary.kt161
-rw-r--r--plugins/javadoc/src/main/resources/static_res/script.js139
-rw-r--r--plugins/javadoc/src/main/resources/views/class.korte274
-rw-r--r--plugins/kotlin-as-java/src/main/kotlin/signatures/JavaSignatureProvider.kt4
14 files changed, 874 insertions, 237 deletions
diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
index dfa7b480..4f292ca1 100644
--- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt
@@ -147,7 +147,8 @@ private class DokkaDescriptorVisitor(
sourceSets = setOf(sourceSet),
extra = PropertyContainer.withAll(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
- descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
+ descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
+ ImplementedInterfaces(info.interfaces)
)
)
}
@@ -173,7 +174,8 @@ private class DokkaDescriptorVisitor(
sourceSets = setOf(sourceSet),
extra = PropertyContainer.withAll(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
- descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
+ descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
+ ImplementedInterfaces(info.interfaces)
)
)
}
@@ -201,7 +203,8 @@ private class DokkaDescriptorVisitor(
sourceSets = setOf(sourceSet),
extra = PropertyContainer.withAll(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
- descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
+ descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
+ ImplementedInterfaces(info.interfaces)
)
)
}
@@ -284,7 +287,8 @@ private class DokkaDescriptorVisitor(
sourceSets = setOf(sourceSet),
extra = PropertyContainer.withAll(
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
- descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
+ descriptor.getAnnotations().toSourceSetDependent().toAnnotations(),
+ ImplementedInterfaces(info.interfaces)
)
)
}
@@ -322,14 +326,14 @@ private class DokkaDescriptorVisitor(
)
}
- fun CallableMemberDescriptor.createDRI(wasOverriden: Boolean = false): Pair<DRI, Boolean> =
+ fun CallableMemberDescriptor.createDRI(wasOverridenBy: DRI? = null): Pair<DRI, DRI?> =
if (kind == CallableMemberDescriptor.Kind.DECLARATION || overriddenDescriptors.isEmpty())
- Pair(DRI.from(this), wasOverriden)
+ Pair(DRI.from(this), wasOverridenBy)
else
- overriddenDescriptors.first().createDRI(true)
+ overriddenDescriptors.first().createDRI(DRI.from(this))
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, parent: DRIWithPlatformInfo): DFunction {
- val (dri, isInherited) = descriptor.createDRI()
+ val (dri, inheritedFrom) = descriptor.createDRI()
val isExpect = descriptor.isExpect
val actual = descriptor.createSources()
@@ -352,7 +356,7 @@ private class DokkaDescriptorVisitor(
type = descriptor.returnType!!.toBound(),
sourceSets = setOf(sourceSet),
extra = PropertyContainer.withAll(
- InheritedFunction(isInherited),
+ InheritedFunction(inheritedFrom),
descriptor.additionalExtras().toSourceSetDependent().toAdditionalModifiers(),
descriptor.getAnnotations().toSourceSetDependent().toAnnotations()
)
@@ -550,8 +554,17 @@ private class DokkaDescriptorVisitor(
getDocumentation()?.toSourceSetDependent() ?: emptyMap()
private fun ClassDescriptor.resolveClassDescriptionData(): ClassInfo {
+ val superClasses = hashSetOf<ClassDescriptor>()
+
+ fun processSuperClasses(supers: List<ClassDescriptor>) {
+ supers.forEach {
+ superClasses.add(it)
+ processSuperClasses(it.getSuperInterfaces() + it.getAllSuperclassesWithoutAny())
+ }
+ }
+ processSuperClasses(getSuperInterfaces() + getAllSuperclassesWithoutAny())
return ClassInfo(
- (getSuperInterfaces() + getAllSuperclassesWithoutAny()).map { DRI.from(it) },
+ superClasses.map { Supertype(DRI.from(it), it.kind == ClassKind.INTERFACE) }.toList(),
resolveDescriptorData()
)
}
@@ -726,7 +739,13 @@ private class DokkaDescriptorVisitor(
private fun ValueArgument.childrenAsText() = this.safeAs<KtValueArgument>()?.children?.map {it.text }.orEmpty()
- private data class ClassInfo(val supertypes: List<DRI>, val docs: SourceSetDependent<DocumentationNode>)
+ private data class ClassInfo(private val allSupertypes: List<Supertype>, val docs: SourceSetDependent<DocumentationNode>){
+ val supertypes: List<DRI>
+ get() = allSupertypes.map { it.dri }
+
+ val interfaces: List<DRI>
+ get() = allSupertypes.filter { it.isInterface }.map { it.dri }
+ }
private fun Visibility.toDokkaVisibility(): org.jetbrains.dokka.model.Visibility = when (this) {
Visibilities.PUBLIC -> KotlinVisibility.Public
@@ -740,6 +759,8 @@ private class DokkaDescriptorVisitor(
"${this.enumClassId.relativeClassName.asString()}.${this.enumEntryName.identifier}"
private fun fallbackPackageName(): String = "[${sourceSet.displayName} root]"// TODO: error-prone, find a better way to do it
+
+ private data class Supertype(val dri: DRI, val isInterface: Boolean)
}
private fun DRI.withPackageFallbackTo(fallbackPackage: String): DRI {
diff --git a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
index 6ec5c4f5..8b397859 100644
--- a/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
+++ b/plugins/base/src/main/kotlin/translators/psi/DefaultPsiToDocumentableTranslator.kt
@@ -1,18 +1,20 @@
package org.jetbrains.dokka.base.translators.psi
-import com.intellij.icons.AllIcons.Nodes.Static
-import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute
import com.intellij.lang.jvm.JvmModifier
+import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute
import com.intellij.lang.jvm.types.JvmReferenceType
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiClassReferenceType
import com.intellij.psi.impl.source.PsiImmediateClassType
-import com.intellij.psi.impl.source.tree.java.PsiArrayInitializerMemberValueImpl
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.doc.DocumentationLink
+import org.jetbrains.dokka.model.doc.DocumentationNode
+import org.jetbrains.dokka.model.doc.Param
+import org.jetbrains.dokka.model.doc.Text
import org.jetbrains.dokka.model.properties.PropertyContainer
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator
@@ -27,9 +29,9 @@ import org.jetbrains.kotlin.load.java.propertyNamesBySetMethodName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
import org.jetbrains.kotlin.resolve.DescriptorUtils
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.io.File
-import java.lang.ClassValue
object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
@@ -120,23 +122,24 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
fun parseClasslike(psi: PsiClass, parent: DRI): DClasslike = with(psi) {
val dri = parent.withClass(name.toString())
- val ancestorsSet = hashSetOf<DRI>()
+ val ancestorsSet = hashSetOf<Ancestor>()
val superMethodsKeys = hashSetOf<Int>()
- val superMethods = mutableListOf<PsiMethod>()
+ val superMethods = mutableListOf<Pair<PsiMethod, DRI>>()
methods.forEach { superMethodsKeys.add(it.hash) }
fun parseSupertypes(superTypes: Array<PsiClassType>) {
superTypes.forEach { type ->
(type as? PsiClassType)?.takeUnless { type.shouldBeIgnored }?.resolve()?.let {
+ val definedAt = DRI.from(it)
it.methods.forEach { method ->
val hash = method.hash
if (!method.isConstructor && !superMethodsKeys.contains(hash) &&
method.getVisibility() != Visibilities.PRIVATE
) {
superMethodsKeys.add(hash)
- superMethods.add(method)
+ superMethods.add(Pair(method, definedAt))
}
}
- ancestorsSet.add(DRI.from(it))
+ ancestorsSet.add(Ancestor(DRI.from(it), it.isInterface))
parseSupertypes(it.superTypes)
}
}
@@ -145,12 +148,13 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
val (regularFunctions, accessors) = splitFunctionsAndAccessors()
val documentation = javadocParser.parseDocumentation(this).toSourceSetDependent()
val allFunctions = regularFunctions.mapNotNull { if (!it.isConstructor) parseFunction(it) else null } +
- superMethods.map { parseFunction(it, isInherited = true) }
+ superMethods.map { parseFunction(it.first, inheritedFrom = it.second) }
val source = PsiDocumentableSource(this).toSourceSetDependent()
val classlikes = innerClasses.map { parseClasslike(it, dri) }
val visibility = getVisibility().toSourceSetDependent()
- val ancestors = ancestorsSet.toList().toSourceSetDependent()
+ val ancestors = ancestorsSet.toList().map { it.dri }.toSourceSetDependent()
val modifiers = getModifier().toSourceSetDependent()
+ val implementedInterfacesExtra = ImplementedInterfaces(ancestorsSet.filter { it.isInterface }.map { it.dri }.toList())
return when {
isAnnotationType ->
DAnnotation(
@@ -167,8 +171,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
constructors.map { parseFunction(it, true) },
mapTypeParameters(dri),
setOf(sourceSetData),
- PropertyContainer.empty<DAnnotation>() + annotations.toList().getAnnotations()
- .toSourceSetDependent().toAnnotations()
+ PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent()
+ .toAnnotations())
)
isEnum -> DEnum(
dri,
@@ -183,8 +187,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
emptyList(),
emptyList(),
setOf(sourceSetData),
- PropertyContainer.empty<DEnumEntry>() + entry.annotations.toList().getAnnotations()
- .toSourceSetDependent().toAnnotations()
+ PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent()
+ .toAnnotations())
)
},
documentation,
@@ -198,8 +202,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
constructors.map { parseFunction(it, true) },
ancestors,
setOf(sourceSetData),
- PropertyContainer.empty<DEnum>() + annotations.toList().getAnnotations().toSourceSetDependent()
- .toAnnotations()
+ PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent()
+ .toAnnotations())
)
isInterface -> DInterface(
dri,
@@ -215,8 +219,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
mapTypeParameters(dri),
ancestors,
setOf(sourceSetData),
- PropertyContainer.empty<DInterface>() + annotations.toList().getAnnotations().toSourceSetDependent()
- .toAnnotations()
+ PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent()
+ .toAnnotations())
)
else -> DClass(
dri,
@@ -234,8 +238,8 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
null,
modifiers,
setOf(sourceSetData),
- PropertyContainer.empty<DClass>() + annotations.toList().getAnnotations().toSourceSetDependent()
- .toAnnotations()
+ PropertyContainer.withAll(implementedInterfacesExtra, annotations.toList().toListOfAnnotations().toSourceSetDependent()
+ .toAnnotations())
)
}
}
@@ -243,9 +247,10 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
private fun parseFunction(
psi: PsiMethod,
isConstructor: Boolean = false,
- isInherited: Boolean = false
+ inheritedFrom: DRI? = null
): DFunction {
val dri = DRI.from(psi)
+ val docs = javadocParser.parseDocumentation(psi).toSourceSetDependent()
return DFunction(
dri,
if (isConstructor) "<init>" else psi.name,
@@ -254,13 +259,13 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
DParameter(
dri.copy(target = dri.target.nextTarget()),
psiParameter.name,
- javadocParser.parseDocumentation(psiParameter).toSourceSetDependent(),
+ DocumentationNode(docs.entries.mapNotNull { it.value.children.filterIsInstance<Param>().firstOrNull { it.root.children.firstIsInstanceOrNull<DocumentationLink>()?.children?.firstIsInstanceOrNull<Text>()?.body == psiParameter.name } }).toSourceSetDependent(),
null,
getBound(psiParameter.type),
setOf(sourceSetData)
)
},
- javadocParser.parseDocumentation(psi).toSourceSetDependent(),
+ docs,
null,
PsiDocumentableSource(psi).toSourceSetDependent(),
psi.getVisibility().toSourceSetDependent(),
@@ -271,9 +276,9 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
setOf(sourceSetData),
psi.additionalExtras().let {
PropertyContainer.withAll(
- InheritedFunction(isInherited),
+ InheritedFunction(inheritedFrom),
it.toSourceSetDependent().toAdditionalModifiers(),
- (psi.annotations.toList().getAnnotations() + it.getAnnotations()).toSourceSetDependent()
+ (psi.annotations.toList().toListOfAnnotations() + it.toListOfAnnotations()).toSourceSetDependent()
.toAnnotations()
)
}
@@ -291,7 +296,7 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
).toSet()
- private fun Set<ExtraModifiers>.getAnnotations() = map {
+ private fun Set<ExtraModifiers>.toListOfAnnotations() = map {
if (it !is ExtraModifiers.JavaOnlyModifiers.Static)
Annotations.Annotation(DRI("kotlin.jvm", it.name.toLowerCase().capitalize()), emptyMap())
else
@@ -398,14 +403,14 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
psi.additionalExtras().let {
PropertyContainer.withAll<DProperty>(
it.toSourceSetDependent().toAdditionalModifiers(),
- (psi.annotations.toList().getAnnotations() + it.getAnnotations()).toSourceSetDependent()
+ (psi.annotations.toList().toListOfAnnotations() + it.toListOfAnnotations()).toSourceSetDependent()
.toAnnotations()
)
}
)
}
- private fun Collection<PsiAnnotation>.getAnnotations() =
+ private fun Collection<PsiAnnotation>.toListOfAnnotations() =
filter { it !is KtLightAbstractAnnotation }.mapNotNull { it.toAnnotation() }
private fun JvmAnnotationAttribute.toValue(): AnnotationParameterValue = when (this) {
@@ -436,4 +441,6 @@ object DefaultPsiToDocumentableTranslator : SourceToDocumentableTranslator {
DRI.from(it)
}
}
+
+ private data class Ancestor(val dri: DRI, val isInterface: Boolean)
}
diff --git a/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt b/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt
index 335d834e..f66f88db 100644
--- a/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt
+++ b/plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt
@@ -1,8 +1,18 @@
package content.params
import matchers.content.*
+import org.jetbrains.dokka.Platform
+import org.jetbrains.dokka.model.DFunction
+import org.jetbrains.dokka.model.Documentable
+import org.jetbrains.dokka.model.SourceSetData
+import org.jetbrains.dokka.model.doc.DocumentationNode
+import org.jetbrains.dokka.model.doc.Param
+import org.jetbrains.dokka.model.doc.Text
import org.jetbrains.dokka.pages.ContentPage
+import org.jetbrains.dokka.pages.MemberPageNode
+import org.jetbrains.dokka.pages.dfs
import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.junit.jupiter.api.Test
import utils.*
@@ -558,4 +568,45 @@ class ContentForParamsTest : AbstractCoreTest() {
}
}
}
+
+ @Test
+ fun javaDocCommentWithDocumentedParameters(){
+ testInline(
+ """
+ |/src/main/java/test/Main.java
+ |package test
+ | public class Main {
+ |
+ | /**
+ | * comment to function
+ | * @param first comment to first param
+ | * @param second comment to second param
+ | */
+ | public void sample(String first, String second) {
+ |
+ | }
+ | }
+ """.trimIndent(), testConfiguration
+ ){
+ pagesTransformationStage = {
+ module ->
+ val sampleFunction = module.dfs {
+ it is MemberPageNode && it.dri.first().toString() == "test/Main/sample/#java.lang.String#java.lang.String/PointingToDeclaration/"
+ } as MemberPageNode
+ val forJvm = (sampleFunction.documentable as DFunction).parameters.mapNotNull {
+ val jvm = it.documentation.keys.first { it.platform == Platform.jvm }
+ it.documentation[jvm]
+ }
+
+ assert(forJvm.size == 2)
+ val (first, second) = forJvm.map { it.paramsDescription() }
+ assert(first == "comment to first param")
+ assert(second == "comment to second param")
+ }
+ }
+ }
+
+ private fun DocumentationNode.paramsDescription(): String =
+ children.firstIsInstanceOrNull<Param>()?.root?.children?.firstIsInstanceOrNull<Text>()?.body.orEmpty()
+
} \ 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 5616a6c3..9121f9ae 100644
--- a/plugins/base/src/test/kotlin/model/ClassesTest.kt
+++ b/plugins/base/src/test/kotlin/model/ClassesTest.kt
@@ -1,6 +1,7 @@
package model
import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.links.sureClassNames
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.KotlinModifier.*
import org.junit.jupiter.api.Assertions.assertNull
@@ -425,7 +426,7 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
"""@Suppress("abc") class Foo() {}"""
) {
with((this / "classes" / "Foo").cast<DClass>()) {
- with(extra[Annotations]!!.content.entries.single().value.firstOrNull().assertNotNull("annotations")) {
+ with(extra[Annotations]?.content?.firstOrNull().assertNotNull("annotations")) {
dri.toString() equals "kotlin/Suppress///PointingToDeclaration/"
(params["names"].assertNotNull("param") as ArrayValue).value equals listOf(StringValue("\"abc\""))
}
@@ -483,4 +484,20 @@ class ClassesTest : AbstractModelTest("/src/main/kotlin/classes/Test.kt", "class
}
}
}
+
+ @Test fun allImplementedInterfaces() {
+ inlineModelTest(
+ """
+ | interface Highest { }
+ | open class HighestImpl: Highest { }
+ | interface Lower { }
+ | interface LowerImplInterface: Lower { }
+ | class Tested : HighestImpl(), LowerImplInterface { }
+ """.trimIndent()
+ ){
+ with((this / "classes" / "Tested").cast<DClass>()){
+ extra[ImplementedInterfaces]?.interfaces?.map { it.sureClassNames }?.sorted() equals listOf("Highest", "Lower", "LowerImplInterface").sorted()
+ }
+ }
+ }
} \ 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 8f52fcc8..77fcc666 100644
--- a/plugins/base/src/test/kotlin/model/JavaTest.kt
+++ b/plugins/base/src/test/kotlin/model/JavaTest.kt
@@ -2,16 +2,22 @@ package model
import org.jetbrains.dokka.base.transformers.documentables.InheritorsInfo
import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.links.sureClassNames
import org.jetbrains.dokka.model.*
+import org.jetbrains.dokka.model.doc.Param
+import org.jetbrains.dokka.model.doc.Text
+import org.jetbrains.dokka.pages.dfs
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import utils.AbstractModelTest
import utils.assertNotNull
+import utils.docs
import utils.name
class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") {
- @Test //todo params in comments
+ @Test
fun function() {
inlineModelTest(
"""
@@ -30,12 +36,27 @@ class JavaTest : AbstractModelTest("/src/main/kotlin/java/Test.java", "java") {
children counts 1
with((this / "fn").cast<DFunction>()) {
name equals "fn"
- this
+ val params = parameters.map { it.documentation.values.first().children.first() as Param }
+ params.mapNotNull { it.root.children.firstIsInstanceOrNull<Text>()?.body } equals listOf("is String parameter", "is int parameter")
}
}
}
}
+ @Test fun allImplementedInterfacesInJava() {
+ inlineModelTest(
+ """
+ |interface Highest { }
+ |interface Lower extends Highest { }
+ |class Extendable { }
+ |class Tested extends Extendable implements Lower { }
+ """){
+ with((this / "java" / "Tested").cast<DClass>()){
+ extra[ImplementedInterfaces]?.interfaces?.map { it.sureClassNames }?.sorted() equals listOf("Highest", "Lower").sorted()
+ }
+ }
+ }
+
//@Test fun function() {
// verifyJavaPackageMember("testdata/java/member.java", defaultModelConfig) { cls ->
// assertEquals("Test", cls.name)
diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt
index 520486f6..a92320dd 100644
--- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt
+++ b/plugins/javadoc/src/main/kotlin/javadoc/JavadocLocationProvider.kt
@@ -91,7 +91,7 @@ class JavadocLocationProvider(pageRoot: RootPageNode, private val context: Dokka
}
}?.joinToString("/")?.let {if (skipExtension) "$it.html" else it}?.let {
Paths.get(dir).relativize(Paths.get(it)).toString()
- } ?: run {throw IllegalStateException("Page for ${link.name} not found")}
+ } ?: run {""} //TODO just a glue to compile it on HMPP
override fun resolveRoot(node: PageNode): String {
TODO("Not yet implemented")
diff --git a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt
index 64fc539f..a3bef099 100644
--- a/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt
+++ b/plugins/javadoc/src/main/kotlin/javadoc/JavadocPageCreator.kt
@@ -3,14 +3,21 @@ package javadoc
import javadoc.pages.*
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.base.signatures.SignatureProvider
+import org.jetbrains.dokka.base.signatures.function
import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter
import org.jetbrains.dokka.base.transformers.pages.comments.DocTagToContentConverter
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.model.doc.Description
+import org.jetbrains.dokka.model.doc.Param
+import org.jetbrains.dokka.model.doc.TagWrapper
+import org.jetbrains.dokka.model.doc.Text
+import org.jetbrains.dokka.model.properties.PropertyContainer
+import org.jetbrains.dokka.model.properties.WithExtraProperties
import org.jetbrains.dokka.pages.ContentKind
import org.jetbrains.dokka.pages.DCI
import org.jetbrains.dokka.utilities.DokkaLogger
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
+import org.jetbrains.kotlin.utils.addToStdlib.safeAs
open class JavadocPageCreator(
commentsToContentConverter: CommentsToContentConverter,
@@ -28,21 +35,28 @@ open class JavadocPageCreator(
fun pageForPackage(p: DPackage) =
JavadocPackagePageNode(p.name, contentForPackage(p), setOf(p.dri), p,
- p.classlikes.map { pageForClasslike(it) } // TODO: nested classlikes
- ).also {
- it
- }
+ p.classlikes.mapNotNull { pageForClasslike(it) } // TODO: nested classlikes
+ )
- fun pageForClasslike(c: DClasslike): JavadocClasslikePageNode {
- val constructors = when (c) {
- is DClass -> c.constructors
- is DEnum -> c.constructors
- else -> emptyList()
+ fun pageForClasslike(c: DClasslike): JavadocClasslikePageNode? =
+ c.sourceSets.firstOrNull { it.platform == Platform.jvm }?.let {jvm ->
+ JavadocClasslikePageNode(
+ name = c.name.orEmpty(),
+ content = contentForClasslike(c),
+ dri = setOf(c.dri),
+ modifiers = listOfNotNull(c.visibility[jvm]?.name),
+ signature = signatureProvider.signature(c),
+ description = c.description(jvm),
+ constructors = c.safeAs<WithConstructors>()?.constructors?.map { it.toJavadocFunction(jvm) }.orEmpty(),
+ methods = c.functions.map { it.toJavadocFunction(jvm) },
+ entries = c.safeAs<DEnum>()?.entries?.map { JavadocEntryNode(signatureProvider.signature(it), it.description(jvm)) }.orEmpty(),
+ classlikes = c.classlikes.mapNotNull { pageForClasslike(it) },
+ properties = c.properties.map { JavadocPropertyNode(signatureProvider.signature(it), TextNode(it.description(jvm), setOf(jvm))) },
+ documentable = c,
+ extras = c.safeAs<WithExtraProperties<Documentable>>()?.extra ?: PropertyContainer.empty()
+ )
}
- return JavadocClasslikePageNode(c.name.orEmpty(), contentForClasslike(c), setOf(c.dri), c, emptyList())
- }
-
fun contentForModule(m: DModule): JavadocContentNode =
JavadocContentGroup(
setOf(m.dri),
@@ -96,5 +110,48 @@ open class JavadocPageCreator(
kind = JavadocContentKind.Class
)
}
+
+ private fun signatureForProjection(p: Projection): String =
+ when (p) {
+ is OtherParameter -> p.name
+ is TypeConstructor -> if (p.function)
+ "TODO"
+ else {
+ val other = if(p.projections.isNotEmpty()){
+ p.projections.joinToString(prefix = "<", postfix = ">") { signatureForProjection(it) }
+ } else {
+ ""
+ }
+ "${p.dri.classNames.orEmpty()} $other"
+ }
+
+ is Variance -> "${p.kind} ${signatureForProjection(p.inner)}"
+ is Star -> "*"
+ is Nullable -> "${signatureForProjection(p.inner)}?"
+ is JavaObject -> "Object"
+ is Void -> "Void"
+ is PrimitiveJavaType -> p.name
+ is Dynamic -> "dynamic"
+ is UnresolvedBound -> p.name
+ }
+
+ private fun DFunction.toJavadocFunction(sourceSetData: SourceSetData) = JavadocFunctionNode(
+ name = name,
+ signature = signatureProvider.signature(this),
+ brief = TextNode(description(sourceSetData), setOf(sourceSetData)),
+ parameters = parameters.map {
+ JavadocParameterNode(
+ name = it.name.orEmpty(),
+ type = signatureForProjection(it.type),
+ description = TextNode(it.findNodeInDocumentation<Param>(sourceSetData), setOf(sourceSetData))
+ )
+ },
+ extras = extra
+ )
+
+ private fun Documentable.description(sourceSetData: SourceSetData): String = findNodeInDocumentation<Description>(sourceSetData)
+
+ private inline fun <reified T: TagWrapper> Documentable.findNodeInDocumentation(sourceSetData: SourceSetData): String =
+ documentation[sourceSetData]?.children?.firstIsInstanceOrNull<T>()?.root?.children?.firstIsInstanceOrNull<Text>()?.body.orEmpty()
}
diff --git a/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt b/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt
index aa7c2dfe..1026ea5c 100644
--- a/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt
+++ b/plugins/javadoc/src/main/kotlin/javadoc/KorteJavadocRenderer.kt
@@ -8,13 +8,19 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.jetbrains.dokka.base.renderers.OutputWriter
import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.links.sureClassNames
+import org.jetbrains.dokka.model.ImplementedInterfaces
+import org.jetbrains.dokka.model.InheritedFunction
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.renderers.Renderer
+import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.nio.file.Path
import java.nio.file.Paths
import java.time.LocalDate
+typealias PageContent = Map<String, Any?>
+
class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaContext, val resourceDir: String) :
Renderer {
private lateinit var locationProvider: JavadocLocationProvider
@@ -67,8 +73,7 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon
"docName" to "docName", // todo docname
"pathToRoot" to pathToRoot,
"dir" to dir
- ) + node.contentMap
-// DokkaConsoleLogger.info("${node::class.java.canonicalName}::${node.name} - $link")
+ ) + renderContentNodes(node)
writeFromTemplate(outputWriter, link, templateForNode(node), contentMap.toList())
node.children.forEach { renderNode(it, link.toNormalized()) }
}
@@ -120,11 +125,11 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon
)
}
- private fun renderContentNode(content: ContentNode) = when(content) {
- is ContentText -> content.text
- is ContentComposite -> renderContent(content.children)
- else -> ""
- }
+// private fun renderContentNode(content: ContentNode) = when(content) {
+// is ContentText -> content.text
+// is ContentComposite -> renderContent(content.children)
+// else -> ""
+// }
private fun renderContent(content: List<ContentNode>): String =
content.joinToString("") { renderContentNode(it) }
@@ -179,7 +184,10 @@ class KorteJavadocRenderer(val outputWriter: OutputWriter, val context: DokkaCon
}
rootNodes.joinToString{ drawRec(it) }
},
- Filter("length") { subject.dynamicLength() }
+ Filter("length") { subject.dynamicLength() },
+ TeFunction("hasAnyDescription"){ args ->
+ args.first().safeAs<List<HashMap<String, String>>>()?.any { it["description"]?.trim()?.isNotEmpty() ?: false }
+ }
).forEach {
when (it) {
is TeFunction