• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.jetbrains.dokka.Formats
2 
3 import com.google.inject.Binder
4 import kotlinx.html.*
5 import org.jetbrains.dokka.*
6 import org.jetbrains.dokka.Utilities.bind
7 import org.jetbrains.dokka.Utilities.lazyBind
8 import org.jetbrains.dokka.Utilities.toOptional
9 import org.jetbrains.dokka.Utilities.toType
10 import java.net.URI
11 import kotlin.reflect.KClass
12 
13 
14 abstract class JavaLayoutHtmlFormatDescriptorBase : FormatDescriptor, DefaultAnalysisComponent {
15 
<lambda>null16     override fun configureOutput(binder: Binder): Unit = with(binder) {
17         bind<Generator>() toType generatorServiceClass
18         bind<LanguageService>() toType languageServiceClass
19         bind<JavaLayoutHtmlTemplateService>() toType templateServiceClass
20         bind<JavaLayoutHtmlUriProvider>() toType generatorServiceClass
21         lazyBind<JavaLayoutHtmlFormatOutlineFactoryService>() toOptional outlineFactoryClass
22         bind<PackageListService>() toType packageListServiceClass
23         bind<JavaLayoutHtmlFormatOutputBuilderFactory>() toType outputBuilderFactoryClass
24     }
25 
26     val generatorServiceClass = JavaLayoutHtmlFormatGenerator::class
27     abstract val languageServiceClass: KClass<out LanguageService>
28     abstract val templateServiceClass: KClass<out JavaLayoutHtmlTemplateService>
29     abstract val outlineFactoryClass: KClass<out JavaLayoutHtmlFormatOutlineFactoryService>?
30     abstract val packageListServiceClass: KClass<out PackageListService>
31     abstract val outputBuilderFactoryClass: KClass<out JavaLayoutHtmlFormatOutputBuilderFactory>
32 }
33 
<lambda>null34 class JavaLayoutHtmlFormatDescriptor : JavaLayoutHtmlFormatDescriptorBase(), DefaultAnalysisComponentServices by KotlinAsKotlin {
35     override val outputBuilderFactoryClass: KClass<out JavaLayoutHtmlFormatOutputBuilderFactory> = JavaLayoutHtmlFormatOutputBuilderFactoryImpl::class
36     override val packageListServiceClass: KClass<out PackageListService> = JavaLayoutHtmlPackageListService::class
37     override val languageServiceClass = KotlinLanguageService::class
38     override val templateServiceClass = JavaLayoutHtmlTemplateService.Default::class
39     override val outlineFactoryClass = null
40 }
41 
<lambda>null42 class JavaLayoutHtmlAsJavaFormatDescriptor : JavaLayoutHtmlFormatDescriptorBase(), DefaultAnalysisComponentServices by KotlinAsJava {
43     override val outputBuilderFactoryClass: KClass<out JavaLayoutHtmlFormatOutputBuilderFactory> = JavaLayoutHtmlFormatOutputBuilderFactoryImpl::class
44     override val packageListServiceClass: KClass<out PackageListService> = JavaLayoutHtmlPackageListService::class
45     override val languageServiceClass = NewJavaLanguageService::class
46     override val templateServiceClass = JavaLayoutHtmlTemplateService.Default::class
47     override val outlineFactoryClass = null
48 }
49 
50 interface JavaLayoutHtmlFormatOutlineFactoryService {
generateOutlinesnull51     fun generateOutlines(outputProvider: (URI) -> Appendable, nodes: Iterable<DocumentationNode>)
52 }
53 
54 
55 interface JavaLayoutHtmlUriProvider {
56     fun tryGetContainerUri(node: DocumentationNode): URI?
57     fun tryGetMainUri(node: DocumentationNode): URI?
58     fun tryGetOutlineRootUri(node: DocumentationNode): URI?
59     fun containerUri(node: DocumentationNode): URI = tryGetContainerUri(node) ?: error("Unsupported ${node.kind}")
60     fun mainUri(node: DocumentationNode): URI = tryGetMainUri(node) ?: error("Unsupported ${node.kind}")
61     fun outlineRootUri(node: DocumentationNode): URI = tryGetOutlineRootUri(node) ?: error("Unsupported ${node.kind}")
62 
63 
64     fun linkTo(to: DocumentationNode, from: URI): String {
65         return mainUri(to).relativeTo(from).toString()
66     }
67 
68     fun linkToFromOutline(to: DocumentationNode, from: URI): String {
69         return outlineRootUri(to).relativeTo(from).toString()
70     }
71 
72     fun mainUriOrWarn(node: DocumentationNode): URI? = tryGetMainUri(node) ?: (null).also {
73         AssertionError("Not implemented mainUri for ${node.kind} (${node})").printStackTrace()
74     }
75 }
76 
77 
78 interface JavaLayoutHtmlTemplateService {
composePagenull79     fun composePage(
80             page: JavaLayoutHtmlFormatOutputBuilder.Page,
81             tagConsumer: TagConsumer<Appendable>,
82             headContent: HEAD.() -> Unit,
83             bodyContent: BODY.() -> Unit
84     )
85 
86     class Default : JavaLayoutHtmlTemplateService {
87         override fun composePage(
88                 page: JavaLayoutHtmlFormatOutputBuilder.Page,
89                 tagConsumer: TagConsumer<Appendable>,
90                 headContent: HEAD.() -> Unit,
91                 bodyContent: BODY.() -> Unit
92         ) {
93             tagConsumer.html {
94                 head {
95                     meta(charset = "UTF-8")
96                     headContent()
97                 }
98                 body(block = bodyContent)
99             }
100         }
101     }
102 }
103 
<lambda>null104 val DocumentationNode.companion get() = members(NodeKind.Object).find { it.details(NodeKind.Modifier).any { it.name == "companion" } }
105 
signatureForAnchornull106 fun DocumentationNode.signatureForAnchor(logger: DokkaLogger): String {
107 
108     fun StringBuilder.appendReceiverIfSo() {
109         detailOrNull(NodeKind.Receiver)?.let {
110             append("(")
111             append(it.detail(NodeKind.Type).qualifiedNameFromType())
112             append(").")
113         }
114     }
115 
116     return when (kind) {
117         NodeKind.Function, NodeKind.Constructor, NodeKind.CompanionObjectFunction -> buildString {
118             if (kind == NodeKind.CompanionObjectFunction) {
119                 append("Companion.")
120             }
121             appendReceiverIfSo()
122             append(prettyName)
123             details(NodeKind.Parameter).joinTo(this, prefix = "(", postfix = ")") { it.detail(NodeKind.Type).qualifiedNameFromType() }
124         }
125         NodeKind.Property, NodeKind.CompanionObjectProperty -> buildString {
126             if (kind == NodeKind.CompanionObjectProperty) {
127                 append("Companion.")
128             }
129             appendReceiverIfSo()
130             append(name)
131             append(":")
132             append(detail(NodeKind.Type).qualifiedNameFromType())
133         }
134         NodeKind.TypeParameter, NodeKind.Parameter -> this.detail(NodeKind.Signature).name // Todo Why not signatureForAnchor
135         NodeKind.Field -> name
136         NodeKind.EnumItem -> "ENUM_VALUE:$name"
137         NodeKind.Attribute -> "attr_$name"
138         else -> "Not implemented signatureForAnchor $this".also { logger.warn(it) }
139     }
140 }
141 
142