diff options
4 files changed, 106 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala index 7485533641..02fadb94fd 100644 --- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala @@ -172,7 +172,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /** Safe HTML tags that can be kept. */ protected val SafeTags = - new Regex("""((&\w+;)|(&#\d+;)|(<code( [^>]*)?>.*?</code>)|(</?(abbr|acronym|address|area|a|bdo|big|blockquote|br|button|b|caption|cite|col|colgroup|dd|del|dfn|em|fieldset|form|hr|img|input|ins|i|kbd|label|legend|link|map|object|optgroup|option|param|pre|q|samp|select|small|span|strong|sub|sup|table|tbody|td|textarea|tfoot|th|thead|tr|tt|var)( [^>]*)?/?>))""") + new Regex("""((&\w+;)|(&#\d+;)|(</?(abbr|acronym|address|area|a|bdo|big|blockquote|br|button|b|caption|cite|code|col|colgroup|dd|del|dfn|em|fieldset|form|hr|img|input|ins|i|kbd|label|legend|link|map|object|optgroup|option|param|pre|q|samp|select|small|span|strong|sub|sup|table|tbody|td|textarea|tfoot|th|thead|tr|tt|var)( [^>]*)?/?>))""") protected val safeTagMarker = '\u000E' @@ -515,10 +515,50 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => /* INLINES */ + val OPEN_TAG = "^<([A-Za-z]+)( [^>]*)?(/?)>$".r + val CLOSE_TAG = "^</([A-Za-z]+)>$".r + private def readHTMLFrom(begin: HtmlTag): String = { + val list = mutable.ListBuffer.empty[String] + val stack = mutable.ListBuffer.empty[String] + + begin.close match { + case Some(HtmlTag(CLOSE_TAG(s))) => + stack += s + case _ => + return "" + } + + do { + readUntil { char == safeTagMarker || char == endOfText } + val str = getRead() + nextChar() + + list += str + + str match { + case OPEN_TAG(s, _, standalone) => { + if (standalone != "/") { + stack += s + } + } + case CLOSE_TAG(s) => { + if (s == stack.last) { + stack.remove(stack.length-1) + } + } + case _ => ; + } + } while (stack.length > 0 && char != endOfText); + + return list.mkString("") + } def inline(isInlineEnd: => Boolean): Inline = { def inline0(): Inline = { - if (char == safeTagMarker) htmlTag() + if (char == safeTagMarker) { + val tag = htmlTag() + HtmlTag(tag.data + readHTMLFrom(tag)) + } else if (check("'''")) bold() else if (check("''")) italic() else if (check("`")) monospace() @@ -563,7 +603,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory => } - def htmlTag(): Inline = { + def htmlTag(): HtmlTag = { jump(safeTagMarker) readUntil(safeTagMarker) if (char != endOfText) jump(safeTagMarker) diff --git a/test/scaladoc/resources/Trac4358.scala b/test/scaladoc/resources/Trac4358.scala new file mode 100644 index 0000000000..39eee3d47e --- /dev/null +++ b/test/scaladoc/resources/Trac4358.scala @@ -0,0 +1,8 @@ +trait EasyMockSugar { + /** + * Implicit conversion that invokes the <code>expect</code> method on the <code>EasyMock</code> companion object (<em>i.e.</em>, the + * static <code>expect</code> method in Java class <code>org.easymock.EasyMock</code>). + * + */ + val foo = 123 +} diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.scala b/test/scaladoc/scala/html/HtmlFactoryTest.scala index ecdbb3cf46..da77aed7da 100644 --- a/test/scaladoc/scala/html/HtmlFactoryTest.scala +++ b/test/scaladoc/scala/html/HtmlFactoryTest.scala @@ -124,4 +124,24 @@ object Test extends Properties("HtmlFactory") { case _ => false } } + + property("Trac #4358") = { + val files = createTemplates("Trac4358.scala") + files("EasyMockSugar.html") match { + case node: scala.xml.Node => { + val comments = XMLUtil.stripGroup(node).descendant.flatMap { + case e: scala.xml.Elem => { + if (e.attribute("class").toString.contains("shortcomment")) { + Some(e) + } else { + None + } + } + case _ => None + } + ! comments.exists { _.toString.contains("<em>i.</em>") } + } + case _ => false + } + } } diff --git a/test/scaladoc/scala/model/CommentFactoryTest.scala b/test/scaladoc/scala/model/CommentFactoryTest.scala index 25a91b1fa2..9f60d2a1b7 100644 --- a/test/scaladoc/scala/model/CommentFactoryTest.scala +++ b/test/scaladoc/scala/model/CommentFactoryTest.scala @@ -92,11 +92,9 @@ object Test extends Properties("CommentFactory") { * */""", Chain(List(Text(""), Text("\n"), - HtmlTag("<pre>"), Text("\n"), - Text("hello "), Chain(List(Text("^"), - Chain(List(Text("world"), - Text("\n"), - HtmlTag("</pre>"))))))) + + + HtmlTag("<pre>\nhello ^world\n</pre>"))) ) property("Trac #4366 - body") = { @@ -109,8 +107,7 @@ object Test extends Properties("CommentFactory") { ) body == Body(List(Paragraph(Chain(List( - Summary(Chain(List(Chain(List(HtmlTag("<strong>"), HtmlTag("<code>foo</code>"), Text(" has been deprecated and will be removed in a future version"))), Text(".")))), - Chain(List(Text(" Please call "), HtmlTag("<code>bar</code>"), Text(" instead."), HtmlTag("</strong>"), Text("\n"), Text(""))) + Summary(Chain(List(HtmlTag("<strong><code>foo</code> has been deprecated and will be removed in a future version. Please call <code>bar</code> instead.</strong>"), Text("\n"), Text("")))) ))))) } @@ -122,7 +119,37 @@ object Test extends Properties("CommentFactory") { */ """ ) + body.summary == Some(Chain(List(HtmlTag("<strong><code>foo</code> has been deprecated and will be removed in a future version. Please call <code>bar</code> instead.</strong>"), Text("\n"), Text("")))) + } - body.summary == Some(Chain(List(Chain(List(HtmlTag("<strong>"), HtmlTag("<code>foo</code>"), Text(" has been deprecated and will be removed in a future version"))), Text(".")))) + property("Trac #4358 - body") = { + factory.createBody( + """ + /** + * Implicit conversion that invokes the <code>expect</code> method on the <code>EasyMock</code> companion object (<em>i.e.</em>, the + * static <code>expect</code> method in Java class <code>org.easymock.EasyMock</code>). + */ + """ + ) match { + case Body(List(Paragraph(Chain(List(Summary(Chain(List(Chain(List( + Text("Implicit conversion that invokes the "), + HtmlTag("<code>expect</code>"), + Text(" method on the "), + HtmlTag("<code>EasyMock</code>"), + Text(" companion object ("), + HtmlTag("<em>i.e.</em>"), + Text(", the\nstatic "), + HtmlTag("<code>expect</code>"), + Text(" method in Java class "), + HtmlTag("<code>org.easymock.EasyMock</code>"), + Text(")") + )), Text(".")))), Text("\n")))))) => + true + case other => { + println(other) + false + } + } } + } |