diff options
Diffstat (limited to 'plugins/base/src/main/kotlin/parsers')
-rw-r--r-- | plugins/base/src/main/kotlin/parsers/HtmlParser.kt | 89 | ||||
-rw-r--r-- | plugins/base/src/main/kotlin/parsers/MarkdownParser.kt | 61 | ||||
-rw-r--r-- | plugins/base/src/main/kotlin/parsers/Parser.kt | 77 |
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" |