aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Ryzhenkov <orangy@jetbrains.com>2014-07-11 18:44:53 +0400
committerIlya Ryzhenkov <orangy@jetbrains.com>2014-07-11 18:44:53 +0400
commit35b64fb01d6b4da4b0dab840a787abc84d1bff06 (patch)
tree6733eeb9f157188d0b7f935e8fecaf97707b8139
parentc540bc28a79092b212e575fa18d33399faee83b9 (diff)
downloaddokka-35b64fb01d6b4da4b0dab840a787abc84d1bff06.tar.gz
dokka-35b64fb01d6b4da4b0dab840a787abc84d1bff06.tar.bz2
dokka-35b64fb01d6b4da4b0dab840a787abc84d1bff06.zip
Build model using recursive visitor, include packages in model, add test for function with parameters, unify model and node.
-rw-r--r--.idea/libraries/kotlin_compiler.xml66
-rw-r--r--src/DocumentationBuilder.kt32
-rw-r--r--src/DocumentationBuildingVisitor.kt114
-rw-r--r--src/DocumentationModel.kt35
-rw-r--r--test/data/functions/function.kt (renamed from test/data/function.kt)0
-rw-r--r--test/data/functions/functionWithParams.kt4
-rw-r--r--test/src/TopLevelFunctionTest.kt17
7 files changed, 243 insertions, 25 deletions
diff --git a/.idea/libraries/kotlin_compiler.xml b/.idea/libraries/kotlin_compiler.xml
index f0b20ad9..8e5c6bd2 100644
--- a/.idea/libraries/kotlin_compiler.xml
+++ b/.idea/libraries/kotlin_compiler.xml
@@ -71,6 +71,72 @@
<root url="file://$PROJECT_DIR$/../kotlin/dependencies/download/asm-src" />
<root url="file://$PROJECT_DIR$/../kotlin/injector-generator/src" />
<root url="file://$PROJECT_DIR$/../kotlin/ide-compiler-runner/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/js/js.tests/test" />
+ <root url="file://$PROJECT_DIR$/../kotlin/js/js.dart-ast/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/js/js.translator/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/j2k/tests/test" />
+ <root url="file://$PROJECT_DIR$/../kotlin/core/descriptors/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/core/runtime.jvm/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/core/util.runtime/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/core/serialization/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/core/serialization.java/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/core/descriptor.loader.java/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/docs/exPuzzlers/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/idea/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/idea/tests" />
+ <root url="file://$PROJECT_DIR$/../kotlin/eval4j/test" />
+ <root url="file://$PROJECT_DIR$/../kotlin/grammar/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/cli/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/cli/cli-common/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/util/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/tests" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/backend/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/frontend/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/preloader/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/preloader/instrumentation/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/android-tests/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/android-tests/tests" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/android-tests/android-module/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/frontend.java/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/backend-common/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/jet.as.java.psi/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/compiler/integration-tests/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/runtime/target/copied-sources" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kdoc-maven-plugin/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kdoc-maven-plugin/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin/src/main/kotlin" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Lib/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/kotlinJavaProject/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin/target/test-classes/testProject/AndroidProject/Lib/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin/target/test-classes/testProject/AndroidProject/Android/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin/target/test-classes/testProject/kotlinJavaProject/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-js-tests-junit/src/test/kotlin" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin-test/src/it/test-classpath/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin-test/src/it/test-helloworld/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin-test/src/it/test-inlineDisabled/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin-test/target/it/test-classpath/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin-test/target/it/test-helloworld/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-maven-plugin-test/target/it/test-inlineDisabled/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/simpleProject/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/additionalJavaSrc/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/additionalJavaSrc/generated" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin-core/target/test-classes/testProject/simpleProject/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin-core/target/test-classes/testProject/additionalJavaSrc/src/main/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/tools/kotlin-gradle-plugin-core/target/test-classes/testProject/additionalJavaSrc/generated" />
+ <root url="file://$PROJECT_DIR$/../kotlin/libraries/examples/kotlin-java-example/src/test/java" />
+ <root url="file://$PROJECT_DIR$/../kotlin/generators/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/generators/tests" />
+ <root url="file://$PROJECT_DIR$/../kotlin/jps-plugin/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/jps-plugin/test" />
+ <root url="file://$PROJECT_DIR$/../kotlin/jps-plugin/kannotator-jps-plugin-test/test" />
+ <root url="file://$PROJECT_DIR$/../kotlin/build-tools/ant/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/build-tools/core/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/dependencies/download/asm-src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/injector-generator/src" />
+ <root url="file://$PROJECT_DIR$/../kotlin/ide-compiler-runner/src" />
</SOURCES>
</library>
</component> \ No newline at end of file
diff --git a/src/DocumentationBuilder.kt b/src/DocumentationBuilder.kt
new file mode 100644
index 00000000..02db3540
--- /dev/null
+++ b/src/DocumentationBuilder.kt
@@ -0,0 +1,32 @@
+package com.jetbrains.dokka
+
+import org.jetbrains.jet.lang.resolve.*
+import org.jetbrains.jet.lang.psi.*
+import org.jetbrains.jet.lang.descriptors.*
+import org.jetbrains.jet.lang.descriptors.impl.*
+
+fun BindingContext.createDocumentation(file: JetFile): DocumentationModel {
+ val model = DocumentationModel()
+ val packageFragment = getPackageFragment(file)
+ if (packageFragment == null) throw IllegalArgumentException("File $file should have package fragment")
+
+ val visitor = DocumentationBuilderVisitor()
+ visitDescriptor(packageFragment, model, visitor)
+
+ return model
+}
+
+class DocumentationBuilderVisitor() : DeclarationDescriptorVisitorEmptyBodies<DocumentationNode, DocumentationNode>() {
+
+ override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = DocumentationNode(descriptor!!.getName().asString(), "doc", DocumentationNodeKind.Function)
+ data?.addReferenceTo(node, DocumentationReferenceKind.Member)
+ return node
+ }
+
+ override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = DocumentationNode(descriptor!!.getName().asString(), "doc", DocumentationNodeKind.Function)
+ data?.addReferenceTo(node, DocumentationReferenceKind.Detail)
+ return node
+ }
+}
diff --git a/src/DocumentationBuildingVisitor.kt b/src/DocumentationBuildingVisitor.kt
new file mode 100644
index 00000000..6486ac90
--- /dev/null
+++ b/src/DocumentationBuildingVisitor.kt
@@ -0,0 +1,114 @@
+package com.jetbrains.dokka
+
+import org.jetbrains.jet.lang.descriptors.*
+import org.jetbrains.jet.lang.resolve.name.FqName
+
+class DocumentationBuildingVisitor(private val worker: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode>)
+: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode> {
+
+ private fun visitChildren(descriptors: Collection<DeclarationDescriptor>, data: DocumentationNode) {
+ for (descriptor in descriptors) {
+ descriptor.accept(this, data)
+ }
+ }
+
+ private fun visitChildren(descriptor: DeclarationDescriptor?, data: DocumentationNode) {
+ descriptor?.accept(this, data)
+ }
+
+ private fun createDocumentation(descriptor: DeclarationDescriptor, data: DocumentationNode): DocumentationNode {
+ return descriptor.accept(worker, data)
+ }
+
+ private fun processCallable(descriptor: CallableDescriptor, data: DocumentationNode): DocumentationNode {
+ val node = createDocumentation(descriptor, data)
+ visitChildren(descriptor.getTypeParameters(), node)
+ visitChildren(descriptor.getReceiverParameter(), node)
+ visitChildren(descriptor.getValueParameters(), node)
+ return node
+ }
+
+ public override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = createDocumentation(descriptor!!, data!!)
+ visitChildren(descriptor.getMemberScope().getAllDescriptors(), node)
+ return node
+ }
+
+ public override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = createDocumentation(descriptor!!, data!!)
+ visitChildren(descriptor.getMemberScope().getAllDescriptors(), node)
+ return node
+ }
+
+ public override fun visitVariableDescriptor(descriptor: VariableDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = processCallable(descriptor!!, data!!)
+ return node
+ }
+
+ public override fun visitPropertyDescriptor(descriptor: PropertyDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = processCallable(descriptor!!, data!!)
+ visitChildren(descriptor.getGetter(), node)
+ visitChildren(descriptor.getSetter(), node)
+ return node
+ }
+
+ public override fun visitFunctionDescriptor(descriptor: FunctionDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = processCallable(descriptor!!, data!!)
+ return node
+ }
+
+ public override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = createDocumentation(descriptor!!, data!!)
+ return node
+ }
+
+ public override fun visitClassDescriptor(descriptor: ClassDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = createDocumentation(descriptor!!, data!!)
+ visitChildren(descriptor.getThisAsReceiverParameter(), node)
+ visitChildren(descriptor.getConstructors(), node)
+ visitChildren(descriptor.getTypeConstructor().getParameters(), node)
+ visitChildren(descriptor.getClassObjectDescriptor(), node)
+ visitChildren(descriptor.getDefaultType().getMemberScope().getAllDescriptors(), node)
+ return node
+ }
+
+ public override fun visitModuleDeclaration(descriptor: ModuleDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = createDocumentation(descriptor!!, data!!)
+ visitChildren(descriptor.getPackage(FqName.ROOT), node)
+ return node
+ }
+
+ public override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = visitFunctionDescriptor(constructorDescriptor, data)
+ return node
+ }
+
+ public override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = visitClassDescriptor(scriptDescriptor!!.getClassDescriptor(), data)
+ return node
+ }
+
+ public override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = visitVariableDescriptor(descriptor, data)
+ return node
+ }
+
+ public override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = visitFunctionDescriptor(descriptor, data)
+ return node
+ }
+
+ public override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = visitFunctionDescriptor(descriptor, data)
+ return node
+ }
+
+ public override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor?, data: DocumentationNode?): DocumentationNode? {
+ val node = createDocumentation(descriptor!!, data!!)
+ return node
+ }
+}
+
+public fun visitDescriptor(descriptor: DeclarationDescriptor, data: DocumentationNode, visitor: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode>): DocumentationNode {
+ return descriptor.accept(DocumentationBuildingVisitor(visitor), data)
+}
diff --git a/src/DocumentationModel.kt b/src/DocumentationModel.kt
index 3391c277..b8ef21b0 100644
--- a/src/DocumentationModel.kt
+++ b/src/DocumentationModel.kt
@@ -1,7 +1,7 @@
package com.jetbrains.dokka
-import com.intellij.psi.PsiFile
import org.jetbrains.jet.lang.resolve.BindingContext
+import org.jetbrains.jet.lang.psi.JetFile
public enum class DocumentationNodeKind {
Package
@@ -13,7 +13,7 @@ public enum class DocumentationNodeKind {
Exception
Page
- Module
+ Model
}
public enum class DocumentationReferenceKind {
@@ -24,7 +24,7 @@ public enum class DocumentationReferenceKind {
Override
}
-public class DocumentationNode(val name: String, val doc: String, val kind: DocumentationNodeKind) {
+public open class DocumentationNode(val name: String, val doc: String, val kind: DocumentationNodeKind) {
private val references = arrayListOf<DocumentationReference>()
public val owner: DocumentationNode
@@ -36,39 +36,28 @@ public class DocumentationNode(val name: String, val doc: String, val kind: Docu
public val links: List<DocumentationNode>
get() = references(DocumentationReferenceKind.Link).map { it.to }
+ // TODO: Should we allow node mutation? Model merge will copy by ref, so references are transparent, which could nice
public fun addReferenceTo(to: DocumentationNode, kind: DocumentationReferenceKind) {
references.add(DocumentationReference(this, to, kind))
}
+ public fun addAllReferencesFrom(other: DocumentationNode) {
+ references.addAll(other.references)
+ }
+
public fun references(kind: DocumentationReferenceKind): List<DocumentationReference> = references.filter { it.kind == kind }
}
-public class DocumentationModel {
- private val items = arrayListOf<DocumentationNode>()
-
+public class DocumentationModel : DocumentationNode("model", "", DocumentationNodeKind.Model) {
fun merge(other: DocumentationModel): DocumentationModel {
val model = DocumentationModel()
- model.addNodes(other.nodes)
- model.addNodes(this.nodes)
+ model.addAllReferencesFrom(other)
+ model.addAllReferencesFrom(this)
return model
}
- public fun addNode(node: DocumentationNode) {
- items.add(node)
- }
-
- public fun addNodes(nodes: List<DocumentationNode>) {
- items.addAll(nodes)
- }
-
public val nodes: List<DocumentationNode>
- get() = items
+ get() = members
}
public data class DocumentationReference(val from: DocumentationNode, val to: DocumentationNode, val kind: DocumentationReferenceKind)
-
-fun BindingContext.createDocumentation(file: PsiFile): DocumentationModel {
- val model = DocumentationModel()
- model.addNode(DocumentationNode("fn", "doc", DocumentationNodeKind.Function))
- return model
-} \ No newline at end of file
diff --git a/test/data/function.kt b/test/data/functions/function.kt
index 878b017b..878b017b 100644
--- a/test/data/function.kt
+++ b/test/data/functions/function.kt
diff --git a/test/data/functions/functionWithParams.kt b/test/data/functions/functionWithParams.kt
new file mode 100644
index 00000000..9d3a0ad7
--- /dev/null
+++ b/test/data/functions/functionWithParams.kt
@@ -0,0 +1,4 @@
+/**
+ * doc
+ */
+fun function(x : Int) {} \ No newline at end of file
diff --git a/test/src/TopLevelFunctionTest.kt b/test/src/TopLevelFunctionTest.kt
index a51b7bdd..dd88a1a0 100644
--- a/test/src/TopLevelFunctionTest.kt
+++ b/test/src/TopLevelFunctionTest.kt
@@ -7,8 +7,8 @@ import com.jetbrains.dokka.*
public class TopLevelFunctionTest {
Test fun function() {
- verifyFiles("test/data/function.kt") { model ->
- val item = model.nodes.single()
+ verifyFiles("test/data/functions/function.kt") { model ->
+ val item = model.nodes.single().members.single()
assertEquals(DocumentationNodeKind.Function, item.kind)
assertEquals("fn", item.name)
assertEquals("doc", item.doc)
@@ -17,4 +17,17 @@ public class TopLevelFunctionTest {
assertTrue(item.links.none())
}
}
+
+ Test fun functionWithParams() {
+ verifyFiles("test/data/functions/functionWithParams.kt") { model ->
+ val item = model.nodes.single().members.single()
+ assertEquals(DocumentationNodeKind.Function, item.kind)
+ assertEquals("function", item.name)
+ assertEquals("doc", item.doc)
+ assertEquals("x", item.details.single().name)
+
+ assertTrue(item.members.none())
+ assertTrue(item.links.none())
+ }
+ }
} \ No newline at end of file