Skip to content

Commit 46ddbe9

Browse files
committed
Fix snippet wrapper. Integrate snippet checker with Wiki and Markdown renderers
1 parent 6021176 commit 46ddbe9

File tree

4 files changed

+67
-26
lines changed

4 files changed

+67
-26
lines changed

scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import translators._
1313
class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) extends DocRender(signatureRenderer):
1414
import signatureRenderer._
1515

16-
def doc(m: Member): Seq[AppliedTag] = m.docs.fold(Nil)(d => Seq(renderDocPart(d.body)))
16+
def doc(m: Member): Seq[AppliedTag] = m.docs.fold(Nil)(d => Seq(renderDocPart(d.body)(using m)))
1717

1818
def tableRow(name: String, content: AppliedTag) = Seq(dt(name), dd(content))
1919

@@ -37,14 +37,14 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
3737
def nested(name: String, on: SortedMap[String, DocPart]): Seq[AppliedTag] =
3838
if on.isEmpty then Nil else
3939
tableRow(name, dl(cls := "attributes")(
40-
on.map { case (name, value) => tableRow(name, renderDocPart(value))}.toList:_*
40+
on.map { case (name, value) => tableRow(name, renderDocPart(value)(using m))}.toList:_*
4141
))
4242

4343
def list(name: String, on: List[DocPart]): Seq[AppliedTag] =
44-
if on.isEmpty then Nil else tableRow(name, div(on.map(e => div(renderDocPart(e)))))
44+
if on.isEmpty then Nil else tableRow(name, div(on.map(e => div(renderDocPart(e)(using m)))))
4545

4646
def opt(name: String, on: Option[DocPart]): Seq[AppliedTag] =
47-
if on.isEmpty then Nil else tableRow(name, renderDocPart(on.get))
47+
if on.isEmpty then Nil else tableRow(name, renderDocPart(on.get)(using m))
4848

4949
m.docs.fold(Nil)(d =>
5050
nested("Type Params", d.typeParams) ++
@@ -87,13 +87,13 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
8787
Seq(
8888
since.map(s => code("[Since version ", parameter(s), "] ")),
8989
message.map(m => parameter(m)))
90-
++ m.docs.map(_.deprecated.toSeq.map(renderDocPart))
90+
++ m.docs.map(_.deprecated.toSeq.map(renderDocPart(_)(using m)))
9191
).flatten
9292
Seq(dt("Deprecated"), dd(content:_*))
9393
}
9494

9595
def memberInfo(m: Member): Seq[AppliedTag] =
96-
val bodyContents = m.docs.fold(Nil)(e => renderDocPart(e.body) :: Nil)
96+
val bodyContents = m.docs.fold(Nil)(e => renderDocPart(e.body)(using m) :: Nil)
9797

