Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move source links into signature #2476

Merged
merged 3 commits into from Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions core/api/core.api
Expand Up @@ -4280,6 +4280,7 @@ public final class org/jetbrains/dokka/pages/TextStyle : java/lang/Enum, org/jet
public static final field Breakable Lorg/jetbrains/dokka/pages/TextStyle;
public static final field BreakableAfter Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Cover Lorg/jetbrains/dokka/pages/TextStyle;
public static final field FloatingRight Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Indented Lorg/jetbrains/dokka/pages/TextStyle;
public static final field InlineComment Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Italic Lorg/jetbrains/dokka/pages/TextStyle;
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/kotlin/pages/ContentNodes.kt
Expand Up @@ -383,7 +383,8 @@ enum class TokenStyle : Style {

enum class TextStyle : Style {
Bold, Italic, Strong, Strikethrough, Paragraph,
Block, Span, Monospace, Indented, Cover, UnderCoverText, BreakableAfter, Breakable, InlineComment, Quotation
Block, Span, Monospace, Indented, Cover, UnderCoverText, BreakableAfter, Breakable, InlineComment, Quotation,
FloatingRight
}

enum class ContentStyle : Style {
Expand Down
4 changes: 0 additions & 4 deletions plugins/base/api/base.api
Expand Up @@ -1328,10 +1328,6 @@ public final class org/jetbrains/dokka/base/transformers/pages/sourcelinks/Sourc
public fun invoke (Lorg/jetbrains/dokka/pages/RootPageNode;)Lorg/jetbrains/dokka/pages/RootPageNode;
}

public final class org/jetbrains/dokka/base/transformers/pages/sourcelinks/SourceLinksTransformerKt {
public static final fun hasTabbedContent (Lorg/jetbrains/dokka/pages/ContentGroup;)Z
}

public abstract interface class org/jetbrains/dokka/base/transformers/pages/tags/CustomTagContentProvider {
public abstract fun contentForBrief (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
public abstract fun contentForDescription (Lorg/jetbrains/dokka/base/translators/documentables/PageContentBuilder$DocumentableContentBuilder;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaSourceSet;Lorg/jetbrains/dokka/model/doc/CustomTagWrapper;)V
Expand Down
Expand Up @@ -129,6 +129,7 @@ open class HtmlRenderer(
node.hasStyle(TextStyle.Paragraph) -> p(additionalClasses) { childrenCallback() }
node.hasStyle(TextStyle.Block) -> div(additionalClasses) { childrenCallback() }
node.hasStyle(TextStyle.Quotation) -> blockQuote(additionalClasses) { childrenCallback() }
node.hasStyle(TextStyle.FloatingRight) -> span("clearfix") { span("floating-right") { childrenCallback() } }
node.isAnchorable -> buildAnchor(
node.anchor!!,
node.anchorLabel!!,
Expand Down
Expand Up @@ -7,11 +7,9 @@ import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet
import org.jetbrains.dokka.analysis.DescriptorDocumentableSource
import org.jetbrains.dokka.analysis.PsiDocumentableSource
import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint
import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder
import org.jetbrains.dokka.model.DocumentableSource
import org.jetbrains.dokka.model.WithSources
import org.jetbrains.dokka.model.toDisplaySourceSets
import org.jetbrains.dokka.links.DRI
import org.jetbrains.dokka.model.*
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.plugability.plugin
Expand All @@ -20,6 +18,7 @@ import org.jetbrains.dokka.transformers.pages.PageTransformer
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import java.io.File

class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
Expand All @@ -35,15 +34,17 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
if (sourceLinks.isEmpty()) {
return input
}
return input.transformContentPagesTree { node ->
return input.transformContentPagesTree { node ->
when (node) {
is WithDocumentables ->
node.documentables
is WithDocumentables -> {
val sources = node.documentables
.filterIsInstance<WithSources>()
.flatMap { resolveSources(sourceLinks, it) }
.takeIf { it.isNotEmpty() }
?.let { node.addSourcesContent(it) }
?: node
.associate { (it as Documentable).dri to resolveSources(sourceLinks, it) }
if (sources.isNotEmpty())
node.modified(content = transformContent(node.content, sources))
else
node
}
else -> node
}
}
Expand All @@ -66,39 +67,6 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
}
}

private fun ContentPage.addSourcesContent(sources: List<Pair<DokkaSourceSet, String>>) = builder
.buildSourcesContent(this, sources)
.let {
this.modified(
content = this.content.addTable(it)
)
}

private fun PageContentBuilder.buildSourcesContent(
node: ContentPage,
sources: List<Pair<DokkaSourceSet, String>>
): ContentGroup {
val documentables = (node as? WithDocumentables)?.documentables.orEmpty()
return contentFor(
node.dri,
documentables.flatMap { it.sourceSets }.toSet()
) {
header(2, "Sources", kind = ContentKind.Source)
+ContentTable(
header = emptyList(),
children = sources.map {
buildGroup(node.dri, setOf(it.first), kind = ContentKind.Source, extra = mainExtra + SymbolAnchorHint(it.second, ContentKind.Source)) {
link("${it.first.displayName} source", it.second)
}
},
dci = DCI(node.dri, ContentKind.Source),
sourceSets = documentables.flatMap { it.sourceSets }.toDisplaySourceSets(),
style = emptySet(),
extra = mainExtra + SimpleAttr.header("Sources")
)
}
}

private fun DocumentableSource.toLink(sourceLink: SourceLink): String {
val sourcePath = File(this.path).invariantSeparatorsPath
val sourceLinkPath = File(sourceLink.path).invariantSeparatorsPath
Expand All @@ -117,33 +85,6 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
"${lineNumber ?: 1}"
}

private fun ContentNode.addTable(table: ContentGroup): ContentNode =
when (this) {
is ContentGroup -> {
if (hasTabbedContent()) {
copy(
children = children.map {
if (it.hasStyle(ContentStyle.TabbedContent) && it is ContentGroup) {
it.copy(children = it.children + table)
} else {
it
}
}
)
} else {
copy(children = children + table)
}

}
else -> ContentGroup(
children = listOf(this, table),
extra = this.extra,
sourceSets = this.sourceSets,
dci = this.dci,
style = this.style
)
}

private fun PsiElement.lineNumber(): Int? {
// synthetic and some light methods might return null
val textRange = textRange ?: return null
Expand All @@ -152,6 +93,40 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
// IJ uses 0-based line-numbers; external source browsers use 1-based
return doc?.getLineNumber(textRange.startOffset)?.plus(1)
}

private fun ContentNode.signatureGroupOrNull() =
(this as? ContentGroup)?.takeIf { it.dci.kind == ContentKind.Symbol }

private fun transformContent(
contentNode: ContentNode, sources: Map<DRI, List<Pair<DokkaSourceSet, String>>>
): ContentNode =
contentNode.signatureGroupOrNull()?.let { sg ->
sources[sg.dci.dri.singleOrNull()]?.let { sourceLinks ->
sourceLinks.filter { it.first.sourceSetID in sg.sourceSets.sourceSetIDs }.ifNotEmpty {
sg.copy(children = sg.children + sourceLinks.map {
buildContentLink(
sg.dci.dri.first(),
it.first,
it.second
)
})
}
}
} ?: when (contentNode) {
is ContentComposite -> contentNode.transformChildren { transformContent(it, sources) }
else -> contentNode
}

private fun buildContentLink(dri: DRI, sourceSet: DokkaSourceSet, link: String) = builder.contentFor(
dri,
setOf(sourceSet),
ContentKind.Source,
setOf(TextStyle.FloatingRight)
) {
text("(")
link("source", link)
text(")")
}
}

data class SourceLink(val path: String, val url: String, val lineSuffix: String?, val sourceSetData: DokkaSourceSet) {
Expand All @@ -161,6 +136,4 @@ data class SourceLink(val path: String, val url: String, val lineSuffix: String?
sourceLinkDefinition.remoteLineSuffix,
sourceSetData
)
}

fun ContentGroup.hasTabbedContent(): Boolean = children.any { it.hasStyle(ContentStyle.TabbedContent) }
}
10 changes: 10 additions & 0 deletions plugins/base/src/main/resources/dokka/styles/style.css
Expand Up @@ -1181,3 +1181,13 @@ div.runnablesample {
display: none;
}
}
.clearfix::after {
content: ' ';
clear: both;
display: block;
height: 0;
}

.floating-right {
float: right;
}
2 changes: 1 addition & 1 deletion plugins/base/src/test/kotlin/enums/JavaEnumsTest.kt
Expand Up @@ -45,7 +45,7 @@ class JavaEnumsTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
val enumPage = writerPlugin.writer.renderedContent("root/testpackage/-java-enum/index.html")
val sourceLink = enumPage.select("div[data-togglable=Sources]")
val sourceLink = enumPage.select(".symbol .floating-right")
.select("a[href]")
.attr("href")

Expand Down
2 changes: 1 addition & 1 deletion plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt
Expand Up @@ -407,7 +407,7 @@ class KotlinEnumsTest : BaseAbstractTest() {
) {
renderingStage = { _, _ ->
val sourceLink = writerPlugin.writer.renderedContent("root/testpackage/-kotlin-enum/index.html")
.select("div[data-togglable=Sources]")
.select(".symbol .floating-right")
.select("a[href]")
.attr("href")

Expand Down
Expand Up @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import utils.assertNotNull
import java.net.URL
import java.nio.file.Paths

Expand Down Expand Up @@ -131,10 +132,8 @@ class LinkableContentTest : BaseAbstractTest() {
Assertions.assertEquals(2, packageChildren.size)
packageChildren.forEach {
val name = it.name.substringBefore("Class")
val crl = it.safeAs<ClasslikePageNode>()?.content?.safeAs<ContentGroup>()?.children?.last()
?.safeAs<ContentGroup>()?.children?.last()?.safeAs<ContentGroup>()?.children?.lastOrNull()
?.safeAs<ContentTable>()?.children?.singleOrNull()
?.safeAs<ContentGroup>()?.children?.singleOrNull().safeAs<ContentResolvedLink>()
val signature = it.safeAs<ClasslikePageNode>()?.content?.dfs { it is ContentGroup && it.dci.kind == ContentKind.Symbol }.assertNotNull("signature")
val crl = signature.children.last().children[1].safeAs<ContentResolvedLink>()
Assertions.assertEquals(
"https://github.com/user/repo/tree/master/src/${name.toLowerCase()}Main/kotlin/${name}Class.kt#L3",
crl?.address
Expand Down