aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorPaweł Marks <pmarks@virtuslab.com>2019-10-31 22:58:42 +0100
committerPaweł Marks <pmarks@virtuslab.com>2019-10-31 22:58:42 +0100
commit5f36bdd75e32743f54193aa8eff8cd5185b3cf67 (patch)
tree51c148449cfec75b455bea34eba89aed0189ebf6 /core
parent2f293770a61220b7ab3a26ea459c4a52501ec053 (diff)
downloaddokka-5f36bdd75e32743f54193aa8eff8cd5185b3cf67.tar.gz
dokka-5f36bdd75e32743f54193aa8eff8cd5185b3cf67.tar.bz2
dokka-5f36bdd75e32743f54193aa8eff8cd5185b3cf67.zip
Adds transformation from descriptors to documentation graph
Diffstat (limited to 'core')
-rw-r--r--core/src/main/kotlin/DokkaDescriptorVisitor.kt86
-rw-r--r--core/src/main/kotlin/DokkaGenerator.kt59
-rw-r--r--core/src/main/kotlin/Model/DocumentationNode.kt59
-rw-r--r--core/src/main/kotlin/Utilities/nodeDebug.kt24
-rw-r--r--core/src/main/kotlin/transformers/DefaultDocumentationToPageTransformer.kt1
-rw-r--r--core/src/main/kotlin/transformers/DocumentationToPageTransformer.kt2
6 files changed, 192 insertions, 39 deletions
diff --git a/core/src/main/kotlin/DokkaDescriptorVisitor.kt b/core/src/main/kotlin/DokkaDescriptorVisitor.kt
new file mode 100644
index 00000000..e2485a2c
--- /dev/null
+++ b/core/src/main/kotlin/DokkaDescriptorVisitor.kt
@@ -0,0 +1,86 @@
+package org.jetbrains.dokka
+
+import org.jetbrains.dokka.Model.*
+import org.jetbrains.dokka.Model.Function
+import org.jetbrains.dokka.links.Callable
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.dokka.links.withClass
+import org.jetbrains.kotlin.descriptors.*
+import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
+import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
+import org.jetbrains.kotlin.resolve.scopes.MemberScope
+
+object DokkaDescriptorVisitor : DeclarationDescriptorVisitorEmptyBodies<DocumentationNode<*>, DRI>() {
+ override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor, parent: DRI): Nothing {
+ throw IllegalStateException("${javaClass.simpleName} should never enter ${descriptor.javaClass.simpleName}")
+ }
+
+ override fun visitPackageFragmentDescriptor(
+ descriptor: PackageFragmentDescriptor,
+ parent: DRI
+ ): Package {
+ val dri = DRI(packageName = descriptor.fqName.asString())
+ return Package(
+ dri,
+ descriptor.getMemberScope().functions(dri),
+ descriptor.getMemberScope().properties(dri),
+ descriptor.getMemberScope().classes(dri)
+ )
+ }
+
+ override fun visitClassDescriptor(descriptor: ClassDescriptor, parent: DRI): Class {
+ val dri = parent.withClass(descriptor.name.asString())
+ return Class(
+ dri,
+ descriptor.name.asString(),
+ descriptor.getMemberScope(emptyList()).functions(dri),
+ descriptor.getMemberScope(emptyList()).properties(dri),
+ descriptor.getMemberScope(emptyList()).classes(dri),
+ descriptor
+ )
+ }
+
+ override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, parent: DRI): Property {
+ val dri = parent.copy(callable = Callable.Companion.from(descriptor))
+ return Property(
+ dri,
+ descriptor.name.asString(),
+ descriptor.extensionReceiverParameter?.let { visitReceiverParameterDescriptor(it, dri) },
+ descriptor
+ )
+ }
+
+ override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, parent: DRI): Function {
+ val dri = parent.copy(callable = Callable.Companion.from(descriptor))
+ return Function(
+ dri,
+ descriptor.name.asString(),
+ descriptor.extensionReceiverParameter?.let { visitReceiverParameterDescriptor(it, dri) },
+ descriptor.valueParameters.mapIndexed { index, desc -> parameter(index, desc, dri) },
+ descriptor
+ )
+ }
+
+ override fun visitReceiverParameterDescriptor(
+ descriptor: ReceiverParameterDescriptor,
+ parent: DRI
+ ) = Parameter(parent.copy(target = 0), null, descriptor)
+
+ private fun parameter(index: Int, descriptor: ValueParameterDescriptor, parent: DRI) =
+ Parameter(parent.copy(target = index + 1), descriptor.name.asString(), descriptor)
+
+ private fun MemberScope.functions(parent: DRI): List<Function> =
+ getContributedDescriptors(DescriptorKindFilter.FUNCTIONS) { true }
+ .filterIsInstance<FunctionDescriptor>()
+ .map { visitFunctionDescriptor(it, parent) }
+
+ private fun MemberScope.properties(parent: DRI): List<Property> =
+ getContributedDescriptors(DescriptorKindFilter.VALUES) { true }
+ .filterIsInstance<PropertyDescriptor>()
+ .map { visitPropertyDescriptor(it, parent) }
+
+ private fun MemberScope.classes(parent: DRI): List<Class> =
+ getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) { true }
+ .filterIsInstance<ClassDescriptor>()
+ .map { visitClassDescriptor(it, parent) }
+}
diff --git a/core/src/main/kotlin/DokkaGenerator.kt b/core/src/main/kotlin/DokkaGenerator.kt
index abb6f069..f1aa7b71 100644
--- a/core/src/main/kotlin/DokkaGenerator.kt
+++ b/core/src/main/kotlin/DokkaGenerator.kt
@@ -1,13 +1,62 @@
package org.jetbrains.dokka
+import kotlinx.html.DD
+import org.jetbrains.dokka.Model.Module
+import org.jetbrains.dokka.Utilities.pretty
+import org.jetbrains.dokka.links.DRI
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
+import org.jetbrains.kotlin.utils.PathUtil
+import java.io.File
+
class DokkaGenerator(
- private val configurationWithLinks: DokkaConfiguration,
+ private val configuration: DokkaConfiguration,
private val logger: DokkaLogger
) {
- fun generate() {
- println("RUNNED")
- logger.error("runned")
- throw AssertionError()
+ fun generate() = configuration.passesConfigurations.forEach { pass ->
+ AnalysisEnvironment(DokkaMessageCollector(logger), pass.analysisPlatform).run {
+ if (analysisPlatform == Platform.jvm) {
+ addClasspath(PathUtil.getJdkClassesRootsFromCurrentJre())
+ }
+ for (element in pass.classpath) {
+ addClasspath(File(element))
+ }
+
+ addSources(pass.sourceRoots.map { it.path })
+
+ loadLanguageVersionSettings(pass.languageVersion, pass.apiVersion)
+
+ val environment = createCoreEnvironment()
+ val (facade, _) = createResolutionFacade(environment)
+
+ environment.getSourceFiles().asSequence()
+ .map { it.packageFqName }
+ .distinct()
+ .mapNotNull { facade.resolveSession.getPackageFragment(it) }
+ .map { DokkaDescriptorVisitor.visitPackageFragmentDescriptor(it, DRI.topLevel) }
+ .toList()
+ .let { Module(it) }
+ }.also { println("${pass.analysisPlatform}:\n${it.pretty()}\n\n") }
}
+
}
+
+private class DokkaMessageCollector(private val logger: DokkaLogger) : MessageCollector {
+ override fun clear() {
+ seenErrors = false
+ }
+
+ private var seenErrors = false
+
+ override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
+ if (severity == CompilerMessageSeverity.ERROR) {
+ seenErrors = true
+ }
+ logger.error(MessageRenderer.PLAIN_FULL_PATHS.render(severity, message, location))
+ }
+
+ override fun hasErrors() = seenErrors
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/Model/DocumentationNode.kt b/core/src/main/kotlin/Model/DocumentationNode.kt
index 8da099ca..1871e21c 100644
--- a/core/src/main/kotlin/Model/DocumentationNode.kt
+++ b/core/src/main/kotlin/Model/DocumentationNode.kt
@@ -1,72 +1,73 @@
package org.jetbrains.dokka.Model
-import org.jetbrains.dokka.links.Callable
import org.jetbrains.dokka.links.DRI
-import org.jetbrains.dokka.links.withClass
import org.jetbrains.kotlin.descriptors.*
-class Module(val packages: List<Package>) : DocumentationNode<Nothing>(DRI.topLevel, DRI.topLevel) {
+class Module(val packages: List<Package>) : DocumentationNode<Nothing>() {
+ override val dri: DRI
+ get() = DRI.topLevel
+
override val children: List<Package>
get() = packages
}
class Package(
- val name: String,
+ override val dri: DRI,
override val functions: List<Function>,
override val properties: List<Property>,
override val classes: List<Class>
-) : ScopeNode<Nothing>(DRI(packageName = name), DRI.topLevel)
+) : ScopeNode<Nothing>() {
+ val name = dri.packageName.orEmpty()
+}
class Class(
+ override val dri: DRI,
val name: String,
override val functions: List<Function>,
override val properties: List<Property>,
override val classes: List<Class>,
- override val descriptor: ClassDescriptor,
- parent: DRI
-) : ScopeNode<ClassDescriptor>(parent.withClass(name), parent)
+ override val descriptor: ClassDescriptor
+) : ScopeNode<ClassDescriptor>()
class Function(
+ override val dri: DRI,
val name: String,
override val receiver: Parameter?,
val parameters: List<Parameter>,
- override val descriptor: FunctionDescriptor,
- parent: DRI
-) : CallableNode<FunctionDescriptor>(parent, descriptor) {
+ override val descriptor: FunctionDescriptor
+) : CallableNode<FunctionDescriptor>() {
override val children: List<Parameter>
get() = listOfNotNull(receiver) + parameters
}
class Property(
+ override val dri: DRI,
val name: String,
override val receiver: Parameter?,
- override val descriptor: PropertyDescriptor,
- parent: DRI
-) : CallableNode<PropertyDescriptor>(parent, descriptor) {
+ override val descriptor: PropertyDescriptor
+) : CallableNode<PropertyDescriptor>() {
override val children: List<Parameter>
get() = listOfNotNull(receiver)
}
class Parameter(
- val name: String,
- override val descriptor: ParameterDescriptor,
- parent: DRI,
- index: Int
-) : DocumentationNode<ParameterDescriptor>(parent, parent.copy(target = index)) {
+ override val dri: DRI,
+ val name: String?,
+ override val descriptor: ParameterDescriptor
+) : DocumentationNode<ParameterDescriptor>() {
override val children: List<DocumentationNode<*>>
get() = emptyList()
}
-abstract class DocumentationNode<out T : DeclarationDescriptor>(
- val dri: DRI,
- val parent: DRI
-) {
+abstract class DocumentationNode<out T : DeclarationDescriptor> {
open val descriptor: T? = null
+ abstract val dri: DRI
+
abstract val children: List<DocumentationNode<*>>
override fun toString(): String {
- return "${javaClass.name}($dri)"
+ return "${javaClass.simpleName}($dri)"
}
override fun equals(other: Any?) = other is DocumentationNode<*> && this.dri == other.dri
@@ -74,10 +75,7 @@ abstract class DocumentationNode<out T : DeclarationDescriptor>(
override fun hashCode() = dri.hashCode()
}
-abstract class ScopeNode<out T : ClassOrPackageFragmentDescriptor>(
- dri: DRI,
- parent: DRI
-) : DocumentationNode<T>(dri, parent) {
+abstract class ScopeNode<out T : ClassOrPackageFragmentDescriptor> : DocumentationNode<T>() {
abstract val functions: List<Function>
abstract val properties: List<Property>
abstract val classes: List<Class>
@@ -86,9 +84,6 @@ abstract class ScopeNode<out T : ClassOrPackageFragmentDescriptor>(
get() = functions + properties + classes
}
-abstract class CallableNode<out T: CallableDescriptor>(
- parent: DRI,
- descriptor: CallableDescriptor
-) : DocumentationNode<T>(parent.copy(callable = Callable.from(descriptor)), parent) {
+abstract class CallableNode<out T : CallableDescriptor> : DocumentationNode<T>() {
abstract val receiver: Parameter?
} \ No newline at end of file
diff --git a/core/src/main/kotlin/Utilities/nodeDebug.kt b/core/src/main/kotlin/Utilities/nodeDebug.kt
new file mode 100644
index 00000000..423e3e5f
--- /dev/null
+++ b/core/src/main/kotlin/Utilities/nodeDebug.kt
@@ -0,0 +1,24 @@
+package org.jetbrains.dokka.Utilities
+
+import org.jetbrains.dokka.Model.DocumentationNode
+import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+
+const val DOWN = '\u2503'
+const val BRANCH = '\u2523'
+const val LAST = '\u2517'
+
+fun <T : DeclarationDescriptor> DocumentationNode<T>.pretty(prefix: String = "", isLast: Boolean = true): String {
+ val nextPrefix = prefix + (if (isLast) ' ' else DOWN) + ' '
+
+ return prefix + (if (isLast) LAST else BRANCH) + this.toString() + children.dropLast(1).map {
+ it.pretty(
+ nextPrefix,
+ false
+ )
+ }.plus(
+ children.lastOrNull()?.pretty(nextPrefix)
+ ).filterNotNull().takeIf { it.isNotEmpty() }?.joinToString(
+ prefix = "\n",
+ separator = ""
+ ).orEmpty() + if (children.isEmpty()) "\n" else ""
+} \ No newline at end of file
diff --git a/core/src/main/kotlin/transformers/DefaultDocumentationToPageTransformer.kt b/core/src/main/kotlin/transformers/DefaultDocumentationToPageTransformer.kt
index fd2e6797..010c46f4 100644
--- a/core/src/main/kotlin/transformers/DefaultDocumentationToPageTransformer.kt
+++ b/core/src/main/kotlin/transformers/DefaultDocumentationToPageTransformer.kt
@@ -1,6 +1,5 @@
package org.jetbrains.dokka.transformers
-import org.jetbrains.dokka.DocumentationNode
import org.jetbrains.dokka.pages.ContentNode
import org.jetbrains.dokka.pages.ContentSymbol
import org.jetbrains.dokka.pages.ModulePageNode
diff --git a/core/src/main/kotlin/transformers/DocumentationToPageTransformer.kt b/core/src/main/kotlin/transformers/DocumentationToPageTransformer.kt
index b410915c..bf9a80ea 100644
--- a/core/src/main/kotlin/transformers/DocumentationToPageTransformer.kt
+++ b/core/src/main/kotlin/transformers/DocumentationToPageTransformer.kt
@@ -1,6 +1,6 @@
package org.jetbrains.dokka.transformers
-import org.jetbrains.dokka.DocumentationNode
+import org.jetbrains.dokka.Model.DocumentationNode
import org.jetbrains.dokka.pages.PageNode
interface DocumentationToPageTransformer {