diff options
Diffstat (limited to 'plugins/base/src')
28 files changed, 925 insertions, 626 deletions
diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index 4c3f35db..7e88d08f 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -209,10 +209,6 @@ class DokkaBase : DokkaPlugin() { htmlPreprocessors providing ::NavigationPageInstaller order { after(rootCreator) } } - val navigationSearchInstaller by extending { - htmlPreprocessors providing ::NavigationSearchInstaller order { after(rootCreator) } - } - val scriptsInstaller by extending { htmlPreprocessors providing ::ScriptsInstaller order { after(rootCreator) } } diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index d63e8da6..31753332 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -15,6 +15,7 @@ import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint import org.jetbrains.dokka.base.resolvers.local.DokkaBaseLocationProvider import org.jetbrains.dokka.base.templating.InsertTemplateExtra import org.jetbrains.dokka.base.templating.PathToRootSubstitutionCommand +import org.jetbrains.dokka.base.templating.ProjectNameSubstitutionCommand import org.jetbrains.dokka.base.templating.ResolveLinkCommand import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.DisplaySourceSet @@ -603,22 +604,13 @@ open class HtmlRenderer( override fun FlowContent.buildNavigation(page: PageNode) = - div("navigation-wrapper") { - id = "navigation-wrapper" - div(classes = "breadcrumbs") { - val path = locationProvider.ancestors(page).filterNot { it is RendererSpecificPage }.asReversed() - if (path.isNotEmpty()) { - buildNavigationElement(path.first(), page) - path.drop(1).forEach { node -> - text("/") - buildNavigationElement(node, page) - } - } - } - div("pull-right d-flex") { - filterButtons(page) - div { - id = "searchBar" + div(classes = "breadcrumbs") { + val path = locationProvider.ancestors(page).filterNot { it is RendererSpecificPage }.asReversed() + if (path.size > 1) { + buildNavigationElement(path.first(), page) + path.drop(1).forEach { node -> + text("/") + buildNavigationElement(node, page) } } } @@ -685,12 +677,15 @@ open class HtmlRenderer( pageContext: ContentPage ) { div("sample-container") { - code(code.style.joinToString(" ") { it.toString().toLowerCase() }) { - attributes["theme"] = "idea" - pre { + val codeLang = "lang-" + code.language.ifEmpty { "kotlin" } + val stylesWithBlock = code.style + TextStyle.Block + codeLang + pre { + code(stylesWithBlock.joinToString(" ") { it.toString().toLowerCase() }) { + attributes["theme"] = "idea" code.children.forEach { buildContentNode(it, pageContext) } } } + copyButton() } } @@ -698,7 +693,9 @@ open class HtmlRenderer( code: ContentCodeInline, pageContext: ContentPage ) { - code { + val codeLang = "lang-" + code.language.ifEmpty { "kotlin" } + val stylesWithBlock = code.style + codeLang + code(stylesWithBlock.joinToString(" ") { it.toString().toLowerCase() }) { code.children.forEach { buildContentNode(it, pageContext) } } } @@ -716,7 +713,7 @@ open class HtmlRenderer( } unappliedStyles.isNotEmpty() -> { val styleToApply = unappliedStyles.first() - applyStyle(styleToApply){ + applyStyle(styleToApply) { buildText(textNode, unappliedStyles - styleToApply) } } @@ -726,12 +723,13 @@ open class HtmlRenderer( } } - private inline fun FlowContent.applyStyle(styleToApply: Style, crossinline body: FlowContent.() -> Unit){ - when(styleToApply){ + private inline fun FlowContent.applyStyle(styleToApply: Style, crossinline body: FlowContent.() -> Unit) { + when (styleToApply) { TextStyle.Bold -> b { body() } TextStyle.Italic -> i { body() } TextStyle.Strikethrough -> strike { body() } TextStyle.Strong -> strong { body() } + is TokenStyle -> span("token " + styleToApply.toString().toLowerCase()) { body() } else -> body() } } @@ -741,8 +739,6 @@ open class HtmlRenderer( super.render(root) } - private fun PageNode.root(path: String) = locationProvider.pathToRoot(this) + path - override fun buildPage(page: ContentPage, content: (FlowContent, ContentPage) -> Unit): String = buildHtml(page, page.embeddedResources) { div("main-content") { @@ -762,11 +758,19 @@ open class HtmlRenderer( meta(name = "viewport", content = "width=device-width, initial-scale=1", charset = "UTF-8") title(page.name) templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { - link(href = page.root("###images/logo-icon.svg"), rel = "icon", type = "image/svg") + link(href = "###images/logo-icon.svg", rel = "icon", type = "image/svg") } templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { script { unsafe { +"""var pathToRoot = "###";""" } } } + // This script doesn't need to be there but it is nice to have since app in dark mode doesn't 'blink' (class is added before it is rendered) + script { unsafe { +""" + const storage = localStorage.getItem("dokka-dark-mode") + const savedDarkMode = storage ? JSON.parse(storage) : false + if(savedDarkMode === true){ + document.getElementsByTagName("html")[0].classList.add("theme-dark") + } + """.trimIndent() } } resources.forEach { when { it.substringBefore('?').substringAfterLast('.') == "css" -> @@ -803,24 +807,41 @@ open class HtmlRenderer( } } body { - div { - id = "container" + div("navigation-wrapper") { + id = "navigation-wrapper" div { - id = "leftColumn" + id = "leftToggler" + span("icon-toggler") + } + div("library-name") { clickableLogo(page, pathToRoot) + } + context.configuration.moduleVersion?.let { moduleVersion -> + div { text(moduleVersion) } + } + div("pull-right d-flex") { + filterButtons(page) + button { + id = "theme-toggle-button" + span { + id = "theme-toggle" + } + } div { - id = "paneSearch" + id = "searchBar" } + } + } + div { + id = "container" + div { + id = "leftColumn" div { id = "sideMenu" } } div { id = "main" - div { - id = "leftToggler" - span("icon-toggler") - } templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { script(type = ScriptType.textJavaScript, src = "###scripts/main.js") {} } @@ -857,15 +878,17 @@ open class HtmlRenderer( templateCommand(PathToRootSubstitutionCommand(pattern = "###", default = pathToRoot)) { a { href = "###index.html" - div { - id = "logo" + templateCommand(ProjectNameSubstitutionCommand(pattern = "@@@", default = context.configuration.moduleName)) { + span { + text("@@@") + } } } } - } else a { - href = pathToRoot + "index.html" - div { - id = "logo" + } else { + a { + href = pathToRoot + "index.html" + text(context.configuration.moduleName) } } } diff --git a/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt b/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt index e2953d46..e0b20f01 100644 --- a/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt +++ b/plugins/base/src/main/kotlin/renderers/html/NavigationPage.kt @@ -40,13 +40,13 @@ class NavigationPage(val root: NavigationNode, val moduleName: String, val conte id = navId attributes["pageId"] = "${moduleName}::${node.pageId}" div("overview") { - buildLink(node.dri, node.sourceSets.toList()) { buildBreakableText(node.name) } if (node.children.isNotEmpty()) { - span("navButton pull-right") { + span("navButton") { onClick = """document.getElementById("$navId").classList.toggle("hidden");""" span("navButtonContent") } } + buildLink(node.dri, node.sourceSets.toList()) { buildBreakableText(node.name) } } node.children.withIndex().forEach { (n, p) -> visit(p, "$navId-$n", renderer) } } diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlFormatingUtils.kt b/plugins/base/src/main/kotlin/renderers/html/htmlFormatingUtils.kt index b9eab293..c77a6e94 100644 --- a/plugins/base/src/main/kotlin/renderers/html/htmlFormatingUtils.kt +++ b/plugins/base/src/main/kotlin/renderers/html/htmlFormatingUtils.kt @@ -3,7 +3,7 @@ package org.jetbrains.dokka.base.renderers.html import kotlinx.html.FlowContent import kotlinx.html.span -fun FlowContent.buildTextBreakableAfterCapitalLetters(name: String) { +fun FlowContent.buildTextBreakableAfterCapitalLetters(name: String, hasLastElement: Boolean = false) { if (name.contains(" ")) { val withOutSpaces = name.split(" ") withOutSpaces.dropLast(1).forEach { @@ -12,8 +12,8 @@ fun FlowContent.buildTextBreakableAfterCapitalLetters(name: String) { } buildBreakableText(withOutSpaces.last()) } else { - val content = name.replace(Regex("(?!^)([A-Z])"), " $1").split(" ") - joinToHtml(content) { + val content = name.replace(Regex("(?<=[a-z])([A-Z])"), " $1").split(" ") + joinToHtml(content, hasLastElement) { it } } @@ -22,32 +22,35 @@ fun FlowContent.buildTextBreakableAfterCapitalLetters(name: String) { fun FlowContent.buildBreakableDotSeparatedHtml(name: String) { val phrases = name.split(".") phrases.forEachIndexed { i, e -> + val elementWithOptionalDot = e.takeIf { i == phrases.lastIndex } ?: "$e." if (e.length > 10) { - buildBreakableText(e) + buildTextBreakableAfterCapitalLetters(elementWithOptionalDot, hasLastElement = i == phrases.lastIndex) } else { - val elementWithOptionalDot = - if (i != phrases.lastIndex) { - "$e." - } else { - e - } - buildBreakableHtmlElement(elementWithOptionalDot) + buildBreakableHtmlElement(elementWithOptionalDot, i == phrases.lastIndex) } } } -private fun FlowContent.joinToHtml(elements: List<String>, onEach: (String) -> String) { +private fun FlowContent.joinToHtml(elements: List<String>, hasLastElement: Boolean = true, onEach: (String) -> String) { elements.dropLast(1).forEach { buildBreakableHtmlElement(onEach(it)) } - span { - buildBreakableHtmlElement(elements.last(), last = true) + elements.takeIf { it.isNotEmpty() && it.last().isNotEmpty() }?.let { + if (hasLastElement) { + span { + buildBreakableHtmlElement(it.last(), last = true) + } + } else { + buildBreakableHtmlElement(it.last(), last = false) + } } } private fun FlowContent.buildBreakableHtmlElement(element: String, last: Boolean = false) { - span { - +element + element.takeIf { it.isNotBlank() }?.let { + span { + +it + } } if (!last) { wbr { } @@ -56,4 +59,4 @@ private fun FlowContent.buildBreakableHtmlElement(element: String, last: Boolean fun FlowContent.buildBreakableText(name: String) = if (name.contains(".")) buildBreakableDotSeparatedHtml(name) - else buildTextBreakableAfterCapitalLetters(name)
\ No newline at end of file + else buildTextBreakableAfterCapitalLetters(name, hasLastElement = true)
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt index b6099e21..347e16bf 100644 --- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt +++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt @@ -49,37 +49,6 @@ abstract class NavigationDataProvider { } } -open class NavigationSearchInstaller(val context: DokkaContext) : NavigationDataProvider(), PageTransformer { - private val mapper = jacksonObjectMapper() - - open fun createSearchRecordFromNode(node: NavigationNode, location: String): SearchRecord = - SearchRecord(name = node.name, location = location) - - override fun invoke(input: RootPageNode): RootPageNode { - val page = RendererSpecificResourcePage( - name = "scripts/navigation-pane.json", - children = emptyList(), - strategy = RenderingStrategy.DriLocationResolvableWrite { resolver -> - val content = navigableChildren(input).withDescendants().map { - createSearchRecordFromNode(it, resolveLocation(resolver, it.dri, it.sourceSets).orEmpty()) - } - if (context.configuration.delayTemplateSubstitution) { - mapper.writeValueAsString(AddToSearch(context.configuration.moduleName, content.toList())) - } else { - mapper.writeValueAsString(content) - } - }) - - return input.modified(children = input.children + page) - } - - private fun resolveLocation(locationResolver: DriResolver, dri: DRI, sourceSets: Set<DisplaySourceSet>): String? = - locationResolver(dri, sourceSets).also { location -> - if (location.isNullOrBlank()) context.logger.warn("Cannot resolve path for $dri and sourceSets: ${sourceSets.joinToString { it.name }}") - } - -} - open class NavigationPageInstaller(val context: DokkaContext) : NavigationDataProvider(), PageTransformer { override fun invoke(input: RootPageNode): RootPageNode = @@ -118,6 +87,7 @@ class ScriptsInstaller(private val dokkaContext: DokkaContext) : PageTransformer "scripts/navigation-loader.js", "scripts/platform-content-handler.js", "scripts/main.js", + "scripts/prism.js" ) override fun invoke(input: RootPageNode): RootPageNode = @@ -134,9 +104,9 @@ class ScriptsInstaller(private val dokkaContext: DokkaContext) : PageTransformer class StylesInstaller(private val dokkaContext: DokkaContext) : PageTransformer { private val stylesPages = listOf( "styles/style.css", - "styles/logo-styles.css", "styles/jetbrains-mono.css", - "styles/main.css" + "styles/main.css", + "styles/prism.css" ) override fun invoke(input: RootPageNode): RootPageNode = @@ -153,13 +123,13 @@ class StylesInstaller(private val dokkaContext: DokkaContext) : PageTransformer object AssetsInstaller : PageTransformer { private val imagesPages = listOf( "images/arrow_down.svg", - "images/docs_logo.svg", "images/logo-icon.svg", "images/go-to-top-icon.svg", "images/footer-go-to-link.svg", "images/anchor-copy-button.svg", "images/copy-icon.svg", "images/copy-successful-icon.svg", + "images/theme-toggle.svg", ) override fun invoke(input: RootPageNode) = input.modified( diff --git a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt index d17fa276..94af96e2 100644 --- a/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt +++ b/plugins/base/src/main/kotlin/signatures/JvmSignatureUtils.kt @@ -8,7 +8,6 @@ import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.base.signatures.KotlinSignatureUtils.drisOfAllNestedBounds import org.jetbrains.dokka.model.AnnotationTarget -import org.jetbrains.dokka.model.doc.DocumentationNode interface JvmSignatureUtils { @@ -80,21 +79,22 @@ interface JvmSignatureUtils { when (renderAtStrategy) { is All, is OnlyOnce -> { - text("@") when(a.scope) { - Annotations.AnnotationScope.GETTER -> text("get:") - Annotations.AnnotationScope.SETTER -> text("set:") + Annotations.AnnotationScope.GETTER -> text("@get:", styles = mainStyles + TokenStyle.Annotation) + Annotations.AnnotationScope.SETTER -> text("@set:", styles = mainStyles + TokenStyle.Annotation) + else -> text("@", styles = mainStyles + TokenStyle.Annotation) } + link(a.dri.classNames!!, a.dri, styles = mainStyles + TokenStyle.Annotation) } - is Never -> Unit + is Never -> link(a.dri.classNames!!, a.dri) } - link(a.dri.classNames!!, a.dri) val isNoWrappedBrackets = a.params.entries.isEmpty() && renderAtStrategy is OnlyOnce listParams( a.params.entries, if (isNoWrappedBrackets) null else Pair('(', ')') ) { - text(it.key + " = ") + text(it.key) + text(" = ", styles = mainStyles + TokenStyle.Operator) when (renderAtStrategy) { is All -> All is Never, is OnlyOnce -> Never @@ -116,8 +116,9 @@ interface JvmSignatureUtils { } is EnumValue -> link(a.enumName, a.enumDri) is ClassValue -> link(a.className + classExtension, a.classDRI) - is StringValue -> group(styles = setOf(TextStyle.Breakable)) { text( "\"${a.text()}\"") } - is LiteralValue -> group(styles = setOf(TextStyle.Breakable)) { text(a.text()) } + is StringValue -> group(styles = setOf(TextStyle.Breakable)) { stringLiteral( "\"${a.text()}\"") } + is BooleanValue -> group(styles = setOf(TextStyle.Breakable)) { booleanLiteral(a.value) } + is LiteralValue -> group(styles = setOf(TextStyle.Breakable)) { constant(a.text()) } } private fun<T> PageContentBuilder.DocumentableContentBuilder.listParams( @@ -125,14 +126,14 @@ interface JvmSignatureUtils { listBrackets: Pair<Char, Char>?, outFn: PageContentBuilder.DocumentableContentBuilder.(T) -> Unit ) { - listBrackets?.let{ text(it.first.toString()) } + listBrackets?.let{ punctuation(it.first.toString()) } params.forEachIndexed { i, it -> group(styles = setOf(TextStyle.BreakableAfter)) { this.outFn(it) - if (i != params.size - 1) text(", ") + if (i != params.size - 1) punctuation(", ") } } - listBrackets?.let{ text(it.second.toString()) } + listBrackets?.let{ punctuation(it.second.toString()) } } fun PageContentBuilder.DocumentableContentBuilder.annotationsBlockWithIgnored( diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index e5f0ae97..8db37012 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -15,6 +15,7 @@ import org.jetbrains.dokka.model.properties.WithExtraProperties import org.jetbrains.dokka.pages.ContentKind import org.jetbrains.dokka.pages.ContentNode import org.jetbrains.dokka.pages.TextStyle +import org.jetbrains.dokka.pages.TokenStyle import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.querySingle @@ -60,7 +61,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog it !in ignoredExtraModifiers || entry.key.analysisPlatform in (platformSpecificModifiers[it] ?: emptySet()) } - } + }, styles = mainStyles + TokenStyle.Keyword ) { it.toSignatureString() } @@ -78,8 +79,15 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog annotationsBlock(e) link(e.name, e.dri, styles = emptySet()) e.extra[ConstructorValues]?.let { constructorValues -> - constructorValues.values[it] - text(constructorValues.values[it]?.joinToString(prefix = "(", postfix = ")") ?: "") + constructorValues.values[it]?.let { values -> + punctuation("(") + list( + elements = values, + separator = ", ", + separatorStyles = mainStyles + TokenStyle.Punctuation, + ) { highlightValue(it) } + punctuation(")") + } } } } @@ -93,9 +101,9 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog ?: emptySet()), sourceSets = setOf(sourceSet) ) { - text("typealias ") + keyword("typealias ") link(c.name.orEmpty(), c.dri) - text(" = ") + operator(" = ") signatureForProjection(aliasedType) } @@ -118,10 +126,9 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog sourceSets = setOf(sourceSet) ) { annotationsBlock(c) - text(c.visibility[sourceSet]?.takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "") + c.visibility[sourceSet]?.takeIf { it !in ignoredVisibilities }?.name?.let { keyword("$it ") } if (c is DClass) { - text( - if (c.modifier[sourceSet] !in ignoredModifiers) + val modifier = if (c.modifier[sourceSet] !in ignoredModifiers) when { c.extra[AdditionalModifiers]?.content?.get(sourceSet)?.contains(ExtraModifiers.KotlinOnlyModifiers.Data) == true -> "" c.modifier[sourceSet] is JavaModifier.Empty -> "${KotlinModifier.Open.name} " @@ -129,33 +136,35 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog } else "" - ) + modifier.takeIf { it.isNotEmpty() }?.let { keyword(it) } } when (c) { is DClass -> { processExtraModifiers(c) - text("class ") + keyword("class ") } is DInterface -> { processExtraModifiers(c) - text("interface ") + keyword("interface ") } is DEnum -> { processExtraModifiers(c) - text("enum ") + keyword("enum ") } is DObject -> { processExtraModifiers(c) - text("object ") + keyword("object ") } is DAnnotation -> { processExtraModifiers(c) - text("annotation class ") + keyword("annotation class ") } } link(c.name!!, c.dri) if (c is WithGenerics) { - list(c.generics, prefix = "<", suffix = ">") { + list(c.generics, prefix = "<", suffix = ">", + separatorStyles = mainStyles + TokenStyle.Punctuation, + surroundingCharactersStyle = mainStyles + TokenStyle.Operator) { annotationsInline(it) +buildSignature(it) } @@ -166,18 +175,20 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog if (pConstructor.annotations().values.any { it.isNotEmpty() }) { text(nbsp.toString()) annotationsInline(pConstructor) - text("constructor") + keyword("constructor") } list( - pConstructor.parameters, - "(", - ")", - ", ", - pConstructor.sourceSets.toSet() + elements = pConstructor.parameters, + prefix = "(", + suffix = ")", + separator = ", ", + separatorStyles = mainStyles + TokenStyle.Punctuation, + surroundingCharactersStyle = mainStyles + TokenStyle.Punctuation, + sourceSets = pConstructor.sourceSets.toSet() ) { annotationsInline(it) - text(it.name ?: "", styles = mainStyles.plus(TextStyle.Bold)) - text(": ") + text(it.name.orEmpty()) + operator(": ") signatureForProjection(it.type) } } @@ -186,7 +197,9 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog c.supertypes.filter { it.key == sourceSet }.map { (s, typeConstructors) -> list(typeConstructors, prefix = " : ", sourceSets = setOf(s)) { link(it.typeConstructor.dri.sureClassNames, it.typeConstructor.dri, sourceSets = setOf(s)) - list(it.typeConstructor.projections, prefix = "<", suffix = "> ") { + list(it.typeConstructor.projections, prefix = "<", suffix = "> ", + separatorStyles = mainStyles + TokenStyle.Punctuation, + surroundingCharactersStyle = mainStyles + TokenStyle.Operator) { signatureForProjection(it) } } @@ -203,31 +216,42 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog sourceSets = setOf(it) ) { annotationsBlock(p) - text(p.visibility[it].takeIf { it !in ignoredVisibilities }?.name?.let { "$it " } ?: "") - text( - p.modifier[it].takeIf { it !in ignoredModifiers }?.let { + p.visibility[it].takeIf { it !in ignoredVisibilities }?.name?.let { keyword("$it ") } + p.modifier[it].takeIf { it !in ignoredModifiers }?.let { if (it is JavaModifier.Empty) KotlinModifier.Open else it - }?.name?.let { "$it " } ?: "" - ) - text(p.modifiers()[it]?.toSignatureStri |
