aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/src/main/kotlin/DokkaException.kt2
-rw-r--r--core/src/main/kotlin/model/doc/DocTag.kt167
-rw-r--r--plugins/base/src/main/kotlin/parsers/ModuleAndPackageDocumentationParser.kt76
-rw-r--r--plugins/base/src/main/kotlin/parsers/Parser.kt41
-rw-r--r--plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt9
-rw-r--r--plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocFragmentsTest.kt199
6 files changed, 394 insertions, 100 deletions
diff --git a/core/src/main/kotlin/DokkaException.kt b/core/src/main/kotlin/DokkaException.kt
index 0010249c..9a5e3d04 100644
--- a/core/src/main/kotlin/DokkaException.kt
+++ b/core/src/main/kotlin/DokkaException.kt
@@ -1,3 +1,3 @@
package org.jetbrains.dokka
-class DokkaException(message: String) : RuntimeException(message)
+open class DokkaException(message: String) : RuntimeException(message)
diff --git a/core/src/main/kotlin/model/doc/DocTag.kt b/core/src/main/kotlin/model/doc/DocTag.kt
index dc2cd2be..0d3b0612 100644
--- a/core/src/main/kotlin/model/doc/DocTag.kt
+++ b/core/src/main/kotlin/model/doc/DocTag.kt
@@ -9,88 +9,105 @@ sealed class DocTag(
) : WithChildren<DocTag> {
override fun equals(other: Any?): Boolean =
(
- other != null &&
- other::class == this::class &&
- this.children == (other as DocTag).children &&
- this.params == other.params
- )
+ other != null &&
+ other::class == this::class &&
+ this.children == (other as DocTag).children &&
+ this.params == other.params
+ )
override fun hashCode(): Int = children.hashCode() + params.hashCode()
}
-class A(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Big(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class B(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class BlockQuote(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-object Br : DocTag(emptyList(), emptyMap())
-class Cite(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-sealed class Code(children: List<DocTag>, params: Map<String, String>) : DocTag(children, params)
-class CodeInline(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : Code(children, params)
-class CodeBlock(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : Code(children, params)
-class Dd(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Dfn(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Dir(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Div(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Dl(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Dt(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Em(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Font(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Footer(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Frame(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class FrameSet(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class H1(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class H2(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class H3(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class H4(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class H5(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class H6(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Head(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Header(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Html(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class I(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class IFrame(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Img(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Input(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Li(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Link(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Listing(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Main(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Menu(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Meta(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Nav(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class NoFrames(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class NoScript(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Ol(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class P(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Pre(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Script(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Section(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Small(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Span(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Strikethrough(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Strong(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Sub(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Sup(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Table(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Text(val body: String = "", children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) {
+class A(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Big(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class B(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class BlockQuote(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params)
+
+object Br : DocTag(emptyList(), emptyMap())
+class Cite(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+sealed class Code(children: List<DocTag>, params: Map<String, String>) : DocTag(children, params)
+class CodeInline(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ Code(children, params)
+
+class CodeBlock(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : Code(children, params)
+class Dd(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Dfn(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Dir(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Div(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Dl(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Dt(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Em(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Font(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Footer(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Frame(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class FrameSet(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params)
+
+class H1(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class H2(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class H3(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class H4(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class H5(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class H6(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Head(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Header(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Html(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class I(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class IFrame(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Img(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Input(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Li(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Link(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Listing(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Main(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Menu(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Meta(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Nav(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class NoFrames(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params)
+
+class NoScript(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params)
+
+class Ol(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class P(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Pre(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Script(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Section(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Small(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Span(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Strikethrough(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params)
+
+class Strong(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Sub(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Sup(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Table(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Text(val body: String = "", children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params) {
override fun equals(other: Any?): Boolean = super.equals(other) && this.body == (other as Text).body
override fun hashCode(): Int = super.hashCode() + body.hashCode()
}
-class TBody(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Td(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class TFoot(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Th(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class THead(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Title(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Tr(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Tt(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class U(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Ul(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class Var(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class DocumentationLink(val dri: DRI, children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params) {
+
+class TBody(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Td(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class TFoot(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Th(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class THead(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Title(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Tr(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Tt(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class U(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Ul(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class Var(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class DocumentationLink(val dri: DRI, children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params) {
override fun equals(other: Any?): Boolean = super.equals(other) && this.dri == (other as DocumentationLink).dri
override fun hashCode(): Int = super.hashCode() + dri.hashCode()
}
-object HorizontalRule : DocTag(emptyList(), emptyMap())
-class Index(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
-class CustomDocTag(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+
+object HorizontalRule : DocTag(emptyList(), emptyMap())
+class Index(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) : DocTag(children, params)
+class CustomDocTag(children: List<DocTag> = emptyList(), params: Map<String, String> = emptyMap()) :
+ DocTag(children, params)
diff --git a/plugins/base/src/main/kotlin/parsers/ModuleAndPackageDocumentationParser.kt b/plugins/base/src/main/kotlin/parsers/ModuleAndPackageDocumentationParser.kt
new file mode 100644
index 00000000..4b46537b
--- /dev/null
+++ b/plugins/base/src/main/kotlin/parsers/ModuleAndPackageDocumentationParser.kt
@@ -0,0 +1,76 @@
+package org.jetbrains.dokka.base.parsers
+
+import org.jetbrains.dokka.DokkaException
+import java.io.File
+
+internal class IllegalModuleAndPackageDocumentation(
+ source: ModuleAndPackageDocumentationSource, message: String
+) : DokkaException("[$source] $message")
+
+data class ModuleAndPackageDocFragment(
+ val classifier: Classifier,
+ val name: String,
+ val documentation: String
+) {
+ enum class Classifier { Module, Package }
+}
+
+internal abstract class ModuleAndPackageDocumentationSource {
+ abstract val sourceDescription: String
+ abstract val documentation: String
+
+ override fun toString(): String {
+ return sourceDescription
+ }
+}
+
+internal class ModuleAndPackageDocumentationFile(private val file: File) : ModuleAndPackageDocumentationSource() {
+ override val sourceDescription: String = file.path
+ override val documentation: String by lazy(LazyThreadSafetyMode.PUBLICATION) { file.readText() }
+}
+
+internal fun parseModuleAndPackageDocFragments(source: File): List<ModuleAndPackageDocFragment> {
+ return parseModuleAndPackageDocFragments(ModuleAndPackageDocumentationFile(source))
+}
+
+internal fun parseModuleAndPackageDocFragments(source: ModuleAndPackageDocumentationSource): List<ModuleAndPackageDocFragment> {
+ val fragmentStrings = source.documentation.split(Regex("(|^)#\\s*(?=(Module|Package))"))
+ return fragmentStrings
+ .filter(String::isNotBlank)
+ .map { fragmentString -> parseModuleAndPackageDocFragment(source, fragmentString) }
+}
+
+private fun parseModuleAndPackageDocFragment(
+ source: ModuleAndPackageDocumentationSource,
+ fragment: String
+): ModuleAndPackageDocFragment {
+ val firstLineAndDocumentation = fragment.split("\r\n", "\n", "\r", limit = 2)
+ val firstLine = firstLineAndDocumentation[0]
+
+ val classifierAndName = firstLine.split(Regex("\\s+"), limit = 2)
+ if (classifierAndName.size != 2) {
+ throw IllegalModuleAndPackageDocumentation(source, "Missing ${classifierAndName.first()} name")
+ }
+
+ val classifier = when (classifierAndName[0].trim()) {
+ "Module" -> ModuleAndPackageDocFragment.Classifier.Module
+ "Package" -> ModuleAndPackageDocFragment.Classifier.Package
+ else -> throw IllegalStateException("Unexpected classifier ${classifierAndName[0]}")
+ }
+
+ val name = classifierAndName[1].trim()
+ if (name.contains(Regex("\\s"))) {
+ throw IllegalModuleAndPackageDocumentation(
+ source, "Module/Package name cannot contain whitespace in '$firstLine'"
+ )
+ }
+
+ return ModuleAndPackageDocFragment(
+ classifier = classifier,
+ name = name,
+ documentation = firstLineAndDocumentation.getOrNull(1)?.trim().orEmpty()
+ )
+}
+
+
+
diff --git a/plugins/base/src/main/kotlin/parsers/Parser.kt b/plugins/base/src/main/kotlin/parsers/Parser.kt
index 1dd0c34a..706f093b 100644
--- a/plugins/base/src/main/kotlin/parsers/Parser.kt
+++ b/plugins/base/src/main/kotlin/parsers/Parser.kt
@@ -5,6 +5,7 @@ import org.jetbrains.dokka.model.doc.*
abstract class Parser {
abstract fun parseStringToDocNode(extractedString: String): DocTag
+
abstract fun preparse(text: String): String
fun parse(text: String): DocumentationNode {
@@ -12,22 +13,28 @@ abstract class Parser {
val list = jkdocToListOfPairs(preparse(text))
val mappedList: List<TagWrapper> = list.map {
- when(it.first) {
- "description" -> Description(parseStringToDocNode(it.second))
- "author" -> Author(parseStringToDocNode(it.second))
- "version" -> Version(parseStringToDocNode(it.second))
- "since" -> Since(parseStringToDocNode(it.second))
- "see" -> See(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '), null)
- "param" -> Param(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '))
- "property" -> Property(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '))
- "return" -> Return(parseStringToDocNode(it.second))
- "constructor" -> Constructor(parseStringToDocNode(it.second))
- "receiver" -> Receiver(parseStringToDocNode(it.second))
- "throws", "exception" -> Throws(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '))
- "deprecated" -> Deprecated(parseStringToDocNode(it.second))
- "sample" -> Sample(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '))
- "suppress" -> Suppress(parseStringToDocNode(it.second))
- else -> CustomTagWrapper(parseStringToDocNode(it.second), it.first)
+ when (it.first) {
+ "description" -> Description(parseStringToDocNode(it.second))
+ "author" -> Author(parseStringToDocNode(it.second))
+ "version" -> Version(parseStringToDocNode(it.second))
+ "since" -> Since(parseStringToDocNode(it.second))
+ "see" -> See(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '), null)
+ "param" -> Param(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '))
+ "property" -> Property(
+ parseStringToDocNode(it.second.substringAfter(' ')),
+ it.second.substringBefore(' ')
+ )
+ "return" -> Return(parseStringToDocNode(it.second))
+ "constructor" -> Constructor(parseStringToDocNode(it.second))
+ "receiver" -> Receiver(parseStringToDocNode(it.second))
+ "throws", "exception" -> Throws(
+ parseStringToDocNode(it.second.substringAfter(' ')),
+ it.second.substringBefore(' ')
+ )
+ "deprecated" -> Deprecated(parseStringToDocNode(it.second))
+ "sample" -> Sample(parseStringToDocNode(it.second.substringAfter(' ')), it.second.substringBefore(' '))
+ "suppress" -> Suppress(parseStringToDocNode(it.second))
+ else -> CustomTagWrapper(parseStringToDocNode(it.second), it.first)
}
}
return DocumentationNode(mappedList)
@@ -39,4 +46,4 @@ abstract class Parser {
.map {
it.substringBefore(' ') to it.substringAfter(' ')
}
-} \ No newline at end of file
+}
diff --git a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt
index 71824922..5f1a540d 100644
--- a/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt
+++ b/plugins/base/src/main/kotlin/transformers/documentables/ModuleAndPackageDocumentationTransformer.kt
@@ -37,12 +37,7 @@ internal class ModuleAndPackageDocumentationTransformer(
.readText()
.split(Regex("(\n|^)# (?=(Module|Package))")) // Matches heading with Module/Package to split by
.filter { it.isNotEmpty() }
- .map {
- it.split(
- Regex(" "),
- 2
- )
- } // Matches space between Module/Package and fully qualified name
+ .map { it.split(Regex(" "), 2) } // Matches space between Module/Package and fully qualified name
}.groupBy({ it[0] }, {
it[1].split(Regex("\n"), 2) // Matches new line after fully qualified name
.let { it[0].trim() to it[1].trim() }
@@ -99,7 +94,7 @@ internal class ModuleAndPackageDocumentationTransformer(
}
}
- private fun mergeDocumentation(origin: Map<DokkaSourceSet, DocumentationNode>, new: Map<DokkaSourceSet, DocumentationNode>) =
+ private fun mergeDocumentation(origin: Map<DokkaSourceSet, DocumentationNode>, new: Map<DokkaSourceSet, DocumentationNode>): Map<DokkaSourceSet, DocumentationNode> =
(origin.asSequence() + new.asSequence())
.distinct()
.groupBy({ it.key }, { it.value })
diff --git a/plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocFragmentsTest.kt b/plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocFragmentsTest.kt
new file mode 100644
index 00000000..49eddaea
--- /dev/null
+++ b/plugins/base/src/test/kotlin/parsers/ParseModuleAndPackageDocFragmentsTest.kt
@@ -0,0 +1,199 @@
+package parsers
+
+import org.jetbrains.dokka.base.parsers.IllegalModuleAndPackageDocumentation
+import org.jetbrains.dokka.base.parsers.ModuleAndPackageDocFragment
+import org.jetbrains.dokka.base.parsers.ModuleAndPackageDocFragment.Classifier.Module
+import org.jetbrains.dokka.base.parsers.ModuleAndPackageDocFragment.Classifier.Package
+import org.jetbrains.dokka.base.parsers.ModuleAndPackageDocumentationSource
+import org.jetbrains.dokka.base.parsers.parseModuleAndPackageDocFragments
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertTrue
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertThrows
+import org.junit.jupiter.api.io.TempDir
+import java.nio.file.Path
+
+class ParseModuleAndPackageDocFragmentsTest {
+
+ @Test
+ fun `basic example`() {
+
+ val fragments = parseModuleAndPackageDocFragments(
+ source(
+ """
+ # Module kotlin-demo
+ Module description
+
+ # Package org.jetbrains.kotlin.demo
+ Package demo description
+ ## Level 2 heading
+ Heading 2
+
+ # Package org.jetbrains.kotlin.demo2
+ Package demo2 description
+ """.trimIndent()
+ )
+ )
+
+ assertEquals(
+ listOf(
+ ModuleAndPackageDocFragment(
+ classifier = Module,
+ name = "kotlin-demo",
+ documentation = "Module description"
+ ),
+ ModuleAndPackageDocFragment(
+ classifier = Package,
+ name = "org.jetbrains.kotlin.demo",
+ documentation = "Package demo description\n## Level 2 heading\nHeading 2"
+ ),
+ ModuleAndPackageDocFragment(
+ classifier = Package,
+ name = "org.jetbrains.kotlin.demo2",
+ documentation = "Package demo2 description"
+ )
+ ),
+ fragments
+ )
+ }
+
+ @Test
+ fun `no module name specified fails`() {
+ val exception = assertThrows<IllegalModuleAndPackageDocumentation> {
+ parseModuleAndPackageDocFragments(
+ source(
+ """
+ # Module
+ No module name given
+ """.trimIndent()
+ )
+ )
+ }
+
+ assertTrue(
+ "Missing Module name" in exception.message.orEmpty(),
+ "Expected 'Missing Module name' in error message"
+ )
+ }
+
+ @Test
+ fun `no package name specified fails`() {
+ val exception = assertThrows<IllegalModuleAndPackageDocumentation> {
+ parseModuleAndPackageDocFragments(
+ source(
+ """
+ # Package
+ No package name given
+ """.trimIndent()
+ )
+ )
+ }
+
+ assertTrue(
+ "Missing Package name" in exception.message.orEmpty(),
+ "Expected 'Missing Package name' in error message"
+ )
+ }
+
+ @Test
+ fun `white space in module name fails`() {
+ val exception = assertThrows<IllegalModuleAndPackageDocumentation> {
+ parseModuleAndPackageDocFragments(
+ source(
+ """
+ # Module My Module
+ """.trimIndent()
+ )
+ )
+ }
+
+ assertTrue(
+ "Module My Module" in exception.message.orEmpty(),
+ "Expected problematic statement in error message"
+ )
+ }
+
+ @Test
+ fun `white space in package name fails`() {
+ val exception = assertThrows<IllegalModuleAndPackageDocumentation> {
+ parseModuleAndPackageDocFragments(
+ source(
+ """
+ # Package my package
+ """.trimIndent()
+ )
+ )
+ }
+
+ assertTrue(
+ "Package my package" in exception.message.orEmpty(),
+ "Expected problematic statement in error message"
+ )
+ }
+
+ @Test
+ fun `multiple whitespaces are supported in first line`() {
+ val fragments = parseModuleAndPackageDocFragments(
+ source(
+ """
+ # Module my-module
+ My Module
+ # Package com.my.package
+ My Package
+ """.trimIndent()
+ )
+ )
+
+ assertEquals(
+ listOf(
+ ModuleAndPackageDocFragment(
+ classifier = Module,
+ name = "my-module",
+ documentation = "My Module"
+ ),
+ ModuleAndPackageDocFragment(
+ classifier = Package,
+ name = "com.my.package",
+ documentation = "My Package"
+ )
+ ),
+ fragments
+ )
+ }
+
+ @Test
+ fun `parse from file`(@TempDir temporaryFolder: Path) {
+ val file = temporaryFolder.resolve("other.md").toFile()
+ file.writeText(
+ """
+ # Module MyModule
+ D1
+ # Package com.sample
+ D2
+ """.trimIndent()
+ )
+
+ assertEquals(
+ listOf(
+ ModuleAndPackageDocFragment(
+ classifier = Module,
+ name = "MyModule",
+ documentation = "D1"
+ ),
+ ModuleAndPackageDocFragment(
+ classifier = Package,
+ name = "com.sample",
+ documentation = "D2"
+ )
+ ),
+ parseModuleAndPackageDocFragments(file)
+ )
+ }
+
+
+ private fun source(documentation: String): ModuleAndPackageDocumentationSource =
+ object : ModuleAndPackageDocumentationSource() {
+ override val sourceDescription: String = "inline test"
+ override val documentation: String = documentation
+ }
+}