From d153ceeed133adfefe6c44a56f8ee502c1278e89 Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Wed, 3 Sep 2014 10:39:22 +0200 Subject: SI-8113 allow a newline between a link target and title Parsing "[[http://foo.bar link title]]" stops at the first whitespace. This breaks pretty badly in: [[http://foo.bar link title]] It stops after "link", interprets what it parsed as a link to a member, obviously fails, and then just ouputs "title". It should at least return a proper error, or, even better, just allow a newline between the target and title. I went for the latter. --- .../tools/nsc/doc/base/CommentFactoryBase.scala | 8 +++-- test/scaladoc/run/t8113.check | 1 + test/scaladoc/run/t8113.scala | 36 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/scaladoc/run/t8113.check create mode 100644 test/scaladoc/run/t8113.scala diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala index d5e2f9a2c4..6f81739031 100755 --- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala @@ -681,10 +681,10 @@ trait CommentFactoryBase { this: MemberLookupBase => jump("[[") val parens = 2 + repeatJump('[') val stop = "]" * parens - val target = readUntil { check(stop) || check(" ") } + val target = readUntil { check(stop) || isWhitespaceOrNewLine(char) } val title = if (!check(stop)) Some({ - jump(" ") + jumpWhitespaceOrNewLine() inline(check(stop)) }) else None @@ -899,6 +899,8 @@ trait CommentFactoryBase { this: MemberLookupBase => def jumpWhitespace() = jumpUntil(!isWhitespace(char)) + def jumpWhitespaceOrNewLine() = jumpUntil(!isWhitespaceOrNewLine(char)) + /* READERS */ final def readUntil(c: Char): String = { @@ -938,5 +940,7 @@ trait CommentFactoryBase { this: MemberLookupBase => /* CHARS CLASSES */ def isWhitespace(c: Char) = c == ' ' || c == '\t' + + def isWhitespaceOrNewLine(c: Char) = isWhitespace(c) || c == '\n' } } diff --git a/test/scaladoc/run/t8113.check b/test/scaladoc/run/t8113.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/t8113.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/t8113.scala b/test/scaladoc/run/t8113.scala new file mode 100644 index 0000000000..f006213ef2 --- /dev/null +++ b/test/scaladoc/run/t8113.scala @@ -0,0 +1,36 @@ +import scala.tools.nsc.doc.base._ +import scala.tools.nsc.doc.base.comment._ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + /** + * Check out [[http://www.scala-lang.org + * this great website]]! + */ + class Test + """ + + def scaladocSettings = "" + + def testModel(rootPackage: Package) = { + import access._ + + val test = rootPackage._class("Test") + + // find Link + def find(body: Any): Option[Link] = body match { + case l: Link => Some(l) + case s: Seq[_] => s.toList.map(find(_)).flatten.headOption + case p: Product => p.productIterator.toList.map(find(_)).flatten.headOption + case _ => None + } + + val link = find(test.comment.get.body).collect { case Link(ta, Text(ti)) => (ta, ti) } + assert(link.isDefined) + val expected = ("http://www.scala-lang.org", "this great website") + link.foreach {l => assert(l == expected, s"$l != $expected")} + } +} -- cgit v1.2.3