blob: 0ee3c888080155fd246472c23e655ff42a44f6e7 [file] [log] [blame]
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +04001package org.jetbrains.dokka
2
3import java.util.LinkedHashMap
Dmitry Jemerov0c584d02015-01-12 17:23:07 +01004import org.jetbrains.dokka.LanguageService.RenderMode
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +04005
Dmitry Jemerovd9bfa022015-02-19 18:59:00 +01006public data class FormatLink(val text: String, val href: String)
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +04007
Dmitry Jemerov66593372015-03-03 19:35:56 +01008enum class ListKind {
9 Ordered
10 Unordered
11}
12
Dmitry Jemerovea1f4cc2015-02-19 19:51:01 +010013public abstract class StructuredFormatService(locationService: LocationService,
14 val languageService: LanguageService,
15 override val extension: String) : FormatService {
16 val locationService: LocationService = locationService.withExtension(extension)
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040017
Dmitry Jemerov44cef5c2015-02-26 19:34:49 +010018 abstract public fun appendBlockCode(to: StringBuilder, line: String, language: String)
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040019 abstract public fun appendHeader(to: StringBuilder, text: String, level: Int = 1)
Dmitry Jemerov8ef68182014-12-30 12:36:14 +010020 abstract public fun appendParagraph(to: StringBuilder, text: String)
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040021 abstract public fun appendLine(to: StringBuilder, text: String)
22 public abstract fun appendLine(to: StringBuilder)
Dmitry Jemerov85a3ae72015-02-20 14:08:30 +010023 public abstract fun appendAnchor(to: StringBuilder, anchor: String)
Ilya Ryzhenkov499d0822014-07-15 16:18:53 +040024
Ilya Ryzhenkovaa59acb2014-07-15 20:05:55 +040025 public abstract fun appendTable(to: StringBuilder, body: () -> Unit)
26 public abstract fun appendTableHeader(to: StringBuilder, body: () -> Unit)
27 public abstract fun appendTableBody(to: StringBuilder, body: () -> Unit)
28 public abstract fun appendTableRow(to: StringBuilder, body: () -> Unit)
29 public abstract fun appendTableCell(to: StringBuilder, body: () -> Unit)
Ilya Ryzhenkov499d0822014-07-15 16:18:53 +040030
Ilya Ryzhenkovaa59acb2014-07-15 20:05:55 +040031 public abstract fun formatText(text: String): String
Ilya Ryzhenkov7c6da4b2014-10-03 19:09:31 +040032 public abstract fun formatSymbol(text: String): String
33 public abstract fun formatKeyword(text: String): String
Dmitry Jemerov4494fd02015-02-26 21:34:27 +010034 public abstract fun formatIdentifier(text: String, kind: IdentifierKind): String
Dmitry Jemerov2e6eda92015-03-10 17:00:14 +010035 public fun formatEntity(text: String): String = text
Ilya Ryzhenkov71cd87e2014-10-03 22:51:44 +040036 public abstract fun formatLink(text: String, href: String): String
Dmitry Jemerovd9bfa022015-02-19 18:59:00 +010037 public open fun formatLink(link: FormatLink): String = formatLink(formatText(link.text), link.href)
Ilya Ryzhenkov9f0ff552014-10-13 13:38:40 +040038 public abstract fun formatStrong(text: String): String
Dmitry Jemerove17eaa52015-01-09 20:59:58 +010039 public abstract fun formatStrikethrough(text: String): String
Ilya Ryzhenkov9f0ff552014-10-13 13:38:40 +040040 public abstract fun formatEmphasis(text: String): String
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040041 public abstract fun formatCode(code: String): String
Dmitry Jemerov66593372015-03-03 19:35:56 +010042 public abstract fun formatUnorderedList(text: String): String
43 public abstract fun formatOrderedList(text: String): String
44 public abstract fun formatListItem(text: String, kind: ListKind): String
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040045 public abstract fun formatBreadcrumbs(items: Iterable<FormatLink>): String
Dmitry Jemerov722c9af2015-02-26 16:28:05 +010046 public abstract fun formatNonBreakingSpace(): String
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040047
Dmitry Jemerov66593372015-03-03 19:35:56 +010048 open fun formatText(location: Location, nodes: Iterable<ContentNode>, listKind: ListKind = ListKind.Unordered): String {
49 return nodes.map { formatText(location, it, listKind) }.join("")
Ilya Ryzhenkov778e2b32014-09-29 20:54:59 +040050 }
51
Dmitry Jemerov66593372015-03-03 19:35:56 +010052 open fun formatText(location: Location, content: ContentNode, listKind: ListKind = ListKind.Unordered): String {
Ilya Ryzhenkov455d74a2014-09-19 22:25:27 +030053 return StringBuilder {
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +040054 when (content) {
Dmitry Jemerov8ef68182014-12-30 12:36:14 +010055 is ContentText -> append(formatText(content.text))
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +040056 is ContentSymbol -> append(formatSymbol(content.text))
57 is ContentKeyword -> append(formatKeyword(content.text))
Dmitry Jemerov4494fd02015-02-26 21:34:27 +010058 is ContentIdentifier -> append(formatIdentifier(content.text, content.kind))
Dmitry Jemerov722c9af2015-02-26 16:28:05 +010059 is ContentNonBreakingSpace -> append(formatNonBreakingSpace())
Dmitry Jemerov2e6eda92015-03-10 17:00:14 +010060 is ContentEntity -> append(formatEntity(content.text))
Ilya Ryzhenkov9f0ff552014-10-13 13:38:40 +040061 is ContentStrong -> append(formatStrong(formatText(location, content.children)))
Dmitry Jemerove17eaa52015-01-09 20:59:58 +010062 is ContentStrikethrough -> append(formatStrikethrough(formatText(location, content.children)))
Ilya Ryzhenkov9f0ff552014-10-13 13:38:40 +040063 is ContentCode -> append(formatCode(formatText(location, content.children)))
64 is ContentEmphasis -> append(formatEmphasis(formatText(location, content.children)))
Dmitry Jemerov66593372015-03-03 19:35:56 +010065 is ContentUnorderedList -> append(formatUnorderedList(formatText(location, content.children, ListKind.Unordered)))
66 is ContentOrderedList -> append(formatOrderedList(formatText(location, content.children, ListKind.Ordered)))
67 is ContentListItem -> append(formatListItem(formatText(location, content.children), listKind))
Ilya Ryzhenkov18399492014-12-22 09:50:17 +020068
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +040069 is ContentNodeLink -> {
Dmitry Jemerov184a24c2015-02-25 19:03:51 +010070 val node = content.node
71 val linkTo = if (node != null) locationHref(location, node) else "#"
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +040072 val linkText = formatText(location, content.children)
Dmitry Jemerov4b61be32015-02-26 21:17:13 +010073 if (linkTo == ".") {
74 append(linkText)
75 } else {
76 append(formatLink(linkText, linkTo))
77 }
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +040078 }
Ilya Ryzhenkov71cd87e2014-10-03 22:51:44 +040079 is ContentExternalLink -> {
80 val linkText = formatText(location, content.children)
Dmitry Jemerov4b61be32015-02-26 21:17:13 +010081 if (content.href == ".") {
82 append(linkText)
83 } else {
84 append(formatLink(linkText, content.href))
85 }
Ilya Ryzhenkov71cd87e2014-10-03 22:51:44 +040086 }
Dmitry Jemerov76e4d3c2015-03-23 18:52:05 +010087 is ContentParagraph -> appendParagraph(this, formatText(location, content.children))
88 is ContentBlockCode -> appendBlockCode(this, formatText(location, content.children), content.language)
89 is ContentHeading -> appendHeader(this, formatText(location, content.children), content.level)
Dmitry Jemerov0d0fc1f2015-02-10 18:32:12 +010090 is ContentBlock -> append(formatText(location, content.children))
Ilya Ryzhenkov455d74a2014-09-19 22:25:27 +030091 }
92 }.toString()
93 }
94
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040095 open public fun link(from: DocumentationNode, to: DocumentationNode): FormatLink = link(from, to, extension)
96
97 open public fun link(from: DocumentationNode, to: DocumentationNode, extension: String): FormatLink {
Dmitry Jemerovea1f4cc2015-02-19 19:51:01 +010098 return FormatLink(to.name, locationService.relativePathToLocation(from, to))
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +040099 }
100
Dmitry Jemerov85a3ae72015-02-20 14:08:30 +0100101 fun locationHref(from: Location, to: DocumentationNode): String {
102 val topLevelPage = to.references(DocumentationReference.Kind.TopLevelPage).singleOrNull()?.to
103 if (topLevelPage != null) {
104 return from.relativePathTo(locationService.location(topLevelPage), to.name)
105 }
106 return from.relativePathTo(locationService.location(to))
107 }
108
Dmitry Jemerove1a38842015-02-10 18:55:12 +0100109 fun appendDocumentation(location: Location, to: StringBuilder, overloads: Iterable<DocumentationNode>) {
110 val breakdownBySummary = overloads.groupByTo(LinkedHashMap()) { node -> node.content }
Dmitry Jemerovbfd9ffd2015-01-30 17:59:15 +0100111
Dmitry Jemerove1a38842015-02-10 18:55:12 +0100112 for ((summary, items) in breakdownBySummary) {
113 items.forEach {
Dmitry Jemerovf90ee502015-02-26 13:55:37 +0100114 appendAsSignature(to) {
115 to.append(formatCode(formatText(location, languageService.render(it))))
116 it.appendSourceLink(to)
117 }
Dmitry Jemerove1a38842015-02-10 18:55:12 +0100118 it.appendOverrides(to)
Dmitry Jemerova60d8ba2015-02-24 16:24:00 +0100119 it.appendDeprecation(location, to)
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400120 }
Dmitry Jemerove1a38842015-02-10 18:55:12 +0100121 // All items have exactly the same documentation, so we can use any item to render it
122 val item = items.first()
Dmitry Jemerovf4623172015-03-02 16:17:28 +0100123 item.details(DocumentationNode.Kind.OverloadGroupNote).forEach {
124 to.append(formatText(location, it.content))
125 }
Dmitry Jemerovebbf2652015-02-10 19:35:27 +0100126 to.append(formatText(location, item.content.summary))
Dmitry Jemerove1a38842015-02-10 18:55:12 +0100127 appendDescription(location, to, item)
Dmitry Jemerovebbf2652015-02-10 19:35:27 +0100128 appendLine(to)
129 appendLine(to)
Dmitry Jemerove1a38842015-02-10 18:55:12 +0100130 }
131 }
132
Dmitry Jemerov76e4d3c2015-03-23 18:52:05 +0100133 private fun DocumentationNode.isModuleOrPackage(): Boolean =
134 kind == DocumentationNode.Kind.Module || kind == DocumentationNode.Kind.Package
135
Dmitry Jemerovf90ee502015-02-26 13:55:37 +0100136 protected open fun appendAsSignature(to: StringBuilder, block: () -> Unit) {
137 block()
138 }
139
Dmitry Jemerove1a38842015-02-10 18:55:12 +0100140 fun appendDescription(location: Location, to: StringBuilder, node: DocumentationNode) {
141 if (node.content.description != ContentEmpty) {
142 appendHeader(to, "Description", 3)
143 appendLine(to, formatText(location, node.content.description))
144 appendLine(to)
145 }
146 node.content.getSectionsWithSubjects().forEach {
147 appendSectionWithSubject(it.getKey(), location, it.getValue(), to)
148 }
149
150 for (section in node.content.sections.filter { it.subjectName == null }) {
151 appendLine(to, formatStrong(formatText(section.tag)))
152 appendLine(to, formatText(location, section))
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400153 }
154 }
155
Dmitry Jemerov0fac1d92015-01-30 19:01:40 +0100156 fun Content.getSectionsWithSubjects(): Map<String, List<ContentSection>> =
157 sections.filter { it.subjectName != null }.groupBy { it.tag }
158
159 fun appendSectionWithSubject(title: String, location: Location, subjectSections: List<ContentSection>, to: StringBuilder) {
Dmitry Jemerovbfd9ffd2015-01-30 17:59:15 +0100160 appendHeader(to, title, 3)
Dmitry Jemerov0fac1d92015-01-30 19:01:40 +0100161 subjectSections.forEach {
162 val subjectName = it.subjectName
163 if (subjectName != null) {
Dmitry Jemerov85a3ae72015-02-20 14:08:30 +0100164 appendAnchor(to, subjectName)
Dmitry Jemerov0fac1d92015-01-30 19:01:40 +0100165 to.append(formatCode(subjectName)).append(" - ")
166 to.append(formatText(location, it))
Dmitry Jemerovbfd9ffd2015-01-30 17:59:15 +0100167 appendLine(to)
168 }
169 }
Dmitry Jemerovc43a4372014-12-29 20:22:43 +0100170 }
171
Dmitry Jemerov0dd5ea32015-01-14 13:30:43 +0100172 private fun DocumentationNode.appendOverrides(to: StringBuilder) {
173 overrides.forEach {
174 to.append("Overrides ")
Dmitry Jemerovea1f4cc2015-02-19 19:51:01 +0100175 val location = locationService.relativePathToLocation(this, it)
Dmitry Jemerov0dd5ea32015-01-14 13:30:43 +0100176 appendLine(to, formatLink(FormatLink(it.owner!!.name + "." + it.name, location)))
177 }
178 }
179
Dmitry Jemerova60d8ba2015-02-24 16:24:00 +0100180 private fun DocumentationNode.appendDeprecation(location: Location, to: StringBuilder) {
Dmitry Jemerov0dd5ea32015-01-14 13:30:43 +0100181 if (deprecation != null) {
182 val deprecationParameter = deprecation!!.details(DocumentationNode.Kind.Parameter).firstOrNull()
183 val deprecationValue = deprecationParameter?.details(DocumentationNode.Kind.Value)?.firstOrNull()
184 if (deprecationValue != null) {
Dmitry Jemerov7003ad82015-02-26 13:20:41 +0100185 to.append(formatStrong("Deprecated:")).append(" ")
Dmitry Jemerov0dd5ea32015-01-14 13:30:43 +0100186 appendLine(to, formatText(deprecationValue.name.trim("\"")))
Dmitry Jemerovf7c2f2a2015-02-26 19:45:36 +0100187 appendLine(to)
Dmitry Jemerova60d8ba2015-02-24 16:24:00 +0100188 } else if (deprecation?.content != Content.Empty) {
Dmitry Jemerov7003ad82015-02-26 13:20:41 +0100189 to.append(formatStrong("Deprecated:")).append(" ")
Dmitry Jemerova60d8ba2015-02-24 16:24:00 +0100190 to.append(formatText(location, deprecation!!.content))
Dmitry Jemerov0dd5ea32015-01-14 13:30:43 +0100191 } else {
192 appendLine(to, formatStrong("Deprecated"))
Dmitry Jemerovf7c2f2a2015-02-26 19:45:36 +0100193 appendLine(to)
Dmitry Jemerov0dd5ea32015-01-14 13:30:43 +0100194 }
195 }
196 }
197
Dmitry Jemerov6146fa82015-01-14 18:46:36 +0100198 private fun DocumentationNode.appendSourceLink(to: StringBuilder) {
199 val sourceUrl = details(DocumentationNode.Kind.SourceUrl).firstOrNull()
200 if (sourceUrl != null) {
Dmitry Jemerovebbf2652015-02-10 19:35:27 +0100201 to.append(" ")
202 appendLine(to, formatLink("(source)", sourceUrl.name))
203 } else {
204 appendLine(to)
Dmitry Jemerov6146fa82015-01-14 18:46:36 +0100205 }
206 }
207
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +0400208 fun appendLocation(location: Location, to: StringBuilder, nodes: Iterable<DocumentationNode>) {
Dmitry Jemerov76e4d3c2015-03-23 18:52:05 +0100209 val singleNode = nodes.singleOrNull()
210 if (singleNode != null && singleNode.isModuleOrPackage()) {
211 if (singleNode.kind == DocumentationNode.Kind.Package) {
212 appendHeader(to, "Package " + formatText(singleNode.name), 2)
213 }
214 to.append(formatText(location, singleNode.content))
215 } else {
216 val breakdownByName = nodes.groupBy { node -> node.name }
217 for ((name, items) in breakdownByName) {
218 appendHeader(to, formatText(name))
219 appendDocumentation(location, to, items)
220 }
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400221 }
222 }
223
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400224 private fun StructuredFormatService.appendSection(location: Location, caption: String, nodes: List<DocumentationNode>, node: DocumentationNode, to: StringBuilder) {
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400225 if (nodes.any()) {
226 appendHeader(to, caption, 3)
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400227
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400228 val children = nodes.sortBy { it.name }
229 val membersMap = children.groupBy { link(node, it) }
Ilya Ryzhenkovaa59acb2014-07-15 20:05:55 +0400230
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400231 appendTable(to) {
232 appendTableBody(to) {
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +0400233 for ((memberLocation, members) in membersMap) {
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400234 appendTableRow(to) {
235 appendTableCell(to) {
Dmitry Jemerov8ef68182014-12-30 12:36:14 +0100236 to.append(formatLink(memberLocation))
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400237 }
238 appendTableCell(to) {
Ilya Ryzhenkov280dc292014-10-14 16:08:10 +0400239 val breakdownBySummary = members.groupBy { formatText(location, it.summary) }
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400240 for ((summary, items) in breakdownBySummary) {
Dmitry Jemerov3fc3e332014-12-30 15:35:00 +0100241 val signatureTexts = items map { signature ->
Dmitry Jemerov7170d632015-03-02 14:35:47 +0100242 val signatureText = languageService.render(signature, RenderMode.SUMMARY)
Dmitry Jemerov673bfdd2015-03-19 10:51:26 +0100243 if (signatureText is ContentBlock && signatureText.isEmpty()) {
244 ""
245 } else {
246 val signatureAsCode = ContentCode()
247 signatureAsCode.append(signatureText)
248 formatText(location, signatureAsCode)
249 }
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400250 }
Dmitry Jemerov3fc3e332014-12-30 15:35:00 +0100251 signatureTexts.subList(0, signatureTexts.size()-1).forEach {
Dmitry Jemerov86a6db82015-02-26 14:40:02 +0100252 appendAsSignature(to) {
253 appendLine(to, it)
254 }
Dmitry Jemerov3fc3e332014-12-30 15:35:00 +0100255 }
Dmitry Jemerovf90ee502015-02-26 13:55:37 +0100256 appendAsSignature(to) {
257 to.append(signatureTexts.last())
258 }
Ilya Ryzhenkova52e1d52014-10-03 15:57:16 +0400259 if (!summary.isEmpty()) {
Dmitry Jemerov8ef68182014-12-30 12:36:14 +0100260 to.append(summary)
Ilya Ryzhenkovaa59acb2014-07-15 20:05:55 +0400261 }
262 }
263 }
Ilya Ryzhenkove8447fd2014-07-15 16:37:50 +0400264 }
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400265 }
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400266 }
267 }
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400268 }
269 }
270
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +0400271 override fun appendNodes(location: Location, to: StringBuilder, nodes: Iterable<DocumentationNode>) {
272 val breakdownByLocation = nodes.groupBy { node ->
Dmitry Jemerovd9bfa022015-02-19 18:59:00 +0100273 formatBreadcrumbs(node.path.filterNot { it.name.isEmpty() }.map { link(node, it) })
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +0400274 }
275
276 for ((breadcrumbs, items) in breakdownByLocation) {
277 appendLine(to, breadcrumbs)
278 appendLine(to)
Dmitry Jemerov4b0dcee2015-01-09 19:48:44 +0100279 appendLocation(location, to, items.filter { it.kind != DocumentationNode.Kind.ExternalClass })
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +0400280 }
281
282 for (node in nodes) {
Dmitry Jemerov4b0dcee2015-01-09 19:48:44 +0100283 if (node.kind == DocumentationNode.Kind.ExternalClass) {
284 appendSection(location, "Extensions for ${node.name}", node.members, node, to)
285 continue
286 }
287
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400288 appendSection(location, "Packages", node.members(DocumentationNode.Kind.Package), node, to)
289 appendSection(location, "Types", node.members.filter {
290 it.kind in setOf(
291 DocumentationNode.Kind.Class,
292 DocumentationNode.Kind.Interface,
293 DocumentationNode.Kind.Enum,
Dmitry Jemerov716483c2014-12-30 17:41:14 +0100294 DocumentationNode.Kind.Object,
295 DocumentationNode.Kind.AnnotationClass)
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400296 }, node, to)
Dmitry Jemerov4b0dcee2015-01-09 19:48:44 +0100297 appendSection(location, "Extensions for External Classes", node.members(DocumentationNode.Kind.ExternalClass), node, to)
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400298 appendSection(location, "Constructors", node.members(DocumentationNode.Kind.Constructor), node, to)
299 appendSection(location, "Properties", node.members(DocumentationNode.Kind.Property), node, to)
300 appendSection(location, "Functions", node.members(DocumentationNode.Kind.Function), node, to)
Dmitry Jemerovc7916f72015-03-17 19:54:11 +0100301 appendSection(location, "Companion Object Properties", node.members(DocumentationNode.Kind.CompanionObjectProperty), node, to)
302 appendSection(location, "Companion Object Functions", node.members(DocumentationNode.Kind.CompanionObjectFunction), node, to)
Dmitry Jemerovc4f40a02015-01-12 16:32:30 +0100303 appendSection(location, "Enum Values", node.members(DocumentationNode.Kind.EnumItem), node, to)
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400304 appendSection(location, "Other members", node.members.filter {
305 it.kind !in setOf(
306 DocumentationNode.Kind.Class,
307 DocumentationNode.Kind.Interface,
Dmitry Jemerov716483c2014-12-30 17:41:14 +0100308 DocumentationNode.Kind.Enum,
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400309 DocumentationNode.Kind.Object,
Dmitry Jemerov716483c2014-12-30 17:41:14 +0100310 DocumentationNode.Kind.AnnotationClass,
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400311 DocumentationNode.Kind.Constructor,
312 DocumentationNode.Kind.Property,
313 DocumentationNode.Kind.Package,
314 DocumentationNode.Kind.Function,
Dmitry Jemerovc7916f72015-03-17 19:54:11 +0100315 DocumentationNode.Kind.CompanionObjectProperty,
316 DocumentationNode.Kind.CompanionObjectFunction,
Dmitry Jemerovc4f40a02015-01-12 16:32:30 +0100317 DocumentationNode.Kind.ExternalClass,
318 DocumentationNode.Kind.EnumItem
Ilya Ryzhenkov49077362014-10-14 19:53:13 +0400319 )
320 }, node, to)
Dmitry Jemerov4f590342015-02-26 19:19:55 +0100321 appendSection(location, "Extension Properties", node.extensions.filter { it.kind == DocumentationNode.Kind.Property }, node, to)
322 appendSection(location, "Extension Functions", node.extensions.filter { it.kind == DocumentationNode.Kind.Function }, node, to)
Dmitry Jemerovc7916f72015-03-17 19:54:11 +0100323 appendSection(location, "Companion Object Extension Properties", node.extensions.filter { it.kind == DocumentationNode.Kind.CompanionObjectProperty }, node, to)
324 appendSection(location, "Companion Object Extension Functions", node.extensions.filter { it.kind == DocumentationNode.Kind.CompanionObjectFunction }, node, to)
Dmitry Jemerovc4f40a02015-01-12 16:32:30 +0100325 appendSection(location, "Inheritors",
326 node.inheritors.filter { it.kind != DocumentationNode.Kind.EnumItem }, node, to)
Ilya Ryzhenkovd6fd0452014-10-03 20:20:02 +0400327 appendSection(location, "Links", node.links, node, to)
328
329 }
330 }
Ilya Ryzhenkov62cb5092014-07-15 15:54:05 +0400331}