aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Java/JavaDocumentationBuilder.kt85
-rw-r--r--src/main.kt60
-rw-r--r--test/data/java/member.java2
-rw-r--r--test/src/model/JavaTest.kt28
4 files changed, 149 insertions, 26 deletions
diff --git a/src/Java/JavaDocumentationBuilder.kt b/src/Java/JavaDocumentationBuilder.kt
new file mode 100644
index 00000000..c9379386
--- /dev/null
+++ b/src/Java/JavaDocumentationBuilder.kt
@@ -0,0 +1,85 @@
+package org.jetbrains.dokka
+
+import com.intellij.psi.PsiJavaFile
+import com.intellij.psi.PsiClass
+import org.jetbrains.dokka.DocumentationNode.Kind
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.javadoc.PsiDocComment
+import com.intellij.psi.PsiType
+import com.intellij.psi.PsiParameter
+import com.intellij.psi.PsiNamedElement
+import com.intellij.psi.PsiDocCommentOwner
+import com.intellij.psi.PsiClassType
+import com.intellij.psi.PsiPrimitiveType
+
+public class JavaDocumentationBuilder() {
+ fun appendFile(file: PsiJavaFile, module: DocumentationModule) {
+ val packageNode = module.findOrCreatePackageNode(file.getPackageName())
+ packageNode.appendChildren(file.getClasses()) { build() }
+ }
+
+ fun parseDocumentation(docComment: PsiDocComment?): Content {
+ if (docComment == null) return Content.Empty
+ val result = Content()
+ docComment.getDescriptionElements().dropWhile { it.getText().trim().isEmpty() }.forEach {
+ val text = if (result.isEmpty()) it.getText().trimLeading() else it.getText()
+ result.append(ContentText(text))
+ }
+ return result
+ }
+
+ fun DocumentationNode(element: PsiNamedElement, kind: Kind): DocumentationNode {
+ val docComment = if (element is PsiDocCommentOwner) parseDocumentation(element.getDocComment()) else Content.Empty
+ val node = DocumentationNode(element.getName() ?: "<anonymous>", docComment, kind)
+ return node
+ }
+
+ fun DocumentationNode.appendChildren<T>(elements: Array<T>,
+ kind: DocumentationReference.Kind = DocumentationReference.Kind.Member,
+ buildFn: T.() -> DocumentationNode) {
+ elements.forEach {
+ append(it.buildFn(), kind)
+ }
+ }
+
+ fun PsiClass.build(): DocumentationNode {
+ val kind = when {
+ isInterface() -> DocumentationNode.Kind.Interface
+ isEnum() -> DocumentationNode.Kind.Enum
+ isAnnotationType() -> DocumentationNode.Kind.AnnotationClass
+ else -> DocumentationNode.Kind.Class
+ }
+ val node = DocumentationNode(this, kind)
+ node.appendChildren(getMethods()) { build() }
+ return node
+ }
+
+ fun PsiMethod.build(): DocumentationNode {
+ val node = DocumentationNode(this, Kind.Function)
+ node.appendType(getReturnType())
+ node.appendChildren(getParameterList().getParameters(), DocumentationReference.Kind.Detail) { build() }
+ return node
+ }
+
+ fun PsiParameter.build(): DocumentationNode {
+ val node = DocumentationNode(this, Kind.Parameter)
+ node.appendType(getType())
+ return node
+ }
+
+ fun DocumentationNode.appendType(psiType: PsiType?, kind: DocumentationNode.Kind = DocumentationNode.Kind.Type) {
+ if (psiType == null) {
+ return
+ }
+ val name = mapTypeName(psiType)
+ val node = DocumentationNode(name, Content.Empty, kind)
+ append(node, DocumentationReference.Kind.Detail)
+ }
+
+ private fun mapTypeName(psiType: PsiType): String = when (psiType) {
+ PsiType.VOID -> "Unit"
+ is PsiPrimitiveType -> psiType.getCanonicalText().capitalize()
+ is PsiClassType -> psiType.getClassName()
+ else -> psiType.getCanonicalText()
+ }
+}
diff --git a/src/main.kt b/src/main.kt
index 1c480f22..d5384ea0 100644
--- a/src/main.kt
+++ b/src/main.kt
@@ -7,6 +7,11 @@ import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import com.intellij.psi.PsiFile
+import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment
+import com.intellij.psi.PsiJavaFile
+import org.jetbrains.kotlin.config.CommonConfigurationKeys
+import com.intellij.psi.PsiManager
+import com.intellij.openapi.vfs.VirtualFileManager
class DokkaArguments {
Argument(value = "src", description = "Source file or directory (allows many paths separated by the system path separator)")
@@ -190,29 +195,52 @@ fun buildDocumentationModule(environment: AnalysisEnvironment,
val documentation = environment.withContext { environment, session ->
val fragmentFiles = environment.getSourceFiles().filter(filesToDocumentFilter)
val fragments = fragmentFiles.map { session.getPackageFragment(it.getPackageFqName()) }.filterNotNull().distinct()
- val documentationBuilder = DocumentationBuilder(session, options, logger)
-
- with(documentationBuilder) {
- val moduleContent = Content()
- for (include in includes) {
- val file = File(include)
- if (file.exists()) {
- val text = file.readText()
- val tree = parseMarkdown(text)
- val content = buildContent(tree)
- moduleContent.children.addAll(content.children)
- } else {
- logger.warn("Include file $file was not found.")
- }
+ val moduleContent = Content()
+ for (include in includes) {
+ val file = File(include)
+ if (file.exists()) {
+ val text = file.readText()
+ val tree = parseMarkdown(text)
+ val content = buildContent(tree)
+ moduleContent.children.addAll(content.children)
+ } else {
+ logger.warn("Include file $file was not found.")
}
+ }
+ val documentationModule = DocumentationModule(moduleName, moduleContent)
- val documentationModule = DocumentationModule(moduleName, moduleContent)
+ val documentationBuilder = DocumentationBuilder(session, options, logger)
+ with(documentationBuilder) {
documentationModule.appendFragments(fragments)
documentationBuilder.resolveReferences(documentationModule)
- documentationModule
}
+
+ val javaFiles = environment.getJavaSourceFiles().filter(filesToDocumentFilter)
+ val javaDocumentationBuilder = JavaDocumentationBuilder()
+ javaFiles.map { javaDocumentationBuilder.appendFile(it, documentationModule) }
+
+ documentationModule
}
return documentation
}
+
+
+fun JetCoreEnvironment.getJavaSourceFiles(): List<PsiJavaFile> {
+ val sourceRoots = getConfiguration().getList(CommonConfigurationKeys.SOURCE_ROOTS_KEY).map { File(it) }
+ val result = arrayListOf<PsiJavaFile>()
+ val localFileSystem = VirtualFileManager.getInstance().getFileSystem("file")
+ sourceRoots.forEach { sourceRoot ->
+ sourceRoot.getAbsoluteFile().recurse {
+ val vFile = localFileSystem.findFileByPath(it.path)
+ if (vFile != null) {
+ val psiFile = PsiManager.getInstance(getProject()).findFile(vFile)
+ if (psiFile is PsiJavaFile) {
+ result.add(psiFile)
+ }
+ }
+ }
+ }
+ return result
+}
diff --git a/test/data/java/member.java b/test/data/java/member.java
index 5eb9209f..cf978444 100644
--- a/test/data/java/member.java
+++ b/test/data/java/member.java
@@ -6,7 +6,7 @@ class Test {
* @param name is String parameter
* @param value is int parameter
*/
- public void Function(String name, int value) {
+ public void fn(String name, int value) {
}
} \ No newline at end of file
diff --git a/test/src/model/JavaTest.kt b/test/src/model/JavaTest.kt
index e57be4a9..602e1382 100644
--- a/test/src/model/JavaTest.kt
+++ b/test/src/model/JavaTest.kt
@@ -5,19 +5,29 @@ import org.jetbrains.dokka.*
import org.junit.*
public class JavaTest {
- Ignore Test fun function() {
+ Test fun function() {
verifyModel("test/data/java/") { model ->
val pkg = model.members.single()
with(pkg.members.single()) {
- assertEquals("fn", name)
- assertEquals(DocumentationNode.Kind.Function, kind)
- assertEquals("Function fn", content.summary)
- assertEquals("Unit", detail(DocumentationNode.Kind.Type).name)
- assertTrue(members.none())
- assertTrue(links.none())
+ assertEquals("Test", name)
+ assertEquals(DocumentationNode.Kind.Class, kind)
+ with(members.single()) {
+ assertEquals("fn", name)
+ assertEquals(DocumentationNode.Kind.Function, kind)
+ assertEquals("Summary for Function", content.summary.toTestString())
+ assertEquals("Unit", detail(DocumentationNode.Kind.Type).name)
+ assertTrue(members.none())
+ assertTrue(links.none())
+ with(details.first { it.name == "name" }) {
+ assertEquals(DocumentationNode.Kind.Parameter, kind)
+ assertEquals("String", detail(DocumentationNode.Kind.Type).name)
+ }
+ with(details.first { it.name == "value" }) {
+ assertEquals(DocumentationNode.Kind.Parameter, kind)
+ assertEquals("Int", detail(DocumentationNode.Kind.Type).name)
+ }
+ }
}
}
}
-
}
-