1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
package org.jetbrains.dokka
import org.jetbrains.dokka.Model.Module
import org.jetbrains.dokka.Utilities.genericPretty
import org.jetbrains.dokka.Model.transformers.ActualExpectedMerger
import org.jetbrains.dokka.Utilities.pretty
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.pages.MarkdownToContentConverter
import org.jetbrains.dokka.pages.ModulePageNode
import org.jetbrains.dokka.pages.PageNode
import org.jetbrains.dokka.renderers.FileWriter
import org.jetbrains.dokka.renderers.HtmlRenderer
import org.jetbrains.dokka.resolvers.DefaultLocationProvider
import org.jetbrains.dokka.transformers.DefaultDocumentationToPageTransformer
import org.jetbrains.dokka.transformers.TopDownPageNodeMerger
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 configuration: DokkaConfiguration,
private val logger: DokkaLogger
) {
fun generate(): Unit {
configuration.passesConfigurations.map { 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)
val markdownConverter = MarkdownToContentConverter(facade, logger)
val module = environment.getSourceFiles().asSequence()
.map { it.packageFqName }
.distinct()
.mapNotNull { facade.resolveSession.getPackageFragment(it) }
.map { DokkaDescriptorVisitor.visitPackageFragmentDescriptor(it, DRI.topLevel) }
.toList()
.let { Module(it) }
.let { ActualExpectedMerger(it) }
.also { println("${pass.analysisPlatform}:\n${it.pretty()}\n\n") }
DefaultDocumentationToPageTransformer(markdownConverter, logger).transform(pass, module)
}
}
.merge()
.also {
HtmlRenderer(
FileWriter(configuration.outputDir, ""),
DefaultLocationProvider(it, configuration, ".${configuration.format}")
).render(it)
}
}
}
private fun Iterable<ModulePageNode>.merge(): PageNode {
this.forEach { it.genericPretty().also(::println) }
return TopDownPageNodeMerger().mergeModules(this).also {
it.genericPretty().also(::println)
}
}
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
}
|