aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/parsers
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/base/src/main/kotlin/parsers')
-rw-r--r--plugins/base/src/main/kotlin/parsers/HtmlParser.kt89
-rw-r--r--plugins/base/src/main/kotlin/parsers/MarkdownParser.kt61
-rw-r--r--plugins/base/src/main/kotlin/parsers/Parser.kt77
3 files changed, 84 insertions, 143 deletions
diff --git a/plugins/base/src/main/kotlin/parsers/HtmlParser.kt b/plugins/base/src/main/kotlin/parsers/HtmlParser.kt
deleted file mode 100644
index ece3cf24..00000000
--- a/plugins/base/src/main/kotlin/parsers/HtmlParser.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.jetbrains.dokka.base.parsers
-
-import org.jetbrains.dokka.model.doc.*
-import org.jetbrains.dokka.base.parsers.factories.DocTagsFromStringFactory
-import org.jsoup.Jsoup
-import org.jsoup.nodes.Node
-import org.jsoup.select.NodeFilter
-import org.jsoup.select.NodeTraversor
-
-class HtmlParser : Parser() {
-
- inner class NodeFilterImpl : NodeFilter {
-
- private val nodesCache: MutableMap<Int, MutableList<DocTag>> = mutableMapOf()
- private var currentDepth = 0
-
- fun collect(): DocTag = nodesCache[currentDepth]!![0]
-
- override fun tail(node: Node?, depth: Int): NodeFilter.FilterResult {
- val nodeName = node!!.nodeName()
- val nodeAttributes = node.attributes()
-
- if(nodeName in listOf("#document", "html", "head"))
- return NodeFilter.FilterResult.CONTINUE
-
- val body: String
- val params: Map<String, String>
-
-
- if(nodeName != "#text") {
- body = ""
- params = nodeAttributes.map { it.key to it.value }.toMap()
- } else {
- body = nodeAttributes["#text"]
- params = emptyMap()
- }
-
- val docNode = if(depth < currentDepth) {
- DocTagsFromStringFactory.getInstance(nodeName, nodesCache.getOrDefault(currentDepth, mutableListOf()).toList(), params, body).also {
- nodesCache[currentDepth] = mutableListOf()
- currentDepth = depth
- }
- } else {
- DocTagsFromStringFactory.getInstance(nodeName, emptyList(), params, body)
- }
-
- nodesCache.getOrDefault(depth, mutableListOf()) += docNode
- return NodeFilter.FilterResult.CONTINUE
- }
-
- override fun head(node: Node?, depth: Int): NodeFilter.FilterResult {
-
- val nodeName = node!!.nodeName()
-
- if(currentDepth < depth) {
- currentDepth = depth
- nodesCache[currentDepth] = mutableListOf()
- }
-
- if(nodeName in listOf("#document", "html", "head"))
- return NodeFilter.FilterResult.CONTINUE
-
- return NodeFilter.FilterResult.CONTINUE
- }
- }
-
-
- private fun htmlToDocNode(string: String): DocTag {
- val document = Jsoup.parse(string)
- val nodeFilterImpl = NodeFilterImpl()
- NodeTraversor.filter(nodeFilterImpl, document.root())
- return nodeFilterImpl.collect()
- }
-
- private fun replaceLinksWithHrefs(javadoc: String): String = Regex("\\{@link .*?}").replace(javadoc) {
- val split = it.value.dropLast(1).split(" ")
- if(split.size !in listOf(2, 3))
- return@replace it.value
- if(split.size == 3)
- return@replace "<documentationlink href=\"${split[1]}\">${split[2]}</documentationlink>"
- else
- return@replace "<documentationlink href=\"${split[1]}\">${split[1]}</documentationlink>"
- }
-
- override fun parseStringToDocNode(extractedString: String) = htmlToDocNode(extractedString)
- override fun preparse(text: String) = replaceLinksWithHrefs(text)
-}
-
-
diff --git a/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt b/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt
index e7a36d3f..f496d704 100644
--- a/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt
+++ b/plugins/base/src/main/kotlin/parsers/MarkdownParser.kt
@@ -38,6 +38,27 @@ open class MarkdownParser(
override fun preparse(text: String) = text
+ override fun parseTagWithBody(tagName: String, content: String): TagWrapper =
+ when (tagName) {
+ "see" -> {
+ val referencedName = content.substringBefore(' ')
+ See(
+ parseStringToDocNode(content.substringAfter(' ')),
+ referencedName,
+ externalDri(referencedName)
+ )
+ }
+ "throws", "exception" -> {
+ val dri = externalDri(content.substringBefore(' '))
+ Throws(
+ parseStringToDocNode(content.substringAfter(' ')),
+ dri?.fqName() ?: content.substringBefore(' '),
+ dri
+ )
+ }
+ else -> super.parseTagWithBody(tagName, content)
+ }
+
private fun headersHandler(node: ASTNode) =
DocTagsFromIElementFactory.getInstance(
node.type,
@@ -424,6 +445,12 @@ open class MarkdownParser(
DocumentationNode(emptyList())
} else {
fun parseStringToDocNode(text: String) = MarkdownParser(externalDri).parseStringToDocNode(text)
+
+ fun pointedLink(tag: KDocTag): DRI? = (parseStringToDocNode("[${tag.getSubjectName()}]")).let {
+ val link = it.children[0].children[0]
+ if (link is DocumentationLink) link.dri else null
+ }
+
DocumentationNode(
(listOf(kDocTag) + getAllKDocTags(findParent(kDocTag))).map {
when (it.knownTag) {
@@ -432,14 +459,22 @@ open class MarkdownParser(
it.name!!
)
KDocKnownTag.AUTHOR -> Author(parseStringToDocNode(it.getContent()))
- KDocKnownTag.THROWS -> Throws(
- parseStringToDocNode(it.getContent()),
- it.getSubjectName().orEmpty()
- )
- KDocKnownTag.EXCEPTION -> Throws(
- parseStringToDocNode(it.getContent()),
- it.getSubjectName().orEmpty()
- )
+ KDocKnownTag.THROWS -> {
+ val dri = pointedLink(it)
+ Throws(
+ parseStringToDocNode(it.getContent()),
+ dri?.fqName() ?: it.getSubjectName().orEmpty(),
+ dri,
+ )
+ }
+ KDocKnownTag.EXCEPTION -> {
+ val dri = pointedLink(it)
+ Throws(
+ parseStringToDocNode(it.getContent()),
+ dri?.fqName() ?: it.getSubjectName().orEmpty(),
+ dri
+ )
+ }
KDocKnownTag.PARAM -> Param(
parseStringToDocNode(it.getContent()),
it.getSubjectName().orEmpty()
@@ -449,12 +484,7 @@ open class MarkdownParser(
KDocKnownTag.SEE -> See(
parseStringToDocNode(it.getContent()),
it.getSubjectName().orEmpty(),
- (parseStringToDocNode("[${it.getSubjectName()}]"))
- .let {
- val link = it.children[0].children[0]
- if (link is DocumentationLink) link.dri
- else null
- }
+ pointedLink(it),
)
KDocKnownTag.SINCE -> Since(parseStringToDocNode(it.getContent()))
KDocKnownTag.CONSTRUCTOR -> Constructor(parseStringToDocNode(it.getContent()))
@@ -473,6 +503,9 @@ open class MarkdownParser(
}
}
+ //Horrible hack but since link resolution is passed as a function i am not able to resolve them otherwise
+ fun DRI.fqName(): String = "$packageName.$classNames"
+
private fun findParent(kDoc: PsiElement): PsiElement =
if (kDoc is KDocSection) findParent(kDoc.parent) else kDoc
diff --git a/plugins/base/src/main/kotlin/parsers/Parser.kt b/plugins/base/src/main/kotlin/parsers/Parser.kt
index 228cc88b..960d7a64 100644
--- a/plugins/base/src/main/kotlin/parsers/Parser.kt
+++ b/plugins/base/src/main/kotlin/parsers/Parser.kt
@@ -8,47 +8,44 @@ abstract class Parser {
abstract fun preparse(text: String): String
- fun parse(text: String): DocumentationNode {
-
- 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)
- }
+ open fun parse(text: String): DocumentationNode =
+ DocumentationNode(jkdocToListOfPairs(preparse(text)).map { (tag, content) -> parseTagWithBody(tag, content) })
+
+ open fun parseTagWithBody(tagName: String, content: String): TagWrapper =
+ when (tagName) {
+ "description" -> Description(parseStringToDocNode(content))
+ "author" -> Author(parseStringToDocNode(content))
+ "version" -> Version(parseStringToDocNode(content))
+ "since" -> Since(parseStringToDocNode(content))
+ "see" -> See(
+ parseStringToDocNode(content.substringAfter(' ')),
+ content.substringBefore(' '),
+ null
+ )
+ "param" -> Param(
+ parseStringToDocNode(content.substringAfter(' ')),
+ content.substringBefore(' ')
+ )
+ "property" -> Property(
+ parseStringToDocNode(content.substringAfter(' ')),
+ content.substringBefore(' ')
+ )
+ "return" -> Return(parseStringToDocNode(content))
+ "constructor" -> Constructor(parseStringToDocNode(content))
+ "receiver" -> Receiver(parseStringToDocNode(content))
+ "throws", "exception" -> Throws(
+ parseStringToDocNode(content.substringAfter(' ')),
+ content.substringBefore(' '),
+ null
+ )
+ "deprecated" -> Deprecated(parseStringToDocNode(content))
+ "sample" -> Sample(
+ parseStringToDocNode(content.substringAfter(' ')),
+ content.substringBefore(' ')
+ )
+ "suppress" -> Suppress(parseStringToDocNode(content))
+ else -> CustomTagWrapper(parseStringToDocNode(content), tagName)
}
- return DocumentationNode(mappedList)
- }
private fun jkdocToListOfPairs(javadoc: String): List<Pair<String, String>> =
"description $javadoc"