aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/kotlin/Formats/FormatService.kt32
-rw-r--r--core/src/main/kotlin/Formats/GFMFormatService.kt61
-rw-r--r--core/src/main/kotlin/Formats/HtmlFormatService.kt166
-rw-r--r--core/src/main/kotlin/Formats/HtmlTemplateService.kt38
-rw-r--r--core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt117
-rw-r--r--core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt91
-rw-r--r--core/src/main/kotlin/Formats/JekyllFormatService.kt44
-rw-r--r--core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt264
-rw-r--r--core/src/main/kotlin/Formats/MarkdownFormatService.kt250
-rw-r--r--core/src/main/kotlin/Formats/OutlineService.kt29
-rw-r--r--core/src/main/kotlin/Formats/PackageListService.kt66
-rw-r--r--core/src/main/kotlin/Formats/StandardFormats.kt55
-rw-r--r--core/src/main/kotlin/Formats/StructuredFormatService.kt1014
-rw-r--r--core/src/main/kotlin/Formats/YamlOutlineService.kt26
-rw-r--r--core/src/main/kotlin/Generation/FileGenerator.kt108
-rw-r--r--core/src/main/kotlin/Generation/Generator.kt29
-rw-r--r--core/src/main/kotlin/Kotlin/ContentBuilder.kt192
-rw-r--r--core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt73
-rw-r--r--core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt305
-rw-r--r--core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt67
-rw-r--r--core/src/main/kotlin/Kotlin/KotlinAsJavaElementSignatureProvider.kt25
-rw-r--r--core/src/main/kotlin/Languages/JavaLanguageService.kt171
-rw-r--r--core/src/main/kotlin/Languages/NewJavaLanguageService.kt197
-rw-r--r--core/src/main/kotlin/Locations/Location.kt78
-rw-r--r--core/src/main/kotlin/Model/Content.kt290
-rw-r--r--core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt103
-rw-r--r--core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt197
-rw-r--r--core/src/main/kotlin/Samples/SampleProcessingService.kt9
-rw-r--r--core/src/test/kotlin/NodeSelect.kt90
-rw-r--r--core/src/test/kotlin/format/FileGeneratorTestCase.kt35
-rw-r--r--core/src/test/kotlin/format/GFMFormatTest.kt38
-rw-r--r--core/src/test/kotlin/format/HtmlFormatTest.kt195
-rw-r--r--core/src/test/kotlin/format/KotlinWebSiteHtmlFormatTest.kt127
-rw-r--r--core/src/test/kotlin/format/MarkdownFormatTest.kt616
-rw-r--r--core/src/test/kotlin/format/PackageDocsTest.kt91
-rw-r--r--core/src/test/kotlin/issues/IssuesTest.kt34
-rw-r--r--core/src/test/kotlin/model/ClassTest.kt322
-rw-r--r--core/src/test/kotlin/model/CommentTest.kt195
-rw-r--r--core/src/test/kotlin/model/FunctionTest.kt284
-rw-r--r--core/src/test/kotlin/model/JavaTest.kt213
-rw-r--r--core/src/test/kotlin/model/KotlinAsJavaTest.kt68
-rw-r--r--core/src/test/kotlin/model/LinkTest.kt94
-rw-r--r--core/src/test/kotlin/model/PackageTest.kt139
-rw-r--r--core/src/test/kotlin/model/PropertyTest.kt131
-rw-r--r--core/src/test/kotlin/model/SourceLinksErrorTest.kt35
-rw-r--r--core/src/test/kotlin/model/SourceLinksTest.kt75
-rw-r--r--core/src/test/kotlin/model/TypeAliasTest.kt134
47 files changed, 0 insertions, 7013 deletions
diff --git a/core/src/main/kotlin/Formats/FormatService.kt b/core/src/main/kotlin/Formats/FormatService.kt
deleted file mode 100644
index 8f4855e3..00000000
--- a/core/src/main/kotlin/Formats/FormatService.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.jetbrains.dokka
-
-/**
- * Abstract representation of a formatting service used to output documentation in desired format
- *
- * Bundled Formatters:
- * * [HtmlFormatService] – outputs documentation to HTML format
- * * [MarkdownFormatService] – outputs documentation in Markdown format
- */
-interface FormatService {
- /** Returns extension for output files */
- val extension: String
-
- /** extension which will be used for internal and external linking */
- val linkExtension: String
- get() = extension
-
- fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder
-
- fun enumerateSupportFiles(callback: (resource: String, targetPath: String) -> Unit) {
- }
-}
-
-interface FormattedOutputBuilder {
- /** Appends formatted content */
- fun appendNodes(nodes: Iterable<DocumentationNode>)
-}
-
-/** Format content to [String] using specified [location] */
-fun FormatService.format(location: Location, nodes: Iterable<DocumentationNode>): String = StringBuilder().apply {
- createOutputBuilder(this, location).appendNodes(nodes)
-}.toString()
diff --git a/core/src/main/kotlin/Formats/GFMFormatService.kt b/core/src/main/kotlin/Formats/GFMFormatService.kt
deleted file mode 100644
index 036ec856..00000000
--- a/core/src/main/kotlin/Formats/GFMFormatService.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.google.inject.name.Named
-import org.jetbrains.dokka.Utilities.impliedPlatformsName
-
-open class GFMOutputBuilder(
- to: StringBuilder,
- location: Location,
- generator: NodeLocationAwareGenerator,
- languageService: LanguageService,
- extension: String,
- impliedPlatforms: List<String>
-) : MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) {
- override fun appendTable(vararg columns: String, body: () -> Unit) {
- to.appendln(columns.joinToString(" | ", "| ", " |"))
- to.appendln("|" + "---|".repeat(columns.size))
- body()
- }
-
- override fun appendUnorderedList(body: () -> Unit) {
- if (inTableCell) {
- wrapInTag("ul", body)
- } else {
- super.appendUnorderedList(body)
- }
- }
-
- override fun appendOrderedList(body: () -> Unit) {
- if (inTableCell) {
- wrapInTag("ol", body)
- } else {
- super.appendOrderedList(body)
- }
- }
-
- override fun appendListItem(body: () -> Unit) {
- if (inTableCell) {
- wrapInTag("li", body)
- } else {
- super.appendListItem(body)
- }
- }
-}
-
-open class GFMFormatService(
- generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- linkExtension: String,
- impliedPlatforms: List<String>
-) : MarkdownFormatService(generator, signatureGenerator, linkExtension, impliedPlatforms) {
-
- @Inject constructor(
- generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- @Named(impliedPlatformsName) impliedPlatforms: List<String>
- ) : this(generator, signatureGenerator, "md", impliedPlatforms)
-
- override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder =
- GFMOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms)
-}
diff --git a/core/src/main/kotlin/Formats/HtmlFormatService.kt b/core/src/main/kotlin/Formats/HtmlFormatService.kt
deleted file mode 100644
index d36ea0a2..00000000
--- a/core/src/main/kotlin/Formats/HtmlFormatService.kt
+++ /dev/null
@@ -1,166 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.google.inject.name.Named
-import org.jetbrains.dokka.Utilities.impliedPlatformsName
-import java.io.File
-
-open class HtmlOutputBuilder(to: StringBuilder,
- location: Location,
- generator: NodeLocationAwareGenerator,
- languageService: LanguageService,
- extension: String,
- impliedPlatforms: List<String>,
- val templateService: HtmlTemplateService)
- : StructuredOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms)
-{
- override fun appendText(text: String) {
- to.append(text.htmlEscape())
- }
-
- override fun appendSymbol(text: String) {
- to.append("<span class=\"symbol\">${text.htmlEscape()}</span>")
- }
-
- override fun appendKeyword(text: String) {
- to.append("<span class=\"keyword\">${text.htmlEscape()}</span>")
- }
-
- override fun appendIdentifier(text: String, kind: IdentifierKind, signature: String?) {
- val id = signature?.let { " id=\"$it\"" }.orEmpty()
- to.append("<span class=\"identifier\"$id>${text.htmlEscape()}</span>")
- }
-
- override fun appendBlockCode(language: String, body: () -> Unit) {
- val openTags = if (language.isNotBlank())
- "<pre><code class=\"lang-$language\">"
- else
- "<pre><code>"
- wrap(openTags, "</code></pre>", body)
- }
-
- override fun appendHeader(level: Int, body: () -> Unit) =
- wrapInTag("h$level", body, newlineBeforeOpen = true, newlineAfterClose = true)
- override fun appendParagraph(body: () -> Unit) =
- wrapInTag("p", body, newlineBeforeOpen = true, newlineAfterClose = true)
-
- override fun appendSoftParagraph(body: () -> Unit) = appendParagraph(body)
-
- override fun appendLine() {
- to.appendln("<br/>")
- }
-
- override fun appendAnchor(anchor: String) {
- to.appendln("<a name=\"${anchor.htmlEscape()}\"></a>")
- }
-
- override fun appendTable(vararg columns: String, body: () -> Unit) =
- wrapInTag("table", body, newlineAfterOpen = true, newlineAfterClose = true)
- override fun appendTableBody(body: () -> Unit) =
- wrapInTag("tbody", body, newlineAfterOpen = true, newlineAfterClose = true)
- override fun appendTableRow(body: () -> Unit) =
- wrapInTag("tr", body, newlineAfterOpen = true, newlineAfterClose = true)
- override fun appendTableCell(body: () -> Unit) =
- wrapInTag("td", body, newlineAfterOpen = true, newlineAfterClose = true)
-
- override fun appendLink(href: String, body: () -> Unit) = wrap("<a href=\"$href\">", "</a>", body)
-
- override fun appendStrong(body: () -> Unit) = wrapInTag("strong", body)
- override fun appendEmphasis(body: () -> Unit) = wrapInTag("em", body)
- override fun appendStrikethrough(body: () -> Unit) = wrapInTag("s", body)
- override fun appendCode(body: () -> Unit) = wrapInTag("code", body)
-
- override fun appendUnorderedList(body: () -> Unit) = wrapInTag("ul", body, newlineAfterClose = true)
- override fun appendOrderedList(body: () -> Unit) = wrapInTag("ol", body, newlineAfterClose = true)
- override fun appendListItem(body: () -> Unit) = wrapInTag("li", body, newlineAfterClose = true)
-
- override fun appendBreadcrumbSeparator() {
- to.append("&nbsp;/&nbsp;")
- }
-
- override fun appendNodes(nodes: Iterable<DocumentationNode>) {
- templateService.appendHeader(to, getPageTitle(nodes), generator.relativePathToRoot(location))
- super.appendNodes(nodes)
- templateService.appendFooter(to)
- }
-
- override fun appendNonBreakingSpace() {
- to.append("&nbsp;")
- }
-
- override fun ensureParagraph() {}
-}
-
-open class HtmlFormatService @Inject constructor(generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- val templateService: HtmlTemplateService,
- @Named(impliedPlatformsName) val impliedPlatforms: List<String>)
-: StructuredFormatService(generator, signatureGenerator, "html"), OutlineFormatService {
-
- override fun enumerateSupportFiles(callback: (String, String) -> Unit) {
- callback("/dokka/styles/style.css", "style.css")
- }
-
- override fun createOutputBuilder(to: StringBuilder, location: Location) =
- HtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService)
-
- override fun appendOutline(location: Location, to: StringBuilder, nodes: Iterable<DocumentationNode>) {
- templateService.appendHeader(to, "Module Contents", generator.relativePathToRoot(location))
- super.appendOutline(location, to, nodes)
- templateService.appendFooter(to)
- }
-
- override fun getOutlineFileName(location: Location): File {
- return File("${location.path}-outline.html")
- }
-
- override fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) {
- val link = ContentNodeDirectLink(node)
- link.append(languageService.render(node, LanguageService.RenderMode.FULL))
- val tempBuilder = StringBuilder()
- createOutputBuilder(tempBuilder, location).appendContent(link)
- to.appendln("<a href=\"${location.path}\">$tempBuilder</a><br/>")
- }
-
- override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) {
- to.appendln("<ul>")
- body()
- to.appendln("</ul>")
- }
-}
-
-fun getPageTitle(nodes: Iterable<DocumentationNode>): String? {
- val breakdownByLocation = nodes.groupBy { node -> formatPageTitle(node) }
- return breakdownByLocation.keys.singleOrNull()
-}
-
-fun formatPageTitle(node: DocumentationNode): String {
- val path = node.path
- val moduleName = path.first().name
- if (path.size == 1) {
- return moduleName
- }
-
- val qName = qualifiedNameForPageTitle(node)
- return "$qName - $moduleName"
-}
-
-private fun qualifiedNameForPageTitle(node: DocumentationNode): String {
- if (node.kind == NodeKind.Package) {
- var packageName = node.qualifiedName()
- if (packageName.isEmpty()) {
- packageName = "root package"
- }
- return packageName
- }
-
- val path = node.path
- var pathFromToplevelMember = path.dropWhile { it.kind !in NodeKind.classLike }
- if (pathFromToplevelMember.isEmpty()) {
- pathFromToplevelMember = path.dropWhile { it.kind != NodeKind.Property && it.kind != NodeKind.Function }
- }
- if (pathFromToplevelMember.isNotEmpty()) {
- return pathFromToplevelMember.map { it.name }.filter { it.length > 0 }.joinToString(".")
- }
- return node.qualifiedName()
-}
diff --git a/core/src/main/kotlin/Formats/HtmlTemplateService.kt b/core/src/main/kotlin/Formats/HtmlTemplateService.kt
deleted file mode 100644
index a65a7b18..00000000
--- a/core/src/main/kotlin/Formats/HtmlTemplateService.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.jetbrains.dokka
-
-import java.io.File
-
-interface HtmlTemplateService {
- fun appendHeader(to: StringBuilder, title: String?, basePath: File)
- fun appendFooter(to: StringBuilder)
-
- companion object {
- fun default(css: String? = null): HtmlTemplateService {
- return object : HtmlTemplateService {
- override fun appendFooter(to: StringBuilder) {
- if (!to.endsWith('\n')) {
- to.append('\n')
- }
- to.appendln("</BODY>")
- to.appendln("</HTML>")
- }
- override fun appendHeader(to: StringBuilder, title: String?, basePath: File) {
- to.appendln("<HTML>")
- to.appendln("<HEAD>")
- to.appendln("<meta charset=\"UTF-8\">")
- if (title != null) {
- to.appendln("<title>$title</title>")
- }
- if (css != null) {
- val cssPath = basePath.resolve(css).toUnixString()
- to.appendln("<link rel=\"stylesheet\" href=\"$cssPath\">")
- }
- to.appendln("</HEAD>")
- to.appendln("<BODY>")
- }
- }
- }
- }
-}
-
-
diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt b/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt
deleted file mode 100644
index 09bb2602..00000000
--- a/core/src/main/kotlin/Formats/JavaLayoutHtml/JavaLayoutHtmlPackageListService.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-package org.jetbrains.dokka.Formats
-
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.ExternalDocumentationLinkResolver.Companion.DOKKA_PARAM_PREFIX
-import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject
-import org.jetbrains.kotlin.types.KotlinType
-
-class JavaLayoutHtmlPackageListService: PackageListService {
-
- private fun StringBuilder.appendParam(name: String, value: String) {
- append(DOKKA_PARAM_PREFIX)
- append(name)
- append(":")
- appendln(value)
- }
-
- override fun formatPackageList(module: DocumentationModule): String {
- val packages = module.members(NodeKind.Package).map { it.name }
-
- return buildString {
- appendParam("format", "java-layout-html")
- appendParam("mode", "kotlin")
- for (p in packages) {
- appendln(p)
- }
- }
- }
-
-}
-
-class JavaLayoutHtmlInboundLinkResolutionService(private val paramMap: Map<String, List<String>>) : InboundExternalLinkResolutionService {
- private fun getContainerPath(symbol: DeclarationDescriptor): String? {
- return when (symbol) {
- is PackageFragmentDescriptor -> symbol.fqName.asString().replace('.', '/') + "/"
- is ClassifierDescriptor -> getContainerPath(symbol.findPackage()) + symbol.nameWithOuter() + ".html"
- else -> null
- }
- }
-
- private fun DeclarationDescriptor.findPackage(): PackageFragmentDescriptor =
- generateSequence(this) { it.containingDeclaration }.filterIsInstance<PackageFragmentDescriptor>().first()
-
- private fun ClassifierDescriptor.nameWithOuter(): String =
- generateSequence(this) { it.containingDeclaration as? ClassifierDescriptor }
- .toList().asReversed().joinToString(".") { it.name.asString() }
-
- private fun getPagePath(symbol: DeclarationDescriptor): String? {
- return when (symbol) {
- is PackageFragmentDescriptor -> getContainerPath(symbol) + "package-summary.html"
- is EnumEntrySyntheticClassDescriptor -> getContainerPath(symbol.containingDeclaration) + "#" + symbol.signatureForAnchorUrlEncoded()
- is ClassifierDescriptor -> getContainerPath(symbol) + "#"
- is FunctionDescriptor, is PropertyDescriptor -> getContainerPath(symbol.containingDeclaration!!) + "#" + symbol.signatureForAnchorUrlEncoded()
- else -> null
- }
- }
-
- private fun DeclarationDescriptor.signatureForAnchor(): String? {
-
- fun ReceiverParameterDescriptor.extractReceiverName(): String {
- var receiverClass: DeclarationDescriptor = type.constructor.declarationDescriptor!!
- if (receiverClass.isCompanionObject()) {
- receiverClass = receiverClass.containingDeclaration!!
- } else if (receiverClass is TypeParameterDescriptor) {
- val upperBoundClass = receiverClass.upperBounds.singleOrNull()?.constructor?.declarationDescriptor
- if (upperBoundClass != null) {
- receiverClass = upperBoundClass
- }
- }
-
- return receiverClass.name.asString()
- }
-
- fun KotlinType.qualifiedNameForSignature(): String {
- val desc = constructor.declarationDescriptor
- return desc?.fqNameUnsafe?.asString() ?: "<ERROR TYPE NAME>"
- }
-
- fun StringBuilder.appendReceiverAndCompanion(desc: CallableDescriptor) {
- if (desc.containingDeclaration.isCompanionObject()) {
- append("Companion.")
- }
- desc.extensionReceiverParameter?.let {
- append("(")
- append(it.extractReceiverName())
- append(").")
- }
- }
-
- return when(this) {
- is EnumEntrySyntheticClassDescriptor -> buildString {
- append("ENUM_VALUE:")
- append(name.asString())
- }
- is FunctionDescriptor -> buildString {
- appendReceiverAndCompanion(this@signatureForAnchor)
- append(name.asString())
- valueParameters.joinTo(this, prefix = "(", postfix = ")") {
- it.type.qualifiedNameForSignature()
- }
- }
- is PropertyDescriptor -> buildString {
- appendReceiverAndCompanion(this@signatureForAnchor)
- append(name.asString())
- append(":")
- append(returnType?.qualifiedNameForSignature())
- }
- else -> null
- }
- }
-
- private fun DeclarationDescriptor.signatureForAnchorUrlEncoded(): String? = signatureForAnchor()?.urlEncoded()
-
- override fun getPath(symbol: DeclarationDescriptor) = getPagePath(symbol)
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt b/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt
deleted file mode 100644
index 885cdf6c..00000000
--- a/core/src/main/kotlin/Formats/JavaLayoutHtmlFormat.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.jetbrains.dokka.Formats
-
-import com.google.inject.Binder
-import com.google.inject.Inject
-import kotlinx.html.li
-import kotlinx.html.stream.appendHTML
-import kotlinx.html.ul
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.Samples.DefaultSampleProcessingService
-import org.jetbrains.dokka.Utilities.bind
-import org.jetbrains.dokka.Utilities.toType
-import java.io.File
-
-
-class JavaLayoutHtmlFormatDescriptor : FormatDescriptor, DefaultAnalysisComponent {
- override val packageDocumentationBuilderClass = KotlinPackageDocumentationBuilder::class
- override val javaDocumentationBuilderClass = KotlinJavaDocumentationBuilder::class
- override val sampleProcessingService = DefaultSampleProcessingService::class
- override val elementSignatureProvider = KotlinElementSignatureProvider::class
-
- override fun configureOutput(binder: Binder): Unit = with(binder) {
- bind<Generator>() toType generatorServiceClass
- }
-
- val formatServiceClass = JavaLayoutHtmlFormatService::class
- val generatorServiceClass = JavaLayoutHtmlFormatGenerator::class
-}
-
-
-class JavaLayoutHtmlFormatService : FormatService {
- override val extension: String
- get() = TODO("not implemented")
-
-
- override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder {
- TODO("not implemented")
- }
-}
-
-class JavaLayoutHtmlFormatOutputBuilder : FormattedOutputBuilder {
- override fun appendNodes(nodes: Iterable<DocumentationNode>) {
-
- }
-}
-
-
-class JavaLayoutHtmlFormatNavListBuilder @Inject constructor() : OutlineFormatService {
- override fun getOutlineFileName(location: Location): File {
- TODO()
- }
-
- override fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) {
- with(to.appendHTML()) {
- //a(href = )
- li {
- when {
- node.kind == NodeKind.Package -> appendOutline(location, to, node.members)
- }
- }
- }
- }
-
- override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) {
- with(to.appendHTML()) {
- ul { body() }
- }
- }
-
-}
-
-class JavaLayoutHtmlFormatGenerator @Inject constructor(
- private val outlineFormatService: OutlineFormatService
-) : Generator {
- override fun buildPages(nodes: Iterable<DocumentationNode>) {
-
- }
-
- override fun buildOutlines(nodes: Iterable<DocumentationNode>) {
- for (node in nodes) {
- if (node.kind == NodeKind.Module) {
- //outlineFormatService.formatOutline()
- }
- }
- }
-
- override fun buildSupportFiles() {}
-
- override fun buildPackageList(nodes: Iterable<DocumentationNode>) {
-
- }
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/Formats/JekyllFormatService.kt b/core/src/main/kotlin/Formats/JekyllFormatService.kt
deleted file mode 100644
index a948dfa9..00000000
--- a/core/src/main/kotlin/Formats/JekyllFormatService.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.google.inject.name.Named
-import org.jetbrains.dokka.Utilities.impliedPlatformsName
-
-open class JekyllOutputBuilder(to: StringBuilder,
- location: Location,
- generator: NodeLocationAwareGenerator,
- languageService: LanguageService,
- extension: String,
- impliedPlatforms: List<String>)
- : MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms) {
- override fun appendNodes(nodes: Iterable<DocumentationNode>) {
- to.appendln("---")
- appendFrontMatter(nodes, to)
- to.appendln("---")
- to.appendln("")
- super.appendNodes(nodes)
- }
-
- protected open fun appendFrontMatter(nodes: Iterable<DocumentationNode>, to: StringBuilder) {
- to.appendln("title: ${getPageTitle(nodes)}")
- }
-}
-
-
-open class JekyllFormatService(
- generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- linkExtension: String,
- impliedPlatforms: List<String>
-) : MarkdownFormatService(generator, signatureGenerator, linkExtension, impliedPlatforms) {
-
- @Inject constructor(
- generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- @Named(impliedPlatformsName) impliedPlatforms: List<String>
- ) : this(generator, signatureGenerator, "html", impliedPlatforms)
-
- override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder =
- JekyllOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms)
-
-}
diff --git a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt b/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt
deleted file mode 100644
index 3cdea156..00000000
--- a/core/src/main/kotlin/Formats/KotlinWebsiteHtmlFormatService.kt
+++ /dev/null
@@ -1,264 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.google.inject.name.Named
-import org.jetbrains.dokka.Utilities.impliedPlatformsName
-import java.io.File
-
-
-object EmptyHtmlTemplateService : HtmlTemplateService {
- override fun appendFooter(to: StringBuilder) {}
-
- override fun appendHeader(to: StringBuilder, title: String?, basePath: File) {}
-}
-
-
-open class KotlinWebsiteHtmlOutputBuilder(
- to: StringBuilder,
- location: Location,
- generator: NodeLocationAwareGenerator,
- languageService: LanguageService,
- extension: String,
- val impliedPlatforms: List<String>,
- templateService: HtmlTemplateService
-) : HtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService) {
- private var needHardLineBreaks = false
- private var insideDiv = 0
-
- override fun appendLine() {}
-
- override fun appendBreadcrumbs(path: Iterable<FormatLink>) {
- if (path.count() > 1) {
- to.append("<div class='api-docs-breadcrumbs'>")
- super.appendBreadcrumbs(path)
- to.append("</div>")
- }
- }
-
- override fun appendSinceKotlin(version: String) {
- }
-
- override fun appendSinceKotlinWrapped(version: String) {
- }
-
- override fun appendCode(body: () -> Unit) = wrapIfNotEmpty("<code>", "</code>", body)
-
- protected fun div(to: StringBuilder, cssClass: String, otherAttributes: String = "", block: () -> Unit) {
- to.append("<div class=\"$cssClass\"$otherAttributes")
- to.append(">")
- insideDiv++
- block()
- insideDiv--
- to.append("</div>\n")
- }
-
- override fun appendAsSignature(node: ContentNode, block: () -> Unit) {
- val contentLength = node.textLength
- if (contentLength == 0) return
- div(to, "signature") {
- needHardLineBreaks = contentLength >= 62
- try {
- block()
- } finally {
- needHardLineBreaks = false
- }
- }
- }
-
- override fun appendAsOverloadGroup(to: StringBuilder, platforms: PlatformsData, block: () -> Unit) {
- div(to, "overload-group", calculateDataAttributes(platforms)) {
- block()
- }
- }
-
- override fun appendLink(href: String, body: () -> Unit) = wrap("<a href=\"$href\">", "</a>", body)
-
- override fun appendTable(vararg columns: String, body: () -> Unit) {
- //to.appendln("<table class=\"api-docs-table\">")
- div(to, "api-declarations-list") {
- body()
- }
- //to.appendln("</table>")
- }
-
- override fun appendTableBody(body: () -> Unit) {
- //to.appendln("<tbody>")
- body()
- //to.appendln("</tbody>")
- }
-
- override fun appendTableRow(body: () -> Unit) {
- //to.appendln("<tr>")
- body()
- //to.appendln("</tr>")
- }
-
- override fun appendTableCell(body: () -> Unit) {
-// to.appendln("<td>")
- body()
-// to.appendln("\n</td>")
- }
-
- override fun appendSymbol(text: String) {
- to.append("<span class=\"symbol\">${text.htmlEscape()}</span>")
- }
-
- override fun appendKeyword(text: String) {
- to.append("<span class=\"keyword\">${text.htmlEscape()}</span>")
- }
-
- override fun appendIdentifier(text: String, kind: IdentifierKind, signature: String?) {
- val id = signature?.let { " id=\"$it\"" }.orEmpty()
- to.append("<span class=\"${identifierClassName(kind)}\"$id>${text.htmlEscape()}</span>")
- }
-
- override fun appendSoftLineBreak() {
- if (needHardLineBreaks)
- to.append("<br/>")
- }
-
- override fun appendIndentedSoftLineBreak() {
- if (needHardLineBreaks) {
- to.append("<br/>&nbsp;&nbsp;&nbsp;&nbsp;")
- }
- }
-
- private fun identifierClassName(kind: IdentifierKind) = when (kind) {
- IdentifierKind.ParameterName -> "parameterName"
- IdentifierKind.SummarizedTypeName -> "summarizedTypeName"
- else -> "identifier"
- }
-
- private data class PlatformsForElement(
- val platformToVersion: Map<String, String>
- )
-
- private fun calculatePlatforms(platforms: PlatformsData): PlatformsForElement {
- //val kotlinVersion = platforms.singleOrNull(String::isKotlinVersion)?.removePrefix("Kotlin ")
- val jreVersion = platforms.keys.filter(String::isJREVersion).min()?.takeUnless { it.endsWith("6") }
- val targetPlatforms = platforms.filterNot { it.key.isJREVersion() } +
- listOfNotNull(jreVersion?.let { it to platforms[it]!! })
-
- return PlatformsForElement(
- targetPlatforms.mapValues { (_, nodes) -> effectiveSinceKotlinForNodes(nodes) }
- )
- }
-
- private fun calculateDataAttributes(platforms: PlatformsData): String {
- val platformToVersion = calculatePlatforms(platforms).platformToVersion
- val (platformNames, versions) = platformToVersion.toList().unzip()
- return "data-platform=\"${platformNames.joinToString()}\" "+
- "data-kotlin-version=\"${versions.joinToString()}\""
- }
-
- override fun appendIndexRow(platforms: PlatformsData, block: () -> Unit) {
-// if (platforms.isNotEmpty())
-// wrap("<tr${calculateDataAttributes(platforms)}>", "</tr>", block)
-// else
-// appendTableRow(block)
- div(to, "declarations", otherAttributes = " ${calculateDataAttributes(platforms)}") {
- block()
- }
- }
-
- override fun appendPlatforms(platforms: PlatformsData) {
- val platformToVersion = calculatePlatforms(platforms).platformToVersion
- div(to, "tags") {
- div(to, "spacer") {}
- platformToVersion.entries.sortedBy {
- platformSortWeight(it.key)
- }.forEach { (platform, version) ->
- div(to, "tags__tag platform tag-value-$platform",
- otherAttributes = " data-tag-version=\"$version\"") {
- to.append(platform)
- }
- }
- div(to, "tags__tag kotlin-version") {
- to.append(mergeVersions(platformToVersion.values.toList()))
- }
- }
- }
-
- override fun appendAsNodeDescription(platforms: PlatformsData, block: () -> Unit) {
- div(to, "node-page-main", otherAttributes = " ${calculateDataAttributes(platforms)}") {
- block()
- }
-
- }
-
- override fun appendBreadcrumbSeparator() {
- to.append(" / ")
- }
-
- override fun appendPlatformsAsText(platforms: PlatformsData) {
- appendHeader(5) {
- val filtered = platforms.keys.filterNot { it.isJREVersion() }.sortedBy { platformSortWeight(it) }
- if (filtered.isNotEmpty()) {
- to.append("For ")
- filtered.joinTo(to)
- }
- }
- }
-
- override fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) {
- div(to, "sample", otherAttributes = " data-min-compiler-version=\"1.3\"") {
- appendBlockCode(language) {
- imports()
- wrap("\n\nfun main(args: Array<String>) {".htmlEscape(), "}") {
- wrap("\n//sampleStart\n", "\n//sampleEnd\n", body)
- }
- }
- }
- }
-
- override fun appendSoftParagraph(body: () -> Unit) = appendParagraph(body)
-
-
- override fun appendSectionWithTag(section: ContentSection) {
- appendParagraph {
- appendStrong { appendText(section.tag) }
- appendText(" ")
- appendContent(section)
- }
- }
-
- override fun appendAsPlatformDependentBlock(platforms: PlatformsData, block: (PlatformsData) -> Unit) {
- if (platforms.isNotEmpty())
- wrap("<div ${calculateDataAttributes(platforms)}>", "</div>") {
- block(platforms)
- }
- else
- block(platforms)
- }
-
- override fun appendAsSummaryGroup(platforms: PlatformsData, block: (PlatformsData) -> Unit) {
- div(to, "summary-group", otherAttributes = " ${calculateDataAttributes(platforms)}") {
- block(platforms)
- }
- }
-
- fun platformSortWeight(name: String) = when(name.toLowerCase()) {
- "common" -> 0
- "jvm" -> 1
- "js" -> 3
- "native" -> 4
- else -> 2 // This is hack to support JRE/JUnit and so on
- }
-}
-
-class KotlinWebsiteHtmlFormatService @Inject constructor(
- generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- @Named(impliedPlatformsName) impliedPlatforms: List<String>,
- templateService: HtmlTemplateService
-) : HtmlFormatService(generator, signatureGenerator, templateService, impliedPlatforms) {
-
- override fun enumerateSupportFiles(callback: (String, String) -> Unit) {}
-
- override fun createOutputBuilder(to: StringBuilder, location: Location) =
- KotlinWebsiteHtmlOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms, templateService)
-}
-
-
-private fun String.isKotlinVersion() = this.startsWith("Kotlin")
-private fun String.isJREVersion() = this.startsWith("JRE", ignoreCase=true) \ No newline at end of file
diff --git a/core/src/main/kotlin/Formats/MarkdownFormatService.kt b/core/src/main/kotlin/Formats/MarkdownFormatService.kt
deleted file mode 100644
index 216dd2ef..00000000
--- a/core/src/main/kotlin/Formats/MarkdownFormatService.kt
+++ /dev/null
@@ -1,250 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.google.inject.name.Named
-import org.jetbrains.dokka.Utilities.impliedPlatformsName
-import java.util.*
-
-enum class ListKind {
- Ordered,
- Unordered
-}
-
-private class ListState(val kind: ListKind, var size: Int = 1) {
- fun getTagAndIncrement() = when (kind) {
- ListKind.Ordered -> "${size++}. "
- else -> "* "
- }
-}
-
-private val TWO_LINE_BREAKS = System.lineSeparator() + System.lineSeparator()
-
-open class MarkdownOutputBuilder(to: StringBuilder,
- location: Location,
- generator: NodeLocationAwareGenerator,
- languageService: LanguageService,
- extension: String,
- impliedPlatforms: List<String>)
- : StructuredOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms)
-{
- private val listStack = ArrayDeque<ListState>()
- protected var inTableCell = false
- protected var inCodeBlock = false
- private var lastTableCellStart = -1
- private var maxBackticksInCodeBlock = 0
-
- private fun appendNewline() {
- while (to.endsWith(' ')) {
- to.setLength(to.length - 1)
- }
- to.appendln()
- }
-
- private fun ensureNewline() {
- if (inTableCell && listStack.isEmpty()) {
- if (to.length != lastTableCellStart && !to.endsWith("<br>")) {
- to.append("<br>")
- }
- }
- else {
- if (!endsWithNewline()) {
- appendNewline()
- }
- }
- }
-
- private fun endsWithNewline(): Boolean {
- var index = to.length - 1
- while (index > 0) {
- val c = to[index]
- if (c != ' ') {
- return c == '\n'
- }
- index--
- }
- return false
- }
-
- override fun ensureParagraph() {
- if (!to.endsWith(TWO_LINE_BREAKS)) {
- if (!to.endsWith('\n')) {
- appendNewline()
- }
- appendNewline()
- }
- }
- override fun appendBreadcrumbSeparator() {
- to.append(" / ")
- }
-
- private val backTickFindingRegex = """(`+)""".toRegex()
-
- override fun appendText(text: String) {
- if (inCodeBlock) {
- to.append(text)
- val backTicks = backTickFindingRegex.findAll(text)
- val longestBackTickRun = backTicks.map { it.value.length }.max() ?: 0
- maxBackticksInCodeBlock = maxBackticksInCodeBlock.coerceAtLeast(longestBackTickRun)
- }
- else {
- if (text == "\n" && inTableCell) {
- to.append(" ")
- } else {
- to.append(text.htmlEscape())
- }
- }
- }
-
- override fun appendCode(body: () -> Unit) {
- inCodeBlock = true
- val codeBlockStart = to.length
- maxBackticksInCodeBlock = 0
-
- wrapIfNotEmpty("`", "`", body, checkEndsWith = true)
-
- if (maxBackticksInCodeBlock > 0) {
- val extraBackticks = "`".repeat(maxBackticksInCodeBlock)
- to.insert(codeBlockStart, extraBackticks)
- to.append(extraBackticks)
- }
-
- inCodeBlock = false
- }
-
- override fun appendUnorderedList(body: () -> Unit) {
- listStack.push(ListState(ListKind.Unordered))
- body()
- listStack.pop()
- ensureNewline()
- }
-
- override fun appendOrderedList(body: () -> Unit) {
- listStack.push(ListState(ListKind.Ordered))
- body()
- listStack.pop()
- ensureNewline()
- }
-
- override fun appendListItem(body: () -> Unit) {
- ensureNewline()
- to.append(listStack.peek()?.getTagAndIncrement())
- body()
- ensureNewline()
- }
-
- override fun appendStrong(body: () -> Unit) = wrap("**", "**", body)
- override fun appendEmphasis(body: () -> Unit) = wrap("*", "*", body)
- override fun appendStrikethrough(body: () -> Unit) = wrap("~~", "~~", body)
-
- override fun appendLink(href: String, body: () -> Unit) {
- if (inCodeBlock) {
- wrap("`[`", "`]($href)`", body)
- }
- else {
- wrap("[", "]($href)", body)
- }
- }
-
- override fun appendLine() {
- if (inTableCell) {
- to.append("<br>")
- }
- else {
- appendNewline()
- }
- }
-
- override fun appendAnchor(anchor: String) {
- // no anchors in Markdown
- }
-
- override fun appendParagraph(body: () -> Unit) {
- when {
- inTableCell -> {
- ensureNewline()
- body()
- }
- listStack.isNotEmpty() -> {
- body()
- ensureNewline()
- }
- else -> {
- ensureParagraph()
- body()
- ensureParagraph()
- }
- }
- }
-
- override fun appendHeader(level: Int, body: () -> Unit) {
- when {
- inTableCell -> {
- body()
- }
- else -> {
- ensureParagraph()
- to.append("${"#".repeat(level)} ")
- body()
- ensureParagraph()
- }
- }
- }
-
- override fun appendBlockCode(language: String, body: () -> Unit) {
- inCodeBlock = true
- ensureParagraph()
- to.appendln(if (language.isEmpty()) "```" else "``` $language")
- body()
- ensureNewline()
- to.appendln("```")
- appendLine()
- inCodeBlock = false
- }
-
- override fun appendTable(vararg columns: String, body: () -> Unit) {
- ensureParagraph()
- body()
- ensureParagraph()
- }
-
- override fun appendTableBody(body: () -> Unit) {
- body()
- }
-
- override fun appendTableRow(body: () -> Unit) {
- to.append("|")
- body()
- appendNewline()
- }
-
- override fun appendTableCell(body: () -> Unit) {
- to.append(" ")
- inTableCell = true
- lastTableCellStart = to.length
- body()
- inTableCell = false
- to.append(" |")
- }
-
- override fun appendNonBreakingSpace() {
- if (inCodeBlock) {
- to.append(" ")
- }
- else {
- to.append("&nbsp;")
- }
- }
-}
-
-open class MarkdownFormatService(generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- linkExtension: String,
- val impliedPlatforms: List<String>)
-: StructuredFormatService(generator, signatureGenerator, "md", linkExtension) {
- @Inject constructor(generator: NodeLocationAwareGenerator,
- signatureGenerator: LanguageService,
- @Named(impliedPlatformsName) impliedPlatforms: List<String>): this(generator, signatureGenerator, "md", impliedPlatforms)
-
- override fun createOutputBuilder(to: StringBuilder, location: Location): FormattedOutputBuilder =
- MarkdownOutputBuilder(to, location, generator, languageService, extension, impliedPlatforms)
-}
diff --git a/core/src/main/kotlin/Formats/OutlineService.kt b/core/src/main/kotlin/Formats/OutlineService.kt
deleted file mode 100644
index 958e93af..00000000
--- a/core/src/main/kotlin/Formats/OutlineService.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.jetbrains.dokka
-
-import java.io.File
-
-/**
- * Service for building the outline of the package contents.
- */
-interface OutlineFormatService {
- fun getOutlineFileName(location: Location): File
-
- fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder)
- fun appendOutlineLevel(to: StringBuilder, body: () -> Unit)
-
- /** Appends formatted outline to [StringBuilder](to) using specified [location] */
- fun appendOutline(location: Location, to: StringBuilder, nodes: Iterable<DocumentationNode>) {
- for (node in nodes) {
- appendOutlineHeader(location, node, to)
- if (node.members.any()) {
- val sortedMembers = node.members.sortedBy { it.name.toLowerCase() }
- appendOutlineLevel(to) {
- appendOutline(location, to, sortedMembers)
- }
- }
- }
- }
-
- fun formatOutline(location: Location, nodes: Iterable<DocumentationNode>): String =
- StringBuilder().apply { appendOutline(location, this, nodes) }.toString()
-}
diff --git a/core/src/main/kotlin/Formats/PackageListService.kt b/core/src/main/kotlin/Formats/PackageListService.kt
deleted file mode 100644
index e675d927..00000000
--- a/core/src/main/kotlin/Formats/PackageListService.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-
-
-interface PackageListService {
- fun formatPackageList(module: DocumentationModule): String
-}
-
-class DefaultPackageListService @Inject constructor(
- val generator: NodeLocationAwareGenerator,
- val formatService: FormatService
-) : PackageListService {
-
- override fun formatPackageList(module: DocumentationModule): String {
- val packages = mutableSetOf<String>()
- val nonStandardLocations = mutableMapOf<String, String>()
-
- fun visit(node: DocumentationNode, relocated: Boolean = false) {
- val nodeKind = node.kind
-
- when (nodeKind) {
- NodeKind.Package -> {
- packages.add(node.qualifiedName())
- node.members.forEach { visit(it) }
- }
- NodeKind.Signature -> {
- if (relocated)
- nonStandardLocations[node.name] = generator.relativePathToLocation(module, node.owner!!)
- }
- NodeKind.ExternalClass -> {
- node.members.forEach { visit(it, relocated = true) }
- }
- NodeKind.GroupNode -> {
- if (node.members.isNotEmpty()) {
- // Only nodes only has single file is need to be relocated
- // TypeAliases for example
- node.origins
- .filter { it.members.isEmpty() }
- .forEach { visit(it, relocated = true) }
- }
- }
- else -> {
- if (nodeKind in NodeKind.classLike || nodeKind in NodeKind.memberLike) {
- node.details(NodeKind.Signature).forEach { visit(it, relocated) }
- node.members.forEach { visit(it, relocated) }
- }
- }
- }
- }
-
- module.members.forEach { visit(it) }
-
- return buildString {
- appendln("\$dokka.linkExtension:${formatService.linkExtension}")
-
- nonStandardLocations.map { (signature, location) -> "\$dokka.location:$signature\u001f$location" }
- .sorted().joinTo(this, separator = "\n", postfix = "\n")
-
- packages.sorted().joinTo(this, separator = "\n", postfix = "\n")
- }
-
- }
-
-}
-
diff --git a/core/src/main/kotlin/Formats/StandardFormats.kt b/core/src/main/kotlin/Formats/StandardFormats.kt
deleted file mode 100644
index 86f70a37..00000000
--- a/core/src/main/kotlin/Formats/StandardFormats.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.jetbrains.dokka.Formats
-
-import com.google.inject.Binder
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.Samples.KotlinWebsiteSampleProcessingService
-import org.jetbrains.dokka.Utilities.bind
-import kotlin.reflect.KClass
-
-abstract class KotlinFormatDescriptorBase
- : FileGeneratorBasedFormatDescriptor(),
- DefaultAnalysisComponent,
- DefaultAnalysisComponentServices by KotlinAsKotlin {
- override val generatorServiceClass = FileGenerator::class
- override val outlineServiceClass: KClass<out OutlineFormatService>? = null
- override val packageListServiceClass: KClass<out PackageListService>? = DefaultPackageListService::class
-}
-
-abstract class HtmlFormatDescriptorBase : FileGeneratorBasedFormatDescriptor(), DefaultAnalysisComponent {
- override val formatServiceClass = HtmlFormatService::class
- override val outlineServiceClass = HtmlFormatService::class
- override val generatorServiceClass = FileGenerator::class
- override val packageListServiceClass = DefaultPackageListService::class
-
- override fun configureOutput(binder: Binder): Unit = with(binder) {
- super.configureOutput(binder)
- bind<HtmlTemplateService>().toProvider { HtmlTemplateService.default("style.css") }
- }
-}
-
-class HtmlFormatDescriptor : HtmlFormatDescriptorBase(), DefaultAnalysisComponentServices by KotlinAsKotlin
-
-class HtmlAsJavaFormatDescriptor : HtmlFormatDescriptorBase(), DefaultAnalysisComponentServices by KotlinAsJava
-
-class KotlinWebsiteHtmlFormatDescriptor : KotlinFormatDescriptorBase() {
- override val formatServiceClass = KotlinWebsiteHtmlFormatService::class
- override val sampleProcessingService = KotlinWebsiteSampleProcessingService::class
- override val outlineServiceClass = YamlOutlineService::class
-
- override fun configureOutput(binder: Binder) = with(binder) {
- super.configureOutput(binder)
- bind<HtmlTemplateService>().toInstance(EmptyHtmlTemplateService)
- }
-}
-
-class JekyllFormatDescriptor : KotlinFormatDescriptorBase() {
- override val formatServiceClass = JekyllFormatService::class
-}
-
-class MarkdownFormatDescriptor : KotlinFormatDescriptorBase() {
- override val formatServiceClass = MarkdownFormatService::class
-}
-
-class GFMFormatDescriptor : KotlinFormatDescriptorBase() {
- override val formatServiceClass = GFMFormatService::class
-}
diff --git a/core/src/main/kotlin/Formats/StructuredFormatService.kt b/core/src/main/kotlin/Formats/StructuredFormatService.kt
deleted file mode 100644
index 76f9366f..00000000
--- a/core/src/main/kotlin/Formats/StructuredFormatService.kt
+++ /dev/null
@@ -1,1014 +0,0 @@
-package org.jetbrains.dokka
-
-import org.jetbrains.dokka.LanguageService.RenderMode
-import org.jetbrains.kotlin.utils.keysToMap
-import java.util.*
-
-data class FormatLink(val text: String, val href: String)
-
-private data class Summarized(
- val data: List<SummarizedBySummary>
-) {
-
- constructor(data: Map<ContentNode, Map<ContentNode, List<DocumentationNode>>>) : this(
- data.entries.map { (summary, signatureToMember) ->
- SummarizedBySummary(
- summary,
- signatureToMember.map { (signature, nodes) ->
- SummarizedNodes(signature, nodes)
- }
- )
- }
- )
-
- data class SummarizedNodes(val content: ContentNode, val nodes: List<DocumentationNode>) {
- val platforms = effectivePlatformsForMembers(nodes)
- }
- data class SummarizedBySummary(val content: ContentNode, val signatures: List<SummarizedNodes>) {
- val platforms = effectivePlatformsForMembers(signatures.flatMap { it.nodes })
- val platformsOnSignature = !samePlatforms(signatures.map { it.platforms })
- }
-
-
- fun computePlatformLevel(): PlatformPlacement {
- if (data.any { it.platformsOnSignature }) {
- return PlatformPlacement.Signature
- }
- if (samePlatforms(data.map { it.platforms })) {
- return PlatformPlacement.Row
- }
- return PlatformPlacement.Summary
- }
- val platformPlacement: PlatformPlacement = computePlatformLevel()
- val platforms = effectivePlatformsForMembers(data.flatMap { it.signatures.flatMap { it.nodes } })
-
-
- enum class PlatformPlacement {
- Row, Summary, Signature
- }
-}
-
-abstract class StructuredOutputBuilder(val to: StringBuilder,
- val location: Location,
- val generator: NodeLocationAwareGenerator,
- val languageService: LanguageService,
- val extension: String,
- impliedPlatforms: List<String>) : FormattedOutputBuilder {
-
- protected fun wrap(prefix: String, suffix: String, body: () -> Unit) {
- to.append(prefix)
- body()
- to.append(suffix)
- }
-
- protected fun wrapIfNotEmpty(prefix: String, suffix: String, body: () -> Unit, checkEndsWith: Boolean = false) {
- val startLength = to.length
- to.append(prefix)
- body()
- if (checkEndsWith && to.endsWith(suffix)) {
- to.setLength(to.length - suffix.length)
- } else if (to.length > startLength + prefix.length) {
- to.append(suffix)
- } else {
- to.setLength(startLength)
- }
- }
-
- protected fun wrapInTag(tag: String,
- body: () -> Unit,
- newlineBeforeOpen: Boolean = false,
- newlineAfterOpen: Boolean = false,
- newlineAfterClose: Boolean = false) {
- if (newlineBeforeOpen && !to.endsWith('\n')) to.appendln()
- to.append("<$tag>")
- if (newlineAfterOpen) to.appendln()
- body()
- to.append("</$tag>")
- if (newlineAfterClose) to.appendln()
- }
-
- protected abstract fun ensureParagraph()
-
- open fun appendSampleBlockCode(language: String, imports: () -> Unit, body: () -> Unit) = appendBlockCode(language, body)
- abstract fun appendBlockCode(language: String, body: () -> Unit)
- abstract fun appendHeader(level: Int = 1, body: () -> Unit)
- abstract fun appendParagraph(body: () -> Unit)
-
- open fun appendSoftParagraph(body: () -> Unit) {
- ensureParagraph()
- body()
- }
-
- abstract fun appendLine()
- abstract fun appendAnchor(anchor: String)
-
- abstract fun appendTable(vararg columns: String, body: () -> Unit)
- abstract fun appendTableBody(body: () -> Unit)
- abstract fun appendTableRow(body: () -> Unit)
- abstract fun appendTableCell(body: () -> Unit)
-
- abstract fun appendText(text: String)
-
- open fun appendSinceKotlin(version: String) {
- appendText("Since: ")
- appendCode { appendText(version) }
- }
-
- open fun appendSinceKotlinWrapped(version: String) {
- wrap(" (", ")") {
- appendSinceKotlin(version)
- }
- }
-
- open fun appendSectionWithTag(section: ContentSection) {
- appendParagraph {
- appendStrong { appendText(section.tag) }
- appendLine()
- appendContent(section)
- }
- }
-
- open fun appendAsPlatformDependentBlock(platforms: PlatformsData, block: (PlatformsData) -> Unit) {
- block(platforms)
- }
-
- open fun appendAsSummaryGroup(platforms: PlatformsData, block: (PlatformsData) -> Unit) {
- appendAsPlatformDependentBlock(platforms, block)
- }
-
- open fun appendSymbol(text: String) {
- appendText(text)
- }
-
- open fun appendKeyword(text: String) {
- appendText(text)
- }
-
- open fun appendIdentifier(text: String, kind: IdentifierKind, signature: String?) {
- appendText(text)
- }
-
- open fun appendAsNodeDescription(platforms: PlatformsData, block: () -> Unit) {
- block()
- }
-
- fun appendEntity(text: String) {
- to.append(text)
- }
-
- abstract fun appendLink(href: String, body: () -> Unit)
-
- open fun appendLink(link: FormatLink) {
- appendLink(link.href) { appendText(link.text) }
- }
-
- abstract fun appendStrong(body: () -> Unit)
- abstract fun appendStrikethrough(body: () -> Unit)
- abstract fun appendEmphasis(body: () -> Unit)
- abstract fun appendCode(body: () -> Unit)
- abstract fun appendUnorderedList(body: () -> Unit)
- abstract fun appendOrderedList(body: () -> Unit)
- abstract fun appendListItem(body: () -> Unit)
-
- abstract fun appendBreadcrumbSeparator()
- abstract fun appendNonBreakingSpace()
- open fun appendSoftLineBreak() {
- }
-
- open fun appendIndentedSoftLineBreak() {
- }
-
- fun appendContent(content: List<ContentNode>) {
- for (contentNode in content) {
- appendContent(contentNode)
- }
- }
-
- open fun appendContent(content: ContentNode) {
- when (content) {
- is ContentText -> appendText(content.text)
- is ContentSymbol -> appendSymbol(content.text)
- is ContentKeyword -> appendKeyword(content.text)
- is ContentIdentifier -> appendIdentifier(content.text, content.kind, content.signature)
- is ContentNonBreakingSpace -> appendNonBreakingSpace()
- is ContentSoftLineBreak -> appendSoftLineBreak()
- is ContentIndentedSoftLineBreak -> appendIndentedSoftLineBreak()
- is ContentEntity -> appendEntity(content.text)
- is ContentStrong -> appendStrong { appendContent(content.children) }
- is ContentStrikethrough -> appendStrikethrough { appendContent(content.children) }
- is ContentCode -> appendCode { appendContent(content.children) }
- is ContentEmphasis -> appendEmphasis { appendContent(content.children) }
- is ContentUnorderedList -> appendUnorderedList { appendContent(content.children) }
- is ContentOrderedList -> appendOrderedList { appendContent(content.children) }
- is ContentListItem -> appendListItem {
- val child = content.children.singleOrNull()
- if (child is ContentParagraph) {
- appendContent(child.children)
- } else {
- appendContent(content.children)
- }
- }
-
- is NodeRenderContent -> {
- val node = content.node
- appendContent(languageService.render(node, content.mode))
- }
- is ContentNodeLink -> {
- val node = content.node
- val linkTo = if (node != null) locationHref(location, node, generator) else "#"
- appendLinkIfNotThisPage(linkTo, content)
- }
- is ContentExternalLink -> appendLinkIfNotThisPage(content.href, content)
-
- is ContentParagraph -> {
- if (!content.isEmpty()) {
- appendParagraph { appendContent(content.children) }
- }
- }
-
- is ContentBlockSampleCode, is ContentBlockCode -> {
- content as ContentBlockCode
- fun ContentBlockCode.appendBlockCodeContent() {
- children
- .dropWhile { it is ContentText && it.text.isBlank() }
- .forEach { appendContent(it) }
- }
- when (content) {
- is ContentBlockSampleCode ->
- appendSampleBlockCode(content.language, content.importsBlock::appendBlockCodeContent) { content.appendBlockCodeContent() }
- is ContentBlockCode ->
- appendBlockCode(content.language) { content.appendBlockCodeContent() }
- }
- }
- is ContentHeading -> appendHeader(content.level) { appendContent(content.children) }
- is ContentBlock -> appendContent(content.children)
- }
- }
-
- private fun appendLinkIfNotThisPage(href: String, content: ContentBlock) {
- if (href == ".") {
- appendContent(content.children)
- } else {
- appendLink(href) { appendContent(content.children) }
- }
- }
-
- open fun link(
- from: DocumentationNode,
- to: DocumentationNode,
- name: (DocumentationNode) -> String = DocumentationNode::name
- ): FormatLink = link(from, to, extension, name)
-
- open fun link(
- from: DocumentationNode,
- to: DocumentationNode,
- extension: String,
- name: (DocumentationNode) -> String = DocumentationNode::name
- ): FormatLink =
- FormatLink(name(to), generator.relativePathToLocation(from, to))
-
- private fun DocumentationNode.isModuleOrPackage(): Boolean =
- kind == NodeKind.Module || kind == NodeKind.Package
-
- protected open fun appendAsSignature(node: ContentNode, block: () -> Unit) {
- block()
- }
-
- protected open fun appendAsOverloadGroup(to: StringBuilder, platforms: PlatformsData, block: () -> Unit) {
- block()
- }
-
- protected open fun appendIndexRow(platforms: PlatformsData, block: () -> Unit) {
- appendTableRow(block)
- }
-
- protected open fun appendPlatformsAsText(platforms: PlatformsData) {
- appendPlatforms(platforms)
- }
-
- protected open fun appendPlatforms(platforms: PlatformsData) {
- if (platforms.isNotEmpty()) {
- appendText(platforms.keys.joinToString(prefix = "(", postfix = ") "))
- }
- }
-
- protected open fun appendBreadcrumbs(path: Iterable<FormatLink>) {
- for ((index, item) in path.withIndex()) {
- if (index > 0) {
- appendBreadcrumbSeparator()
- }
- appendLink(item)
- }
- }
-
- fun Content.getSectionsWithSubjects(): Map<String, List<ContentSection>> =
- sections.filter { it.subjectName != null }.groupBy { it.tag }
-
- private fun ContentNode.appendSignature() {
- if (this is ContentBlock && this.isEmpty()) {
- return
- }
-
- val signatureAsCode = ContentCode()
- signatureAsCode.append(this)
- appendContent(signatureAsCode)
- }
-
- open inner class PageBuilder(val nodes: Iterable<DocumentationNode>, val noHeader: Boolean = false) {
- open fun build() {
- val breakdownByLocation = nodes.groupBy { node ->
- node.path.filterNot { it.name.isEmpty() }.map { link(node, it) }.distinct()
- }
-
- for ((path, nodes) in breakdownByLocation) {
- if (!noHeader && path.isNotEmpty()) {
- appendBreadcrumbs(path)
- appendLine()
- appendLine()
- }
- appendLocation(nodes.filter { it.kind != NodeKind.ExternalClass })
- }
- }
-
- private fun appendLocation(nodes: Iterable<DocumentationNode>) {
- val singleNode = nodes.singleOrNull()
- if (singleNode != null && singleNode.isModuleOrPackage()) {
- if (singleNode.kind == NodeKind.Package) {
- val packageName = if (singleNode.name.isEmpty()) "<root>" else singleNode.name
- appendHeader(2) { appendText("Package $packageName") }
- }
- appendContent(singleNode.content)
- } else {
- val breakdownByName = nodes.groupBy { node -> node.name }
- for ((name, items) in breakdownByName) {
- if (!noHeader)
- appendHeader { appendText(name) }
- appendDocumentation(items, singleNode != null)
- }
- }
- }
-
- private fun appendDocumentation(overloads: Iterable<DocumentationNode>, isSingleNode: Boolean) {
- val breakdownBySummary = overloads.groupByTo(LinkedHashMap()) { node ->
- when (node.kind) {
- NodeKind.GroupNode -> node.origins.map { it.content }
- else -> node.content
- }
- }
-
- if (breakdownBySummary.size == 1) {
- val node = breakdownBySummary.values.single()
- appendAsNodeDescription(effectivePlatformsForMembers(node)) {
- formatOverloadGroup(node, isSingleNode)
- }
- } else {
- for ((_, items) in breakdownBySummary) {
- appendAsOverloadGroup(to, effectivePlatformsForMembers(items)) {
- formatOverloadGroup(items)
- }
- }
- }
- }
-
- private fun formatOverloadGroup(items: List<DocumentationNode>, isSingleNode: Boolean = false) {
-
- val platformsPerGroup = samePlatforms(
- items.flatMap {
- if (it.kind == NodeKind.GroupNode) {
- it.origins.groupBy { origin ->
- languageService.render(origin)
- }.values.map { origins -> effectivePlatformsForMembers(origins) }
- } else {
- listOf(effectivePlatformsForNode(it))
- }
- }
- )
-
- if (platformsPerGroup) {
- appendAsPlatformDependentBlock(effectivePlatformsForMembers(items)) { platforms ->
- appendPlatforms(platforms)
- }
- }
- for ((index, item) in items.withIndex()) {
- if (index > 0) appendLine()
-
- if (item.kind == NodeKind.GroupNode) {
- renderGroupNode(item, isSingleNode, !platformsPerGroup)
- } else {
- renderSimpleNode(item, isSingleNode, !platformsPerGroup)
- }
-
- }
- // All items have exactly the same documentation, so we can use any item to render it
- val item = items.first()
- // TODO: remove this block cause there is no one node with OverloadGroupNote detail
- item.details(NodeKind.OverloadGroupNote).forEach {
- appendContent(it.content)
- }
-
- if (item.kind == NodeKind.GroupNode) {
- val groupByContent = item.origins.groupBy { it.content }
- if (groupByContent.count { !it.key.isEmpty() } > 1) {
- if (groupByContent.size > 1) println("[mult] Found ov diff: ${generator.location(item).path}")
- }
- for ((content, origins) in groupByContent) {
- if (content.isEmpty()) continue
- appendAsPlatformDependentBlock(effectivePlatformsForMembers(origins)) { platforms ->
- if (groupByContent.count { !it.key.isEmpty() } > 1) {
- appendPlatformsAsText(platforms)
- }
- appendContent(content.summary)
- content.appendDescription()
- }
- }
- } else {
- val platforms = effectivePlatformsForNode(item)
- appendAsPlatformDependentBlock(platforms) {
- appendContent(item.summary)
- item.content.appendDescription()
- }
- }
- }
-
-
- fun renderSimpleNode(item: DocumentationNode, isSingleNode: Boolean, withPlatforms: Boolean = true) {
- appendAsPlatformDependentBlock(effectivePlatformsForMembers(listOf(item))) { platforms ->
- // TODO: use summarizesignatures
- val rendered = languageService.render(item)
- item.detailOrNull(NodeKind.Signature)?.let {
- if (item.kind !in NodeKind.classLike || !isSingleNode)
- appendAnchor(it.name)
- }
- if (withPlatforms) {
- appendPlatforms(platforms)
- }
- appendAsSignature(rendered) {
- appendCode { appendContent(rendered) }
- item.appendSourceLink()
- }
- item.appendOverrides()
- item.appendDeprecation()
- }
- }
-
- fun renderGroupNode(item: DocumentationNode, isSingleNode: Boolean, withPlatforms: Boolean = true) {
- // TODO: use summarizesignatures
- val groupBySignature = item.origins.groupBy {
- languageService.render(it)
- }
-
- for ((sign, nodes) in groupBySignature) {
- appendAsPlatformDependentBlock(effectivePlatformsForMembers(nodes)) { platforms ->
- val first = nodes.first()
- first.detailOrNull(NodeKind.Signature)?.let {
- if (item.kind !in NodeKind.classLike || !isSingleNode)
- appendAnchor(it.name)
- }
-
- if (withPlatforms) {
- appendPlatforms(platforms)
- }
-
- appendAsSignature(sign) {
- appendCode { appendContent(sign) }
- }
- first.appendOverrides()
- first.appendDeprecation()
- }
-
- }
- }
-
- private fun DocumentationNode.appendSourceLink() {
- val sourceUrl = details(NodeKind.SourceUrl).firstOrNull()
- if (sourceUrl != null) {
- to.append(" ")
- appendLink(sourceUrl.name) { to.append("(source)") }
- }
- }
-
- private fun DocumentationNode.appendOverrides() {
- overrides.forEach {
- appendParagraph {
- to.append("Overrides ")
- val location = generator.relativePathToLocation(this, it)
-
- appendLink(FormatLink(it.owner!!.name + "." + it.name, location))
- }
- }
- }
-
- private fun DocumentationNode.appendDeprecation() {
- if (deprecation != null) {
- val deprecationParameter = deprecation!!.details(NodeKind.Parameter).firstOrNull()
- val deprecationValue = deprecationParameter?.details(NodeKind.Value)?.firstOrNull()
- appendLine()
- when {
- deprecationValue != null -> {
- appendStrong { to.append("Deprecated:") }
- appendText(" " + deprecationValue.name.removeSurrounding("\""))
- appendLine()
- appendLine()
- }
- deprecation?.content != Content.Empty -> {
- appendStrong { to.append("Deprecated:") }
- to.append(" ")
- appendContent(deprecation!!.content)
- }
- else -> {
- appendStrong { to.append("Deprecated") }
- appendLine()
- appendLine()
- }
- }
- }
- }
-
-
-// protected fun platformsOfItems(items: List<DocumentationNode>): Set<String> {
-// val platforms = items.asSequence().map {
-// when (it.kind) {
-// NodeKind.ExternalClass, NodeKind.Package, NodeKind.Module -> platformsOfItems(it.members)
-// NodeKind.GroupNode -> platformsOfItems(it.origins)
-// else -> it.platformsToShow.toSet()
-// }
-// }
-//
-// fun String.isKotlinVersion() = this.startsWith("Kotlin")
-//
-// if (platforms.count() == 0) return emptySet()
-//
-// // Calculating common platforms for items
-// return platforms.reduce { result, platformsOfItem ->
-// val otherKotlinVersion = result.find { it.isKotlinVersion() }
-// val (kotlinVersions, otherPlatforms) = platformsOfItem.partition { it.isKotlinVersion() }
-//
-// // When no Kotlin version specified, it means that version is 1.0
-// if (otherKotlinVersion != null && kotlinVersions.isNotEmpty()) {
-// result.intersect(platformsOfItem) + mergeVersions(otherKotlinVersion, kotlinVersions)
-// } else {
-// result.intersect(platformsOfItem)
-// }
-// }
-// }
-//
-// protected fun unionPlatformsOfItems(items: List<DocumentationNode>): Set<String> {
-// val platforms = items.asSequence().map {
-// when (it.kind) {
-// NodeKind.GroupNode -> unionPlatformsOfItems(it.origins)
-// else -> it.platformsToShow.toSet()
-// }
-// }
-//
-// fun String.isKotlinVersion() = this.startsWith("Kotlin")
-//
-// if (platforms.count() == 0) return emptySet()
-//
-// // Calculating common platforms for items
-// return platforms.reduce { result, platformsOfItem ->
-// val otherKotlinVersion = result.find { it.isKotlinVersion() }
-// val (kotlinVersions, otherPlatforms) = platformsOfItem.partition { it.isKotlinVersion() }
-//
-// // When no Kotlin version specified, it means that version is 1.0
-// if (otherKotlinVersion != null && kotlinVersions.isNotEmpty()) {
-// result.union(otherPlatforms) + mergeVersions(otherKotlinVersion, kotlinVersions)
-// } else {
-// result.union(otherPlatforms)
-// }
-// }
-// }
-
-// val DocumentationNode.platformsToShow: List<String>
-// get() = platforms
-
- private fun Content.appendDescription() {
- if (description != ContentEmpty) {
- appendContent(description)
- }
-
-
- getSectionsWithSubjects().forEach {
- appendSectionWithSubject(it.key, it.value)
- }
-
- for (section in sections.filter { it.subjectName == null }) {
- appendSectionWithTag(section)
- }
- }
-
- fun appendSectionWithSubject(title: String, subjectSections: List<ContentSection>) {
- appendHeader(3) { appendText(title) }
- subjectSections.forEach {
- val subjectName = it.subjectName
- if (subjectName != null) {
- appendSoftParagraph {
- appendAnchor(subjectName)
- appendCode { to.append(subjectName) }
- to.append(" - ")
- appendContent(it)
- }
- }
- }
- }
-
- fun appendOriginsGroupByContent(node: DocumentationNode) {
- require(node.kind == NodeKind.GroupNode)
- val groupByContent =
- node.origins.groupBy { it.content }
- .mapValues { (_, origins) ->
- effectivePlatformsForMembers(origins)
- }
- .filterNot { it.key.isEmpty() }
- .toList()
- .sortedByDescending { it.second.size }
-
- if (groupByContent.size > 1) println("[mult] Found diff: ${generator.location(node).path}")
- for ((content, platforms) in groupByContent) {
- appendAsPlatformDependentBlock(platforms) {
- if (groupByContent.size > 1) {
- appendPlatformsAsText(platforms)
- }
- appendContent(content.summary)
- content.appendDescription()
- }
- }
- }
- }
-
- inner class SingleNodePageBuilder(val node: DocumentationNode, noHeader: Boolean = false) :
- PageBuilder(listOf(node), noHeader) {
-
- override fun build() {
- super.build()
- SectionsBuilder(node).build()
- }
- }
-
- inner class GroupNodePageBuilder(val node: DocumentationNode) : PageBuilder(listOf(node)) {
-
- override fun build() {
- val breakdownByLocation = node.path.filterNot { it.name.isEmpty() }.map { link(node, it) }
-
- appendBreadcrumbs(breakdownByLocation)
- appendLine()
- appendLine()
- appendHeader { appendText(node.name) }
-
- appendAsNodeDescription(effectivePlatformsForNode(node)) {
- renderGroupNode(node, true)
-
- appendOriginsGroupByContent(node)
- }
-
- SectionsBuilder(node).build()
- }
- }
-//
-// private fun unionPlatformsOfItems(items: List<DocumentationNode>): Set<String> {
-// val platforms = items.flatMapTo(mutableSetOf<String>()) {
-// when (it.kind) {
-// NodeKind.GroupNode -> unionPlatformsOfItems(it.origins)
-// else -> it.platforms
-// }
-// }
-//
-// return platforms
-// }
-
-
- inner class SectionsBuilder(val node: DocumentationNode): PageBuilder(listOf(node)) {
- override fun build() {
- if (node.kind == NodeKind.ExternalClass) {
- appendSection("Extensions for ${node.name}", node.members)
- return
- }
-
- fun DocumentationNode.membersOrGroupMembers(predicate: (DocumentationNode) -> Boolean): List<DocumentationNode> {
- return members.filter(predicate) + members(NodeKind.GroupNode).filter{ it.origins.isNotEmpty() && predicate(it.origins.first()) }
- }
-
- fun DocumentationNode.membersOrGroupMembers(kind: NodeKind): List<DocumentationNode> {
- return membersOrGroupMembers { it.kind == kind }
- }
-
- appendSection("Packages", node.members(NodeKind.Package), platformsBasedOnMembers = true)
- appendSection("Types", node.membersOrGroupMembers { it.kind in NodeKind.classLike /*&& it.kind != NodeKind.TypeAlias*/ && it.kind != NodeKind.AnnotationClass && it.kind != NodeKind.Exception })
- appendSection("Annotations", node.membersOrGroupMembers(NodeKind.AnnotationClass))
- appendSection("Exceptions", node.membersOrGroupMembers(NodeKind.Exception))
- appendSection("Extensions for External Classes", node.members(NodeKind.ExternalClass))
- appendSection("Enum Values", node.membersOrGroupMembers(NodeKind.EnumItem), sortMembers = false, omitSamePlatforms = true)
- appendSection("Constructors", node.membersOrGroupMembers(NodeKind.Constructor), omitSamePlatforms = true)
- appendSection("Properties", node.membersOrGroupMembers(NodeKind.Property), omitSamePlatforms = true)
- appendSection("Inherited Properties", node.inheritedMembers(NodeKind.Property))
- appendSection("Functions", node.membersOrGroupMembers(NodeKind.Function), omitSamePlatforms = true)
- appendSection("Inherited Functions", node.inheritedMembers(NodeKind.Function))
- appendSection("Companion Object Properties", node.membersOrGroupMembers(NodeKind.CompanionObjectProperty), omitSamePlatforms = true)
- appendSection("Inherited Companion Object Properties", node.inheritedCompanionObjectMembers(NodeKind.Property))
- appendSection("Companion Object Functions", node.membersOrGroupMembers(NodeKind.CompanionObjectFunction), omitSamePlatforms = true)
- appendSection("Inherited Companion Object Functions", node.inheritedCompanionObjectMembers(NodeKind.Function))
- appendSection("Other members", node.members.filter {
- it.kind !in setOf(
- NodeKind.Class,
- NodeKind.Interface,
- NodeKind.Enum,
- NodeKind.Object,
- NodeKind.AnnotationClass,
- NodeKind.Exception,
- NodeKind.TypeAlias,
- NodeKind.Constructor,
- NodeKind.Property,
- NodeKind.Package,
- NodeKind.Function,
- NodeKind.CompanionObjectProperty,
- NodeKind.CompanionObjectFunction,
- NodeKind.ExternalClass,
- NodeKind.EnumItem,
- NodeKind.AllTypes,
- NodeKind.GroupNode
- )
- })
-
- val allExtensions = node.extensions
- appendSection("Extension Properties", allExtensions.filter { it.kind == NodeKind.Property })
- appendSection("Extension Functions", allExtensions.filter { it.kind == NodeKind.Function })
- appendSection("Companion Object Extension Properties", allExtensions.filter { it.kind == NodeKind.CompanionObjectProperty })
- appendSection("Companion Object Extension Functions", allExtensions.filter { it.kind == NodeKind.CompanionObjectFunction })
- appendSection("Inheritors",
- node.inheritors.filter { it.kind != NodeKind.EnumItem })
-
- if (node.kind == NodeKind.Module) {
- appendHeader(3) { to.append("Index") }
- node.members(NodeKind.AllTypes).singleOrNull()?.let { allTypes ->
- appendLink(link(node, allTypes) { "All Types" })
- }
- }
- }
-
- private fun appendSection(caption: String, members: List<DocumentationNode>,
- sortMembers: Boolean = true,
- omitSamePlatforms: Boolean = false,
- platformsBasedOnMembers: Boolean = false) {
- if (members.isEmpty()) return
-
- appendHeader(3) { appendText(caption) }
-
- val children = if (sortMembers) members.sortedBy { it.name.toLowerCase() } else members
- val membersMap = children.groupBy { link(node, it) }
-
-
-
- appendTable("Name", "Summary") {
- appendTableBody {
- for ((memberLocation, membersList) in membersMap) {
- val platforms = effectivePlatformsForMembers(membersList)
-// val platforms = if (platformsBasedOnMembers)
-// members.flatMapTo(mutableSetOf()) { platformsOfItems(it.members) } + elementPlatforms
-// else
-// elementPlatforms
-
- val summarized = computeSummarySignatures(membersList)
-
- appendIndexRow(platforms) {
- appendTableCell {
- if (summarized.platformPlacement == Summarized.PlatformPlacement.Row) {
- appendPlatforms(platforms)
- }
- appendHeader(level = 4) {
- // appendParagraph {
- appendLink(memberLocation)
- }
- if (node.sinceKotlin != null) {
- appendSinceKotlin(node.sinceKotlin.toString())
- }
-
- if (membersList.singleOrNull()?.sinceKotlin != null){
- appendSinceKotlinWrapped(membersList.single().sinceKotlin.toString())
- }
-// }
-// if (members.singleOrNull()?.kind != NodeKind.ExternalClass) {
-// appendPlatforms(platforms)
-// }
-// }
- }
- appendTableCell {
- appendSummarySignatures(summarized)
- }
- }
- }
- }
- }
- }
-
-//
-// private fun platformsOfItems(items: List<DocumentationNode>, omitSamePlatforms: Boolean = true): Set<String> {
-// if (items.all { it.kind != NodeKind.Package && it.kind != NodeKind.Module && it.kind != NodeKind.ExternalClass }) {
-// return unionPlatformsOfItems(items)
-// }
-//
-// val platforms = platformsOfItems(items)
-// if (platforms.isNotEmpty() && (platforms != node.platformsToShow.toSet() || !omitSamePlatforms)) {
-// return platforms
-// }
-// return emptySet()
-// }
-
-
-
- private fun computeSummarySignatures(items: List<DocumentationNode>): Summarized =
- Summarized(items.groupBy { it.summary }.mapValues { (_, nodes) ->
- val nodesToAppend = nodes.flatMap { if(it.kind == NodeKind.GroupNode) it.origins else listOf(it) }
-
- val summarySignature = languageService.summarizeSignatures(nodesToAppend)
- if (summarySignature != null) {
- mapOf(summarySignature to nodesToAppend)
- } else {
- nodesToAppend.groupBy {
- languageService.render(it, RenderMode.SUMMARY)
- }
- }
- })
-
-
- private fun appendSummarySignatures(
- summarized: Summarized
- ) {
- for(summary in summarized.data) {
-
- appendAsSummaryGroup(summary.platforms) {
- if (summarized.platformPlacement == Summarized.PlatformPlacement.Summary) {
- appendPlatforms(summary.platforms)
- }
- appendContent(summary.content)
- summary.signatures.subList(0, summary.signatures.size - 1).forEach {
- appendSignatures(
- it,
- summarized.platformPlacement == Summarized.PlatformPlacement.Signature
- )
- appendLine()
- }
- appendSignatures(
- summary.signatures.last(),
- summarized.platformPlacement == Summarized.PlatformPlacement.Signature
- )
- }
-
- }
- }
-
- private fun appendSignatures(
- signature: Summarized.SummarizedNodes,
- withPlatforms: Boolean
- ) {
-
-// val platforms = if (platformsBasedOnMembers)
-// items.flatMapTo(mutableSetOf()) { platformsOfItems(it.members) } + elementPlatforms
-// else
-// elementPlatforms
-
-
- appendAsPlatformDependentBlock(signature.platforms) {
- if (withPlatforms) {
- appendPlatforms(signature.platforms)
- }
- appendAsSignature(signature.content) {
- signature.content.appendSignature()
- }
- appendSoftLineBreak()
- }
- }
- }
-
- private fun DocumentationNode.isClassLikeGroupNode(): Boolean {
- if (kind != NodeKind.GroupNode) {
- return false
- }
-
- return origins.all { it.kind in NodeKind.classLike }
- }
-
-
- inner class AllTypesNodeBuilder(val node: DocumentationNode)
- : PageBuilder(listOf(node)) {
-
- override fun build() {
- appendContent(node.owner!!.summary)
- appendHeader(3) { to.append("All Types") }
-
- appendTable("Name", "Summary") {
- appendTableBody {
- for (type in node.members) {
- val platforms = effectivePlatformsForNode(type)
- appendIndexRow(platforms) {
- appendPlatforms(platforms)
- if (type.kind == NodeKind.ExternalClass) {
- val packageName = type.owner?.name
- if (packageName != null) {
- appendText(" (extensions in package $packageName)")
- }
- }
- appendHeader(level = 5) {
- appendLink(link(node, type) {
- if (it.kind == NodeKind.ExternalClass) it.name else it.qualifiedName()
- })
- }
-
- appendContent(type.summary)
- }
- }
- }
- }
- }
- }
-
- override fun appendNodes(nodes: Iterable<DocumentationNode>) {
- val singleNode = nodes.singleOrNull()
- when (singleNode?.kind) {
- NodeKind.AllTypes -> AllTypesNodeBuilder(singleNode).build()
- NodeKind.GroupNode -> GroupNodePageBuilder(singleNode).build()
- null -> PageBuilder(nodes).build()
- else -> SingleNodePageBuilder(singleNode).build()
- }
- }
-}
-
-abstract class StructuredFormatService(val generator: NodeLocationAwareGenerator,
- val languageService: LanguageService,
- override val extension: String,
- override final val linkExtension: String = extension) : FormatService {
-
-}
-
-typealias PlatformsData = Map<String, Set<DocumentationNode>>
-
-fun memberPlatforms(node: DocumentationNode): PlatformsData {
- val members = when {
- node.kind == NodeKind.GroupNode -> node.origins
- node.kind in NodeKind.classLike -> emptyList()
- node.kind in NodeKind.memberLike -> emptyList()
- else -> node.members
- }
-
- return members.map(::effectivePlatformsForNode).fold(mapOf(), ::mergePlatforms)
-}
-
-fun mergePlatforms(a: PlatformsData, b: PlatformsData): PlatformsData {
- val mutable = a.toMutableMap()
- b.forEach { (name, declarations) ->
- mutable.merge(name, declarations) { a, b -> a.union(b) }
- }
- return mutable
-}
-
-fun effectivePlatformsForNode(node: DocumentationNode): PlatformsData {
- val platforms = node.platforms + memberPlatforms(node).keys
- return platforms.keysToMap { setOf(node) }
-}
-
-fun effectivePlatformsForMembers(nodes: Collection<DocumentationNode>): PlatformsData {
- return nodes.map { effectivePlatformsForNode(it) }.reduce(::mergePlatforms)
-}
-
-fun mergeVersions(kotlinVersions: List<String>): String {
- return kotlinVersions.distinct().min().orEmpty()
-}
-
-fun effectiveSinceKotlinForNode(node: DocumentationNode, baseVersion: String = "1.0"): String {
- val members = when {
- node.kind == NodeKind.GroupNode -> node.origins
- node.kind in NodeKind.classLike -> emptyList()
- node.kind in NodeKind.memberLike -> emptyList()
- else -> node.members
- }
- val newBase = node.sinceKotlin ?: baseVersion
- val memberVersion = if (members.isNotEmpty()) effectiveSinceKotlinForNodes(members, newBase) else newBase
-
- return node.sinceKotlin ?: memberVersion
-}
-
-fun effectiveSinceKotlinForNodes(nodes: Collection<DocumentationNode>, baseVersion: String = "1.0"): String {
- val map = nodes.map { effectiveSinceKotlinForNode(it, baseVersion) }
- return mergeVersions(map)
-}
-
-fun samePlatforms(platformsPerNode: Collection<PlatformsData>): Boolean {
-
- val first = platformsPerNode.firstOrNull()?.keys ?: return true
- return platformsPerNode.all { it.keys == first }
-}
-
-fun locationHref(
- from: Location,
- to: DocumentationNode,
- generator: NodeLocationAwareGenerator,
- pathOnly: Boolean = false
-): String {
- val topLevelPage = to.references(RefKind.TopLevelPage).singleOrNull()?.to
- if (topLevelPage != null) {
- val signature = to.detailOrNull(NodeKind.Signature)
- return from.relativePathTo(
- generator.location(topLevelPage),
- (signature?.name ?: to.name).takeUnless { pathOnly }
- )
- }
- return from.relativePathTo(generator.location(to))
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/Formats/YamlOutlineService.kt b/core/src/main/kotlin/Formats/YamlOutlineService.kt
deleted file mode 100644
index 3c92d8ff..00000000
--- a/core/src/main/kotlin/Formats/YamlOutlineService.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import java.io.File
-
-class YamlOutlineService @Inject constructor(
- val generator: NodeLocationAwareGenerator,
- val languageService: LanguageService
-) : OutlineFormatService {
- override fun getOutlineFileName(location: Location): File = File("${location.path}.yml")
-
- var outlineLevel = 0
- override fun appendOutlineHeader(location: Location, node: DocumentationNode, to: StringBuilder) {
- val indent = " ".repeat(outlineLevel)
- to.appendln("$indent- title: ${languageService.renderName(node)}")
- to.appendln("$indent url: ${generator.relativePathToLocation(node.path.first(), node)}")
- }
-
- override fun appendOutlineLevel(to: StringBuilder, body: () -> Unit) {
- val indent = " ".repeat(outlineLevel)
- to.appendln("$indent content:")
- outlineLevel++
- body()
- outlineLevel--
- }
-}
diff --git a/core/src/main/kotlin/Generation/FileGenerator.kt b/core/src/main/kotlin/Generation/FileGenerator.kt
deleted file mode 100644
index ee2c068e..00000000
--- a/core/src/main/kotlin/Generation/FileGenerator.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.google.inject.name.Named
-import java.io.File
-import java.io.IOException
-import java.io.PrintWriter
-import java.io.StringWriter
-
-class FileGenerator @Inject constructor(@Named("outputDir") override val root: File) : NodeLocationAwareGenerator {
-
- @set:Inject(optional = true) var outlineService: OutlineFormatService? = null
- @set:Inject(optional = true) lateinit var formatService: FormatService
- @set:Inject(optional = true) lateinit var dokkaConfiguration: DokkaConfiguration
- @set:Inject(optional = true) var packageListService: PackageListService? = null
-
- private val createdFiles = mutableMapOf<File, List<String>>()
-
- private fun File.writeFileAndAssert(context: String, action: (File) -> Unit) {
- //TODO: there is a possible refactoring to drop FileLocation
- //TODO: aad File from API, Location#path.
- //TODO: turn [Location] into a final class,
- //TODO: Use [Location] all over the place without full
- //TODO: reference to the real target path,
- //TODO: it opens the way to safely track all files created
- //TODO: to make sure no files were overwritten by mistake
- //TODO: also, the NodeLocationAwareGenerator should be removed
-
- val writes = createdFiles.getOrDefault(this, listOf()) + context
- createdFiles[this] = writes
- if (writes.size > 1) {
- println("ERROR. An attempt to write ${this.relativeTo(root)} several times!")
- return
- }
-
- try {
- parentFile?.mkdirsOrFail()
- action(this)
- } catch (e : Throwable) {
- println("Failed to write $this. ${e.message}")
- e.printStackTrace()
- }
- }
-
- private fun File.mkdirsOrFail() {
- if (!mkdirs() && !exists()) {
- throw IOException("Failed to create directory $this")
- }
- }
-
- override fun location(node: DocumentationNode): FileLocation {
- return FileLocation(fileForNode(node, formatService.linkExtension))
- }
-
- private fun fileForNode(node: DocumentationNode, extension: String = ""): File {
- return File(root, relativePathToNode(node)).appendExtension(extension)
- }
-
- private fun locationWithoutExtension(node: DocumentationNode): FileLocation {
- return FileLocation(fileForNode(node))
- }
-
- override fun buildPages(nodes: Iterable<DocumentationNode>) {
-
- for ((file, items) in nodes.groupBy { fileForNode(it, formatService.extension) }) {
- file.writeFileAndAssert("pages") { it ->
- it.writeText(formatService.format(location(items.first()), items))
- }
-
- buildPages(items.filterNot { it.kind == NodeKind.AllTypes }.flatMap { it.members })
- }
- }
-
- override fun buildOutlines(nodes: Iterable<DocumentationNode>) {
- val outlineService = this.outlineService ?: return
- for ((location, items) in nodes.groupBy { locationWithoutExtension(it) }) {
- outlineService.getOutlineFileName(location).writeFileAndAssert("outlines") { file ->
- file.writeText(outlineService.formatOutline(location, items))
- }
- }
- }
-
- override fun buildSupportFiles() {
- formatService.enumerateSupportFiles { resource, targetPath ->
- File(root, relativePathToNode(listOf(targetPath), false)).writeFileAndAssert("support files") { file ->
- file.outputStream().use {
- javaClass.getResourceAsStream(resource).copyTo(it)
- }
- }
- }
- }
-
- override fun buildPackageList(nodes: Iterable<DocumentationNode>) {
- if (packageListService == null) return
-
- for (module in nodes) {
-
- val moduleRoot = location(module).file.parentFile
- val packageListFile = File(moduleRoot, "package-list")
-
- val text = "\$dokka.format:${dokkaConfiguration.format}\n" + packageListService!!.formatPackageList(module as DocumentationModule)
-
- packageListFile.writeFileAndAssert("packages-list") { file ->
- file.writeText(text)
- }
- }
- }
-}
diff --git a/core/src/main/kotlin/Generation/Generator.kt b/core/src/main/kotlin/Generation/Generator.kt
deleted file mode 100644
index 23286e29..00000000
--- a/core/src/main/kotlin/Generation/Generator.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.jetbrains.dokka
-
-import java.io.File
-
-interface Generator {
- fun buildPages(nodes: Iterable<DocumentationNode>)
- fun buildOutlines(nodes: Iterable<DocumentationNode>)
- fun buildSupportFiles()
- fun buildPackageList(nodes: Iterable<DocumentationNode>)
-}
-
-fun Generator.buildAll(nodes: Iterable<DocumentationNode>) {
- buildPages(nodes)
- buildOutlines(nodes)
- buildSupportFiles()
- buildPackageList(nodes)
-}
-
-fun Generator.buildPage(node: DocumentationNode): Unit = buildPages(listOf(node))
-
-fun Generator.buildOutline(node: DocumentationNode): Unit = buildOutlines(listOf(node))
-
-fun Generator.buildAll(node: DocumentationNode): Unit = buildAll(listOf(node))
-
-
-interface NodeLocationAwareGenerator: Generator {
- fun location(node: DocumentationNode): Location
- val root: File
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/Kotlin/ContentBuilder.kt b/core/src/main/kotlin/Kotlin/ContentBuilder.kt
deleted file mode 100644
index 0e60ff26..00000000
--- a/core/src/main/kotlin/Kotlin/ContentBuilder.kt
+++ /dev/null
@@ -1,192 +0,0 @@
-package org.jetbrains.dokka
-
-import org.intellij.markdown.MarkdownElementTypes
-import org.intellij.markdown.MarkdownTokenTypes
-import org.intellij.markdown.html.entities.EntityConverter
-import org.intellij.markdown.parser.LinkMap
-import java.util.*
-
-class LinkResolver(private val linkMap: LinkMap, private val contentFactory: (String) -> ContentBlock) {
- fun getLinkInfo(refLabel: String) = linkMap.getLinkInfo(refLabel)
- fun resolve(href: String): ContentBlock = contentFactory(href)
-}
-
-fun buildContent(tree: MarkdownNode, linkResolver: LinkResolver, inline: Boolean = false): MutableContent {
- val result = MutableContent()
- if (inline) {
- buildInlineContentTo(tree, result, linkResolver)
- } else {
- buildContentTo(tree, result, linkResolver)
- }
- return result
-}
-
-fun buildContentTo(tree: MarkdownNode, target: ContentBlock, linkResolver: LinkResolver) {
-// println(tree.toTestString())
- val nodeStack = ArrayDeque<ContentBlock>()
- nodeStack.push(target)
-
- tree.visit { node, processChildren ->
- val parent = nodeStack.peek()
-
- fun appendNodeWithChildren(content: ContentBlock) {
- nodeStack.push(content)
- processChildren()
- parent.append(nodeStack.pop())
- }
-
- when (node.type) {
- MarkdownElementTypes.ATX_1 -> appendNodeWithChildren(ContentHeading(1))
- MarkdownElementTypes.ATX_2 -> appendNodeWithChildren(ContentHeading(2))
- MarkdownElementTypes.ATX_3 -> appendNodeWithChildren(ContentHeading(3))
- MarkdownElementTypes.ATX_4 -> appendNodeWithChildren(ContentHeading(4))
- MarkdownElementTypes.ATX_5 -> appendNodeWithChildren(ContentHeading(5))
- MarkdownElementTypes.ATX_6 -> appendNodeWithChildren(ContentHeading(6))
- MarkdownElementTypes.UNORDERED_LIST -> appendNodeWithChildren(ContentUnorderedList())
- MarkdownElementTypes.ORDERED_LIST -> appendNodeWithChildren(ContentOrderedList())
- MarkdownElementTypes.LIST_ITEM -> appendNodeWithChildren(ContentListItem())
- MarkdownElementTypes.EMPH -> appendNodeWithChildren(ContentEmphasis())
- MarkdownElementTypes.STRONG -> appendNodeWithChildren(ContentStrong())
- MarkdownElementTypes.CODE_SPAN -> {
- val startDelimiter = node.child(MarkdownTokenTypes.BACKTICK)?.text
- if (startDelimiter != null) {
- val text = node.text.substring(startDelimiter.length).removeSuffix(startDelimiter)
- val codeSpan = ContentCode().apply { append(ContentText(text)) }
- parent.append(codeSpan)
- }
- }
- MarkdownElementTypes.CODE_BLOCK,
- MarkdownElementTypes.CODE_FENCE -> {
- val language = node.child(MarkdownTokenTypes.FENCE_LANG)?.text?.trim() ?: ""
- appendNodeWithChildren(ContentBlockCode(language))
- }
- MarkdownElementTypes.PARAGRAPH -> appendNodeWithChildren(ContentParagraph())
-
- MarkdownElementTypes.INLINE_LINK -> {
- val linkTextNode = node.child(MarkdownElementTypes.LINK_TEXT)
- val destination = node.child(MarkdownElementTypes.LINK_DESTINATION)
- if (linkTextNode != null) {
- if (destination != null) {
- val link = ContentExternalLink(destination.text)
- renderLinkTextTo(linkTextNode, link, linkResolver)
- parent.append(link)
- } else {
- val link = ContentExternalLink(linkTextNode.getLabelText())
- renderLinkTextTo(linkTextNode, link, linkResolver)
- parent.append(link)
- }
- }
- }
- MarkdownElementTypes.SHORT_REFERENCE_LINK,
- MarkdownElementTypes.FULL_REFERENCE_LINK -> {
- val labelElement = node.child(MarkdownElementTypes.LINK_LABEL)
- if (labelElement != null) {
- val linkInfo = linkResolver.getLinkInfo(labelElement.text)
- val labelText = labelElement.getLabelText()
- val link = linkInfo?.let { linkResolver.resolve(it.destination.toString()) } ?: linkResolver.resolve(labelText)
- val linkText = node.child(MarkdownElementTypes.LINK_TEXT)
- if (linkText != null) {
- renderLinkTextTo(linkText, link, linkResolver)
- } else {
- link.append(ContentText(labelText))
- }
- parent.append(link)
- }
- }
- MarkdownTokenTypes.WHITE_SPACE -> {
- // Don't append first space if start of header (it is added during formatting later)
- // v
- // #### Some Heading
- if (nodeStack.peek() !is ContentHeading || node.parent?.children?.first() != node) {
- parent.append(ContentText(node.text))
- }
- }
- MarkdownTokenTypes.EOL -> {
- if ((keepEol(nodeStack.peek()) && node.parent?.children?.last() != node) ||
- // Keep extra blank lines when processing lists (affects Markdown formatting)
- (processingList(nodeStack.peek()) && node.previous?.type == MarkdownTokenTypes.EOL)) {
- parent.append(ContentText(node.text))
- }
- }
-
- MarkdownTokenTypes.CODE_LINE -> {
- val content = ContentText(node.text)
- if (parent is ContentBlockCode) {
- parent.append(content)
- } else {
- parent.append(ContentBlockCode().apply { append(content) })
- }
- }
-
- MarkdownTokenTypes.TEXT -> {
- fun createEntityOrText(text: String): ContentNode {
- if (text == "&amp;" || text == "&quot;" || text == "&lt;" || text == "&gt;") {
- return ContentEntity(text)
- }
- if (text == "&") {
- return ContentEntity("&amp;")
- }
- val decodedText = EntityConverter.replaceEntities(text, true, true)
- if (decodedText != text) {
- return ContentEntity(text)
- }
- return ContentText(text)
- }
-
- parent.append(createEntityOrText(node.text))
- }
-
- MarkdownTokenTypes.EMPH -> {
- val parentNodeType = node.parent?.type
- if (parentNodeType != MarkdownElementTypes.EMPH && parentNodeType != MarkdownElementTypes.STRONG) {
- parent.append(ContentText(node.text))
- }
- }
-
- MarkdownTokenTypes.COLON,
- MarkdownTokenTypes.SINGLE_QUOTE,
- MarkdownTokenTypes.DOUBLE_QUOTE,
- MarkdownTokenTypes.LT,
- MarkdownTokenTypes.GT,
- MarkdownTokenTypes.LPAREN,
- MarkdownTokenTypes.RPAREN,
- MarkdownTokenTypes.LBRACKET,
- MarkdownTokenTypes.RBRACKET,
- MarkdownTokenTypes.EXCLAMATION_MARK,
- MarkdownTokenTypes.BACKTICK,
- MarkdownTokenTypes.CODE_FENCE_CONTENT -> {
- parent.append(ContentText(node.text))
- }
-
- MarkdownElementTypes.LINK_DEFINITION -> {
- }
-
- MarkdownTokenTypes.EMAIL_AUTOLINK -> {
- parent.append(ContentText(node.text)) // TODO: create new ContentType for email to create mailto: links
- }
-
- else -> {
- processChildren()
- }
- }
- }
-}
-
-private fun MarkdownNode.getLabelText() = children.filter { it.type == MarkdownTokenTypes.TEXT || it.type == MarkdownTokenTypes.EMPH || it.type == MarkdownTokenTypes.COLON }.joinToString("") { it.text }
-
-private fun keepEol(node: ContentNode) = node is ContentParagraph || node is ContentSection || node is ContentBlockCode
-private fun processingList(node: ContentNode) = node is ContentOrderedList || node is ContentUnorderedList
-
-fun buildInlineContentTo(tree: MarkdownNode, target: ContentBlock, linkResolver: LinkResolver) {
- val inlineContent = tree.children.singleOrNull { it.type == MarkdownElementTypes.PARAGRAPH }?.children ?: listOf(tree)
- inlineContent.forEach {
- buildContentTo(it, target, linkResolver)
- }
-}
-
-fun renderLinkTextTo(tree: MarkdownNode, target: ContentBlock, linkResolver: LinkResolver) {
- val linkTextNodes = tree.children.drop(1).dropLast(1)
- linkTextNodes.forEach {
- buildContentTo(it, target, linkResolver)
- }
-}
diff --git a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt b/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt
deleted file mode 100644
index 88494581..00000000
--- a/core/src/main/kotlin/Kotlin/DeclarationLinkResolver.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
-import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
-
-class DeclarationLinkResolver
- @Inject constructor(val resolutionFacade: DokkaResolutionFacade,
- val refGraph: NodeReferenceGraph,
- val logger: DokkaLogger,
- val passConfiguration: DokkaConfiguration.PassConfiguration,
- val externalDocumentationLinkResolver: ExternalDocumentationLinkResolver,
- val elementSignatureProvider: ElementSignatureProvider) {
-
-
- fun tryResolveContentLink(fromDescriptor: DeclarationDescriptor, href: String): ContentBlock? {
- val symbol = try {
- val symbols = resolveKDocLink(resolutionFacade.resolveSession.bindingContext,
- resolutionFacade, fromDescriptor, null, href.split('.').toList())
- findTargetSymbol(symbols)
- } catch(e: Exception) {
- null
- }
-
- // don't include unresolved links in generated doc
- // assume that if an href doesn't contain '/', it's not an attempt to reference an external file
- if (symbol != null) {
- val externalHref = externalDocumentationLinkResolver.buildExternalDocumentationLink(symbol)
- if (externalHref != null) {
- return ContentExternalLink(externalHref)
- }
- val signature = elementSignatureProvider.signature(symbol)
- val referencedAt = fromDescriptor.signatureWithSourceLocation()
-
- return ContentNodeLazyLink(href) {
- val target = refGraph.lookup(signature)
-
- if (target == null) {
- logger.warn("Can't find node by signature `$signature`, referenced at $referencedAt. " +
- "This is probably caused by invalid configuration of cross-module dependencies")
- }
- target
- }
- }
- if ("/" in href) {
- return ContentExternalLink(href)
- }
- return null
- }
-
- fun resolveContentLink(fromDescriptor: DeclarationDescriptor, href: String) =
- tryResolveContentLink(fromDescriptor, href) ?: run {
- logger.warn("Unresolved link to $href in doc comment of ${fromDescriptor.signatureWithSourceLocation()}")
- ContentExternalLink("#")
- }
-
- fun findTargetSymbol(symbols: Collection<DeclarationDescriptor>): DeclarationDescriptor? {
- if (symbols.isEmpty()) {
- return null
- }
- val symbol = symbols.first()
- if (symbol is CallableMemberDescriptor && symbol.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
- return symbol.overriddenDescriptors.firstOrNull()
- }
- if (symbol is TypeAliasDescriptor && !symbol.isDocumented(passConfiguration)) {
- return symbol.classDescriptor
- }
- return symbol
- }
-
-}
diff --git a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt b/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt
deleted file mode 100644
index 793f9589..00000000
--- a/core/src/main/kotlin/Kotlin/ExternalDocumentationLinkResolver.kt
+++ /dev/null
@@ -1,305 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiMethod
-import com.intellij.util.io.*
-import org.jetbrains.dokka.Formats.FileGeneratorBasedFormatDescriptor
-import org.jetbrains.dokka.Formats.FormatDescriptor
-import org.jetbrains.dokka.Utilities.ServiceLocator
-import org.jetbrains.dokka.Utilities.lookup
-import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor
-import org.jetbrains.kotlin.load.java.descriptors.*
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.resolve.DescriptorUtils
-import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
-import org.jetbrains.kotlin.resolve.descriptorUtil.parents
-import java.io.ByteArrayOutputStream
-import java.io.PrintWriter
-import java.net.HttpURLConnection
-import java.net.URL
-import java.net.URLConnection
-import java.nio.file.Path
-import java.nio.file.Paths
-import java.security.MessageDigest
-import javax.inject.Named
-import kotlin.reflect.full.findAnnotation
-
-fun ByteArray.toHexString() = this.joinToString(separator = "") { "%02x".format(it) }
-
-typealias PackageFqNameToLocation = MutableMap<FqName, PackageListProvider.ExternalDocumentationRoot>
-
-@Singleton
-class PackageListProvider @Inject constructor(
- val configuration: DokkaConfiguration,
- val logger: DokkaLogger
-) {
- val storage = mutableMapOf<DokkaConfiguration.ExternalDocumentationLink, PackageFqNameToLocation>()
-
- val cacheDir: Path? = when {
- configuration.cacheRoot == "default" -> Paths.get(System.getProperty("user.home"), ".cache", "dokka")
- configuration.cacheRoot != null -> Paths.get(configuration.cacheRoot)
- else -> null
- }?.resolve("packageListCache")?.apply { createDirectories() }
-
- val cachedProtocols = setOf("http", "https", "ftp")
-
- init {
- for (conf in configuration.passesConfigurations) {
- for (link in conf.externalDocumentationLinks) {
- if (link in storage) {
- continue
- }
-
- try {
- loadPackageList(link)
- } catch (e: Exception) {
- throw RuntimeException("Exception while loading package-list from $link", e)
- }
- }
-
- }
- }
-
-
-
- fun URL.doOpenConnectionToReadContent(timeout: Int = 10000, redirectsAllowed: Int = 16): URLConnection {
- val connection = this.openConnection()
- connection.connectTimeout = timeout
- connection.readTimeout = timeout
-
- when (connection) {
- is HttpURLConnection -> {
- return when (connection.responseCode) {
- in 200..299 -> {
- connection
- }
- HttpURLConnection.HTTP_MOVED_PERM,
- HttpURLConnection.HTTP_MOVED_TEMP,
- HttpURLConnection.HTTP_SEE_OTHER -> {
- if (redirectsAllowed > 0) {
- val newUrl = connection.getHeaderField("Location")
- URL(newUrl).doOpenConnectionToReadContent(timeout, redirectsAllowed - 1)
- } else {
- throw RuntimeException("Too many redirects")
- }
- }
- else -> {
- throw RuntimeException("Unhandled http code: ${connection.responseCode}")
- }
- }
- }
- else -> return connection
- }
- }
-
- fun loadPackageList(link: DokkaConfiguration.ExternalDocumentationLink) {
-
- val packageListUrl = link.packageListUrl
- val needsCache = packageListUrl.protocol in cachedProtocols
-
- val packageListStream = if (cacheDir != null && needsCache) {
- val packageListLink = packageListUrl.toExternalForm()
-
- val digest = MessageDigest.getInstance("SHA-256")
- val hash = digest.digest(packageListLink.toByteArray(Charsets.UTF_8)).toHexString()
- val cacheEntry = cacheDir.resolve(hash)
-
- if (cacheEntry.exists()) {
- try {
- val connection = packageListUrl.doOpenConnectionToReadContent()
- val originModifiedDate = connection.date
- val cacheDate = cacheEntry.lastModified().toMillis()
- if (originModifiedDate > cacheDate || originModifiedDate == 0L) {
- if (originModifiedDate == 0L)
- logger.warn("No date header for $packageListUrl, downloading anyway")
- else
- logger.info("Renewing package-list from $packageListUrl")
- connection.getInputStream().copyTo(cacheEntry.outputStream())
- }
- } catch (e: Exception) {
- logger.error("Failed to update package-list cache for $link")
- val baos = ByteArrayOutputStream()
- PrintWriter(baos).use {
- e.printStackTrace(it)
- }
- baos.flush()
- logger.error(baos.toString())
- }
- } else {
- logger.info("Downloading package-list from $packageListUrl")
- packageListUrl.openStream().copyTo(cacheEntry.outputStream())
- }
- cacheEntry.inputStream()
- } else {
- packageListUrl.doOpenConnectionToReadContent().getInputStream()
- }
-
- val (params, packages) =
- packageListStream
- .bufferedReader()
- .useLines { lines -> lines.partition { it.startsWith(ExternalDocumentationLinkResolver.DOKKA_PARAM_PREFIX) } }
-
- val paramsMap = params.asSequence()
- .map { it.removePrefix(ExternalDocumentationLinkResolver.DOKKA_PARAM_PREFIX).split(":", limit = 2) }
- .groupBy({ (key, _) -> key }, { (_, value) -> value })
-
- val format = paramsMap["format"]?.singleOrNull() ?: "javadoc"
-
- val locations = paramsMap["location"].orEmpty()
- .map { it.split("\u001f", limit = 2) }
- .map { (key, value) -> key to value }
- .toMap()
-
-
- val defaultResolverDesc = ExternalDocumentationLinkResolver.services.getValue("dokka-default")
- val resolverDesc = ExternalDocumentationLinkResolver.services[format]
- ?: defaultResolverDesc.takeIf { format in formatsWithDefaultResolver }
- ?: defaultResolverDesc.also {
- logger.warn("Couldn't find InboundExternalLinkResolutionService(format = `$format`) for $link, using Dokka default")
- }
-
-
- val resolverClass = javaClass.classLoader.loadClass(resolverDesc.className).kotlin
-
- val constructors = resolverClass.constructors
-
- val constructor = constructors.singleOrNull()
- ?: constructors.first { it.findAnnotation<Inject>() != null }
- val resolver = constructor.call(paramsMap) as InboundExternalLinkResolutionService
-
- val rootInfo = ExternalDocumentationRoot(link.url, resolver, locations)
-
- val packageFqNameToLocation = mutableMapOf<FqName, ExternalDocumentationRoot>()
- storage[link] = packageFqNameToLocation
-
- val fqNames = packages.map { FqName(it) }
- for(name in fqNames) {
- packageFqNameToLocation[name] = rootInfo
- }
- }
-
-
-
- class ExternalDocumentationRoot(val rootUrl: URL, val resolver: InboundExternalLinkResolutionService, val locations: Map<String, String>) {
- override fun toString(): String = rootUrl.toString()
- }
-
- companion object {
- private val formatsWithDefaultResolver =
- ServiceLocator
- .allServices("format")
- .filter {
- val desc = ServiceLocator.lookup<FormatDescriptor>(it) as? FileGeneratorBasedFormatDescriptor
- desc?.generatorServiceClass == FileGenerator::class
- }.map { it.name }
- .toSet()
-
- }
-
-}
-
-class ExternalDocumentationLinkResolver @Inject constructor(
- val configuration: DokkaConfiguration,
- val passConfiguration: DokkaConfiguration.PassConfiguration,
- @Named("libraryResolutionFacade") val libraryResolutionFacade: DokkaResolutionFacade,
- val logger: DokkaLogger,
- val packageListProvider: PackageListProvider
-) {
-
- val formats = mutableMapOf<String, InboundExternalLinkResolutionService>()
- val packageFqNameToLocation = mutableMapOf<FqName, PackageListProvider.ExternalDocumentationRoot>()
-
- init {
- val fqNameToLocationMaps = passConfiguration.externalDocumentationLinks
- .mapNotNull { packageListProvider.storage[it] }
-
- for(map in fqNameToLocationMaps) {
- packageFqNameToLocation.putAll(map)
- }
- }
-
- fun buildExternalDocumentationLink(element: PsiElement): String? {
- return element.extractDescriptor(libraryResolutionFacade)?.let {
- buildExternalDocumentationLink(it)
- }
- }
-
- fun buildExternalDocumentationLink(symbol: DeclarationDescriptor): String? {
- val packageFqName: FqName =
- when (symbol) {
- is PackageFragmentDescriptor -> symbol.fqName
- is DeclarationDescriptorNonRoot -> symbol.parents.firstOrNull { it is PackageFragmentDescriptor }?.fqNameSafe ?: return null
- else -> return null
- }
-
- val externalLocation = packageFqNameToLocation[packageFqName] ?: return null
-
- val path = externalLocation.locations[symbol.signature()] ?:
- externalLocation.resolver.getPath(symbol) ?: return null
-
- return URL(externalLocation.rootUrl, path).toExternalForm()
- }
-
- companion object {
- const val DOKKA_PARAM_PREFIX = "\$dokka."
- val services = ServiceLocator.allServices("inbound-link-resolver").associateBy { it.name }
- }
-}
-
-
-interface InboundExternalLinkResolutionService {
- fun getPath(symbol: DeclarationDescriptor): String?
-
- class Javadoc(paramsMap: Map<String, List<String>>) : InboundExternalLinkResolutionService {
- override fun getPath(symbol: DeclarationDescriptor): String? {
- if (symbol is EnumEntrySyntheticClassDescriptor) {
- return getPath(symbol.containingDeclaration)?.let { it + "#" + symbol.name.asString() }
- } else if (symbol is JavaClassDescriptor) {
- return DescriptorUtils.getFqName(symbol).asString().replace(".", "/") + ".html"
- } else if (symbol is JavaCallableMemberDescriptor) {
- val containingClass = symbol.containingDeclaration as? JavaClassDescriptor ?: return null
- val containingClassLink = getPath(containingClass)
- if (containingClassLink != null) {
- if (symbol is JavaMethodDescriptor || symbol is JavaClassConstructorDescriptor) {
- val psi = symbol.sourcePsi() as? PsiMethod
- if (psi != null) {
- val params = psi.parameterList.parameters.joinToString { it.type.canonicalText }
- return containingClassLink + "#" + symbol.name + "(" + params + ")"
- }
- } else if (symbol is JavaPropertyDescriptor) {
- return "$containingClassLink#${symbol.name}"
- }
- }
- }
- // TODO Kotlin javadoc
- return null
- }
- }
-
- class Dokka(val paramsMap: Map<String, List<String>>) : InboundExternalLinkResolutionService {
- val extension = paramsMap["linkExtension"]?.singleOrNull() ?: error("linkExtension not provided for Dokka resolver")
-
- override fun getPath(symbol: DeclarationDescriptor): String? {
- val leafElement = when (symbol) {
- is CallableDescriptor, is TypeAliasDescriptor -> true
- else -> false
- }
- val path = getPathWithoutExtension(symbol)
- if (leafElement) return "$path.$extension"
- else return "$path/index.$extension"
- }
-
- private fun getPathWithoutExtension(symbol: DeclarationDescriptor): String {
- return when {
- symbol.containingDeclaration == null -> identifierToFilename(symbol.name.asString())
- symbol is PackageFragmentDescriptor -> identifierToFilename(symbol.fqName.asString())
- else -> getPathWithoutExtension(symbol.containingDeclaration!!) + '/' + identifierToFilename(symbol.name.asString())
- }
- }
-
- }
-}
-
diff --git a/core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt b/core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt
deleted file mode 100644
index 70c04da6..00000000
--- a/core/src/main/kotlin/Kotlin/KotlinAsJavaDocumentationBuilder.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.jetbrains.dokka
-
-import com.google.inject.Inject
-import com.intellij.psi.JavaPsiFacade
-import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiNamedElement
-import org.jetbrains.dokka.Kotlin.DescriptorDocumentationParser
-import org.jetbrains.kotlin.asJava.elements.KtLightElement
-import org.jetbrains.kotlin.asJava.elements.KtLightMethod
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtClass
-import org.jetbrains.kotlin.psi.KtDeclaration
-import org.jetbrains.kotlin.psi.KtParameter
-import org.jetbrains.kotlin.psi.KtPropertyAccessor
-
-class KotlinAsJavaDocumentationBuilder
- @Inject constructor(val kotlinAsJavaDocumentationParser: KotlinAsJavaDocumentationParser) : PackageDocumentationBuilder
-{
- override fun buildPackageDocumentation(documentationBuilder: DocumentationBuilder,
- packageName: FqName,
- packageNode: DocumentationNode,
- declarations: List<DeclarationDescriptor>,
- allFqNames: Collection<FqName>) {
- val project = documentationBuilder.resolutionFacade.project
- val psiPackage = JavaPsiFacade.getInstance(project).findPackage(packageName.asString())
- if (psiPackage == null) {
- documentationBuilder.logger.error("Cannot find Java package by qualified name: ${packageName.asString()}")
- return
- }
-
- val javaDocumentationBuilder = JavaPsiDocumentationBuilder(documentationBuilder,
- kotlinAsJavaDocumentationParser)
-
- psiPackage.classes.filter { it is KtLightElement<*, *> }.filter { it.isVisibleInDocumentation() }.forEach {
- javaDocumentationBuilder.appendClasses(packageNode, arrayOf(it))
- }
- }
-
- fun PsiClass.isVisibleInDocumentation(): Boolean {
- val origin: KtDeclaration = (this as KtLightElement<*, *>).kotlinOrigin as? KtDeclaration ?: return true
-
- return !origin.hasModifier(KtTokens.INTERNAL_KEYWORD) && !origin.hasModifier(KtTokens.PRIVATE_KEYWORD)
- }
-}
-
-class KotlinAsJavaDocumentationParser
- @Inject constructor(val resolutionFacade: DokkaResolutionFacade,
- val descriptorDocumentationParser: DescriptorDocumentationParser) : JavaDocumentationParser
-{
- override fun parseDocumentation(element: PsiNamedElement): JavadocParseResult {
- val kotlinLightElement = element as? KtLightElement<*, *> ?: return JavadocParseResult.Empty
- val origin = kotlinLightElement.kotlinOrigin as? KtDeclaration ?: return JavadocParseResult.Empty
- if (origin is KtParameter) {
- // LazyDeclarationResolver does not support setter parameters
- val grandFather = origin.parent?.parent
- if (grandFather is KtPropertyAccessor) {
- return JavadocParseResult.Empty
- }
- }
- val isDefaultNoArgConstructor = kotlinLightElement is KtLightMethod && origin is KtClass
- val descriptor = resolutionFacade.resolveToDescriptor(origin)
- val content = descriptorDocumentationParser.parseDocumentation(descriptor, origin is KtParameter, isDefaultNoArgConstructor)
- return JavadocParseResult(content, null)
- }
-}
diff --git a/core/src/main/kotlin/Kotlin/KotlinAsJavaElementSignatureProvider.kt b/core/src/main/kotlin/Kotlin/KotlinAsJavaElementSignatureProvider.kt
deleted file mode 100644
index 20ea179e..00000000
--- a/core/src/main/kotlin/Kotlin/KotlinAsJavaElementSignatureProvider.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.jetbrains.dokka
-
-import com.intellij.psi.PsiElement
-import org.jetbrains.kotlin.asJava.toLightElements
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.psi.KtElement
-
-class KotlinAsJavaElementSignatureProvider : ElementSignatureProvider {
-
- private fun PsiElement.javaLikePsi() = when {
- this is KtElement -> toLightElements().firstOrNull()
- else -> this
- }
-
- override fun signature(forPsi: PsiElement): String {
- return getSignature(forPsi.javaLikePsi()) ?:
- "not implemented for $forPsi"
- }
-
- override fun signature(forDesc: DeclarationDescriptor): String {
- val sourcePsi = forDesc.sourcePsi()
- return getSignature(sourcePsi?.javaLikePsi()) ?:
- "not implemented for $forDesc with psi: $sourcePsi"
- }
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/Languages/JavaLanguageService.kt b/core/src/main/kotlin/Languages/JavaLanguageService.kt
deleted file mode 100644
index ad66123b..00000000
--- a/core/src/main/kotlin/Languages/JavaLanguageService.kt
+++ /dev/null
@@ -1,171 +0,0 @@
-package org.jetbrains.dokka
-
-import org.jetbrains.dokka.LanguageService.RenderMode
-
-/**
- * Implements [LanguageService] and provides rendering of symbols in Java language
- */
-class JavaLanguageService : LanguageService {
- override fun render(node: DocumentationNode, renderMode: RenderMode): ContentNode {
- return ContentText(when (node.kind) {
- NodeKind.Package -> renderPackage(node)
- in NodeKind.classLike -> renderClass(node)
-
- NodeKind.TypeParameter -> renderTypeParameter(node)
- NodeKind.Type,
- NodeKind.UpperBound -> renderType(node)
-
- NodeKind.Constructor,
- NodeKind.Function -> renderFunction(node)
- NodeKind.Property -> renderProperty(node)
- else -> "${node.kind}: ${node.name}"
- })
- }
-
- override fun renderName(node: DocumentationNode): String {
- return when (node.kind) {
- NodeKind.Constructor -> node.owner!!.name
- else -> node.name
- }
- }
-
- override fun summarizeSignatures(nodes: List<DocumentationNode>): ContentNode? = null
-
- private fun renderPackage(node: DocumentationNode): String {
- return "package ${node.name}"
- }
-
- private fun renderModifier(node: DocumentationNode): String {
- return when (node.name) {
- "open" -> ""
- "internal" -> ""
- else -> node.name
- }
- }
-
- fun getArrayElementType(node: DocumentationNode): DocumentationNode? = when (node.qualifiedName()) {
- "kotlin.Array" ->
- node.details(NodeKind.Type).singleOrNull()?.let { et -> getArrayElementType(et) ?: et } ?:
- DocumentationNode("Object", node.content, NodeKind.ExternalClass)
-
- "kotlin.IntArray", "kotlin.LongArray", "kotlin.ShortArray", "kotlin.ByteArray",
- "kotlin.CharArray", "kotlin.DoubleArray", "kotlin.FloatArray", "kotlin.BooleanArray" ->
- DocumentationNode(node.name.removeSuffix("Array").toLowerCase(), node.content, NodeKind.Type)
-
- else -> null
- }
-
- fun getArrayDimension(node: DocumentationNode): Int = when (node.qualifiedName()) {
- "kotlin.Array" ->
- 1 + (node.details(NodeKind.Type).singleOrNull()?.let { getArrayDimension(it) } ?: 0)
-
- "kotlin.IntArray", "kotlin.LongArray", "kotlin.ShortArray", "kotlin.ByteArray",
- "kotlin.CharArray", "kotlin.DoubleArray", "kotlin.FloatArray", "kotlin.BooleanArray" ->
- 1
- else -> 0
- }
-
- fun renderType(node: DocumentationNode): String {
- return when (node.name) {
- "Unit" -> "void"
- "Int" -> "int"
- "Long" -> "long"
- "Double" -> "double"
- "Float" -> "float"
- "Char" -> "char"
- "Boolean" -> "bool"
- // TODO: render arrays
- else -> node.name
- }
- }
-
- private fun renderTypeParameter(node: DocumentationNode): String {
- val constraints = node.details(NodeKind.UpperBound)
- return if (constraints.none())
- node.name
- else {
- node.name + " extends " + constraints.joinToString { renderType(node) }
- }
- }
-
- private fun renderParameter(node: DocumentationNode): String {
- return "${renderType(node.detail(NodeKind.Type))} ${node.name}"
- }
-
- private fun renderTypeParametersForNode(node: DocumentationNode): String {
- return StringBuilder().apply {
- val typeParameters = node.details(NodeKind.TypeParameter)
- if (typeParameters.any()) {
- append("<")
- append(typeParameters.joinToString { renderTypeParameter(it) })
- append("> ")
- }
- }.toString()
- }
-
- private fun renderModifiersForNode(node: DocumentationNode): String {
- val modifiers = node.details(NodeKind.Modifier).map { renderModifier(it) }.filter { it != "" }
- if (modifiers.none())
- return ""
- return modifiers.joinToString(" ", postfix = " ")
- }
-
- private fun renderClass(node: DocumentationNode): String {
- return StringBuilder().apply {
- when (node.kind) {
- NodeKind.Class -> append("class ")
- NodeKind.Interface -> append("interface ")
- NodeKind.Enum -> append("enum ")
- NodeKind.EnumItem -> append("enum value ")
- NodeKind.Object -> append("class ")
- else -> throw IllegalArgumentException("Node $node is not a class-like object")
- }
-
- append(node.name)
- append(renderTypeParametersForNode(node))
- }.toString()
- }
-
- private fun renderFunction(node: DocumentationNode): String {
- return StringBuilder().apply {
- when (node.kind) {
- NodeKind.Constructor -> append(node.owner?.name)
- NodeKind.Function -> {
- append(renderTypeParametersForNode(node))
- append(renderType(node.detail(NodeKind.Type)))
- append(" ")
- append(node.name)
- }
- else -> throw IllegalArgumentException("Node $node is not a function-like object")
- }
-
- val receiver = node.details(NodeKind.Receiver).singleOrNull()
- append("(")
- if (receiver != null)
- (listOf(receiver) + node.details(NodeKind.Parameter)).joinTo(this) { renderParameter(it) }
- else
- node.details(NodeKind.Parameter).joinTo(this) { renderParameter(it) }
-
- append(")")
- }.toString()
- }
-
- private fun renderProperty(node: DocumentationNode): String {
- return StringBuilder().apply {
- when (node.kind) {
- NodeKind.Property -> append("val ")
- else -> throw IllegalArgumentException("Node $node is not a property")
- }
- append(renderTypeParametersForNode(node))
- val receiver = node.details(NodeKind.Receiver).singleOrNull()
- if (receiver != null) {
- append(renderType(receiver.detail(NodeKind.Type)))
- append(".")
- }
-
- append(node.name)
- append(": ")
- append(renderType(node.detail(NodeKind.Type)))
- }.toString()
- }
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/Languages/NewJavaLanguageService.kt b/core/src/main/kotlin/Languages/NewJavaLanguageService.kt
deleted file mode 100644
index 992cd090..00000000
--- a/core/src/main/kotlin/Languages/NewJavaLanguageService.kt
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.jetbrains.dokka
-
-import org.jetbrains.dokka.LanguageService.RenderMode
-
-/**
- * Implements [LanguageService] and provides rendering of symbols in Java language
- */
-class NewJavaLanguageService : CommonLanguageService() {
- override fun showModifierInSummary(node: DocumentationNode): Boolean {
- return true
- }
-
- override fun render(node: DocumentationNode, renderMode: RenderMode): ContentNode {
- return content {
- (when (node.kind) {
- NodeKind.Package -> renderPackage(node)
- in NodeKind.classLike -> renderClass(node, renderMode)
-
- NodeKind.Modifier -> renderModifier(this, node, renderMode)
- NodeKind.TypeParameter -> renderTypeParameter(node)
- NodeKind.Type,
- NodeKind.UpperBound -> renderType(node)
- NodeKind.Parameter -> renderParameter(node)
- NodeKind.Constructor,
- NodeKind.Function -> renderFunction(node)
- NodeKind.Property -> renderProperty(node)
- else -> "${node.kind}: ${node.name}"
- })
- }
- }
-
- override fun summarizeSignatures(nodes: List<DocumentationNode>): ContentNode? = null
-
-
- override fun renderModifier(block: ContentBlock, node: DocumentationNode, renderMode: RenderMode, nowrap: Boolean) {
- when (node.name) {
- "open", "internal" -> {
- }
- else -> super.renderModifier(block, node, renderMode, nowrap)
- }
- }
-
- fun getArrayElementType(node: DocumentationNode): DocumentationNode? = when (node.qualifiedName()) {
- "kotlin.Array" ->
- node.details(NodeKind.Type).singleOrNull()?.let { et -> getArrayElementType(et) ?: et }
- ?: DocumentationNode("Object", node.content, NodeKind.ExternalClass)
-
- "kotlin.IntArray", "kotlin.LongArray", "kotlin.ShortArray", "kotlin.ByteArray",
- "kotlin.CharArray", "kotlin.DoubleArray", "kotlin.FloatArray", "kotlin.BooleanArray" ->
- DocumentationNode(node.name.removeSuffix("Array").toLowerCase(), node.content, NodeKind.Type)
-
- else -> null
- }
-
- fun getArrayDimension(node: DocumentationNode): Int = when (node.qualifiedName()) {
- "kotlin.Array" ->
- 1 + (node.details(NodeKind.Type).singleOrNull()?.let { getArrayDimension(it) } ?: 0)
-
- "kotlin.IntArray", "kotlin.LongArray", "kotlin.ShortArray", "kotlin.ByteArray",
- "kotlin.CharArray", "kotlin.DoubleArray", "kotlin.FloatArray", "kotlin.BooleanArray" ->
- 1
- else -> 0
- }
-
- fun ContentBlock.renderType(node: DocumentationNode) {
- when (node.name) {
- "Unit" -> identifier("void")
- "Int" -> identifier("int")
- "Long" -> identifier("long")
- "Double" -> identifier("double")
- "Float" -> identifier("float")
- "Char" -> identifier("char")
- "Boolean" -> identifier("bool")
- // TODO: render arrays
- else -> renderLinked(this, node) {
- identifier(node.name)
- }
- }
- }
-
- private fun ContentBlock.renderTypeParameter(node: DocumentationNode) {
- val constraints = node.details(NodeKind.UpperBound)
- if (constraints.none())
- identifier(node.name)
- else {
- identifier(node.name)
- text(" ")
- keyword("extends")
- text(" ")
- constraints.forEach { renderType(node) }
- }
- }
-
- private fun ContentBlock.renderParameter(node: DocumentationNode) {
- renderType(node.detail(NodeKind.Type))
- text(" ")
- identifier(node.name)
- }
-
- private fun ContentBlock.renderTypeParametersForNode(node: DocumentationNode) {
- val typeParameters = node.details(NodeKind.TypeParameter)
- if (typeParameters.any()) {
- symbol("<")
- renderList(typeParameters, noWrap = true) {
- renderTypeParameter(it)
- }
- symbol(">")
- text(" ")
- }
- }
-
-// private fun renderModifiersForNode(node: DocumentationNode): String {
-// val modifiers = node.details(NodeKind.Modifier).map { renderModifier(it) }.filter { it != "" }
-// if (modifiers.none())
-// return ""
-// return modifiers.joinToString(" ", postfix = " ")
-// }
-
- private fun ContentBlock.renderClassKind(node: DocumentationNode) {
- when (node.kind) {
- NodeKind.Interface -> {
- keyword("interface")
- }
- NodeKind.EnumItem -> {
- keyword("enum value")
- }
- NodeKind.Enum -> {
- keyword("enum")
- }
- NodeKind.Class, NodeKind.Exception, NodeKind.Object -> {
- keyword("class")
- }
- else -> throw IllegalArgumentException("Node $node is not a class-like object")
- }
- text(" ")
- }
-
- private fun ContentBlock.renderClass(node: DocumentationNode, renderMode: RenderMode) {
- renderModifiersForNode(node, renderMode)
- renderClassKind(node)
-
- identifier(node.name)
- renderTypeParametersForNode(node)
- }
-
- private fun ContentBlock.renderParameters(nodes: List<DocumentationNode>) {
- renderList(nodes) {
- renderParameter(it)
- }
- }
-
- private fun ContentBlock.renderFunction(node: DocumentationNode) {
- when (node.kind) {
- NodeKind.Constructor -> identifier(node.owner?.name ?: "")
- NodeKind.Function -> {
- renderTypeParametersForNode(node)
- renderType(node.detail(NodeKind.Type))
- text(" ")
- identifier(node.name)
-
- }
- else -> throw IllegalArgumentException("Node $node is not a function-like object")
- }
-
- val receiver = node.details(NodeKind.Receiver).singleOrNull()
- symbol("(")
- if (receiver != null)
- renderParameters(listOf(receiver) + node.details(NodeKind.Parameter))
- else
- renderParameters(node.details(NodeKind.Parameter))
-
- symbol(")")
- }
-
- private fun ContentBlock.renderProperty(node: DocumentationNode) {
-
- when (node.kind) {
- NodeKind.Property -> {
- keyword("val")
- text(" ")
- }
- else -> throw IllegalArgumentException("Node $node is not a property")
- }
- renderTypeParametersForNode(node)
- val receiver = node.details(NodeKind.Receiver).singleOrNull()
- if (receiver != null) {
- renderType(receiver.detail(NodeKind.Type))
- symbol(".")
- }
-
- identifier(node.name)
- symbol(":")
- text(" ")
- renderType(node.detail(NodeKind.Type))
-
- }
-} \ No newline at end of file
diff --git a/core/src/main/kotlin/Locations/Location.kt b/core/src/main/kotlin/Locations/Location.kt
deleted file mode 100644
index 2ad6b652..00000000
--- a/core/src/main/kotlin/Locations/Location.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.jetbrains.dokka
-
-import java.io.File
-
-interface Location {
- val path: String get
- fun relativePathTo(other: Location, anchor: String? = null): String
-}
-
-/**
- * Represents locations in the documentation in the form of [path](File).
- *
- * $file: [File] for this location
- * $path: [String] representing path of this location
- */
-data class FileLocation(val file: File) : Location {
- override val path: String
- get() = file.path
-
- override fun relativePathTo(other: Location, anchor: String?): String {
- if (other !is FileLocation) {
- throw IllegalArgumentException("$other is not a FileLocation")
- }
- if (file.path.substringBeforeLast(".") == other.file.path.substringBeforeLast(".") && anchor == null) {
- return "./${file.name}"
- }
- val ownerFolder = file.parentFile!!
- val relativePath = ownerFolder.toPath().relativize(other.file.toPath()).toString().replace(File.separatorChar, '/')
- return if (anchor == null) relativePath else "$relativePath#$anchor"
- }
-}
-
-fun relativePathToNode(qualifiedName: List<String>, hasMembers: Boolean): String {
- val parts = qualifiedName.map { identifierToFilename(it) }.filterNot { it.isEmpty() }
- return if (!hasMembers) {
- // leaf node, use file in owner's folder
- parts.joinToString("/")
- } else {
- parts.joinToString("/") + (if (parts.none()) "" else "/") + "index"
- }
-}
-
-fun nodeActualQualifier(node: DocumentationNode): List<DocumentationNode> {
- val topLevelPage = node.references(RefKind.TopLevelPage).singleOrNull()?.to
- if (topLevelPage != null) {
- return nodeActualQualifier(topLevelPage)
- }
- return node.owner?.let { nodeActualQualifier(it) }.orEmpty() + node
-}
-
-fun relativePathToNode(node: DocumentationNode): String {
- val qualifier = nodeActualQualifier(node)
- return relativePathToNode(
- qualifier.map { it.name },
- qualifier.last().members.any()
- )
-}
-
-
-private val reservedFilenames = setOf("index", "con", "aux", "lst", "prn", "nul", "eof", "inp", "out")
-
-fun identifierToFilename(path: String): String {
- if (path.isEmpty()) return "--root--"
- val escaped = path.replace('<', '-').replace('>', '-')
- val lowercase = escaped.replace("[A-Z]".toRegex()) { matchResult -> "-" + matchResult.value.toLowerCase() }
- return if (lowercase in reservedFilenames) "--$lowercase--" else lowercase
-}
-
-fun NodeLocationAwareGenerator.relativePathToLocation(owner: DocumentationNode, node: DocumentationNode): String {
- return location(owner).relativePathTo(location(node), null)
-}
-
-fun NodeLocationAwareGenerator.relativePathToRoot(from: Location): File {
- val file = File(from.path).parentFile
- return root.relativeTo(file)
-}
-
-fun File.toUnixString() = toString().replace(File.separatorChar, '/')
diff --git a/core/src/main/kotlin/Model/Content.kt b/core/src/main/kotlin/Model/Content.kt
deleted file mode 100644
index 3881ee20..00000000
--- a/core/src/main/kotlin/Model/Content.kt
+++ /dev/null
@@ -1,290 +0,0 @@
-package org.jetbrains.dokka
-
-interface ContentNode {
- val textLength: Int
-}
-
-object ContentEmpty : ContentNode {
- override val textLength: Int get() = 0
-}
-
-open class ContentBlock() : ContentNode {
- open val children = arrayListOf<ContentNode>()
-
- fun append(node: ContentNode) {
- children.add(node)
- }
-
- fun isEmpty() = children.isEmpty()
-
- override fun equals(other: Any?): Boolean =
- other is ContentBlock && javaClass == other.javaClass && children == other.children
-
- override fun hashCode(): Int =
- children.hashCode()
-
- override val textLength: Int
- get() = children.sumBy { it.textLength }
-}
-
-class NodeRenderContent(
- val node: DocumentationNode,
- val mode: LanguageService.RenderMode
-): ContentNode {
- override val textLength: Int
- get() = 0 //TODO: Clarify?
-}
-
-class LazyContentBlock(private val fillChildren: () -> List<ContentNode>) : ContentBlock() {
- private var computed = false
- override val children: ArrayList<ContentNode>
- get() {
- if (!computed) {
- computed = true
- children.addAll(fillChildren())
- }
- return super.children
- }
-
- override fun equals(other: Any?): Boolean {
- return other is LazyContentBlock && other.fillChildren == fillChildren && super.equals(other)
- }
-
- override fun hashCode(): Int {
- return super.hashCode() + 31 * fillChildren.hashCode()
- }
-}
-
-enum class IdentifierKind {
- TypeName,
- ParameterName,
- AnnotationName,
- SummarizedTypeName,
- Other
-}
-
-data class ContentText(val text: String) : ContentNode {
- override val textLength: Int
- get() = text.length
-}
-
-data class ContentKeyword(val text: String) : ContentNode {
- override val textLength: Int
- get() = text.length
-}
-
-data class ContentIdentifier(val text: String,
- val kind: IdentifierKind = IdentifierKind.Other,
- val signature: String? = null) : ContentNode {
- override val textLength: Int
- get() = text.length
-}
-
-data class ContentSymbol(val text: String) : ContentNode {
- override val textLength: Int
- get() = text.length
-}
-
-data class ContentEntity(val text: String) : ContentNode {
- override val textLength: Int
- get() = text.length
-}
-
-object ContentNonBreakingSpace: ContentNode {
- override val textLength: Int
- get() = 1
-}
-
-object ContentSoftLineBreak: ContentNode {
- override val textLength: Int
- get() = 0
-}
-
-object ContentIndentedSoftLineBreak: ContentNode {
- override val textLength: Int
- get() = 0
-}
-
-class ContentParagraph() : ContentBlock()
-class ContentEmphasis() : ContentBlock()
-class ContentStrong() : ContentBlock()
-class ContentStrikethrough() : ContentBlock()
-class ContentCode() : ContentBlock()
-open class ContentBlockCode(val language: String = "") : ContentBlock()
-class ContentBlockSampleCode(language: String = "kotlin", val importsBlock: ContentBlockCode = ContentBlockCode(language)) : ContentBlockCode(language)
-
-abstract class ContentNodeLink() : ContentBlock() {
- abstract val node: DocumentationNode?
- abstract val text: String?
-}
-
-object ContentHardLineBreak : ContentNode {
- override val textLength: Int
- get() = 0
-}
-
-class ContentNodeDirectLink(override val node: DocumentationNode): ContentNodeLink() {
- override fun equals(other: Any?): Boolean =
- super.equals(other) && other is ContentNodeDirectLink && node.name == other.node.name
-
- override fun hashCode(): Int =
- children.hashCode() * 31 + node.name.hashCode()
-
- override val text: String? = null
-}
-
-class ContentNodeLazyLink(val linkText: String, val lazyNode: () -> DocumentationNode?): ContentNodeLink() {
- override val node: DocumentationNode? get() = lazyNode()
-
- override fun equals(other: Any?): Boolean =
- super.equals(other) && other is ContentNodeLazyLink && linkText == other.linkText
-
- override fun hashCode(): Int =
- children.hashCode() * 31 + linkText.hashCode()
-
- override val text: String? = linkText
-}
-
-class ContentExternalLink(val href : String) : ContentBlock() {
- override fun equals(other: Any?): Boolean =
- super.equals(other) && other is ContentExternalLink && href == other.href
-
- override fun hashCode(): Int =
- children.hashCode() * 31 + href.hashCode()
-}
-
-data class ContentBookmark(val name: String): ContentBlock()
-data class ContentLocalLink(val href: String) : ContentBlock()
-
-class ContentUnorderedList() : ContentBlock()
-class ContentOrderedList() : ContentBlock()
-class ContentListItem() : ContentBlock()
-
-class ContentHeading(val level: Int) : ContentBlock()
-
-class ContentSection(val tag: String, val subjectName: String?) : ContentBlock() {
- override fun equals(other: Any?): Boolean =
- super.equals(other) && other is ContentSection && tag == other.tag && subjectName == other.subjectName
-
- override fun hashCode(): Int =
- children.hashCode() * 31 * 31 + tag.hashCode() * 31 + (subjectName?.hashCode() ?: 0)
-}
-
-object ContentTags {
- const val Description = "Description"
- const val SeeAlso = "See Also"
- const val Return = "Return"
- const val Exceptions = "Exceptions"
-}
-
-fun content(body: ContentBlock.() -> Unit): ContentBlock {
- val block = ContentBlock()
- block.body()
- return block
-}
-
-fun ContentBlock.text(value: String) = append(ContentText(value))
-fun ContentBlock.keyword(value: String) = append(ContentKeyword(value))
-fun ContentBlock.symbol(value: String) = append(ContentSymbol(value))
-
-fun ContentBlock.identifier(value: String, kind: IdentifierKind = IdentifierKind.Other, signature: String? = null) {
- append(ContentIdentifier(value, kind, signature))
-}
-
-fun ContentBlock.nbsp() = append(ContentNonBreakingSpace)
-fun ContentBlock.softLineBreak() = append(ContentSoftLineBreak)
-fun ContentBlock.indentedSoftLineBreak() = append(ContentIndentedSoftLineBreak)
-fun ContentBlock.hardLineBreak() = append(ContentHardLineBreak)
-
-fun ContentBlock.strong(body: ContentBlock.() -> Unit) {
- val strong = ContentStrong()
- strong.body()
- append(strong)
-}
-
-fun ContentBlock.code(body: ContentBlock.() -> Unit) {
- val code = ContentCode()
- code.body()
- append(code)
-}
-
-fun ContentBlock.link(to: DocumentationNode, body: ContentBlock.() -> Unit) {
- val block = if (to is DocumentationNodes.ExternalLink)
- ContentExternalLink(to.name)
- else
- ContentNodeDirectLink(to)
-
- block.body()
- append(block)
-}
-
-open class Content(): ContentBlock() {
- open val sections: List<ContentSection> get() = emptyList()
- open val summary: ContentNode get() = ContentEmpty
- open val description: ContentNode get() = ContentEmpty
-
- fun findSectionByTag(tag: String): ContentSection? =
- sections.firstOrNull { tag.equals(it.tag, ignoreCase = true) }
-
- companion object {
- val Empty = object: Content() {
- override fun toString(): String {
- return "EMPTY_CONTENT"
- }
- }
-
- fun of(vararg child: ContentNode): Content {
- val result = MutableContent()
- child.forEach { result.append(it) }
- return result
- }
- }
-}
-
-open class MutableContent() : Content() {
- private val sectionList = arrayListOf<ContentSection>()
- override val sections: List<ContentSection>
- get() = sectionList
-
- fun addSection(tag: String?, subjectName: String?): ContentSection {
- val section = ContentSection(tag ?: "", subjectName)
- sectionList.add(section)
- return section
- }
-
- override val summary: ContentNode get() = children.firstOrNull() ?: ContentEmpty
-
- override val description: ContentNode by lazy {
- val descriptionNodes = children.drop(1)
- if (descriptionNodes.isEmpty()) {
- ContentEmpty
- } else {
- val result = ContentSection(ContentTags.Description, null)
- result.children.addAll(descriptionNodes)
- result
- }
- }
-
- override fun equals(other: Any?): Boolean {
- if (other !is Content)
- return false
- return sections == other.sections && children == other.children
- }
-
- override fun hashCode(): Int {
- return sections.map { it.hashCode() }.sum()
- }
-
- override fun toString(): String {
- if (sections.isEmpty())
- return "<empty>"
- return (listOf(summary, description) + sections).joinToString()
- }
-}
-
-fun javadocSectionDisplayName(sectionName: String?): String? =
- when(sectionName) {
- "param" -> "Parameters"
- "throws", "exception" -> ContentTags.Exceptions
- else -> sectionName?.capitalize()
- }
diff --git a/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt b/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt
deleted file mode 100644
index da74495f..00000000
--- a/core/src/main/kotlin/Samples/DefaultSampleProcessingService.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.jetbrains.dokka.Samples
-
-import com.google.inject.Inject
-import com.intellij.psi.PsiElement
-import org.jetbrains.dokka.*
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
-import org.jetbrains.kotlin.idea.kdoc.getKDocLinkResolutionScope
-import org.jetbrains.kotlin.idea.kdoc.resolveKDocLink
-import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
-import org.jetbrains.kotlin.name.Name
-import org.jetbrains.kotlin.psi.KtBlockExpression
-import org.jetbrains.kotlin.psi.KtDeclarationWithBody
-import org.jetbrains.kotlin.psi.KtFile
-import org.jetbrains.kotlin.resolve.BindingContext
-import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
-import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
-import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
-
-
-open class DefaultSampleProcessingService
-@Inject constructor(val configuration: DokkaConfiguration,
- val logger: DokkaLogger,
- val resolutionFacade: DokkaResolutionFacade)
- : SampleProcessingService {
-
- override fun resolveSample(descriptor: DeclarationDescriptor, functionName: String?, kdocTag: KDocTag): ContentNode {
- if (functionName == null) {
- logger.warn("Missing function name in @sample in ${descriptor.signature()}")
- return ContentBlockSampleCode().apply { append(ContentText("//Missing function name in @sample")) }
- }
- val bindingContext = BindingContext.EMPTY
- val symbol = resolveKDocLink(bindingContext, resolutionFacade, descriptor, kdocTag, functionName.split(".")).firstOrNull()
- if (symbol == null) {
- logger.warn("Unresolved function $functionName in @sample in ${descriptor.signature()}")
- return ContentBlockSampleCode().apply { append(ContentText("//Unresolved: $functionName")) }
- }
- val psiElement = DescriptorToSourceUtils.descriptorToDeclaration(symbol)
- if (psiElement == null) {
- logger.warn("Can't find source for function $functionName in @sample in ${descriptor.signature()}")
- return ContentBlockSampleCode().apply { append(ContentText("//Source not found: $functionName")) }
- }
-
- val text = processSampleBody(psiElement).trim { it == '\n' || it == '\r' }.trimEnd()
- val lines = text.split("\n")
- val indent = lines.filter(String::isNotBlank).map { it.takeWhile(Char::isWhitespace).count() }.min() ?: 0
- val finalText = lines.joinToString("\n") { it.drop(indent) }
-
- return ContentBlockSampleCode(importsBlock = processImports(psiElement)).apply { append(ContentText(finalText)) }
- }
-
- protected open fun processSampleBody(psiElement: PsiElement): String = when (psiElement) {
- is KtDeclarationWithBody -> {
- val bodyExpression = psiElement.bodyExpression
- when (bodyExpression) {
- is KtBlockExpression -> bodyExpression.text.removeSurrounding("{", "}")
- else -> bodyExpression!!.text
- }
- }
- else -> psiElement.text
- }
-
- protected open fun processImports(psiElement: PsiElement): ContentBlockCode {
- val psiFile = psiElement.containingFile
- if (psiFile is KtFile) {
- return ContentBlockCode("kotlin").apply {
- append(ContentText(psiFile.importList?.text ?: ""))
- }
- } else {
- return ContentBlockCode("")
- }
- }
-
- private fun resolveInScope(functionName: String, scope: ResolutionScope): DeclarationDescriptor? {
- var currentScope = scope
- val parts = functionName.split('.')
-
- var symbol: DeclarationDescriptor? = null
-
- for (part in parts) {
- // short name
- val symbolName = Name.identifier(part)
- val partSymbol = currentScope.getContributedDescriptors(DescriptorKindFilter.ALL) { it == symbolName }.firstOrNull { it.name == symbolName }
-
- if (partSymbol == null) {
- symbol = null
- break
- }
- @Suppress("IfThenToElvis")
- currentScope = if (partSymbol is ClassDescriptor)
- partSymbol.defaultType.memberScope
- else if (partSymbol is PackageViewDescriptor)
- partSymbol.memberScope
- else
- getKDocLinkResolutionScope(resolutionFacade, partSymbol)
- symbol = partSymbol
- }
-
- return symbol
- }
-}
-
diff --git a/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt b/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt
deleted file mode 100644
index 4525e9d9..00000000
--- a/core/src/main/kotlin/Samples/KotlinWebsiteSampleProcessingService.kt
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.jetbrains.dokka.Samples
-
-import com.google.inject.Inject
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiElementVisitor
-import com.intellij.psi.PsiWhiteSpace
-import com.intellij.psi.impl.source.tree.LeafPsiElement
-import com.intellij.psi.util.PsiTreeUtil
-import org.jetbrains.dokka.*
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.psi.psiUtil.allChildren
-import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
-import org.jetbrains.kotlin.psi.psiUtil.startOffset
-import org.jetbrains.kotlin.resolve.ImportPath
-import java.io.PrintWriter
-import java.io.StringWriter
-
-
-open class KotlinWebsiteSampleProcessingService
-@Inject constructor(dokkaConfiguration: DokkaConfiguration,
- logger: DokkaLogger,
- resolutionFacade: DokkaResolutionFacade)
- : DefaultSampleProcessingService(dokkaConfiguration, logger, resolutionFacade) {
-
- private class SampleBuilder : KtTreeVisitorVoid() {
- val builder = StringBuilder()
- val text: String
- get() = builder.toString()
-
- val errors = mutableListOf<ConvertError>()
-
- data class ConvertError(val e: Exception, val text: String, val loc: String)
-
- fun KtValueArgument.extractStringArgumentValue() =
- (getArgumentExpression() as KtStringTemplateExpression)
- .entries.joinToString("") { it.text }
-
-
- fun convertAssertPrints(expression: KtCallExpression) {
- val (argument, commentArgument) = expression.valueArguments
- builder.apply {
- append("println(")
- append(argument.text)
- append(") // ")
- append(commentArgument.extractStringArgumentValue())
- }
- }
-
- fun convertAssertTrueFalse(expression: KtCallExpression, expectedResult: Boolean) {
- val (argument) = expression.valueArguments
- builder.apply {
- expression.valueArguments.getOrNull(1)?.let {
- append("// ${it.extractStringArgumentValue()}")
- val ws = expression.prevLeaf { it is PsiWhiteSpace }
- append(ws?.text ?: "\n")
- }
- append("println(\"")
- append(argument.text)
- append(" is \${")
- append(argument.text)
- append("}\") // $expectedResult")
- }
- }
-
- fun convertAssertFails(expression: KtCallExpression) {
- val valueArguments = expression.valueArguments
-
- val funcArgument: KtValueArgument
- val message: KtValueArgument?
-
- if (valueArguments.size == 1) {
- message = null
- funcArgument = valueArguments.first()
- } else {
- message = valueArguments.first()
- funcArgument = valueArguments.last()
- }
-
- builder.apply {
- val argument = funcArgument.extractFunctionalArgumentText()
- append(argument.lines().joinToString(separator = "\n") { "// $it" })
- append(" // ")
- if (message != null) {
- append(message.extractStringArgumentValue())
- }
- append(" will fail")
- }
- }
-
- private fun KtValueArgument.extractFunctionalArgumentText(): String {
- return if (getArgumentExpression() is KtLambdaExpression)
- PsiTreeUtil.findChildOfType(this, KtBlockExpression::class.java)?.text ?: ""
- else
- text
- }
-
- fun convertAssertFailsWith(expression: KtCallExpression) {
- val (funcArgument) = expression.valueArguments
- val (exceptionType) = expression.typeArguments
- builder.apply {
- val argument = funcArgument.extractFunctionalArgumentText()
- append(argument.lines().joinToString(separator = "\n") { "// $it" })
- append(" // will fail with ")
- append(exceptionType.text)
- }
- }
-
- override fun visitCallExpression(expression: KtCallExpression) {
- when (expression.calleeExpression?.text) {
- "assertPrints" -> convertAssertPrints(expression)
- "assertTrue" -> convertAssertTrueFalse(expression, expectedResult = true)
- "assertFalse" -> convertAssertTrueFalse(expression, expectedResult = false)
- "assertFails" -> convertAssertFails(expression)
- "assertFailsWith" -> convertAssertFailsWith(expression)
- else -> super.visitCallExpression(expression)
- }
- }
-
- private fun reportProblemConvertingElement(element: PsiElement, e: Exception) {
- val text = element.text
- val document = PsiDocumentManager.getInstance(element.project).getDocument(element.containingFile)
-
- val lineInfo = if (document != null) {
- val lineNumber = document.getLineNumber(element.startOffset)
- "$lineNumber, ${element.startOffset - document.getLineStartOffset(lineNumber)}"
- } else {
- "offset: ${element.startOffset}"
- }
- errors += ConvertError(e, text, lineInfo)
- }
-
- override fun visitElement(element: PsiElement) {
- if (element is LeafPsiElement)
- builder.append(element.text)
-
- element.acceptChildren(object : PsiElementVisitor() {
- override fun visitElement(element: PsiElement) {
- try {
- element.accept(this@SampleBuilder)
- } catch (e: Exception) {
- try {
- reportProblemConvertingElement(element, e)
- } finally {
- builder.append(element.text) //recover
- }
- }
- }
- })
- }
-
- }
-
- private fun PsiElement.buildSampleText(): String {
- val sampleBuilder = SampleBuilder()
- this.accept(sampleBuilder)
-
- sampleBuilder.errors.forEach {
- val sw = StringWriter()
- val pw = PrintWriter(sw)
- it.e.printStackTrace(pw)
-
- logger.error("${containingFile.name}: (${it.loc}): Exception thrown while converting \n```\n${it.text}\n```\n$sw")
- }
- return sampleBuilder.text
- }
-
- val importsToIgnore = arrayOf("samples.*").map { ImportPath.fromString(it) }
-
- override fun processImports(psiElement: PsiElement): ContentBlockCode {
- val psiFile = psiElement.containingFile
- if (psiFile is KtFile) {
- return ContentBlockCode("kotlin").apply {
- append(ContentText("\n"))
- psiFile.importList?.let {
- it.allChildren.filter {
- it !is KtImportDirective || it.importPath !in importsToIgnore
- }.forEach { append(ContentText(it.text)) }
- }
- }
- }
- return super.processImports(psiElement)
- }
-
- override fun processSampleBody(psiElement: PsiElement) = when (psiElement) {
- is KtDeclarationWithBody -> {
- val bodyExpression = psiElement.bodyExpression
- val bodyExpressionText = bodyExpression!!.buildSampleText()
- when (bodyExpression) {
- is KtBlockExpression -> bodyExpressionText.removeSurrounding("{", "}")
- else -> bodyExpressionText
- }
- }
- else -> psiElement.buildSampleText()
- }
-}
-
diff --git a/core/src/main/kotlin/Samples/SampleProcessingService.kt b/core/src/main/kotlin/Samples/SampleProcessingService.kt
deleted file mode 100644
index 86c917cf..00000000
--- a/core/src/main/kotlin/Samples/SampleProcessingService.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.jetbrains.dokka.Samples
-
-import org.jetbrains.dokka.ContentNode
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
-
-interface SampleProcessingService {
- fun resolveSample(descriptor: DeclarationDescriptor, functionName: String?, kdocTag: KDocTag): ContentNode
-} \ No newline at end of file
diff --git a/core/src/test/kotlin/NodeSelect.kt b/core/src/test/kotlin/NodeSelect.kt
deleted file mode 100644
index fe0394f9..00000000
--- a/core/src/test/kotlin/NodeSelect.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.DocumentationNode
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.RefKind
-
-class SelectBuilder {
- private val root = ChainFilterNode(SubgraphTraverseFilter(), null)
- private var activeNode = root
- private val chainEnds = mutableListOf<SelectFilter>()
-
- fun withName(name: String) = matching { it.name == name }
-
- fun withKind(kind: NodeKind) = matching{ it.kind == kind }
-
- fun matching(block: (DocumentationNode) -> Boolean) {
- attachFilterAndMakeActive(PredicateFilter(block))
- }
-
- fun subgraph() {
- attachFilterAndMakeActive(SubgraphTraverseFilter())
- }
-
- fun subgraphOf(kind: RefKind) {
- attachFilterAndMakeActive(DirectEdgeFilter(kind))
- }
-
- private fun attachFilterAndMakeActive(next: SelectFilter) {
- activeNode = ChainFilterNode(next, activeNode)
- }
-
- private fun endChain() {
- chainEnds += activeNode
- }
-
- fun build(): SelectFilter {
- endChain()
- return CombineFilterNode(chainEnds)
- }
-}
-
-private class ChainFilterNode(val filter: SelectFilter, val previous: SelectFilter?): SelectFilter() {
- override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
- return filter.select(previous?.select(roots) ?: roots)
- }
-}
-
-private class CombineFilterNode(val previous: List<SelectFilter>): SelectFilter() {
- override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
- return previous.asSequence().flatMap { it.select(roots) }
- }
-}
-
-abstract class SelectFilter {
- abstract fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode>
-}
-
-private class SubgraphTraverseFilter: SelectFilter() {
- override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
- val visited = mutableSetOf<DocumentationNode>()
- return roots.flatMap {
- generateSequence(listOf(it)) { nodes ->
- nodes.flatMap { it.allReferences() }
- .map { it.to }
- .filter { visited.add(it) }
- .takeUnless { it.isEmpty() }
- }
- }.flatten()
- }
-
-}
-
-private class PredicateFilter(val condition: (DocumentationNode) -> Boolean): SelectFilter() {
- override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
- return roots.filter(condition)
- }
-}
-
-private class DirectEdgeFilter(val kind: RefKind): SelectFilter() {
- override fun select(roots: Sequence<DocumentationNode>): Sequence<DocumentationNode> {
- return roots.flatMap { it.references(kind).asSequence() }.map { it.to }
- }
-}
-
-
-fun selectNodes(root: DocumentationNode, block: SelectBuilder.() -> Unit): List<DocumentationNode> {
- val builder = SelectBuilder()
- builder.apply(block)
- return builder.build().select(sequenceOf(root)).toMutableSet().toList()
-} \ No newline at end of file
diff --git a/core/src/test/kotlin/format/FileGeneratorTestCase.kt b/core/src/test/kotlin/format/FileGeneratorTestCase.kt
deleted file mode 100644
index ef9e815d..00000000
--- a/core/src/test/kotlin/format/FileGeneratorTestCase.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.*
-import org.junit.Before
-import org.junit.Rule
-import org.junit.rules.TemporaryFolder
-
-
-abstract class FileGeneratorTestCase {
- abstract val formatService: FormatService
-
- @get:Rule
- var folder = TemporaryFolder()
-
- val fileGenerator = FileGenerator(folder.apply { create() }.root)
-
- @Before
- fun bindGenerator() {
- fileGenerator.formatService = formatService
- }
-
- fun buildPagesAndReadInto(nodes: List<DocumentationNode>, sb: StringBuilder) = with(fileGenerator) {
- buildPages(nodes)
- val byLocations = nodes.groupBy { location(it) }
- byLocations.forEach { (loc, _) ->
- if (byLocations.size > 1) {
- if (sb.isNotBlank() && !sb.endsWith('\n')) {
- sb.appendln()
- }
- sb.appendln("<!-- File: ${loc.file.relativeTo(root).toUnixString()} -->")
- }
- sb.append(loc.file.readText())
- }
- }
-} \ No newline at end of file
diff --git a/core/src/test/kotlin/format/GFMFormatTest.kt b/core/src/test/kotlin/format/GFMFormatTest.kt
deleted file mode 100644
index 4807d0f2..00000000
--- a/core/src/test/kotlin/format/GFMFormatTest.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.GFMFormatService
-import org.jetbrains.dokka.KotlinLanguageService
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.verifyOutput
-import org.junit.Test
-
-abstract class BaseGFMFormatTest(val analysisPlatform: Platform) : FileGeneratorTestCase() {
- override val formatService = GFMFormatService(fileGenerator, KotlinLanguageService(), listOf())
- private val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
-
-
- @Test
- fun sample() {
- verifyGFMNodeByName("sample", "Foo", defaultModelConfig)
- }
-
- @Test
- fun listInTableCell() {
- verifyGFMNodeByName("listInTableCell", "Foo", defaultModelConfig)
- }
-
- private fun verifyGFMNodeByName(fileName: String, name: String, modelConfig: ModelConfig) {
- verifyOutput("testdata/format/gfm/$fileName.kt", ".md", modelConfig) { model, output ->
- buildPagesAndReadInto(
- model.members.single().members.filter { it.name == name },
- output
- )
- }
- }
-}
-
-
-class JsGFMFormatTest : BaseGFMFormatTest(Platform.js)
-class JvmGFMFormatTest : BaseGFMFormatTest(Platform.jvm)
-class CommonGFMFormatTest : BaseGFMFormatTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/format/HtmlFormatTest.kt b/core/src/test/kotlin/format/HtmlFormatTest.kt
deleted file mode 100644
index a1742280..00000000
--- a/core/src/test/kotlin/format/HtmlFormatTest.kt
+++ /dev/null
@@ -1,195 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.verifyJavaOutput
-import org.jetbrains.dokka.testApi.verifyOutput
-import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
-import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
-import org.junit.Test
-import java.io.File
-
-abstract class BaseHtmlFormatTest(val analysisPlatform: Platform): FileGeneratorTestCase() {
- protected val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- override val formatService = HtmlFormatService(fileGenerator, KotlinLanguageService(), HtmlTemplateService.default(), listOf())
-
- @Test fun classWithCompanionObject() {
- verifyHtmlNode("classWithCompanionObject", defaultModelConfig)
- }
-
- @Test fun htmlEscaping() {
- verifyHtmlNode("htmlEscaping", defaultModelConfig)
- }
-
- @Test fun overloads() {
- verifyHtmlNodes("overloads", defaultModelConfig) { model -> model.members }
- }
-
- @Test fun overloadsWithDescription() {
- verifyHtmlNode("overloadsWithDescription", defaultModelConfig)
- }
-
- @Test fun overloadsWithDifferentDescriptions() {
- verifyHtmlNode("overloadsWithDifferentDescriptions", defaultModelConfig)
- }
-
- @Test fun deprecated() {
- verifyOutput("testdata/format/deprecated.kt", ".package.html", defaultModelConfig) { model, output ->
- buildPagesAndReadInto(model.members, output)
- }
- verifyOutput("testdata/format/deprecated.kt", ".class.html", defaultModelConfig) { model, output ->
- buildPagesAndReadInto(model.members.single().members, output)
- }
- }
-
- @Test fun brokenLink() {
- verifyHtmlNode("brokenLink", defaultModelConfig)
- }
-
- @Test fun codeSpan() {
- verifyHtmlNode("codeSpan", defaultModelConfig)
- }
-
- @Test fun parenthesis() {
- verifyHtmlNode("parenthesis", defaultModelConfig)
- }
-
- @Test fun bracket() {
- verifyHtmlNode("bracket", defaultModelConfig)
- }
-
- @Test fun see() {
- verifyHtmlNode("see", defaultModelConfig)
- }
-
- @Test fun tripleBackticks() {
- verifyHtmlNode("tripleBackticks", defaultModelConfig)
- }
-
- @Test fun typeLink() {
- verifyHtmlNodes("typeLink", defaultModelConfig) { model -> model.members.single().members.filter { it.name == "Bar" } }
- }
-
- @Test fun parameterAnchor() {
- verifyHtmlNode("parameterAnchor", defaultModelConfig)
- }
-
- @Test fun codeBlock() {
- verifyHtmlNode("codeBlock", defaultModelConfig)
- }
- @Test fun orderedList() {
- verifyHtmlNodes("orderedList", defaultModelConfig) { model -> model.members.single().members.filter { it.name == "Bar" } }
- }
-
- @Test fun linkWithLabel() {
- verifyHtmlNodes("linkWithLabel", defaultModelConfig) { model -> model.members.single().members.filter { it.name == "Bar" } }
- }
-
- @Test fun entity() {
- verifyHtmlNodes("entity", defaultModelConfig) { model -> model.members.single().members.filter { it.name == "Bar" } }
- }
-
- @Test fun uninterpretedEmphasisCharacters() {
- verifyHtmlNode("uninterpretedEmphasisCharacters", defaultModelConfig)
- }
-
- @Test fun markdownInLinks() {
- verifyHtmlNode("markdownInLinks", defaultModelConfig)
- }
-
- @Test fun returnWithLink() {
- verifyHtmlNode("returnWithLink", defaultModelConfig)
- }
-
- @Test fun linkWithStarProjection() {
- verifyHtmlNode("linkWithStarProjection", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun functionalTypeWithNamedParameters() {
- verifyHtmlNode("functionalTypeWithNamedParameters", defaultModelConfig)
- }
-
- @Test fun sinceKotlin() {
- verifyHtmlNode("sinceKotlin", defaultModelConfig)
- }
-
- @Test fun blankLineInsideCodeBlock() {
- verifyHtmlNode("blankLineInsideCodeBlock", defaultModelConfig)
- }
-
- @Test fun indentedCodeBlock() {
- verifyHtmlNode("indentedCodeBlock", defaultModelConfig)
- }
-
- private fun verifyHtmlNode(fileName: String, modelConfig: ModelConfig = ModelConfig()) {
- verifyHtmlNodes(fileName, modelConfig) { model -> model.members.single().members }
- }
-
- private fun verifyHtmlNodes(fileName: String,
- modelConfig: ModelConfig = ModelConfig(),
- nodeFilter: (DocumentationModule) -> List<DocumentationNode>) {
- verifyOutput("testdata/format/$fileName.kt", ".html", modelConfig) { model, output ->
- buildPagesAndReadInto(nodeFilter(model), output)
- }
- }
-
- protected fun verifyJavaHtmlNode(fileName: String, modelConfig: ModelConfig = ModelConfig()) {
- verifyJavaHtmlNodes(fileName, modelConfig) { model -> model.members.single().members }
- }
-
- protected fun verifyJavaHtmlNodes(fileName: String,
- modelConfig: ModelConfig = ModelConfig(),
- nodeFilter: (DocumentationModule) -> List<DocumentationNode>) {
- verifyJavaOutput("testdata/format/$fileName.java", ".html", modelConfig) { model, output ->
- buildPagesAndReadInto(nodeFilter(model), output)
- }
- }
-}
-
-class JSHtmlFormatTest: BaseHtmlFormatTest(Platform.js)
-
-class JVMHtmlFormatTest: BaseHtmlFormatTest(Platform.jvm) {
- @Test
- fun javaSeeTag() {
- verifyJavaHtmlNode("javaSeeTag", defaultModelConfig)
- }
-
- @Test fun javaDeprecated() {
- verifyJavaHtmlNodes("javaDeprecated", defaultModelConfig) { model ->
- model.members.single().members.single { it.name == "Foo" }.members.filter { it.name == "foo" }
- }
- }
-
- @Test fun crossLanguageKotlinExtendsJava() {
- verifyOutput(
- ModelConfig(
- roots = arrayOf(
- KotlinSourceRoot("testdata/format/crossLanguage/kotlinExtendsJava/Bar.kt", false),
- JavaSourceRoot(File("testdata/format/crossLanguage/kotlinExtendsJava"), null)
- ),
- analysisPlatform = analysisPlatform
- ), ".html") { model, output ->
- buildPagesAndReadInto(
- model.members.single().members.filter { it.name == "Bar" },
- output
- )
- }
- }
-
- @Test fun javaLinkTag() {
- verifyJavaHtmlNode("javaLinkTag", defaultModelConfig)
- }
-
- @Test fun javaLinkTagWithLabel() {
- verifyJavaHtmlNode("javaLinkTagWithLabel", defaultModelConfig)
- }
-
- @Test fun javaSupertypeLink() {
- verifyJavaHtmlNodes("JavaSupertype", defaultModelConfig) { model ->
- model.members.single().members.single { it.name == "JavaSupertype" }.members.filter { it.name == "Bar" }
- }
- }
-
-}
-
-class CommonHtmlFormatTest: BaseHtmlFormatTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/format/KotlinWebSiteHtmlFormatTest.kt b/core/src/test/kotlin/format/KotlinWebSiteHtmlFormatTest.kt
deleted file mode 100644
index d8b34394..00000000
--- a/core/src/test/kotlin/format/KotlinWebSiteHtmlFormatTest.kt
+++ /dev/null
@@ -1,127 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.Generation.DocumentationMerger
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.appendDocumentation
-import org.jetbrains.dokka.testApi.verifyModelOutput
-import org.jetbrains.dokka.testApi.verifyOutput
-import org.junit.Test
-
-abstract class BaseKotlinWebSiteHtmlFormatTest(val analysisPlatform: Platform): FileGeneratorTestCase() {
- val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- override val formatService = KotlinWebsiteHtmlFormatService(fileGenerator, KotlinLanguageService(), listOf(), EmptyHtmlTemplateService)
-
- @Test fun dropImport() {
- verifyKWSNodeByName("dropImport", "foo", defaultModelConfig)
- }
-
- @Test fun sample() {
- verifyKWSNodeByName("sample", "foo", defaultModelConfig)
- }
-
- @Test fun sampleWithAsserts() {
- verifyKWSNodeByName("sampleWithAsserts", "a", defaultModelConfig)
- }
-
- @Test fun newLinesInSamples() {
- verifyKWSNodeByName("newLinesInSamples", "foo", defaultModelConfig)
- }
-
- @Test fun newLinesInImportList() {
- verifyKWSNodeByName("newLinesInImportList", "foo", defaultModelConfig)
- }
-
- @Test fun returnTag() {
- verifyKWSNodeByName("returnTag", "indexOf", defaultModelConfig)
- }
-
- @Test fun overloadGroup() {
- verifyKWSNodeByName("overloadGroup", "magic", defaultModelConfig)
- }
-
- @Test fun dataTags() {
- val module = buildMultiplePlatforms("dataTags")
- verifyMultiplatformPackage(module, "dataTags")
- }
-
- @Test fun dataTagsInGroupNode() {
- val path = "dataTagsInGroupNode"
- val module = buildMultiplePlatforms(path)
- verifyModelOutput(module, ".html", "testdata/format/website-html/$path/multiplatform.kt") { model, output ->
- buildPagesAndReadInto(
- listOfNotNull(model.members.single().members.find { it.kind == NodeKind.GroupNode }),
- output
- )
- }
- verifyMultiplatformPackage(module, path)
- }
-
- private fun verifyKWSNodeByName(fileName: String, name: String, modelConfig: ModelConfig) {
- verifyOutput(
- "testdata/format/website-html/$fileName.kt",
- ".html",
- ModelConfig(analysisPlatform = modelConfig.analysisPlatform, format = "kotlin-website-html")
- ) { model, output ->
- buildPagesAndReadInto(model.members.single().members.filter { it.name == name }, output)
- }
- }
-
- private fun buildMultiplePlatforms(path: String): DocumentationModule {
- val moduleName = "test"
- val passConfiguration = org.jetbrains.dokka.testApi.PassConfigurationImpl(
- noStdlibLink = true,
- noJdkLink = true,
- languageVersion = null,
- apiVersion = null
- )
-
- val dokkaConfiguration = org.jetbrains.dokka.testApi.DokkaConfigurationImpl(
- outputDir = "",
- format = "kotlin-website-html",
- generateIndexPages = false,
- passesConfigurations = listOf(
- passConfiguration
- )
-
- )
-
- val module1 = DocumentationModule(moduleName)
- appendDocumentation(
- module1, dokkaConfiguration, passConfiguration, ModelConfig(
- roots = arrayOf(contentRootFromPath("testdata/format/website-html/$path/jvm.kt")),
- defaultPlatforms = listOf("JVM")
- )
- )
-
- val module2 = DocumentationModule(moduleName)
- appendDocumentation(
- module2, dokkaConfiguration, passConfiguration, ModelConfig(
- roots = arrayOf(contentRootFromPath("testdata/format/website-html/$path/jre7.kt")),
- defaultPlatforms = listOf("JVM", "JRE7")
- )
- )
-
- val module3 = DocumentationModule(moduleName)
- appendDocumentation(
- module3, dokkaConfiguration, passConfiguration, ModelConfig(
- roots = arrayOf(contentRootFromPath("testdata/format/website-html/$path/js.kt")),
- defaultPlatforms = listOf("JS")
- )
- )
-
- return DocumentationMerger(listOf(module1, module2, module3), DokkaConsoleLogger).merge()
- }
-
- private fun verifyMultiplatformPackage(module: DocumentationModule, path: String) {
- verifyModelOutput(module, ".package.html", "testdata/format/website-html/$path/multiplatform.kt") { model, output ->
- buildPagesAndReadInto(model.members, output)
- }
- }
-
-}
-class JsKotlinWebSiteHtmlFormatTest: BaseKotlinWebSiteHtmlFormatTest(Platform.js)
-
-class JvmKotlinWebSiteHtmlFormatTest: BaseKotlinWebSiteHtmlFormatTest(Platform.jvm)
-
-class CommonKotlinWebSiteHtmlFormatTest: BaseKotlinWebSiteHtmlFormatTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/format/MarkdownFormatTest.kt b/core/src/test/kotlin/format/MarkdownFormatTest.kt
deleted file mode 100644
index 8900b267..00000000
--- a/core/src/test/kotlin/format/MarkdownFormatTest.kt
+++ /dev/null
@@ -1,616 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.Generation.DocumentationMerger
-import org.jetbrains.dokka.testApi.*
-import org.junit.Test
-
-abstract class BaseMarkdownFormatTest(val analysisPlatform: Platform): FileGeneratorTestCase() {
- override val formatService = MarkdownFormatService(fileGenerator, KotlinLanguageService(), listOf())
-
- protected val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
-
- @Test fun emptyDescription() {
- verifyMarkdownNode("emptyDescription", defaultModelConfig)
- }
-
- @Test fun classWithCompanionObject() {
- verifyMarkdownNode("classWithCompanionObject", defaultModelConfig)
- }
-
- @Test fun annotations() {
- verifyMarkdownNode("annotations", defaultModelConfig)
- }
-
- @Test fun annotationClass() {
- verifyMarkdownNode("annotationClass", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- verifyMarkdownPackage("annotationClass", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun enumClass() {
- verifyOutput("testdata/format/enumClass.kt", ".md", defaultModelConfig) { model, output ->
- buildPagesAndReadInto(model.members.single().members, output)
- }
- verifyOutput("testdata/format/enumClass.kt", ".value.md", defaultModelConfig) { model, output ->
- val enumClassNode = model.members.single().members[0]
- buildPagesAndReadInto(
- enumClassNode.members.filter { it.name == "LOCAL_CONTINUE_AND_BREAK" },
- output
- )
- }
- }
-
- @Test fun varargsFunction() {
- verifyMarkdownNode("varargsFunction", defaultModelConfig)
- }
-
- @Test fun overridingFunction() {
- verifyMarkdownNodes("overridingFunction", defaultModelConfig) { model->
- val classMembers = model.members.single().members.first { it.name == "D" }.members
- classMembers.filter { it.name == "f" }
- }
- }
-
- @Test fun propertyVar() {
- verifyMarkdownNode("propertyVar", defaultModelConfig)
- }
-
- @Test fun functionWithDefaultParameter() {
- verifyMarkdownNode("functionWithDefaultParameter", defaultModelConfig)
- }
-
- @Test fun accessor() {
- verifyMarkdownNodes("accessor", defaultModelConfig) { model ->
- model.members.single().members.first { it.name == "C" }.members.filter { it.name == "x" }
- }
- }
-
- @Test fun paramTag() {
- verifyMarkdownNode("paramTag", defaultModelConfig)
- }
-
- @Test fun throwsTag() {
- verifyMarkdownNode("throwsTag", defaultModelConfig)
- }
-
- @Test fun typeParameterBounds() {
- verifyMarkdownNode("typeParameterBounds", defaultModelConfig)
- }
-
- @Test fun typeParameterVariance() {
- verifyMarkdownNode("typeParameterVariance", defaultModelConfig)
- }
-
- @Test fun typeProjectionVariance() {
- verifyMarkdownNode("typeProjectionVariance", defaultModelConfig)
- }
-
- @Test fun codeBlockNoHtmlEscape() {
- verifyMarkdownNodeByName("codeBlockNoHtmlEscape", "hackTheArithmetic", defaultModelConfig)
- }
-
- @Test fun companionObjectExtension() {
- verifyMarkdownNodeByName("companionObjectExtension", "Foo", defaultModelConfig)
- }
-
- @Test fun starProjection() {
- verifyMarkdownNode("starProjection", defaultModelConfig)
- }
-
- @Test fun extensionFunctionParameter() {
- verifyMarkdownNode("extensionFunctionParameter", defaultModelConfig)
- }
-
- @Test fun summarizeSignatures() {
- verifyMarkdownNodes("summarizeSignatures", defaultModelConfig) { model -> model.members }
- }
-
- @Test fun reifiedTypeParameter() {
- verifyMarkdownNode("reifiedTypeParameter", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun suspendInlineFunctionOrder() {
- verifyMarkdownNode("suspendInlineFunction", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun inlineSuspendFunctionOrderChanged() {
- verifyMarkdownNode("inlineSuspendFunction", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun annotatedTypeParameter() {
- verifyMarkdownNode("annotatedTypeParameter", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun inheritedMembers() {
- verifyMarkdownNodeByName("inheritedMembers", "Bar", defaultModelConfig)
- }
-
- @Test fun inheritedExtensions() {
- verifyMarkdownNodeByName("inheritedExtensions", "Bar", defaultModelConfig)
- }
-
- @Test fun genericInheritedExtensions() {
- verifyMarkdownNodeByName("genericInheritedExtensions", "Bar", defaultModelConfig)
- }
-
- @Test fun arrayAverage() {
- verifyMarkdownNodeByName("arrayAverage", "XArray", defaultModelConfig)
- }
-
- @Test fun multipleTypeParameterConstraints() {
- verifyMarkdownNode("multipleTypeParameterConstraints", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun inheritedCompanionObjectProperties() {
- verifyMarkdownNodeByName("inheritedCompanionObjectProperties", "C", defaultModelConfig)
- }
-
- @Test fun shadowedExtensionFunctions() {
- verifyMarkdownNodeByName("shadowedExtensionFunctions", "Bar", defaultModelConfig)
- }
-
- @Test fun inapplicableExtensionFunctions() {
- verifyMarkdownNodeByName("inapplicableExtensionFunctions", "Bar", defaultModelConfig)
- }
-
- @Test fun receiverParameterTypeBound() {
- verifyMarkdownNodeByName("receiverParameterTypeBound", "Foo", defaultModelConfig)
- }
-
- @Test fun extensionWithDocumentedReceiver() {
- verifyMarkdownNodes("extensionWithDocumentedReceiver", defaultModelConfig) { model ->
- model.members.single().members.single().members.filter { it.name == "fn" }
- }
- }
-
- @Test fun codeBlock() {
- verifyMarkdownNode("codeBlock", defaultModelConfig)
- }
-
- @Test fun exclInCodeBlock() {
- verifyMarkdownNodeByName("exclInCodeBlock", "foo", defaultModelConfig)
- }
-
- @Test fun backtickInCodeBlock() {
- verifyMarkdownNodeByName("backtickInCodeBlock", "foo", defaultModelConfig)
- }
-
- @Test fun qualifiedNameLink() {
- verifyMarkdownNodeByName("qualifiedNameLink", "foo",
- ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun functionalTypeWithNamedParameters() {
- verifyMarkdownNode("functionalTypeWithNamedParameters", defaultModelConfig)
- }
-
- @Test fun typeAliases() {
- verifyMarkdownNode("typeAliases", defaultModelConfig)
- verifyMarkdownPackage("typeAliases", defaultModelConfig)
- }
-
- @Test fun sampleByShortName() {
- verifyMarkdownNode("sampleByShortName", defaultModelConfig)
- }
-
-
- @Test fun suspendParam() {
- verifyMarkdownNode("suspendParam", defaultModelConfig)
- verifyMarkdownPackage("suspendParam", defaultModelConfig)
- }
-
- @Test fun sinceKotlin() {
- verifyMarkdownNode("sinceKotlin", defaultModelConfig)
- verifyMarkdownPackage("sinceKotlin", defaultModelConfig)
- }
-
- @Test fun sinceKotlinWide() {
- verifyMarkdownPackage("sinceKotlinWide", defaultModelConfig)
- }
-
- @Test fun dynamicType() {
- verifyMarkdownNode("dynamicType", defaultModelConfig)
- }
-
- @Test fun dynamicExtension() {
- verifyMarkdownNodes("dynamicExtension", defaultModelConfig) { model -> model.members.single().members.filter { it.name == "Foo" } }
- }
-
- @Test fun memberExtension() {
- verifyMarkdownNodes("memberExtension", defaultModelConfig) { model -> model.members.single().members.filter { it.name == "Foo" } }
- }
-
- @Test fun renderFunctionalTypeInParenthesisWhenItIsReceiver() {
- verifyMarkdownNode("renderFunctionalTypeInParenthesisWhenItIsReceiver", defaultModelConfig)
- }
-
- @Test fun multiplePlatforms() {
- verifyMultiplatformPackage(buildMultiplePlatforms("multiplatform/simple"), "multiplatform/simple")
- }
-
- @Test fun multiplePlatformsMerge() {
- verifyMultiplatformPackage(buildMultiplePlatforms("multiplatform/merge"), "multiplatform/merge")
- }
-
- @Test fun multiplePlatformsMergeMembers() {
- val module = buildMultiplePlatforms("multiplatform/mergeMembers")
- verifyModelOutput(module, ".md", "testdata/format/multiplatform/mergeMembers/foo.kt") { model, output ->
- buildPagesAndReadInto(model.members.single().members, output)
- }
- }
-
- @Test fun multiplePlatformsOmitRedundant() {
- val module = buildMultiplePlatforms("multiplatform/omitRedundant")
- verifyModelOutput(module, ".md", "testdata/format/multiplatform/omitRedundant/foo.kt") { model, output ->
- buildPagesAndReadInto(model.members.single().members, output)
- }
- }
-
- @Test fun multiplePlatformsImplied() {
- val module = buildMultiplePlatforms("multiplatform/implied")
- verifyModelOutput(module, ".md", "testdata/format/multiplatform/implied/foo.kt") { model, output ->
- val service = MarkdownFormatService(fileGenerator, KotlinLanguageService(), listOf("JVM", "JS"))
- fileGenerator.formatService = service
- buildPagesAndReadInto(model.members.single().members, output)
- }
- }
-
- @Test fun packagePlatformsWithExtExtensions() {
- val path = "multiplatform/packagePlatformsWithExtExtensions"
- val module = DocumentationModule("test")
- val passConfiguration = org.jetbrains.dokka.testApi.PassConfigurationImpl(
- noStdlibLink = true,
- noJdkLink = true,
- languageVersion = null,
- apiVersion = null
- )
-
- val dokkaConfiguration = org.jetbrains.dokka.testApi.DokkaConfigurationImpl(
- outputDir = "",
- format = "html",
- generateIndexPages = false,
- passesConfigurations = listOf(
- passConfiguration
- )
- )
-
- appendDocumentation(module, dokkaConfiguration, passConfiguration, ModelConfig(
- roots = arrayOf(contentRootFromPath("testdata/format/$path/jvm.kt")),
- defaultPlatforms = listOf("JVM"),
- withKotlinRuntime = true,
- analysisPlatform = analysisPlatform
- )
- )
- verifyMultiplatformIndex(module, path)
- verifyMultiplatformPackage(module, path)
- }
-
- @Test fun multiplePlatformsPackagePlatformFromMembers() {
- val path = "multiplatform/packagePlatformsFromMembers"
- val module = buildMultiplePlatforms(path)
- verifyMultiplatformIndex(module, path)
- verifyMultiplatformPackage(module, path)
- }
-
- @Test fun multiplePlatformsGroupNode() {
- val path = "multiplatform/groupNode"
- val module = buildMultiplePlatforms(path)
- verifyModelOutput(module, ".md", "testdata/format/$path/multiplatform.kt") { model, output ->
- buildPagesAndReadInto(
- listOfNotNull(model.members.single().members.find { it.kind == NodeKind.GroupNode }),
- output
- )
- }
- verifyMultiplatformPackage(module, path)
- }
-
- @Test fun multiplePlatformsBreadcrumbsInMemberOfMemberOfGroupNode() {
- val path = "multiplatform/breadcrumbsInMemberOfMemberOfGroupNode"
- val module = buildMultiplePlatforms(path)
- verifyModelOutput(module, ".md", "testdata/format/$path/multiplatform.kt") { model, output ->
- buildPagesAndReadInto(
- listOfNotNull(model.members.single().members.find { it.kind == NodeKind.GroupNode }?.member(NodeKind.Function)),
- output
- )
- }
- }
-
- @Test fun linksInEmphasis() {
- verifyMarkdownNode("linksInEmphasis", defaultModelConfig)
- }
-
- @Test fun linksInStrong() {
- verifyMarkdownNode("linksInStrong", defaultModelConfig)
- }
-
- @Test fun linksInHeaders() {
- verifyMarkdownNode("linksInHeaders", defaultModelConfig)
- }
-
- @Test fun tokensInEmphasis() {
- verifyMarkdownNode("tokensInEmphasis", defaultModelConfig)
- }
-
- @Test fun tokensInStrong() {
- verifyMarkdownNode("tokensInStrong", defaultModelConfig)
- }
-
- @Test fun tokensInHeaders() {
- verifyMarkdownNode("tokensInHeaders", defaultModelConfig)
- }
-
- @Test fun unorderedLists() {
- verifyMarkdownNode("unorderedLists", defaultModelConfig)
- }
-
- @Test fun nestedLists() {
- verifyMarkdownNode("nestedLists", defaultModelConfig)
- }
-
- @Test fun referenceLink() {
- verifyMarkdownNode("referenceLink", defaultModelConfig)
- }
-
- @Test fun externalReferenceLink() {
- verifyMarkdownNode("externalReferenceLink", defaultModelConfig)
- }
-
- @Test fun newlineInTableCell() {
- verifyMarkdownPackage("newlineInTableCell", defaultModelConfig)
- }
-
- @Test fun indentedCodeBlock() {
- verifyMarkdownNode("indentedCodeBlock", defaultModelConfig)
- }
-
- @Test fun receiverReference() {
- verifyMarkdownNode("receiverReference", defaultModelConfig)
- }
-
- @Test fun extensionScope() {
- verifyMarkdownNodeByName("extensionScope", "test", defaultModelConfig)
- }
-
- @Test fun typeParameterReference() {
- verifyMarkdownNode("typeParameterReference", defaultModelConfig)
- }
-
- @Test fun notPublishedTypeAliasAutoExpansion() {
- verifyMarkdownNodeByName("notPublishedTypeAliasAutoExpansion", "foo", ModelConfig(
- analysisPlatform = analysisPlatform,
- includeNonPublic = false
- ))
- }
-
- @Test fun companionImplements() {
- verifyMarkdownNodeByName("companionImplements", "Foo", defaultModelConfig)
- }
-
-
- private fun buildMultiplePlatforms(path: String): DocumentationModule {
- val moduleName = "test"
- val passConfiguration = org.jetbrains.dokka.testApi.PassConfigurationImpl(
- noStdlibLink = true,
- noJdkLink = true,
- languageVersion = null,
- apiVersion = null
- )
- val dokkaConfiguration = org.jetbrains.dokka.testApi.DokkaConfigurationImpl(
- outputDir = "",
- format = "html",
- generateIndexPages = false,
- passesConfigurations = listOf(
- passConfiguration
- )
-
- )
- val module1 = DocumentationModule(moduleName)
- appendDocumentation(
- module1, dokkaConfiguration, passConfiguration, ModelConfig(
- roots = arrayOf(contentRootFromPath("testdata/format/$path/jvm.kt")),
- defaultPlatforms = listOf("JVM"),
- analysisPlatform = Platform.jvm
- )
- )
-
- val module2 = DocumentationModule(moduleName)
- appendDocumentation(
- module2, dokkaConfiguration, passConfiguration, ModelConfig(
- roots = arrayOf(contentRootFromPath("testdata/format/$path/js.kt")),
- defaultPlatforms = listOf("JS"),
- analysisPlatform = Platform.js
- )
- )
-
- return DocumentationMerger(listOf(module1, module2), DokkaConsoleLogger).merge()
- }
-
- private fun verifyMultiplatformPackage(module: DocumentationModule, path: String) {
- verifyModelOutput(module, ".package.md", "testdata/format/$path/multiplatform.kt") { model, output ->
- buildPagesAndReadInto(model.members, output)
- }
- }
-
- private fun verifyMultiplatformIndex(module: DocumentationModule, path: String) {
- verifyModelOutput(module, ".md", "testdata/format/$path/multiplatform.index.kt") {
- model, output ->
- val service = MarkdownFormatService(fileGenerator, KotlinLanguageService(), listOf())
- fileGenerator.formatService = service
- buildPagesAndReadInto(listOf(model), output)
- }
- }
-
- @Test fun blankLineInsideCodeBlock() {
- verifyMarkdownNode("blankLineInsideCodeBlock", defaultModelConfig)
- }
-
- protected fun verifyMarkdownPackage(fileName: String, modelConfig: ModelConfig = ModelConfig()) {
- verifyOutput("testdata/format/$fileName.kt", ".package.md", modelConfig) { model, output ->
- buildPagesAndReadInto(model.members, output)
- }
- }
-
- protected fun verifyMarkdownNode(fileName: String, modelConfig: ModelConfig = ModelConfig()) {
- verifyMarkdownNodes(fileName, modelConfig) { model -> model.members.single().members }
- }
-
- protected fun verifyMarkdownNodes(
- fileName: String,
- modelConfig: ModelConfig = ModelConfig(),
- nodeFilter: (DocumentationModule) -> List<DocumentationNode>
- ) {
- verifyOutput(
- "testdata/format/$fileName.kt",
- ".md",
- modelConfig
- ) { model, output ->
- buildPagesAndReadInto(nodeFilter(model), output)
- }
- }
-
- protected fun verifyJavaMarkdownNode(fileName: String, modelConfig: ModelConfig = ModelConfig()) {
- verifyJavaMarkdownNodes(fileName, modelConfig) { model -> model.members.single().members }
- }
-
- protected fun verifyJavaMarkdownNodes(fileName: String, modelConfig: ModelConfig = ModelConfig(), nodeFilter: (DocumentationModule) -> List<DocumentationNode>) {
- verifyJavaOutput("testdata/format/$fileName.java", ".md", modelConfig) { model, output ->
- buildPagesAndReadInto(nodeFilter(model), output)
- }
- }
-
- protected fun verifyMarkdownNodeByName(
- fileName: String,
- name: String,
- modelConfig: ModelConfig = ModelConfig()
- ) {
- verifyMarkdownNodes(fileName, modelConfig) { model->
- val nodesWithName = model.members.single().members.filter { it.name == name }
- if (nodesWithName.isEmpty()) {
- throw IllegalArgumentException("Found no nodes named $name")
- }
- nodesWithName
- }
- }
-
- @Test fun nullableTypeParameterFunction() {
- verifyMarkdownNode("nullableTypeParameterFunction", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-}
-
-class JSMarkdownFormatTest: BaseMarkdownFormatTest(Platform.js)
-
-class JVMMarkdownFormatTest: BaseMarkdownFormatTest(Platform.jvm) {
-
- @Test
- fun enumRef() {
- verifyMarkdownNode("enumRef", defaultModelConfig)
- }
-
- @Test
- fun javaCodeLiteralTags() {
- verifyJavaMarkdownNode("javaCodeLiteralTags", defaultModelConfig)
- }
-
- @Test
- fun nullability() {
- verifyMarkdownNode("nullability", defaultModelConfig)
- }
-
- @Test
- fun exceptionClass() {
- verifyMarkdownNode(
- "exceptionClass", ModelConfig(
- analysisPlatform = analysisPlatform,
- withKotlinRuntime = true
- )
- )
- verifyMarkdownPackage(
- "exceptionClass", ModelConfig(
- analysisPlatform = analysisPlatform,
- withKotlinRuntime = true
- )
- )
- }
-
- @Test
- fun operatorOverloading() {
- verifyMarkdownNodes("operatorOverloading", defaultModelConfig) { model->
- model.members.single().members.single { it.name == "C" }.members.filter { it.name == "plus" }
- }
- }
-
- @Test
- fun extensions() {
- verifyOutput("testdata/format/extensions.kt", ".package.md", defaultModelConfig) { model, output ->
- buildPagesAndReadInto(model.members, output)
- }
- verifyOutput("testdata/format/extensions.kt", ".class.md", defaultModelConfig) { model, output ->
- buildPagesAndReadInto(model.members.single().members, output)
- }
- }
-
- @Test
- fun summarizeSignaturesProperty() {
- verifyMarkdownNodes("summarizeSignaturesProperty", defaultModelConfig) { model -> model.members }
- }
-
- @Test
- fun javaSpaceInAuthor() {
- verifyJavaMarkdownNode("javaSpaceInAuthor", defaultModelConfig)
- }
-
- @Test
- fun javaCodeInParam() {
- verifyJavaMarkdownNodes("javaCodeInParam", defaultModelConfig) {
- selectNodes(it) {
- subgraphOf(RefKind.Member)
- withKind(NodeKind.Function)
- }
- }
- }
-
- @Test
- fun annotationParams() {
- verifyMarkdownNode("annotationParams", ModelConfig(analysisPlatform = analysisPlatform, withKotlinRuntime = true))
- }
-
- @Test fun inheritedLink() {
- val filePath = "testdata/format/inheritedLink"
- verifyOutput(
- filePath,
- ".md",
- ModelConfig(
- roots = arrayOf(
- contentRootFromPath("$filePath.kt"),
- contentRootFromPath("$filePath.1.kt")
- ),
- withJdk = true,
- withKotlinRuntime = true,
- includeNonPublic = false,
- analysisPlatform = analysisPlatform
-
- )
- ) { model, output ->
- buildPagesAndReadInto(model.members.single { it.name == "p2" }.members.single().members, output)
- }
- }
-
- @Test
- fun javadocOrderedList() {
- verifyJavaMarkdownNodes("javadocOrderedList", defaultModelConfig) { model ->
- model.members.single().members.filter { it.name == "Bar" }
- }
- }
-
- @Test
- fun jdkLinks() {
- verifyMarkdownNode("jdkLinks", ModelConfig(withKotlinRuntime = true, analysisPlatform = analysisPlatform))
- }
-
- @Test
- fun javadocHtml() {
- verifyJavaMarkdownNode("javadocHtml", defaultModelConfig)
- }
-}
-
-class CommonMarkdownFormatTest: BaseMarkdownFormatTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/format/PackageDocsTest.kt b/core/src/test/kotlin/format/PackageDocsTest.kt
deleted file mode 100644
index c5fe7beb..00000000
--- a/core/src/test/kotlin/format/PackageDocsTest.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.jetbrains.dokka.tests.format
-
-import com.intellij.openapi.Disposable
-import com.intellij.openapi.util.Disposer
-import com.nhaarman.mockito_kotlin.any
-import com.nhaarman.mockito_kotlin.doAnswer
-import com.nhaarman.mockito_kotlin.eq
-import com.nhaarman.mockito_kotlin.mock
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.testApi.assertEqualsIgnoringSeparators
-import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
-import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
-import org.jetbrains.kotlin.config.CompilerConfiguration
-import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
-import org.junit.After
-import org.junit.Assert.assertEquals
-import org.junit.Before
-import org.junit.Test
-import java.io.File
-
-class PackageDocsTest {
-
- private lateinit var testDisposable: Disposable
-
- @Before
- fun setup() {
- testDisposable = Disposer.newDisposable()
- }
-
- @After
- fun cleanup() {
- Disposer.dispose(testDisposable)
- }
-
- fun createPackageDocs(linkResolver: DeclarationLinkResolver?): PackageDocs {
- val environment = KotlinCoreEnvironment.createForTests(testDisposable, CompilerConfiguration.EMPTY, EnvironmentConfigFiles.JVM_CONFIG_FILES)
- return PackageDocs(linkResolver, DokkaConsoleLogger, environment, mock(), mock())
- }
-
- @Test fun verifyParse() {
-
- val docs = createPackageDocs(null)
- docs.parse("testdata/packagedocs/stdlib.md", emptyList())
- val packageContent = docs.packageContent["kotlin"]!!
- val block = (packageContent.children.single() as ContentBlock).children.first() as ContentText
- assertEquals("Core functions and types", block.text)
- }
-
- @Test fun testReferenceLinksInPackageDocs() {
- val mockLinkResolver = mock<DeclarationLinkResolver> {
- val exampleCom = "https://example.com"
- on { tryResolveContentLink(any(), eq(exampleCom)) } doAnswer { ContentExternalLink(exampleCom) }
- }
-
- val mockPackageDescriptor = mock<PackageFragmentDescriptor> {}
-
- val docs = createPackageDocs(mockLinkResolver)
- docs.parse("testdata/packagedocs/referenceLinks.md", listOf(mockPackageDescriptor))
-
- checkMarkdownOutput(docs, "testdata/packagedocs/referenceLinks")
- }
-
- fun checkMarkdownOutput(docs: PackageDocs, expectedFilePrefix: String) {
-
- val generator = FileGenerator(File(""))
-
- val out = StringBuilder()
- val outputBuilder = MarkdownOutputBuilder(
- out,
- FileLocation(generator.root),
- generator,
- KotlinLanguageService(),
- ".md",
- emptyList()
- )
- fun checkOutput(content: Content, filePostfix: String) {
- outputBuilder.appendContent(content)
- val expectedFile = File(expectedFilePrefix + filePostfix)
- assertEqualsIgnoringSeparators(expectedFile, out.toString())
- out.setLength(0)
- }
-
- checkOutput(docs.moduleContent, ".module.md")
-
- docs.packageContent.forEach {
- (name, content) ->
- checkOutput(content, ".$name.md")
- }
-
- }
-}
diff --git a/core/src/test/kotlin/issues/IssuesTest.kt b/core/src/test/kotlin/issues/IssuesTest.kt
deleted file mode 100644
index 80370d5e..00000000
--- a/core/src/test/kotlin/issues/IssuesTest.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package issues
-
-import org.jetbrains.dokka.DocumentationNode
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.junit.Test
-import kotlin.test.assertEquals
-
-abstract class BaseIssuesTest(val analysisPlatform: Platform) {
- val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
-
- @Test
- fun errorClasses() {
- checkSourceExistsAndVerifyModel("testdata/issues/errorClasses.kt",
- modelConfig = ModelConfig(analysisPlatform = analysisPlatform, withJdk = true, withKotlinRuntime = true)) { model ->
- val cls = model.members.single().members.single()
-
- fun DocumentationNode.returnType() = this.details.find { it.kind == NodeKind.Type }?.name
- assertEquals("Test", cls.members[1].returnType())
- assertEquals("Test", cls.members[2].returnType())
- assertEquals("Test", cls.members[3].returnType())
- assertEquals("List", cls.members[4].returnType())
- assertEquals("String", cls.members[5].returnType())
- assertEquals("String", cls.members[6].returnType())
- assertEquals("String", cls.members[7].returnType())
- }
- }
-}
-
-class JSIssuesTest: BaseIssuesTest(Platform.js)
-class JVMIssuesTest: BaseIssuesTest(Platform.jvm)
-class CommonIssuesTest: BaseIssuesTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/model/ClassTest.kt b/core/src/test/kotlin/model/ClassTest.kt
deleted file mode 100644
index b479e59e..00000000
--- a/core/src/test/kotlin/model/ClassTest.kt
+++ /dev/null
@@ -1,322 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.Content
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.RefKind
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.jetbrains.dokka.testApi.toTestString
-import org.jetbrains.dokka.testApi.verifyPackageMember
-import org.junit.Assert
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-abstract class BaseClassTest(val analysisPlatform: Platform) {
- protected val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- @Test fun emptyClass() {
- checkSourceExistsAndVerifyModel("testdata/classes/emptyClass.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals(NodeKind.Class, kind)
- assertEquals("Klass", name)
- assertEquals(Content.Empty, content)
- assertEquals("<init>", members.single().name)
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun emptyObject() {
- checkSourceExistsAndVerifyModel("testdata/classes/emptyObject.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals(NodeKind.Object, kind)
- assertEquals("Obj", name)
- assertEquals(Content.Empty, content)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun classWithConstructor() {
- checkSourceExistsAndVerifyModel("testdata/classes/classWithConstructor.kt", defaultModelConfig) { model ->
- with (model.members.single().members.single()) {
- assertEquals(NodeKind.Class, kind)
- assertEquals("Klass", name)
- assertEquals(Content.Empty, content)
- assertTrue(links.none())
-
- assertEquals(1, members.count())
- with(members.elementAt(0)) {
- assertEquals("<init>", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Constructor, kind)
- assertEquals(3, details.count())
- assertEquals("public", details.elementAt(0).name)
- with(details.elementAt(2)) {
- assertEquals("name", name)
- assertEquals(NodeKind.Parameter, kind)
- assertEquals(Content.Empty, content)
- assertEquals("String", detail(NodeKind.Type).name)
- assertTrue(links.none())
- assertTrue(members.none())
- }
- assertTrue(links.none())
- assertTrue(members.none())
- }
- }
- }
- }
-
- @Test fun classWithFunction() {
- checkSourceExistsAndVerifyModel("testdata/classes/classWithFunction.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals(NodeKind.Class, kind)
- assertEquals("Klass", name)
- assertEquals(Content.Empty, content)
- assertTrue(links.none())
-
- assertEquals(2, members.count())
- with(members.elementAt(0)) {
- assertEquals("<init>", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Constructor, kind)
- assertEquals(2, details.count())
- assertEquals("public", details.elementAt(0).name)
- assertTrue(links.none())
- assertTrue(members.none())
- }
- with(members.elementAt(1)) {
- assertEquals("fn", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Function, kind)
- assertEquals("Unit", detail(NodeKind.Type).name)
- assertTrue(links.none())
- assertTrue(members.none())
- }
- }
- }
- }
-
- @Test fun classWithProperty() {
- checkSourceExistsAndVerifyModel("testdata/classes/classWithProperty.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals(NodeKind.Class, kind)
- assertEquals("Klass", name)
- assertEquals(Content.Empty, content)
- assertTrue(links.none())
-
- assertEquals(2, members.count())
- with(members.elementAt(0)) {
- assertEquals("<init>", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Constructor, kind)
- assertEquals(2, details.count())
- assertEquals("public", details.elementAt(0).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- with(members.elementAt(1)) {
- assertEquals("name", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Property, kind)
- assertEquals("String", detail(NodeKind.Type).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
- }
-
- @Test fun classWithCompanionObject() {
- checkSourceExistsAndVerifyModel("testdata/classes/classWithCompanionObject.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals(NodeKind.Class, kind)
- assertEquals("Klass", name)
- assertEquals(Content.Empty, content)
- assertTrue(links.none())
-
- assertEquals(3, members.count())
- with(members.elementAt(0)) {
- assertEquals("<init>", name)
- assertEquals(Content.Empty, content)
- }
- with(members.elementAt(1)) {
- assertEquals("x", name)
- assertEquals(NodeKind.CompanionObjectProperty, kind)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- with(members.elementAt(2)) {
- assertEquals("foo", name)
- assertEquals(NodeKind.CompanionObjectFunction, kind)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
- }
-
- @Test fun dataClass() {
- verifyPackageMember("testdata/classes/dataClass.kt", defaultModelConfig) { cls ->
- val modifiers = cls.details(NodeKind.Modifier).map { it.name }
- assertTrue("data" in modifiers)
- }
- }
-
- @Test fun sealedClass() {
- verifyPackageMember("testdata/classes/sealedClass.kt", defaultModelConfig) { cls ->
- val modifiers = cls.details(NodeKind.Modifier).map { it.name }
- assertEquals(1, modifiers.count { it == "sealed" })
- }
- }
-
- @Test fun annotatedClassWithAnnotationParameters() {
- checkSourceExistsAndVerifyModel(
- "testdata/classes/annotatedClassWithAnnotationParameters.kt",
- defaultModelConfig
- ) { model ->
- with(model.members.single().members.single()) {
- with(deprecation!!) {
- assertEquals("Deprecated", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Annotation, kind)
- assertEquals(1, details.count())
- with(details[0]) {
- assertEquals(NodeKind.Parameter, kind)
- assertEquals(1, details.count())
- with(details[0]) {
- assertEquals(NodeKind.Value, kind)
- assertEquals("\"should no longer be used\"", name)
- }
- }
- }
- }
- }
- }
-
- @Test fun notOpenClass() {
- checkSourceExistsAndVerifyModel("testdata/classes/notOpenClass.kt", defaultModelConfig) { model ->
- with(model.members.single().members.first { it.name == "D"}.members.first { it.name == "f" }) {
- val modifiers = details(NodeKind.Modifier)
- assertEquals(2, modifiers.size)
- assertEquals("final", modifiers[1].name)
-
- val overrideReferences = references(RefKind.Override)
- assertEquals(1, overrideReferences.size)
- }
- }
- }
-
- @Test fun indirectOverride() {
- checkSourceExistsAndVerifyModel("testdata/classes/indirectOverride.kt", defaultModelConfig) { model ->
- with(model.members.single().members.first { it.name == "E"}.members.first { it.name == "foo" }) {
- val modifiers = details(NodeKind.Modifier)
- assertEquals(2, modifiers.size)
- assertEquals("final", modifiers[1].name)
-
- val overrideReferences = references(RefKind.Override)
- assertEquals(1, overrideReferences.size)
- }
- }
- }
-
- @Test fun innerClass() {
- verifyPackageMember("testdata/classes/innerClass.kt", defaultModelConfig) { cls ->
- val innerClass = cls.members.single { it.name == "D" }
- val modifiers = innerClass.details(NodeKind.Modifier)
- assertEquals(3, modifiers.size)
- assertEquals("inner", modifiers[2].name)
- }
- }
-
- @Test fun companionObjectExtension() {
- checkSourceExistsAndVerifyModel("testdata/classes/companionObjectExtension.kt", defaultModelConfig) { model ->
- val pkg = model.members.single()
- val cls = pkg.members.single { it.name == "Foo" }
- val extensions = cls.extensions.filter { it.kind == NodeKind.CompanionObjectProperty }
- assertEquals(1, extensions.size)
- }
- }
-
- @Test fun secondaryConstructor() {
- verifyPackageMember("testdata/classes/secondaryConstructor.kt", defaultModelConfig) { cls ->
- val constructors = cls.members(NodeKind.Constructor)
- assertEquals(2, constructors.size)
- with (constructors.first { it.details(NodeKind.Parameter).size == 1}) {
- assertEquals("<init>", name)
- assertEquals("This is a secondary constructor.", summary.toTestString())
- }
- }
- }
-
- @Test fun sinceKotlin() {
- checkSourceExistsAndVerifyModel("testdata/classes/sinceKotlin.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("1.1", sinceKotlin)
- }
- }
- }
-
- @Test fun privateCompanionObject() {
- checkSourceExistsAndVerifyModel(
- "testdata/classes/privateCompanionObject.kt",
- modelConfig = ModelConfig(analysisPlatform = analysisPlatform, includeNonPublic = false)
- ) { model ->
- with(model.members.single().members.single()) {
- assertEquals(0, members(NodeKind.CompanionObjectFunction).size)
- assertEquals(0, members(NodeKind.CompanionObjectProperty).size)
- }
- }
- }
-
-}
-
-class JSClassTest: BaseClassTest(Platform.js) {}
-
-class JVMClassTest: BaseClassTest(Platform.jvm) {
- @Test
- fun annotatedClass() {
- verifyPackageMember("testdata/classes/annotatedClass.kt", ModelConfig(
- analysisPlatform = analysisPlatform,
- withKotlinRuntime = true
- )
- ) { cls ->
- Assert.assertEquals(1, cls.annotations.count())
- with(cls.annotations[0]) {
- Assert.assertEquals("Strictfp", name)
- Assert.assertEquals(Content.Empty, content)
- Assert.assertEquals(NodeKind.Annotation, kind)
- }
- }
- }
-
-
- @Test fun javaAnnotationClass() {
- checkSourceExistsAndVerifyModel(
- "testdata/classes/javaAnnotationClass.kt",
- modelConfig = ModelConfig(analysisPlatform = analysisPlatform, withJdk = true)
- ) { model ->
- with(model.members.single().members.single()) {
- Assert.assertEquals(1, annotations.count())
- with(annotations[0]) {
- Assert.assertEquals("Retention", name)
- Assert.assertEquals(Content.Empty, content)
- Assert.assertEquals(NodeKind.Annotation, kind)
- with(details[0]) {
- Assert.assertEquals(NodeKind.Parameter, kind)
- Assert.assertEquals(1, details.count())
- with(details[0]) {
- Assert.assertEquals(NodeKind.Value, kind)
- Assert.assertEquals("RetentionPolicy.SOURCE", name)
- }
- }
- }
- }
- }
- }
-
-}
-
-class CommonClassTest: BaseClassTest(Platform.common) {} \ No newline at end of file
diff --git a/core/src/test/kotlin/model/CommentTest.kt b/core/src/test/kotlin/model/CommentTest.kt
deleted file mode 100644
index b94e9d0c..00000000
--- a/core/src/test/kotlin/model/CommentTest.kt
+++ /dev/null
@@ -1,195 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.Content
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.assertEqualsIgnoringSeparators
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.jetbrains.dokka.testApi.toTestString
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-abstract class BaseCommentTest(val analysisPlatform: Platform) {
- val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- @Test fun codeBlockComment() {
- checkSourceExistsAndVerifyModel("testdata/comments/codeBlockComment.kt", defaultModelConfig) { model ->
- with(model.members.single().members.first()) {
- assertEqualsIgnoringSeparators("""[code lang=brainfuck]
- |
- |++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
- |
- |[/code]
- |""".trimMargin(),
- content.toTestString())
- }
- with(model.members.single().members.last()) {
- assertEqualsIgnoringSeparators("""[code]
- |
- |a + b - c
- |
- |[/code]
- |""".trimMargin(),
- content.toTestString())
- }
- }
- }
-
- @Test fun emptyDoc() {
- checkSourceExistsAndVerifyModel("testdata/comments/emptyDoc.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals(Content.Empty, content)
- }
- }
- }
-
- @Test fun emptyDocButComment() {
- checkSourceExistsAndVerifyModel("testdata/comments/emptyDocButComment.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals(Content.Empty, content)
- }
- }
- }
-
- @Test fun multilineDoc() {
- checkSourceExistsAndVerifyModel("testdata/comments/multilineDoc.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("doc1", content.summary.toTestString())
- assertEquals("doc2\ndoc3", content.description.toTestString())
- }
- }
- }
-
- @Test fun multilineDocWithComment() {
- checkSourceExistsAndVerifyModel("testdata/comments/multilineDocWithComment.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("doc1", content.summary.toTestString())
- assertEquals("doc2\ndoc3", content.description.toTestString())
- }
- }
- }
-
- @Test fun oneLineDoc() {
- checkSourceExistsAndVerifyModel("testdata/comments/oneLineDoc.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("doc", content.summary.toTestString())
- }
- }
- }
-
- @Test fun oneLineDocWithComment() {
- checkSourceExistsAndVerifyModel("testdata/comments/oneLineDocWithComment.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("doc", content.summary.toTestString())
- }
- }
- }
-
- @Test fun oneLineDocWithEmptyLine() {
- checkSourceExistsAndVerifyModel("testdata/comments/oneLineDocWithEmptyLine.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("doc", content.summary.toTestString())
- }
- }
- }
-
- @Test fun emptySection() {
- checkSourceExistsAndVerifyModel("testdata/comments/emptySection.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Summary", content.summary.toTestString())
- assertEquals(1, content.sections.count())
- with (content.findSectionByTag("one")!!) {
- assertEquals("One", tag)
- assertEquals("", toTestString())
- }
- }
- }
- }
-
- @Test fun quotes() {
- checkSourceExistsAndVerifyModel("testdata/comments/quotes.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("it's \"useful\"", content.summary.toTestString())
- }
- }
- }
-
- @Test fun section1() {
- checkSourceExistsAndVerifyModel("testdata/comments/section1.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Summary", content.summary.toTestString())
- assertEquals(1, content.sections.count())
- with (content.findSectionByTag("one")!!) {
- assertEquals("One", tag)
- assertEquals("section one", toTestString())
- }
- }
- }
- }
-
- @Test fun section2() {
- checkSourceExistsAndVerifyModel("testdata/comments/section2.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Summary", content.summary.toTestString())
- assertEquals(2, content.sections.count())
- with (content.findSectionByTag("one")!!) {
- assertEquals("One", tag)
- assertEquals("section one", toTestString())
- }
- with (content.findSectionByTag("two")!!) {
- assertEquals("Two", tag)
- assertEquals("section two", toTestString())
- }
- }
- }
- }
-
- @Test fun multilineSection() {
- checkSourceExistsAndVerifyModel("testdata/comments/multilineSection.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Summary", content.summary.toTestString())
- assertEquals(1, content.sections.count())
- with (content.findSectionByTag("one")!!) {
- assertEquals("One", tag)
- assertEquals("""line one
-line two""", toTestString())
- }
- }
- }
- }
-
- @Test fun directive() {
- checkSourceExistsAndVerifyModel("testdata/comments/directive.kt", defaultModelConfig) { model ->
- with(model.members.single().members.first()) {
- assertEquals("Summary", content.summary.toTestString())
- with (content.description) {
- assertEqualsIgnoringSeparators("""
- |[code lang=kotlin]
- |if (true) {
- | println(property)
- |}
- |[/code]
- |[code lang=kotlin]
- |if (true) {
- | println(property)
- |}
- |[/code]
- |[code lang=kotlin]
- |if (true) {
- | println(property)
- |}
- |[/code]
- |[code lang=kotlin]
- |if (true) {
- | println(property)
- |}
- |[/code]
- |""".trimMargin(), toTestString())
- }
- }
- }
- }
-}
-
-class JSCommentTest: BaseCommentTest(Platform.js)
-class JVMCommentTest: BaseCommentTest(Platform.jvm)
-class CommonCommentTest: BaseCommentTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/model/FunctionTest.kt b/core/src/test/kotlin/model/FunctionTest.kt
deleted file mode 100644
index 9900446a..00000000
--- a/core/src/test/kotlin/model/FunctionTest.kt
+++ /dev/null
@@ -1,284 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.Content
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.jetbrains.dokka.testApi.toTestString
-import org.jetbrains.dokka.testApi.verifyPackageMember
-import org.junit.Assert
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-abstract class BaseFunctionTest(val analysisPlatform: Platform) {
- protected val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- @Test fun function() {
- checkSourceExistsAndVerifyModel("testdata/functions/function.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("fn", name)
- assertEquals(NodeKind.Function, kind)
- assertEquals("Function fn", content.summary.toTestString())
- assertEquals("Unit", detail(NodeKind.Type).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun functionWithReceiver() {
- checkSourceExistsAndVerifyModel("testdata/functions/functionWithReceiver.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("kotlin.String", name)
- assertEquals(NodeKind.ExternalClass, kind)
- assertEquals(2, members.count())
- with(members[0]) {
- assertEquals("fn", name)
- assertEquals(NodeKind.Function, kind)
- assertEquals("Function with receiver", content.summary.toTestString())
- assertEquals("public", details.elementAt(0).name)
- assertEquals("final", details.elementAt(1).name)
- with(details.elementAt(3)) {
- assertEquals("<this>", name)
- assertEquals(NodeKind.Receiver, kind)
- assertEquals(Content.Empty, content)
- assertEquals("String", details.single().name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- assertEquals("Unit", details.elementAt(4).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- with(members[1]) {
- assertEquals("fn", name)
- assertEquals(NodeKind.Function, kind)
- }
- }
- }
- }
-
- @Test fun genericFunction() {
- checkSourceExistsAndVerifyModel("testdata/functions/genericFunction.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("generic", name)
- assertEquals(NodeKind.Function, kind)
- assertEquals("generic function", content.summary.toTestString())
-
- assertEquals("private", details.elementAt(0).name)
- assertEquals("final", details.elementAt(1).name)
- with(details.elementAt(3)) {
- assertEquals("T", name)
- assertEquals(NodeKind.TypeParameter, kind)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.none())
- }
- assertEquals("Unit", details.elementAt(4).name)
-
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
- @Test fun genericFunctionWithConstraints() {
- checkSourceExistsAndVerifyModel("testdata/functions/genericFunctionWithConstraints.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("generic", name)
- assertEquals(NodeKind.Function, kind)
- assertEquals("generic function", content.summary.toTestString())
-
- val functionDetails = details
- assertEquals("public", functionDetails.elementAt(0).name)
- assertEquals("final", functionDetails.elementAt(1).name)
- with(functionDetails.elementAt(3)) {
- assertEquals("T", name)
- assertEquals(NodeKind.TypeParameter, kind)
- assertEquals(Content.Empty, content)
- with(details.single()) {
- assertEquals("R", name)
- assertEquals(NodeKind.UpperBound, kind)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.singleOrNull() == functionDetails.elementAt(4))
- }
- assertTrue(members.none())
- assertTrue(links.none())
- }
- with(functionDetails.elementAt(4)) {
- assertEquals("R", name)
- assertEquals(NodeKind.TypeParameter, kind)
- assertEquals(Content.Empty, content)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- assertEquals("Unit", functionDetails.elementAt(5).name)
-
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun functionWithParams() {
- checkSourceExistsAndVerifyModel("testdata/functions/functionWithParams.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("function", name)
- assertEquals(NodeKind.Function, kind)
- assertEquals("Multiline", content.summary.toTestString())
- assertEquals("""Function
-Documentation""", content.description.toTestString())
-
- assertEquals("public", details.elementAt(0).name)
- assertEquals("final", details.elementAt(1).name)
- with(details.elementAt(3)) {
- assertEquals("x", name)
- assertEquals(NodeKind.Parameter, kind)
- assertEquals("parameter", content.summary.toTestString())
- assertEquals("Int", detail(NodeKind.Type).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- assertEquals("Unit", details.elementAt(4).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun functionWithNotDocumentedAnnotation() {
- verifyPackageMember("testdata/functions/functionWithNotDocumentedAnnotation.kt", defaultModelConfig) { func ->
- assertEquals(0, func.annotations.count())
- }
- }
-
- @Test fun inlineFunction() {
- verifyPackageMember("testdata/functions/inlineFunction.kt", defaultModelConfig) { func ->
- val modifiers = func.details(NodeKind.Modifier).map { it.name }
- assertTrue("inline" in modifiers)
- }
- }
-
- @Test fun suspendFunction() {
- verifyPackageMember("testdata/functions/suspendFunction.kt") { func ->
- val modifiers = func.details(NodeKind.Modifier).map { it.name }
- assertTrue("suspend" in modifiers)
- }
- }
-
- @Test fun suspendInlineFunctionOrder() {
- verifyPackageMember("testdata/functions/suspendInlineFunction.kt") { func ->
- val modifiers = func.details(NodeKind.Modifier).map { it.name }.filter {
- it == "suspend" || it == "inline"
- }
-
- assertEquals(listOf("suspend", "inline"), modifiers)
- }
- }
-
- @Test fun inlineSuspendFunctionOrderChanged() {
- verifyPackageMember("testdata/functions/inlineSuspendFunction.kt") { func ->
- val modifiers = func.details(NodeKind.Modifier).map { it.name }.filter {
- it == "suspend" || it == "inline"
- }
-
- assertEquals(listOf("suspend", "inline"), modifiers)
- }
- }
-
- @Test fun functionWithAnnotatedParam() {
- checkSourceExistsAndVerifyModel("testdata/functions/functionWithAnnotatedParam.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single { it.name == "function" }) {
- with(details(NodeKind.Parameter).first()) {
- assertEquals(1, annotations.count())
- with(annotations[0]) {
- assertEquals("Fancy", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Annotation, kind)
- }
- }
- }
- }
- }
-
- @Test fun functionWithNoinlineParam() {
- verifyPackageMember("testdata/functions/functionWithNoinlineParam.kt", defaultModelConfig) { func ->
- with(func.details(NodeKind.Parameter).first()) {
- val modifiers = details(NodeKind.Modifier).map { it.name }
- assertTrue("noinline" in modifiers)
- }
- }
- }
-
- @Test fun annotatedFunctionWithAnnotationParameters() {
- checkSourceExistsAndVerifyModel(
- "testdata/functions/annotatedFunctionWithAnnotationParameters.kt",
- defaultModelConfig
- ) { model ->
- with(model.members.single().members.single { it.name == "f" }) {
- assertEquals(1, annotations.count())
- with(annotations[0]) {
- assertEquals("Fancy", name)
- assertEquals(Content.Empty, content)
- assertEquals(NodeKind.Annotation, kind)
- assertEquals(1, details.count())
- with(details[0]) {
- assertEquals(NodeKind.Parameter, kind)
- assertEquals(1, details.count())
- with(details[0]) {
- assertEquals(NodeKind.Value, kind)
- assertEquals("1", name)
- }
- }
- }
- }
- }
- }
-
- @Test fun functionWithDefaultParameter() {
- checkSourceExistsAndVerifyModel("testdata/functions/functionWithDefaultParameter.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- with(details.elementAt(3)) {
- val value = details(NodeKind.Value)
- assertEquals(1, value.count())
- with(value[0]) {
- assertEquals("\"\"", name)
- }
- }
- }
- }
- }
-
- @Test fun sinceKotlin() {
- checkSourceExistsAndVerifyModel("testdata/functions/sinceKotlin.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("1.1", sinceKotlin)
- }
- }
- }
-}
-
-class JSFunctionTest: BaseFunctionTest(Platform.js)
-
-class JVMFunctionTest: BaseFunctionTest(Platform.jvm) {
- @Test
- fun annotatedFunction() {
- verifyPackageMember("testdata/functions/annotatedFunction.kt", ModelConfig(
- analysisPlatform = Platform.jvm,
- withKotlinRuntime = true
- )) { func ->
- Assert.assertEquals(1, func.annotations.count())
- with(func.annotations[0]) {
- Assert.assertEquals("Strictfp", name)
- Assert.assertEquals(Content.Empty, content)
- Assert.assertEquals(NodeKind.Annotation, kind)
- }
- }
- }
-
-}
-
-class CommonFunctionTest: BaseFunctionTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/model/JavaTest.kt b/core/src/test/kotlin/model/JavaTest.kt
deleted file mode 100644
index 018ab089..00000000
--- a/core/src/test/kotlin/model/JavaTest.kt
+++ /dev/null
@@ -1,213 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.RefKind
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.toTestString
-import org.jetbrains.dokka.testApi.verifyJavaPackageMember
-import org.junit.Assert.*
-import org.junit.Ignore
-import org.junit.Test
-
-public class JavaTest {
- private val defaultModelConfig = ModelConfig(analysisPlatform = Platform.jvm)
- @Test fun function() {
- verifyJavaPackageMember("testdata/java/member.java", defaultModelConfig) { cls ->
- assertEquals("Test", cls.name)
- assertEquals(NodeKind.Class, cls.kind)
- with(cls.members(NodeKind.Function).single()) {
- assertEquals("fn", name)
- assertEquals("Summary for Function", content.summary.toTestString().trimEnd())
- assertEquals(3, content.sections.size)
- with(content.sections[0]) {
- assertEquals("Parameters", tag)
- assertEquals("name", subjectName)
- assertEquals("render(Type:String,SUMMARY): is String parameter", toTestString())
- }
- with(content.sections[1]) {
- assertEquals("Parameters", tag)
- assertEquals("value", subjectName)
- assertEquals("render(Type:Int,SUMMARY): is int parameter", toTestString())
- }
- with(content.sections[2]) {
- assertEquals("Author", tag)
- assertEquals("yole", toTestString())
- }
- assertEquals("Unit", detail(NodeKind.Type).name)
- assertTrue(members.none())
- assertTrue(links.none())
- with(details.first { it.name == "name" }) {
- assertEquals(NodeKind.Parameter, kind)
- assertEquals("String", detail(NodeKind.Type).name)
- }
- with(details.first { it.name == "value" }) {
- assertEquals(NodeKind.Parameter, kind)
- assertEquals("Int", detail(NodeKind.Type).name)
- }
- }
- }
- }
-
- @Test fun memberWithModifiers() {
- verifyJavaPackageMember("testdata/java/memberWithModifiers.java", defaultModelConfig) { cls ->
- val modifiers = cls.details(NodeKind.Modifier).map { it.name }
- assertTrue("abstract" in modifiers)
- with(cls.members.single { it.name == "fn" }) {
- assertEquals("protected", details[0].name)
- }
- with(cls.members.single { it.name == "openFn" }) {
- assertEquals("open", details[1].name)
- }
- }
- }
-
- @Test fun superClass() {
- verifyJavaPackageMember("testdata/java/superClass.java", defaultModelConfig) { cls ->
- val superTypes = cls.details(NodeKind.Supertype)
- assertEquals(2, superTypes.size)
- assertEquals("Exception", superTypes[0].name)
- assertEquals("Cloneable", superTypes[1].name)
- }
- }
-
- @Test fun arrayType() {
- verifyJavaPackageMember("testdata/java/arrayType.java", defaultModelConfig) { cls ->
- with(cls.members(NodeKind.Function).single()) {
- val type = detail(NodeKind.Type)
- assertEquals("Array", type.name)
- assertEquals("String", type.detail(NodeKind.Type).name)
- with(details(NodeKind.Parameter).single()) {
- val parameterType = detail(NodeKind.Type)
- assertEquals("IntArray", parameterType.name)
- }
- }
- }
- }
-
- @Test fun typeParameter() {
- verifyJavaPackageMember("testdata/java/typeParameter.java", defaultModelConfig) { cls ->
- val typeParameters = cls.details(NodeKind.TypeParameter)
- with(typeParameters.single()) {
- assertEquals("T", name)
- with(detail(NodeKind.UpperBound)) {
- assertEquals("Comparable", name)
- assertEquals("T", detail(NodeKind.Type).name)
- }
- }
- with(cls.members(NodeKind.Function).single()) {
- val methodTypeParameters = details(NodeKind.TypeParameter)
- with(methodTypeParameters.single()) {
- assertEquals("E", name)
- }
- }
- }
- }
-
- @Test fun constructors() {
- verifyJavaPackageMember("testdata/java/constructors.java", defaultModelConfig) { cls ->
- val constructors = cls.members(NodeKind.Constructor)
- assertEquals(2, constructors.size)
- with(constructors[0]) {
- assertEquals("<init>", name)
- }
- }
- }
-
- @Test fun innerClass() {
- verifyJavaPackageMember("testdata/java/InnerClass.java", defaultModelConfig) { cls ->
- val innerClass = cls.members(NodeKind.Class).single()
- assertEquals("D", innerClass.name)
- }
- }
-
- @Test fun varargs() {
- verifyJavaPackageMember("testdata/java/varargs.java", defaultModelConfig) { cls ->
- val fn = cls.members(NodeKind.Function).single()
- val param = fn.detail(NodeKind.Parameter)
- assertEquals("vararg", param.details(NodeKind.Modifier).first().name)
- val psiType = param.detail(NodeKind.Type)
- assertEquals("String", psiType.name)
- assertTrue(psiType.details(NodeKind.Type).isEmpty())
- }
- }
-
- @Test fun fields() {
- verifyJavaPackageMember("testdata/java/field.java", defaultModelConfig) { cls ->
- val i = cls.members(NodeKind.Property).single { it.name == "i" }
- assertEquals("Int", i.detail(NodeKind.Type).name)
- assertTrue("var" in i.details(NodeKind.Modifier).map { it.name })
-
- val s = cls.members(NodeKind.Property).single { it.name == "s" }
- assertEquals("String", s.detail(NodeKind.Type).name)
- assertFalse("var" in s.details(NodeKind.Modifier).map { it.name })
- assertTrue("static" in s.details(NodeKind.Modifier).map { it.name })
- }
- }
-
- @Test fun staticMethod() {
- verifyJavaPackageMember("testdata/java/staticMethod.java", defaultModelConfig) { cls ->
- val m = cls.members(NodeKind.Function).single { it.name == "foo" }
- assertTrue("static" in m.details(NodeKind.Modifier).map { it.name })
- }
- }
-
- /**
- * `@suppress` not supported in Java!
- *
- * [Proposed tags](https://www.oracle.com/technetwork/java/javase/documentation/proposed-tags-142378.html)
- * Proposed tag `@exclude` for it, but not supported yet
- */
- @Ignore("@suppress not supported in Java!") @Test fun suppressTag() {
- verifyJavaPackageMember("testdata/java/suppressTag.java", defaultModelConfig) { cls ->
- assertEquals(1, cls.members(NodeKind.Function).size)
- }
- }
-
- @Test fun annotatedAnnotation() {
- verifyJavaPackageMember("testdata/java/annotatedAnnotation.java", defaultModelConfig) { cls ->
- assertEquals(1, cls.annotations.size)
- with(cls.annotations[0]) {
- assertEquals(1, details.count())
- with(details[0]) {
- assertEquals(NodeKind.Parameter, kind)
- assertEquals(1, details.count())
- with(details[0]) {
- assertEquals(NodeKind.Value, kind)
- assertEquals("[AnnotationTarget.FIELD, AnnotationTarget.CLASS, AnnotationTarget.FILE, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER]", name)
- }
- }
- }
- }
- }
-
- @Test fun deprecation() {
- verifyJavaPackageMember("testdata/java/deprecation.java", defaultModelConfig) { cls ->
- val fn = cls.members(NodeKind.Function).single()
- assertEquals("This should no longer be used", fn.deprecation!!.content.toTestString())
- }
- }
-
- @Test fun javaLangObject() {
- verifyJavaPackageMember("testdata/java/javaLangObject.java", defaultModelConfig) { cls ->
- val fn = cls.members(NodeKind.Function).single()
- assertEquals("Any", fn.detail(NodeKind.Type).name)
- }
- }
-
- @Test fun enumValues() {
- verifyJavaPackageMember("testdata/java/enumValues.java", defaultModelConfig) { cls ->
- val superTypes = cls.details(NodeKind.Supertype)
- assertEquals(1, superTypes.size)
- assertEquals(1, cls.members(NodeKind.EnumItem).size)
- }
- }
-
- @Test fun inheritorLinks() {
- verifyJavaPackageMember("testdata/java/InheritorLinks.java", defaultModelConfig) { cls ->
- val fooClass = cls.members.single { it.name == "Foo" }
- val inheritors = fooClass.references(RefKind.Inheritor)
- assertEquals(1, inheritors.size)
- }
- }
-}
diff --git a/core/src/test/kotlin/model/KotlinAsJavaTest.kt b/core/src/test/kotlin/model/KotlinAsJavaTest.kt
deleted file mode 100644
index 80ff95bd..00000000
--- a/core/src/test/kotlin/model/KotlinAsJavaTest.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.DocumentationModule
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.RefKind
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.jetbrains.dokka.testApi.toTestString
-import org.junit.Assert
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-class KotlinAsJavaTest {
- @Test fun function() {
- verifyModelAsJava("testdata/functions/function.kt") { model ->
- val pkg = model.members.single()
-
- val facadeClass = pkg.members.single { it.name == "FunctionKt" }
- assertEquals(NodeKind.Class, facadeClass.kind)
-
- val fn = facadeClass.members.single()
- assertEquals("fn", fn.name)
- assertEquals(NodeKind.Function, fn.kind)
- }
- }
-
- @Test fun propertyWithComment() {
- verifyModelAsJava("testdata/comments/oneLineDoc.kt") { model ->
- val facadeClass = model.members.single().members.single { it.name == "OneLineDocKt" }
- val getter = facadeClass.members.single { it.name == "getProperty" }
- assertEquals(NodeKind.Function, getter.kind)
- assertEquals("doc", getter.content.summary.toTestString())
- }
- }
-
-
- @Test fun constants() {
- verifyModelAsJava("testdata/java/constants.java") { cls ->
- selectNodes(cls) {
- subgraphOf(RefKind.Member)
- matching { it.name == "constStr" || it.name == "refConst" }
- }.forEach {
- assertEquals("In $it", "\"some value\"", it.detailOrNull(NodeKind.Value)?.name)
- }
- val nullConstNode = selectNodes(cls) {
- subgraphOf(RefKind.Member)
- withName("nullConst")
- }.single()
-
- Assert.assertNull(nullConstNode.detailOrNull(NodeKind.Value))
- }
- }
-}
-
-fun verifyModelAsJava(source: String,
- modelConfig: ModelConfig = ModelConfig(),
- verifier: (DocumentationModule) -> Unit) {
- checkSourceExistsAndVerifyModel(
- source,
- modelConfig = ModelConfig(
- withJdk = modelConfig.withJdk,
- withKotlinRuntime = modelConfig.withKotlinRuntime,
- format = "html-as-java",
- analysisPlatform = Platform.jvm),
- verifier = verifier
- )
-}
diff --git a/core/src/test/kotlin/model/LinkTest.kt b/core/src/test/kotlin/model/LinkTest.kt
deleted file mode 100644
index 08e27db8..00000000
--- a/core/src/test/kotlin/model/LinkTest.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.ContentBlock
-import org.jetbrains.dokka.ContentNodeLazyLink
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.jetbrains.dokka.testApi.toTestString
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-abstract class BaseLinkTest(val analysisPlatform: Platform) {
- private val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- @Test fun linkToSelf() {
- checkSourceExistsAndVerifyModel("testdata/links/linkToSelf.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Foo", name)
- assertEquals(NodeKind.Class, kind)
- assertEquals("This is link to [Foo -> Class:Foo]", content.summary.toTestString())
- }
- }
- }
-
- @Test fun linkToExternalSite() {
- checkSourceExistsAndVerifyModel("testdata/links/linkToExternalSite.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Foo", name)
- assertEquals(NodeKind.Class, kind)
- assertEquals("This is link to http://example.com/#example", content.summary.toTestString())
- }
- }
- }
-
- @Test fun linkToMember() {
- checkSourceExistsAndVerifyModel("testdata/links/linkToMember.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Foo", name)
- assertEquals(NodeKind.Class, kind)
- assertEquals("This is link to [member -> Function:member]", content.summary.toTestString())
- }
- }
- }
-
- @Test fun linkToConstantWithUnderscores() {
- checkSourceExistsAndVerifyModel("testdata/links/linkToConstantWithUnderscores.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Foo", name)
- assertEquals(NodeKind.Class, kind)
- assertEquals("This is link to [MY_CONSTANT_VALUE -> CompanionObjectProperty:MY_CONSTANT_VALUE]", content.summary.toTestString())
- }
- }
- }
-
- @Test fun linkToQualifiedMember() {
- checkSourceExistsAndVerifyModel("testdata/links/linkToQualifiedMember.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Foo", name)
- assertEquals(NodeKind.Class, kind)
- assertEquals("This is link to [Foo.member -> Function:member]", content.summary.toTestString())
- }
- }
- }
-
- @Test fun linkToParam() {
- checkSourceExistsAndVerifyModel("testdata/links/linkToParam.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("Foo", name)
- assertEquals(NodeKind.Function, kind)
- assertEquals("This is link to [param -> Parameter:param]", content.summary.toTestString())
- }
- }
- }
-
- @Test fun linkToPackage() {
- checkSourceExistsAndVerifyModel("testdata/links/linkToPackage.kt", defaultModelConfig) { model ->
- val packageNode = model.members.single()
- with(packageNode) {
- assertEquals(this.name, "test.magic")
- }
- with(packageNode.members.single()) {
- assertEquals("Magic", name)
- assertEquals(NodeKind.Class, kind)
- assertEquals("Basic implementations of [Magic -> Class:Magic] are located in [test.magic -> Package:test.magic] package", content.summary.toTestString())
- assertEquals(packageNode, ((this.content.summary as ContentBlock).children.filterIsInstance<ContentNodeLazyLink>().last()).lazyNode.invoke())
- }
- }
- }
-
-}
-
-class JSLinkTest: BaseLinkTest(Platform.js)
-class JVMLinkTest: BaseLinkTest(Platform.jvm)
-class CommonLinkTest: BaseLinkTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/model/PackageTest.kt b/core/src/test/kotlin/model/PackageTest.kt
deleted file mode 100644
index 0afbbb5d..00000000
--- a/core/src/test/kotlin/model/PackageTest.kt
+++ /dev/null
@@ -1,139 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.jetbrains.dokka.testApi.verifyModel
-import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
-import org.junit.Assert.*
-import org.junit.Test
-
-abstract class BasePackageTest(val analysisPlatform: Platform) {
- val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- @Test fun rootPackage() {
- checkSourceExistsAndVerifyModel("testdata/packages/rootPackage.kt", defaultModelConfig) { model ->
- with(model.members.single()) {
- assertEquals(NodeKind.Package, kind)
- assertEquals("", name)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun simpleNamePackage() {
- checkSourceExistsAndVerifyModel("testdata/packages/simpleNamePackage.kt", defaultModelConfig) { model ->
- with(model.members.single()) {
- assertEquals(NodeKind.Package, kind)
- assertEquals("simple", name)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun dottedNamePackage() {
- checkSourceExistsAndVerifyModel("testdata/packages/dottedNamePackage.kt", defaultModelConfig) { model ->
- with(model.members.single()) {
- assertEquals(NodeKind.Package, kind)
- assertEquals("dot.name", name)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun multipleFiles() {
- verifyModel(
- ModelConfig(
- roots = arrayOf(
- KotlinSourceRoot("testdata/packages/dottedNamePackage.kt", false),
- KotlinSourceRoot("testdata/packages/simpleNamePackage.kt", false)
- ),
- analysisPlatform = analysisPlatform
- )
- ) { model ->
- assertEquals(2, model.members.count())
- with(model.members.single { it.name == "simple" }) {
- assertEquals(NodeKind.Package, kind)
- assertEquals("simple", name)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.none())
- }
- with(model.members.single { it.name == "dot.name" }) {
- assertEquals(NodeKind.Package, kind)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun multipleFilesSamePackage() {
- verifyModel(
- ModelConfig(
- roots = arrayOf(
- KotlinSourceRoot("testdata/packages/simpleNamePackage.kt", false),
- KotlinSourceRoot("testdata/packages/simpleNamePackage2.kt", false)
- ),
- analysisPlatform = analysisPlatform
- )
- ) { model ->
- assertEquals(1, model.members.count())
- with(model.members.elementAt(0)) {
- assertEquals(NodeKind.Package, kind)
- assertEquals("simple", name)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun classAtPackageLevel() {
- verifyModel(
- ModelConfig(
- roots = arrayOf(KotlinSourceRoot("testdata/packages/classInPackage.kt", false)),
- analysisPlatform = analysisPlatform
- )
- ) { model ->
- assertEquals(1, model.members.count())
- with(model.members.elementAt(0)) {
- assertEquals(NodeKind.Package, kind)
- assertEquals("simple.name", name)
- assertEquals(Content.Empty, content)
- assertTrue(details.none())
- assertEquals(1, members.size)
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun suppressAtPackageLevel() {
- verifyModel(
- ModelConfig(
- roots = arrayOf(KotlinSourceRoot("testdata/packages/classInPackage.kt", false)),
- perPackageOptions = listOf(
- org.jetbrains.dokka.testApi.PackageOptionsImpl(prefix = "simple.name", suppress = true)
- ),
- analysisPlatform = analysisPlatform
- )
- ) { model ->
- assertEquals(0, model.members.count())
- }
- }
-}
-
-class JSPackageTest : BasePackageTest(Platform.js)
-class JVMPackageTest : BasePackageTest(Platform.jvm)
-class CommonPackageTest : BasePackageTest(Platform.common) \ No newline at end of file
diff --git a/core/src/test/kotlin/model/PropertyTest.kt b/core/src/test/kotlin/model/PropertyTest.kt
deleted file mode 100644
index bce3c585..00000000
--- a/core/src/test/kotlin/model/PropertyTest.kt
+++ /dev/null
@@ -1,131 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import org.jetbrains.dokka.*
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.junit.Assert
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Test
-
-abstract class BasePropertyTest(val analysisPlatform: Platform) {
-
- protected val defaultModelConfig = ModelConfig(analysisPlatform = analysisPlatform)
- @Test fun valueProperty() {
- checkSourceExistsAndVerifyModel("testdata/properties/valueProperty.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("property", name)
- assertEquals(NodeKind.Property, kind)
- assertEquals(Content.Empty, content)
- assertEquals("String", detail(NodeKind.Type).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun variableProperty() {
- checkSourceExistsAndVerifyModel("testdata/properties/variableProperty.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("property", name)
- assertEquals(NodeKind.Property, kind)
- assertEquals(Content.Empty, content)
- assertEquals("String", detail(NodeKind.Type).name)
- assertTrue(members.none())
- assertTrue(links.none())
- }
- }
- }
-
- @Test fun valuePropertyWithGetter() {
- checkSourceExistsAndVerifyModel("testdata/properties/valuePropertyWithGetter.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("property", name)
- assertEquals(NodeKind.Property, kind)
- assertEquals(Content.Empty, content)
- assertEquals("String", detail(NodeKind.Type).name)
- assertTrue(links.none())
- assertTrue(members.none())
- }
- }
- }
-
- @Test fun variablePropertyWithAccessors() {
- checkSourceExistsAndVerifyModel("testdata/properties/variablePropertyWithAccessors.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("property", name)
- assertEquals(NodeKind.Property, kind)
- assertEquals(Content.Empty, content)
- assertEquals("String", detail(NodeKind.Type).name)
- val modifiers = details(NodeKind.Modifier).map { it.name }
- assertTrue("final" in modifiers)
- assertTrue("public" in modifiers)
- assertTrue("var" in modifiers)
- assertTrue(links.none())
- assertTrue(members.none())
- }
- }
- }
-
- @Test fun propertyWithReceiver() {
- checkSourceExistsAndVerifyModel(
- "testdata/properties/propertyWithReceiver.kt",
- defaultModelConfig
- ) { model ->
- with(model.members.single().members.single()) {
- assertEquals("kotlin.String", name)
- assertEquals(NodeKind.ExternalClass, kind)
- with(members.single()) {
- assertEquals("foobar", name)
- assertEquals(NodeKind.Property, kind)
- }
- }
- }
- }
-
- @Test fun propertyOverride() {
- checkSourceExistsAndVerifyModel("testdata/properties/propertyOverride.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single { it.name == "Bar" }.members.single { it.name == "xyzzy"}) {
- assertEquals("xyzzy", name)
- val override = references(RefKind.Override).single().to
- assertEquals("xyzzy", override.name)
- assertEquals("Foo", override.owner!!.name)
- }
- }
- }
-
- @Test fun sinceKotlin() {
- checkSourceExistsAndVerifyModel("testdata/properties/sinceKotlin.kt", defaultModelConfig) { model ->
- with(model.members.single().members.single()) {
- assertEquals("1.1", sinceKotlin)
- }
- }
- }
-}
-
-class JSPropertyTest: BasePropertyTest(Platform.js) {}
-
-class JVMPropertyTest : BasePropertyTest(Platform.jvm) {
- @Test
- fun annotatedProperty() {
- checkSourceExistsAndVerifyModel(
- "testdata/properties/annotatedProperty.kt",
- modelConfig = ModelConfig(
- analysisPlatform = analysisPlatform,
- withKotlinRuntime = true
- )
- ) { model ->
- with(model.members.single().members.single()) {
- Assert.assertEquals(1, annotations.count())
- with(annotations[0]) {
- Assert.assertEquals("Strictfp", name)
- Assert.assertEquals(Content.Empty, content)
- Assert.assertEquals(NodeKind.Annotation, kind)
- }
- }
- }
- }
-
-}
-
-class CommonPropertyTest: BasePropertyTest(Platform.common) {} \ No newline at end of file
diff --git a/core/src/test/kotlin/model/SourceLinksErrorTest.kt b/core/src/test/kotlin/model/SourceLinksErrorTest.kt
deleted file mode 100644
index 2d587856..00000000
--- a/core/src/test/kotlin/model/SourceLinksErrorTest.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.jetbrains.dokka.tests.model
-
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.SourceLinkDefinitionImpl
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.junit.Assert
-import org.junit.Test
-import java.io.File
-
-class SourceLinksErrorTest {
-
- @Test
- fun absolutePath_notMatching() {
- val sourceLink = SourceLinkDefinitionImpl(File("testdata/nonExisting").absolutePath, "http://...", null)
- verifyNoSourceUrl(sourceLink)
- }
-
- @Test
- fun relativePath_notMatching() {
- val sourceLink = SourceLinkDefinitionImpl("testdata/nonExisting", "http://...", null)
- verifyNoSourceUrl(sourceLink)
- }
-
- private fun verifyNoSourceUrl(sourceLink: SourceLinkDefinitionImpl) {
- checkSourceExistsAndVerifyModel("testdata/sourceLinks/dummy.kt", ModelConfig(sourceLinks = listOf(sourceLink))) { model ->
- with(model.members.single().members.single()) {
- Assert.assertEquals("foo", name)
- Assert.assertEquals(NodeKind.Function, kind)
- Assert.assertTrue("should not have source urls", details(NodeKind.SourceUrl).isEmpty())
- }
- }
- }
-}
-
diff --git a/core/src/test/kotlin/model/SourceLinksTest.kt b/core/src/test/kotlin/model/SourceLinksTest.kt
deleted file mode 100644
index 8f7766f6..00000000
--- a/core/src/test/kotlin/model/SourceLinksTest.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.jetbrains.dokka.tests.model
-
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.SourceLinkDefinitionImpl
-import org.jetbrains.dokka.testApi.ModelConfig
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.junit.Assert
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import java.io.File
-
-@RunWith(Parameterized::class)
-class SourceLinksTest(
- private val srcLink: String,
- private val url: String,
- private val lineSuffix: String?,
- private val expectedUrl: String
-) {
-
- @Test
- fun test() {
- val link = if(srcLink.contains(sourceLinks)){
- srcLink.substringBeforeLast(sourceLinks) + sourceLinks
- } else {
- srcLink.substringBeforeLast(testdata) + testdata
- }
- val sourceLink = SourceLinkDefinitionImpl(link, url, lineSuffix)
-
- checkSourceExistsAndVerifyModel(filePath, ModelConfig(sourceLinks = listOf(sourceLink))) { model ->
- with(model.members.single().members.single()) {
- Assert.assertEquals("foo", name)
- Assert.assertEquals(NodeKind.Function, kind)
- Assert.assertEquals(expectedUrl, details(NodeKind.SourceUrl).single().name)
- }
- }
- }
-
- companion object {
- private const val testdata = "testdata"
- private const val sourceLinks = "sourceLinks"
- private const val dummy = "dummy.kt"
- private const val pathSuffix = "$sourceLinks/$dummy"
- private const val filePath = "$testdata/$pathSuffix"
- private const val url = "https://example.com"
-
- @Parameterized.Parameters(name = "{index}: {0}, {1}, {2} = {3}")
- @JvmStatic
- fun data(): Collection<Array<String?>> {
- val longestPath = File(testdata).absolutePath.removeSuffix("/") + "/../$testdata/"
- val maxLength = longestPath.length
- val list = listOf(
- arrayOf(File(testdata).absolutePath.removeSuffix("/"), "$url/$pathSuffix"),
- arrayOf(File("$testdata/$sourceLinks").absolutePath.removeSuffix("/") + "/", "$url/$dummy"),
- arrayOf(longestPath, "$url/$pathSuffix"),
-
- arrayOf(testdata, "$url/$pathSuffix"),
- arrayOf("./$testdata", "$url/$pathSuffix"),
- arrayOf("../core/$testdata", "$url/$pathSuffix"),
- arrayOf("$testdata/$sourceLinks", "$url/$dummy"),
- arrayOf("./$testdata/../$testdata/$sourceLinks", "$url/$dummy")
- )
-
- return list.map { arrayOf(it[0].padEnd(maxLength, '_'), url, null, it[1]) } +
- listOf(
- // check that it also works if url ends with /
- arrayOf((File(testdata).absolutePath.removeSuffix("/") + "/").padEnd(maxLength, '_'), "$url/", null, "$url/$pathSuffix"),
- // check if line suffix work
- arrayOf<String?>("../core/../core/./$testdata/$sourceLinks/".padEnd(maxLength, '_'), "$url/", "#L", "$url/$dummy#L4")
- )
- }
- }
-
-}
-
diff --git a/core/src/test/kotlin/model/TypeAliasTest.kt b/core/src/test/kotlin/model/TypeAliasTest.kt
deleted file mode 100644
index 6c9b90a8..00000000
--- a/core/src/test/kotlin/model/TypeAliasTest.kt
+++ /dev/null
@@ -1,134 +0,0 @@
-package org.jetbrains.dokka.tests
-
-import junit.framework.TestCase.assertEquals
-import org.jetbrains.dokka.Content
-import org.jetbrains.dokka.NodeKind
-import org.jetbrains.dokka.testApi.checkSourceExistsAndVerifyModel
-import org.jetbrains.dokka.testApi.toTestString
-import org.junit.Test
-
-class TypeAliasTest {
- @Test
- fun testSimple() {
- checkSourceExistsAndVerifyModel("testdata/typealias/simple.kt") {
- val pkg = it.members.single()
- with(pkg.member(NodeKind.TypeAlias)) {
- assertEquals(Content.Empty, content)
- assertEquals("B", name)
- assertEquals("A", detail(NodeKind.TypeAliasUnderlyingType).name)
- }
- }
- }
-
- @Test
- fun testInheritanceFromTypeAlias() {
- checkSourceExistsAndVerifyModel("testdata/typealias/inheritanceFromTypeAlias.kt") {
- val pkg = it.members.single()
- with(pkg.member(NodeKind.TypeAlias)) {
- assertEquals(Content.Empty, content)
- assertEquals("Same", name)
- assertEquals("Some", detail(NodeKind.TypeAliasUnderlyingType).name)
- assertEquals("My", inheritors.single().name)
- }
- with(pkg.members(NodeKind.Class).find { it.name == "My" }!!) {
- assertEquals("Same", detail(NodeKind.Supertype).name)
- }
- }
- }
-
- @Test
- fun testChain() {
- checkSourceExistsAndVerifyModel("testdata/typealias/chain.kt") {
- val pkg = it.members.single()
- with(pkg.members(NodeKind.TypeAlias).find { it.name == "B" }!!) {
- assertEquals(Content.Empty, content)
- assertEquals("A", detail(NodeKind.TypeAliasUnderlyingType).name)
- }
- with(pkg.members(NodeKind.TypeAlias).find { it.name == "C" }!!) {
- assertEquals(Content.Empty, content)
- assertEquals("B", detail(NodeKind.TypeAliasUnderlyingType).name)
- }
- }
- }
-
- @Test
- fun testDocumented() {
- checkSourceExistsAndVerifyModel("testdata/typealias/documented.kt") {
- val pkg = it.members.single()
- with(pkg.member(NodeKind.TypeAlias)) {
- assertEquals("Just typealias", content.summary.toTestString())
- }
- }
- }
-
- @Test
- fun testDeprecated() {
- checkSourceExistsAndVerifyModel("testdata/typealias/deprecated.kt") {
- val pkg = it.members.single()
- with(pkg.member(NodeKind.TypeAlias)) {
- assertEquals(Content.Empty, content)
- assertEquals("Deprecated", deprecation!!.name)
- assertEquals("\"Not mainstream now\"", deprecation!!.detail(NodeKind.Parameter).detail(NodeKind.Value).name)
- }
- }
- }
-
- @Test
- fun testGeneric() {
- checkSourceExistsAndVerifyModel("testdata/typealias/generic.kt") {
- val pkg = it.members.single()
- with(pkg.members(NodeKind.TypeAlias).find { it.name == "B" }!!) {
- assertEquals("Any", detail(NodeKind.TypeAliasUnderlyingType).detail(NodeKind.Type).name)
- }
-
- with(pkg.members(NodeKind.TypeAlias).find { it.name == "C" }!!) {
- assertEquals("T", detail(NodeKind.TypeAliasUnderlyingType).detail(NodeKind.Type).name)
- assertEquals("T", detail(NodeKind.TypeParameter).name)
- }
- }
- }
-
- @Test
- fun testFunctional() {
- checkSourceExistsAndVerifyModel("testdata/typealias/functional.kt") {
- val pkg = it.members.single()
- with(pkg.member(NodeKind.TypeAlias)) {
- assertEquals("Function1", detail(NodeKind.TypeAliasUnderlyingType).name)
- val typeParams = detail(NodeKind.TypeAliasUnderlyingType).details(NodeKind.Type)
- assertEquals("A", typeParams.first().name)
- assertEquals("B", typeParams.last().name)
- }
-
- with(pkg.member(NodeKind.Function)) {
- assertEquals("Spell", detail(NodeKind.Parameter).detail(NodeKind.Type).name)
- }
- }
- }
-
- @Test
- fun testAsTypeBoundWithVariance() {
- checkSourceExistsAndVerifyModel("testdata/typealias/asTypeBoundWithVariance.kt") {
- val pkg = it.members.single()
- with(pkg.members(NodeKind.Class).find { it.name == "C" }!!) {
- val tParam = detail(NodeKind.TypeParameter)
- assertEquals("out", tParam.detail(NodeKind.Modifier).name)
- assertEquals("B", tParam.detail(NodeKind.Type).link(NodeKind.TypeAlias).name)
- }
-
- with(pkg.members(NodeKind.Class).find { it.name == "D" }!!) {
- val tParam = detail(NodeKind.TypeParameter)
- assertEquals("in", tParam.detail(NodeKind.Modifier).name)
- assertEquals("B", tParam.detail(NodeKind.Type).link(NodeKind.TypeAlias).name)
- }
- }
- }
-
- @Test
- fun sinceKotlin() {
- checkSourceExistsAndVerifyModel("testdata/typealias/sinceKotlin.kt") { model ->
- with(model.members.single().members.single()) {
- assertEquals("1.1", sinceKotlin)
- }
- }
- }
-} \ No newline at end of file