@@ -20,33 +20,59 @@ 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
59
+ allClasses.filter(_.contains(query.pattern)) match {
60
+ case Seq () =>
61
+ // No matches? then try globbing
62
+ val regex = (query.pattern.replaceAll(" \\ ." , " \\\\ ." ).replaceAll(" \\ *" , " .*" ) + " $" ).r
63
+ allClasses.filter(cls => regex.findFirstMatchIn(cls).isDefined) match {
64
+ case Seq () =>
65
+ throw new java.lang.IllegalStateException (s " Class not found for @apidoc[ $query] " )
66
+ case results =>
67
+ renderMatches(query, results, node, visitor, printer)
68
+ }
69
+ case results =>
70
+ renderMatches(query, results, node, visitor, printer)
71
+ }
72
+ } else {
73
+ renderMatches(query, allClasses.filter(_.endsWith('.' + query.pattern)), node, visitor, printer)
74
+ }
75
+ }
50
76
51
77
def syntheticNode (group : String , label : String , fqcn : String , node : DirectiveNode ): DirectiveNode = {
52
78
val syntheticSource = new DirectiveNode .Source .Direct (fqcn)
@@ -68,31 +94,32 @@ class ApidocDirective(allClasses: IndexedSeq[String]) extends InlineDirective("a
68
94
)
69
95
}
70
96
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 " "
97
+ def renderMatches (query : Query ,
98
+ matches : Seq [String ],
99
+ node : DirectiveNode ,
100
+ visitor : Visitor ,
101
+ printer : Printer ): Unit = {
102
+ val scalaClassSuffix = if (query.linkToObject) " $" else " "
75
103
76
- val matches = allClasses.filter(_.endsWith('.' + className))
77
104
matches.size match {
78
105
case 0 =>
79
106
throw new java.lang.IllegalStateException (s " No matches found for $query" )
80
107
case 1 if matches(0 ).contains(" adsl" ) =>
81
108
throw new java.lang.IllegalStateException (s " Match for $query only found in one language: ${matches(0 )}" )
82
109
case 1 =>
83
- syntheticNode(" scala" , scalaLabel(query ), matches(0 ) + scalaClassSuffix, node).accept(visitor)
84
- syntheticNode(" java" , javaLabel(query ), matches(0 ), node).accept(visitor)
110
+ syntheticNode(" scala" , query. scalaLabel(matches( 0 ) ), matches(0 ) + scalaClassSuffix, node).accept(visitor)
111
+ syntheticNode(" java" , query. javaLabel(matches( 0 ) ), matches(0 ), node).accept(visitor)
85
112
case 2 if matches.forall(_.contains(" adsl" )) =>
86
113
matches.foreach(m => {
87
114
if (! m.contains(" javadsl" ))
88
- syntheticNode(" scala" , scalaLabel(query ), m + scalaClassSuffix, node).accept(visitor)
115
+ syntheticNode(" scala" , query. scalaLabel(m ), m + scalaClassSuffix, node).accept(visitor)
89
116
if (! m.contains(" scaladsl" ))
90
- syntheticNode(" java" , javaLabel(query ), m, node).accept(visitor)
117
+ syntheticNode(" java" , query. javaLabel(m ), m, node).accept(visitor)
91
118
})
92
119
case n =>
93
120
throw new java.lang.IllegalStateException (
94
121
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} ]. "
122
+ s " You may want to use the fully qualified class name as @apidoc[fqcn] instead of @apidoc[ $query ]. "
96
123
)
97
124
}
98
125
}
0 commit comments