9898
Seq(
9999
div(cls := "documentableBrief doc")(bodyContents.take(1)),
@@ -246,8 +246,8 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
246246
val rawGroups = membersInGroups.groupBy(_.docs.flatMap(_.group)).collect {
247247
case (Some(groupName), members) =>
248248
ExpandedGroup(
249-
names.get(groupName).fold(raw(groupName))(renderDocPart),
250-
descriptions.get(groupName).fold(raw(""))(renderDocPart),
249+
names.get(groupName).fold(raw(groupName))(renderDocPart(_)(using m)),
250+
descriptions.get(groupName).fold(raw(""))(renderDocPart(_)(using m)),
251251
prios.getOrElse(groupName, 1000)
252252
) -> members
253253
}

scaladoc/src/dotty/tools/scaladoc/renderers/WikiDocRenderer.scala

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,38 @@ import util.HTML._
66
import com.vladsch.flexmark.util.ast.{Node => MdNode}
77
import dotty.tools.scaladoc.tasty.comments.wiki.WikiDocElement
88
import dotty.tools.scaladoc.tasty.comments.markdown.DocFlexmarkRenderer
9+
import dotty.tools.scaladoc.snippets._
910

1011
class DocRender(signatureRenderer: SignatureRenderer)(using DocContext):
1112

12-
def renderDocPart(doc: DocPart): AppliedTag = doc match
13+
private val snippetChecker = SnippetChecker()
14+
15+
private val snippetCheckingFunc: Member => String => Unit =
16+
(m: Member) => {
17+
(str: String) => {
18+
snippetChecker.checkSnippet(str) match {
19+
case r @ SnippetCompilationResult(None, _) =>
20+
println(s"In member ${m.name}:")
21+
println(r.getSummary)
22+
case _ =>
23+
}
24+
}
25+
}
26+
27+
def renderDocPart(doc: DocPart)(using Member): AppliedTag = doc match
1328
case md: MdNode => renderMarkdown(md)
1429
case Nil => raw("")
1530
case Seq(elem: WikiDocElement) => renderElement(elem)
1631
case list: Seq[WikiDocElement @unchecked] => div(list.map(renderElement))
1732

18-
private def renderMarkdown(el: MdNode): AppliedTag =
19-
raw(DocFlexmarkRenderer.render(el)( (link,name) =>
20-
renderLink(link, default => text(if name.isEmpty then default else name)).toString
33+
private def renderMarkdown(el: MdNode)(using m: Member): AppliedTag =
34+
raw(DocFlexmarkRenderer.render(el)(
35+
(link,name) =>
36+
renderLink(link, default => text(if name.isEmpty then default else name)).toString,
37+
snippetCheckingFunc(m)
2138
))
2239

23-
private def listItems(items: Seq[WikiDocElement]) =
40+
private def listItems(items: Seq[WikiDocElement])(using m: Member) =
2441
items.map(i => li(renderElement(i)))
2542
private def notSupported(name: String, content: AppliedTag): AppliedTag =
2643
report.warning(s"Wiki syntax does not support $name in ${signatureRenderer.currentDri.location}")
@@ -35,7 +52,7 @@ class DocRender(signatureRenderer: SignatureRenderer)(using DocContext):
3552
val tooltip = s"Problem linking $query: $msg"
3653
signatureRenderer.unresolvedLink(linkBody(query), titleAttr := tooltip)
3754

38-
private def renderElement(e: WikiDocElement): AppliedTag = e match
55+
private def renderElement(e: WikiDocElement)(using m: Member): AppliedTag = e match
3956
case Title(text, level) =>
4057
val content = renderElement(text)
4158
level match
@@ -46,7 +63,9 @@ class DocRender(signatureRenderer: SignatureRenderer)(using DocContext):
4663
case 5 => h5(content)
4764
case 6 => h6(content)
4865
case Paragraph(text) => p(renderElement(text))
49-
case Code(data: String) => pre(code(raw(data))) // TODO add classes
66+
case Code(data: String) =>
67+
snippetCheckingFunc(m)(data)
68+
pre(code(raw(data))) // TODO add classes
5069
case HorizontalRule => hr
5170

5271
case UnorderedList(items) => ul(listItems(items))

scaladoc/src/dotty/tools/scaladoc/snippets/SnippetWrapper.scala

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
package dotty.tools.scaladoc
22
package snippets
33

4+
import java.io.ByteArrayOutputStream
5+
import java.io.PrintStream
6+
47
class SnippetWrapper:
5-
def wrap(str: String): String = s"""
6-
|package snippets
7-
|object Snippet {
8-
| $str
9-
|}
10-
|""".stripMargin
8+
extension (ps: PrintStream) def printlnWithIndent(indent: Int, str: String) =
9+
ps.println((" " * indent) + str)
10+
def wrap(str: String): String =
11+
val baos = new ByteArrayOutputStream()
12+
val ps = new PrintStream(baos)
13+
ps.println("package snippets")
14+
ps.println("object Snippet {")
15+
str.split('\n').foreach(ps.printlnWithIndent(2, _))
16+
ps.println("}")
17+
baos.toString
1118

1219
object SnippetWrapper:
1320
val lineOffset = 2

scaladoc/src/dotty/tools/scaladoc/tasty/comments/markdown/DocFlexmarkExtension.scala

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import com.vladsch.flexmark.ext.wikilink.internal.WikiLinkLinkRefProcessor
1010
import com.vladsch.flexmark.util.ast._
1111
import com.vladsch.flexmark.util.options._
1212
import com.vladsch.flexmark.util.sequence.BasedSequence
13-
13+
import com.vladsch.flexmark._
1414

1515
class DocLinkNode(
1616
val target: DocLink,
@@ -45,17 +45,32 @@ object DocFlexmarkParser {
4545
}
4646
}
4747

48-
case class DocFlexmarkRenderer(renderLink: (DocLink, String) => String)
48+
case class DocFlexmarkRenderer(renderLink: (DocLink, String) => String, snippetCheckingFunc: (String) => Unit)
4949
extends HtmlRenderer.HtmlRendererExtension:
50+
5051
def rendererOptions(opt: MutableDataHolder): Unit = () // noop
5152

53+
object CodeHandler extends CustomNodeRenderer[ast.Code]:
54+
override def render(node: ast.Code, c: NodeRendererContext, html: HtmlWriter): Unit =
55+
snippetCheckingFunc(node.getText.toString)
56+
c.delegateRender()
57+
58+
object CodeBlockHandler extends CustomNodeRenderer[ast.CodeBlock]:
59+
override def render(node: ast.CodeBlock, c: NodeRendererContext, html: HtmlWriter): Unit =
60+
snippetCheckingFunc(node.getContentChars.toString)
61+
c.delegateRender()
62+
5263
object Handler extends CustomNodeRenderer[DocLinkNode]:
5364
override def render(node: DocLinkNode, c: NodeRendererContext, html: HtmlWriter): Unit =
5465
html.raw(renderLink(node.target, node.body))
5566

5667
object Render extends NodeRenderer:
5768
override def getNodeRenderingHandlers: JSet[NodeRenderingHandler[_]] =
58-
JSet(new NodeRenderingHandler(classOf[DocLinkNode], Handler))
69+
JSet(
70+
new NodeRenderingHandler(classOf[DocLinkNode], Handler),
71+
new NodeRenderingHandler(classOf[ast.Code], CodeHandler),
72+
new NodeRenderingHandler(classOf[ast.CodeBlock], CodeBlockHandler)
73+
)
5974

6075
object Factory extends NodeRendererFactory:
6176
override def create(options: DataHolder): NodeRenderer = Render
@@ -64,6 +79,6 @@ case class DocFlexmarkRenderer(renderLink: (DocLink, String) => String)
6479
htmlRendererBuilder.nodeRendererFactory(Factory)
6580

6681
object DocFlexmarkRenderer:
67-
def render(node: Node)(renderLink: (DocLink, String) => String) =
68-
val opts = MarkdownParser.mkMarkdownOptions(Seq(DocFlexmarkRenderer(renderLink)))
82+
def render(node: Node)(renderLink: (DocLink, String) => String, snippetCheckingFunc: (String) => Unit) =
83+
val opts = MarkdownParser.mkMarkdownOptions(Seq(DocFlexmarkRenderer(renderLink, snippetCheckingFunc)))
6984
HtmlRenderer.builder(opts).build().render(node)

0 commit comments

Comments
 (0)