From 079e3db0f157ee6eae9e8a34b3bbf7a75cdaa929 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Mon, 8 Aug 2016 14:19:57 +0200 Subject: Implement annotation parsing like CommentFactoryBase from nsc --- dottydoc/js/src/html/EntityLayout.scala | 48 +++++---- dottydoc/js/src/model/entities.scala | 22 +++- .../tools/dottydoc/model/comment/Comment.scala | 24 ++++- .../dottydoc/model/comment/CommentParser.scala | 119 +++++++++++++++------ .../jvm/src/dotty/tools/dottydoc/model/json.scala | 3 +- .../src/dotty/tools/dottydoc/model/parsers.scala | 9 +- 6 files changed, 158 insertions(+), 67 deletions(-) diff --git a/dottydoc/js/src/html/EntityLayout.scala b/dottydoc/js/src/html/EntityLayout.scala index 251644075..f81f42e02 100644 --- a/dottydoc/js/src/html/EntityLayout.scala +++ b/dottydoc/js/src/html/EntityLayout.scala @@ -58,28 +58,34 @@ case class EntityLayout(entity: Entity) extends MemberLayout { main( id := "entity-container", cls := "mdl-layout__content", - div( - cls := "page-content", - div(cls := "entity-title", entityTitle), - div(raw(entity.comment.fold("")(_.body))), - entity match { - case x if x.hasMembers => - val e = x.asInstanceOf[Entity with Members] - if (e.members.nonEmpty) - Seq( - h5("Members"), - div( - cls := "mld-grid", - e.members - .collect { - case x if x.hasModifiers && !x.isPrivate => x - } - .flatMap(member(_, entity)).toList + div( + cls := "page-content", + div(cls := "entity-title", entityTitle), + div(raw(entity.comment.fold("")(_.body))), + entity.comment.filter(_.authors.nonEmpty).map { comment => + dl( + dt(cls := "entity-authors", "Authors"), + comment.authors.map(x => dd(cls := "entity-author", raw(x))).toList + ) + }.toOption, + entity match { + case x if x.hasMembers => + val e = x.asInstanceOf[Entity with Members] + if (e.members.nonEmpty) + Seq( + h5("Members"), + div( + cls := "mdl-grid", + e.members + .collect { + case x if x.hasModifiers && !x.isPrivate => x + } + .flatMap(member(_, entity)).toList + ) ) - ) - case _ => () - } - ) + case _ => () + } + ) ), main( id := "search-results", diff --git a/dottydoc/js/src/model/entities.scala b/dottydoc/js/src/model/entities.scala index 4180ad431..ca1b5ec69 100644 --- a/dottydoc/js/src/model/entities.scala +++ b/dottydoc/js/src/model/entities.scala @@ -28,8 +28,26 @@ trait Entity extends sjs.Object { @ScalaJSDefined trait Comment extends sjs.Object { - val body: String - val short: String + val body: String + val short: String + val authors: sjs.Array[String] + val see: sjs.Array[String] + val result: sjs.UndefOr[String] + val throws: Map[String, String] + val valueParams: Map[String, String] + val typeParams: Map[String, String] + val version: sjs.UndefOr[String] + val since: sjs.UndefOr[String] + val todo: List[String] + val deprecated: sjs.UndefOr[String] + val note: List[String] + val example: List[String] + val constructor: sjs.UndefOr[String] + val group: sjs.UndefOr[String] + val groupDesc: Map[String, String] + val groupNames: Map[String, String] + val groupPrio: Map[String, String] + val hideImplicitConversions: List[String] } @ScalaJSDefined diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala index ad53b9ae7..c4f6ccf5d 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/Comment.scala @@ -3,4 +3,26 @@ package dottydoc package model package comment -case class Comment(body: String, short: String) +case class Comment ( + body: String, + short: String, + authors: List[String], + see: List[String], + result: Option[String], + throws: Map[String, String], + valueParams: Map[String, String], + typeParams: Map[String, String], + version: Option[String], + since: Option[String], + todo: List[String], + deprecated: Option[String], + note: List[String], + example: List[String], + constructor: Option[String], + group: Option[String], + groupDesc: Map[String, String], + groupNames: Map[String, String], + groupPrio: Map[String, String], + /** List of conversions to hide - containing e.g: `scala.Predef.FloatArrayOps` */ + hideImplicitConversions: List[String] +) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala index fb2119fc0..589e2ebe2 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/CommentParser.scala @@ -13,6 +13,59 @@ trait CommentParser extends util.MemberLookup { import Regexes._ import model.internal._ + case class FullComment ( + body: Body, + authors: List[Body], + see: List[Body], + result: Option[Body], + throws: Map[String, Body], + valueParams: Map[String, Body], + typeParams: Map[String, Body], + version: Option[Body], + since: Option[Body], + todo: List[Body], + deprecated: Option[Body], + note: List[Body], + example: List[Body], + constructor: Option[Body], + group: Option[Body], + groupDesc: Map[String, Body], + groupNames: Map[String, Body], + groupPrio: Map[String, Body], + hideImplicitConversions: List[Body], + shortDescription: List[Body] + ) { + + /** + * Transform this CommentParser.FullComment to a Comment using the supplied + * Body transformer + */ + def toComment(transform: Body => String) = Comment( + transform(body), + short = + if (shortDescription.nonEmpty) shortDescription.map(transform).mkString + else body.summary.map(transform).getOrElse(""), + authors.map(transform), + see.map(transform), + result.map(transform), + throws.map { case (k, v) => (k, transform(v)) }, + valueParams.map { case (k, v) => (k, transform(v)) }, + typeParams.map { case (k, v) => (k, transform(v)) }, + version.map(transform), + since.map(transform), + todo.map(transform), + deprecated.map(transform), + note.map(transform), + example.map(transform), + constructor.map(transform), + group.map(transform), + groupDesc.map { case (k, v) => (k, transform(v)) }, + groupNames.map { case (k, v) => (k, transform(v)) }, + groupPrio.map { case (k, v) => (k, transform(v)) }, + hideImplicitConversions.map(transform) + ) + } + /** Parses a raw comment string into a `Comment` object. * @param packages all packages parsed by Scaladoc tool, used for lookup * @param cleanComment a cleaned comment to be parsed @@ -26,7 +79,7 @@ trait CommentParser extends util.MemberLookup { src: String, pos: Position, site: Symbol = NoSymbol - )(implicit ctx: Context): Body = { + )(implicit ctx: Context): FullComment = { /** Parses a comment (in the form of a list of lines) to a `Comment` * instance, recursively on lines. To do so, it splits the whole comment @@ -48,7 +101,7 @@ trait CommentParser extends util.MemberLookup { lastTagKey: Option[TagKey], remaining: List[String], inCodeBlock: Boolean - ): Body = remaining match { + ): FullComment = remaining match { case CodeBlockStartRegex(before, marker, after) :: ls if (!inCodeBlock) => if (!before.trim.isEmpty && !after.trim.isEmpty) @@ -155,8 +208,8 @@ trait CommentParser extends util.MemberLookup { case _ => None } - def allTags(key: SimpleTagKey): List[Body] = - (bodyTags remove key).getOrElse(Nil).filterNot(_.blocks.isEmpty) + def allTags[B](key: SimpleTagKey): List[Body] = + (bodyTags remove key).getOrElse(Nil).filterNot(_.blocks.isEmpty).reverse def allSymsOneTag(key: TagKey, filterEmpty: Boolean = true): Map[String, Body] = { val keys: Seq[SymbolTagKey] = @@ -193,37 +246,33 @@ trait CommentParser extends util.MemberLookup { } } - // TODO: this method should return a parsed comment with the members below - //val com = createComment ( - // body0 = Some(parseWikiAtSymbol(docBody.toString, pos, site)), - // authors0 = allTags(SimpleTagKey("author")), - // see0 = allTags(SimpleTagKey("see")), - // result0 = oneTag(SimpleTagKey("return")), - // throws0 = linkedExceptions, - // valueParams0 = allSymsOneTag(SimpleTagKey("param")), - // typeParams0 = allSymsOneTag(SimpleTagKey("tparam")), - // version0 = oneTag(SimpleTagKey("version")), - // since0 = oneTag(SimpleTagKey("since")), - // todo0 = allTags(SimpleTagKey("todo")), - // deprecated0 = oneTag(SimpleTagKey("deprecated"), filterEmpty = false), - // note0 = allTags(SimpleTagKey("note")), - // example0 = allTags(SimpleTagKey("example")), - // constructor0 = oneTag(SimpleTagKey("constructor")), - // source0 = Some(clean(src).mkString("\n")), - // inheritDiagram0 = inheritDiagramText, - // contentDiagram0 = contentDiagramText, - // group0 = oneTag(SimpleTagKey("group")), - // groupDesc0 = allSymsOneTag(SimpleTagKey("groupdesc")), - // groupNames0 = allSymsOneTag(SimpleTagKey("groupname")), - // groupPrio0 = allSymsOneTag(SimpleTagKey("groupprio")), - // hideImplicitConversions0 = allTags(SimpleTagKey("hideImplicitConversion")), - // shortDescription0 = allTags(SimpleTagKey("shortDescription")) - //) - // - //for ((key, _) <- bodyTags) - // dottydoc.println(s"$pos: Tag '@${key.name}' is not recognised") - - parseWikiAtSymbol(entity, packages, docBody.toString, pos, site) + val cmt = FullComment( + body = parseWikiAtSymbol(entity, packages, docBody.toString, pos, site), + authors = allTags(SimpleTagKey("author")), + see = allTags(SimpleTagKey("see")), + result = oneTag(SimpleTagKey("return")), + throws = linkedExceptions, + valueParams = allSymsOneTag(SimpleTagKey("param")), + typeParams = allSymsOneTag(SimpleTagKey("tparam")), + version = oneTag(SimpleTagKey("version")), + since = oneTag(SimpleTagKey("since")), + todo = allTags(SimpleTagKey("todo")), + deprecated = oneTag(SimpleTagKey("deprecated"), filterEmpty = false), + note = allTags(SimpleTagKey("note")), + example = allTags(SimpleTagKey("example")), + constructor = oneTag(SimpleTagKey("constructor")), + group = oneTag(SimpleTagKey("group")), + groupDesc = allSymsOneTag(SimpleTagKey("groupdesc")), + groupNames = allSymsOneTag(SimpleTagKey("groupname")), + groupPrio = allSymsOneTag(SimpleTagKey("groupprio")), + hideImplicitConversions = allTags(SimpleTagKey("hideImplicitConversion")), + shortDescription = allTags(SimpleTagKey("shortDescription")) + ) + + for ((key, _) <- bodyTags) + dottydoc.println(s"$pos: Tag '@${key.name}' is not recognised") + + cmt } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala index f83f43138..a512ee352 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/json.scala @@ -25,7 +25,8 @@ object json { } implicit class JsonComment(val cmt: Comment) extends AnyVal { - def json: String = s"""{"body":${cmt.body.json},"short":${cmt.short.json}}""" + def json: String = + s"""{"body":${cmt.body.json},"short":${cmt.short.json},"authors":${cmt.authors.map(_.json).mkString("[",",","]")},"see":${cmt.see.map(_.json).mkString("[",",","]")},${cmt.result.map(res => s""""result":${res.json},""").getOrElse("")}"throws":${cmt.throws.map { case (k, v) => s"${k.json}:${v.json}" }.mkString("{",",","}")},"valueParams":${cmt.valueParams.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"typeParams":${cmt.typeParams.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},${cmt.version.map(x => s""""version":${x.json},""").getOrElse("")}${cmt.since.map(x => s""""since":${x.json},""").getOrElse("")}"todo":${cmt.todo.map(_.json).mkString("[",",","]")},${cmt.deprecated.map(x => s""""deprecated":${x.json},""").getOrElse("")}"note":${cmt.note.map(_.json).mkString("[",",","]")},"example":${cmt.example.map(_.json).mkString("[",",","]")},${cmt.constructor.map(x => s""""constructor":${x.json},""").getOrElse("")}${cmt.group.map(x => s""""group":${x.json},""").getOrElse("")}"groupDesc":${cmt.groupDesc.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"groupNames":${cmt.groupNames.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"groupPrio":${cmt.groupPrio.map { case (k, v) => s"${k.json}:${v.json}"}.mkString("{",",","}")},"hideImplicitConversions":${cmt.hideImplicitConversions.map(_.json).mkString("[",",","]")}}""" } implicit class LinkJson(val link: MaterializableLink) extends AnyVal { diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index afd1cf982..fa54163e5 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -25,13 +25,8 @@ object parsers { def parseHtml(sym: Symbol, parent: Symbol, entity: Entity, packages: Map[String, Package])(implicit ctx: Context): (String, Option[Comment]) = { val cmt = ctx.docbase.docstring(sym).map { d => val expanded = expand(sym, parent) - val body = parse(entity, packages, clean(expanded), expanded, d.pos) - val summary = body.summary.map(_.toHtml(entity)).getOrElse("") - body.toHtml(entity) match { - case "" => None - case x => Some(Comment(x, summary)) - } - }.flatten + parse(entity, packages, clean(expanded), expanded, d.pos).toComment(_.toHtml(entity)) + } (entity.path.mkString("."), cmt) } -- cgit v1.2.3