Unidoc directives for cluster md files #22904

This commit is contained in:
Richard Imaoka 2018-03-09 17:12:54 +09:00 committed by Johan Andrén
parent 7d67524bb5
commit bcc86f7703
6 changed files with 84 additions and 72 deletions

View file

@ -8,6 +8,7 @@ import _root_.io.github.lukehutch.fastclasspathscanner.FastClasspathScanner
import com.lightbend.paradox.markdown._
import com.lightbend.paradox.sbt.ParadoxPlugin.autoImport._
import org.pegdown.Printer
import org.pegdown.ast.DirectiveNode.Source
import org.pegdown.ast._
import sbt.Keys._
import sbt._
@ -29,23 +30,31 @@ object ParadoxSupport {
class UnidocDirective(allClasses: IndexedSeq[String]) extends InlineDirective("unidoc") {
def render(node: DirectiveNode, visitor: Visitor, printer: Printer): Unit = {
if (node.label.split('[')(0).contains('.')) {
val fqcn = node.label
val (directive, label, source) = node.source match {
case direct: Source.Direct => (s"@unidoc[${node.label}](${direct.value})", node.label, direct.value)
case ref: Source.Ref => (s"@unidoc[${node.label}](${ref.value})", node.label, ref.value)
case Source.Empty => (s"@unidoc[${node.label}]", node.label.split('.').last, node.label)
}
if (source.split('[')(0).contains('.')) {
val fqcn = source
if (allClasses.contains(fqcn)) {
val label = fqcn.split('.').last
syntheticNode("java", javaLabel(label), fqcn, node).accept(visitor)
syntheticNode("scala", label, fqcn, node).accept(visitor)
syntheticNode("scala", scalaLabel(label), fqcn, node).accept(visitor)
} else {
throw new java.lang.IllegalStateException(s"fqcn not found by @unidoc[$fqcn]")
throw new java.lang.IllegalStateException(s"fqcn not found by $directive")
}
}
else {
renderByClassName(node.label, node, visitor, printer)
renderByClassName(directive, source, node, visitor, printer)
}
}
def javaLabel(label: String): String =
label.replaceAll("\\[", "<").replaceAll("\\]", ">").replace('_', '?')
def javaLabel(splitLabel: String): String =
splitLabel.replaceAll("\\\\_", "_").replaceAll("\\[", "<").replaceAll("\\]", ">").replace('_', '?')
def scalaLabel(splitLabel: String): String =
splitLabel.replaceAll("\\\\_", "_")
def syntheticNode(group: String, label: String, fqcn: String, node: DirectiveNode): DirectiveNode = {
val syntheticSource = new DirectiveNode.Source.Direct(fqcn)
@ -56,30 +65,33 @@ object ParadoxSupport {
))
}
def renderByClassName(label: String, node: DirectiveNode, visitor: Visitor, printer: Printer): Unit = {
val label = node.label.replaceAll("\\\\_", "_")
val labelWithoutGenericParameters = label.split("\\[")(0)
val labelWithJavaGenerics = javaLabel(label)
val matches = allClasses.filter(_.endsWith('.' + labelWithoutGenericParameters))
def renderByClassName(directive: String, source: String, node: DirectiveNode, visitor: Visitor, printer: Printer): Unit = {
val sourceWithoutGenericParameters = source.replaceAll("\\\\_", "_").split("\\[")(0)
val labelWithScalaGenerics = scalaLabel(node.label)
val labelWithJavaGenerics = javaLabel(node.label)
val matches = allClasses.filter(_.endsWith('.' + sourceWithoutGenericParameters))
matches.size match {
case 0 =>
throw new java.lang.IllegalStateException(s"No matches found for $label")
throw new java.lang.IllegalStateException(
s"No matches found for $directive. " +
s"You may want to use the fully qualified class name as @unidoc[fqcn]."
)
case 1 if matches(0).contains("adsl") =>
throw new java.lang.IllegalStateException(s"Match for $label only found in one language: ${matches(0)}")
throw new java.lang.IllegalStateException(s"Match for $directive only found in one language: ${matches(0)}")
case 1 =>
syntheticNode("scala", label, matches(0), node).accept(visitor)
syntheticNode("scala", labelWithScalaGenerics, matches(0), node).accept(visitor)
syntheticNode("java", labelWithJavaGenerics, matches(0), node).accept(visitor)
case 2 if matches.forall(_.contains("adsl")) =>
matches.foreach(m => {
if (!m.contains("javadsl"))
syntheticNode("scala", label, m, node).accept(visitor)
syntheticNode("scala", labelWithScalaGenerics, m, node).accept(visitor)
if (!m.contains("scaladsl"))
syntheticNode("java", labelWithJavaGenerics, m, node).accept(visitor)
})
case n =>
throw new java.lang.IllegalStateException(
s"$n matches found for @unidoc[$label], but not javadsl/scaladsl: ${matches.mkString(", ")}. " +
s"You may want to use the fully qualified class name as @unidoc[fqcn] instead of @unidoc[${label}]."
s"$n matches found for $directive, but not javadsl/scaladsl: ${matches.mkString(", ")}. " +
s"You may want to use the fully qualified class name as @unidoc[fqcn] instead of ."
)
}
}