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 2 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 @@ -4286,6 +4286,7 @@ public final class org/jetbrains/dokka/pages/TextStyle : java/lang/Enum, org/jet
public static final field Monospace Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Paragraph Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Quotation Lorg/jetbrains/dokka/pages/TextStyle;
public static final field RightAligned Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Span Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Strikethrough Lorg/jetbrains/dokka/pages/TextStyle;
public static final field Strong 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,
RightAligned
IgnatBeresnev marked this conversation as resolved.
Show resolved Hide resolved
}

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.RightAligned) -> span("clearfix") { span("right-aligned") { 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,18 @@ class SourceLinksTransformer(val context: DokkaContext) : PageTransformer {
if (sourceLinks.isEmpty()) {
return input
}
return input.transformContentPagesTree { node ->
context.logger.warn("sourceLinks.size " + sourceLinks.size)
vmishenev marked this conversation as resolved.
Show resolved Hide resolved
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 +68,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 +86,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 +94,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 { cg ->
vmishenev marked this conversation as resolved.
Show resolved Hide resolved
sources[cg.dci.dri.singleOrNull()]?.let { sourceLinks ->
sourceLinks.filter { it.first.sourceSetID in cg.sourceSets.sourceSetIDs }.ifNotEmpty {
cg.copy(children = cg.children + sourceLinks.map {
buildContentLink(
cg.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.RightAligned)
) {
text("(")
link("source", link)
text(")")
}
}

data class SourceLink(val path: String, val url: String, val lineSuffix: String?, val sourceSetData: DokkaSourceSet) {
Expand All @@ -161,6 +137,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;
}

.right-aligned {
float: right;
}
vmishenev marked this conversation as resolved.
Show resolved Hide resolved
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 .right-aligned")
.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 .right-aligned")
.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