@@ -20,33 +20,58 @@ import com.lightbend.paradox.markdown.InlineDirective
20
20
import org .pegdown .Printer
21
21
import org .pegdown .ast .{DirectiveNode , TextNode , Visitor }
22
22
23
- class ApidocDirective (allClasses : IndexedSeq [String ]) extends InlineDirective (" apidoc" ) {
24
- def render (node : DirectiveNode , visitor : Visitor , printer : Printer ): Unit =
25
- if (node.label.split('[' )(0 ).contains('.' )) {
26
- val fqcn = node.label
27
- if (allClasses.contains(fqcn)) {
28
- val label = fqcn.split('.' ).last
29
- syntheticNode(" scala" , scalaLabel(label), fqcn, node).accept(visitor)
30
- syntheticNode(" java" , javaLabel(label), fqcn, node).accept(visitor)
31
- } else {
32
- throw new java.lang.IllegalStateException (s " fqcn not found by @apidoc[ $fqcn] " )
23
+ class ApidocDirective (allClassesAndObjects : IndexedSeq [String ]) extends InlineDirective (" apidoc" ) {
24
+ val allClasses = allClassesAndObjects.filterNot(_.endsWith(" $" ))
25
+
26
+ private case class Query (pattern : String , generics : String , linkToObject : Boolean ) {
27
+
28
+ def scalaLabel (matched : String ): String =
29
+ matched.split('.' ).last + generics
30
+ def javaLabel (matched : String ): String =
31
+ scalaLabel(matched)
32
+ .replaceAll(" \\ [" , " <" )
33
+ .replaceAll(" \\ ]" , " >" )
34
+ .replaceAll(" _" , " ?" )
35
+
36
+ override def toString =
37
+ if (linkToObject) pattern + " $" + generics
38
+ else pattern + generics
39
+ }
40
+ private object Query {
41
+ def apply (label : String ): Query = {
42
+ val (pattern, generics) = label.indexOf('[' ) match {
43
+ case - 1 => (label, " " )
44
+ case n => label.replaceAll(" \\\\ _" , " _" ).splitAt(n)
33
45
}
34
- } else {
35
- renderByClassName(node.label, node, visitor, printer)
46
+ if (pattern.endsWith(" $" ))
47
+ Query (pattern.init, generics, linkToObject = true )
48
+ else
49
+ Query (pattern, generics, linkToObject = false )
36
50
}
37
-
38
- private def baseClassName (label : String ) = {
39
- val labelWithoutGenerics = label.split(" \\ [" )(0 )
40
- if (labelWithoutGenerics.endsWith(" $" )) labelWithoutGenerics.init
41
- else labelWithoutGenerics
42
51
}
43
52
44
- def javaLabel (label : String ): String =
45
- scalaLabel(label).replaceAll(" \\ [" , " <" ).replaceAll(" \\ ]" , " >" ).replace('_' , '?' )
46
-
47
- def scalaLabel (label : String ): String =
48
- if (label.endsWith(" $" )) label.init
49
- else label
53
+ def render (node : DirectiveNode , visitor : Visitor , printer : Printer ): Unit = {
54
+ val query = Query (node.label)
55
+ if (query.pattern.contains('.' )) {
56
+ if (allClasses.contains(query.pattern)) {
57
+ renderMatches(query, Seq (query.pattern), node, visitor, printer)
58
+ } else allClasses.filter(_.contains(query.pattern)) match {
59
+ case Seq () =>
60
+ // No matches? only then try as regex.
61
+ val regex = (query.pattern + " $" ).r
62
+ allClasses.filter(cls => regex.findFirstMatchIn(cls).isDefined) match {
63
+ case Seq () =>
64
+ throw new java.lang.IllegalStateException (s " Class not found for by @apidoc[ $query] " )
65
+ case results =>
66
+ renderMatches(query, results, node, visitor, printer)
67
+ }
68
+ case results =>
69
+ renderMatches(query, results, node, visitor, printer)
70
+ }
71
+ } else {
72
+ renderMatches(query, allClasses.filter(_.endsWith('.' + query.pattern)), node, visitor, printer)
73
+ }
74
+ }
50
75
51
76
def syntheticNode (group : String , label : String , fqcn : String , node : DirectiveNode ): DirectiveNode = {
52
77
val syntheticSource = new DirectiveNode .Source .Direct (fqcn)
@@ -68,31 +93,28 @@ class ApidocDirective(allClasses: IndexedSeq[String]) extends InlineDirective("a
68
93
)
69
94
}
70
95
71
- def renderByClassName (label : String , node : DirectiveNode , visitor : Visitor , printer : Printer ): Unit = {
72
- val query = node.label.replaceAll(" \\\\ _" , " _" )
73
- val className = baseClassName(query)
74
- val scalaClassSuffix = if (query.endsWith(" $" )) " $" else " "
96
+ def renderMatches (query : Query , matches : Seq [String ], node : DirectiveNode , visitor : Visitor , printer : Printer ): Unit = {
97
+ val scalaClassSuffix = if (query.linkToObject) " $" else " "
75
98
76
- val matches = allClasses.filter(_.endsWith('.' + className))
77
99
matches.size match {
78
100
case 0 =>
79
101
throw new java.lang.IllegalStateException (s " No matches found for $query" )
80
102
case 1 if matches(0 ).contains(" adsl" ) =>
81
103
throw new java.lang.IllegalStateException (s " Match for $query only found in one language: ${matches(0 )}" )
82
104
case 1 =>
83
- syntheticNode(" scala" , scalaLabel(query ), matches(0 ) + scalaClassSuffix, node).accept(visitor)
84
- syntheticNode(" java" , javaLabel(query ), matches(0 ), node).accept(visitor)
105
+ syntheticNode(" scala" , query. scalaLabel(matches( 0 ) ), matches(0 ) + scalaClassSuffix, node).accept(visitor)
106
+ syntheticNode(" java" , query. javaLabel(matches( 0 ) ), matches(0 ), node).accept(visitor)
85
107
case 2 if matches.forall(_.contains(" adsl" )) =>
86
108
matches.foreach(m => {
87
109
if (! m.contains(" javadsl" ))
88
- syntheticNode(" scala" , scalaLabel(query ), m + scalaClassSuffix, node).accept(visitor)
110
+ syntheticNode(" scala" , query. scalaLabel(m ), m + scalaClassSuffix, node).accept(visitor)
89
111
if (! m.contains(" scaladsl" ))
90
- syntheticNode(" java" , javaLabel(query ), m, node).accept(visitor)
112
+ syntheticNode(" java" , query. javaLabel(m ), m, node).accept(visitor)
91
113
})
92
114
case n =>
93
115
throw new java.lang.IllegalStateException (
94
116
s " $n matches found for $query, but not javadsl/scaladsl: ${matches.mkString(" , " )}. " +
95
- s " You may want to use the fully qualified class name as @apidoc[fqcn] instead of @apidoc[ ${label} ]. "
117
+ s " You may want to use the fully qualified class name as @apidoc[fqcn] instead of @apidoc[ $query ]. "
96
118
)
97
119
}
98
120
}
0 commit comments