diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-05-30 17:45:32 +0200 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2016-08-19 15:37:24 +0200 |
commit | 59055f28c7f6f3b01216ccbbd701e138101912d3 (patch) | |
tree | c5aee716316c5d34bb215a5a2f4eec22afc90a42 /dottydoc/jvm/src | |
parent | 926a81c358b58ea09de86f8d55519cc38bc97034 (diff) | |
download | dotty-59055f28c7f6f3b01216ccbbd701e138101912d3.tar.gz dotty-59055f28c7f6f3b01216ccbbd701e138101912d3.tar.bz2 dotty-59055f28c7f6f3b01216ccbbd701e138101912d3.zip |
Add basic member-lookup for result types
Diffstat (limited to 'dottydoc/jvm/src')
-rw-r--r-- | dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala | 11 | ||||
-rw-r--r-- | dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala | 92 | ||||
-rw-r--r-- | dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala | 68 | ||||
-rw-r--r-- | dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala (renamed from dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala) | 22 | ||||
-rw-r--r-- | dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala | 19 | ||||
-rw-r--r-- | dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala | 11 |
6 files changed, 88 insertions, 135 deletions
diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala index 81dc21bbc..e4da0a971 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala @@ -13,7 +13,7 @@ import dotc.core.Symbols.Symbol object Phases { class DocPhase extends Phase { - import model.CommentParsers.WikiParser + import model.parsers.{ WikiParser, ReturnTypeParser } import model._ import model.factories._ import model.internal._ @@ -26,6 +26,7 @@ object Phases { def phaseName = "docphase" private[this] val commentParser = new WikiParser + private[this] val returnLinker = new ReturnTypeParser /** Saves the commentParser function for later evaluation, for when the AST has been filled */ def track(symbol: Symbol, ctx: Context)(op: => Entity) = { @@ -79,11 +80,11 @@ object Phases { /** def */ case d: DefDef => - DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d.tpt)) + DefImpl(filteredName(d.name.toString), flags(d), path(d), returnType(d, d.tpt)) /** val */ case v: ValDef if !v.symbol.is(Flags.ModuleVal) => - ValImpl(filteredName(v.name.toString), flags(v), path(v), returnType(v.tpt)) + ValImpl(filteredName(v.name.toString), flags(v), path(v), returnType(v, v.tpt)) case x => { //dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}") @@ -137,6 +138,10 @@ object Phases { child <- parent.children } setParent(child, to = parent) + + // (3) Set returntypes to correct entities + returnLinker.link(packages) + // (3) Create documentation template from docstrings, with internal links println("Generating documentation, this might take a while...") commentParser.parse(packages) diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala deleted file mode 100644 index f423cf8de..000000000 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala +++ /dev/null @@ -1,92 +0,0 @@ -package dotty.tools.dottydoc -package model -package comment - -import scala.collection._ - -/** A body of text. A comment has a single body, which is composed of - * at least one block. Inside every body is exactly one summary (see - * [[scala.tools.nsc.doc.model.comment.Summary]]). */ -final case class Body(blocks: Seq[Block]) { - - /** The summary text of the comment body. */ - lazy val summary: Option[Body] = { - def summaryInBlock(block: Block): Seq[Inline] = block match { - case Title(text, _) => summaryInInline(text) - case Paragraph(text) => summaryInInline(text) - case UnorderedList(items) => items flatMap summaryInBlock - case OrderedList(items, _) => items flatMap summaryInBlock - case DefinitionList(items) => items.values.toSeq flatMap summaryInBlock - case _ => Nil - } - def summaryInInline(text: Inline): Seq[Inline] = text match { - case Summary(text) => List(text) - case Chain(items) => items flatMap summaryInInline - case Italic(text) => summaryInInline(text) - case Bold(text) => summaryInInline(text) - case Underline(text) => summaryInInline(text) - case Superscript(text) => summaryInInline(text) - case Subscript(text) => summaryInInline(text) - case Link(_, title) => summaryInInline(title) - case _ => Nil - } - (blocks flatMap summaryInBlock).toList match { - case Nil => None - case inline :: Nil => Some(Body(Seq(Paragraph(inline)))) - case inlines => Some(Body(Seq(Paragraph(Chain(inlines))))) - } - } -} - -/** A block-level element of text, such as a paragraph or code block. */ -sealed abstract class Block - -final case class Title(text: Inline, level: Int) extends Block -final case class Paragraph(text: Inline) extends Block -final case class Code(data: String) extends Block -final case class UnorderedList(items: Seq[Block]) extends Block -final case class OrderedList(items: Seq[Block], style: String) extends Block -final case class DefinitionList(items: SortedMap[Inline, Block]) extends Block -final case class HorizontalRule() extends Block - -/** An section of text inside a block, possibly with formatting. */ -sealed abstract class Inline - -final case class Chain(items: Seq[Inline]) extends Inline -final case class Italic(text: Inline) extends Inline -final case class Bold(text: Inline) extends Inline -final case class Underline(text: Inline) extends Inline -final case class Superscript(text: Inline) extends Inline -final case class Subscript(text: Inline) extends Inline -final case class Link(target: String, title: Inline) extends Inline -final case class Monospace(text: Inline) extends Inline -final case class Text(text: String) extends Inline -abstract class EntityLink(val title: Inline) extends Inline { def link: LinkTo } -object EntityLink { - def apply(title: Inline, linkTo: LinkTo) = new EntityLink(title) { def link: LinkTo = linkTo } - def unapply(el: EntityLink): Option[(Inline, LinkTo)] = Some((el.title, el.link)) -} -final case class HtmlTag(data: String) extends Inline { - private val Pattern = """(?ms)\A<(/?)(.*?)[\s>].*\z""".r - private val (isEnd, tagName) = data match { - case Pattern(s1, s2) => - (! s1.isEmpty, Some(s2.toLowerCase)) - case _ => - (false, None) - } - - def canClose(open: HtmlTag) = { - isEnd && tagName == open.tagName - } - - private val TagsNotToClose = Set("br", "img") - def close = tagName collect { case name if !TagsNotToClose(name) => HtmlTag(s"</$name>") } -} - -/** The summary of a comment, usually its first sentence. There must be exactly one summary per body. */ -final case class Summary(text: Inline) extends Inline - -sealed trait LinkTo -final case class LinkToEntity(entity: Entity) extends LinkTo -final case class LinkToExternal(name: String, url: String) extends LinkTo -final case class Tooltip(name: String) extends LinkTo diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala index 725d83557..8c1fa8d49 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala @@ -6,37 +6,7 @@ object BodyParsers { implicit class BodyToHtml(val body: Body) extends AnyVal { def toHtml(origin: Entity): String = { - def inlineToHtml(inl: Inline): String = inl match { - case Chain(items) => (items map inlineToHtml).mkString - case Italic(in) => s"<i>${inlineToHtml(in)}</i>" - case Bold(in) => s"<b>${inlineToHtml(in)}</b>" - case Underline(in) => s"<u>${inlineToHtml(in)}</u>" - case Superscript(in) => s"<sup>${inlineToHtml(in)}</sup>" - case Subscript(in) => s"<sub>${inlineToHtml(in) }</sub>" - case Link(raw, title) => s"""<a href=$raw target="_blank">${inlineToHtml(title)}</a>""" - case Monospace(in) => s"<code>${inlineToHtml(in)}</code>" - case Text(text) => text - case Summary(in) => inlineToHtml(in) - case HtmlTag(tag) => tag - case EntityLink(target, link) => enityLinkToHtml(target, link) - } - - def enityLinkToHtml(target: Inline, link: LinkTo) = link match { - case Tooltip(_) => inlineToHtml(target) - case LinkToExternal(n, url) => s"""<a href="$url">$n</a>""" - case LinkToEntity(t: Entity) => t match { - // Entity is a package member - case e: Entity with Members => - s"""<a href="${relativePath(t)}">${inlineToHtml(target)}</a>""" - // Entity is a Val / Def - case x => x.parent.fold(inlineToHtml(target)) { xpar => - s"""<a href="${relativePath(xpar)}#${x.name}">${inlineToHtml(target)}</a>""" - } - } - } - - def relativePath(target: Entity) = - util.traversing.relativePath(origin, target) + val inlineToHtml = InlineToHtml(origin) def bodyToHtml(body: Body): String = (body.blocks map blockToHtml).mkString @@ -73,4 +43,40 @@ object BodyParsers { bodyToHtml(body) } } + + case class InlineToHtml(origin: Entity) { + def apply(inline: Inline) = toHtml(inline) + + def relativePath(target: Entity) = + util.traversing.relativePath(origin, target) + + def toHtml(inline: Inline): String = inline match { + case Chain(items) => (items map toHtml).mkString + case Italic(in) => s"<i>${toHtml(in)}</i>" + case Bold(in) => s"<b>${toHtml(in)}</b>" + case Underline(in) => s"<u>${toHtml(in)}</u>" + case Superscript(in) => s"<sup>${toHtml(in)}</sup>" + case Subscript(in) => s"<sub>${toHtml(in) }</sub>" + case Link(raw, title) => s"""<a href=$raw target="_blank">${toHtml(title)}</a>""" + case Monospace(in) => s"<code>${toHtml(in)}</code>" + case Text(text) => text + case Summary(in) => toHtml(in) + case HtmlTag(tag) => tag + case EntityLink(target, link) => enityLinkToHtml(target, link) + } + + def enityLinkToHtml(target: Inline, link: LinkTo) = link match { + case Tooltip(_) => toHtml(target) + case LinkToExternal(n, url) => s"""<a href="$url">$n</a>""" + case LinkToEntity(t: Entity) => t match { + // Entity is a package member + case e: Entity with Members => + s"""<a href="${relativePath(t)}">${toHtml(target)}</a>""" + // Entity is a Val / Def + case x => x.parent.fold(toHtml(target)) { xpar => + s"""<a href="${relativePath(xpar)}#${x.name}">${toHtml(target)}</a>""" + } + } + } + } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala index 9320bb5fe..8d5eb3467 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/CommentParsers.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/model/parsers.scala @@ -4,11 +4,13 @@ package model import dotc.core.Symbols.Symbol import dotc.core.Contexts.Context +import dotc.util.Positions.NoPosition -object CommentParsers { +object parsers { import comment._ import BodyParsers._ import model.internal._ + import util.MemberLookup import util.traversing._ import util.internal.setters._ @@ -81,4 +83,22 @@ object CommentParsers { def clear(): Unit = commentCache = Map.empty } + + class ReturnTypeParser extends MemberLookup { + def link(packs: Map[String, Package]): Unit = + for (pack <- packs.values) mutateEntities(pack) { ent => + if (ent.isInstanceOf[ReturnValue]) + setReturnValue(ent, returnValue(ent, ent.asInstanceOf[ReturnValue], packs)) + } + + private def returnValue(ent: Entity, rv: ReturnValue, packs: Map[String, Package]): MaterializableLink = { + if (rv.returnValue.isInstanceOf[UnsetLink]) { + val unset = rv.returnValue.asInstanceOf[UnsetLink] + val el = makeEntityLink(ent, packs, unset.title, NoPosition, unset.query) + val inlineToHtml = InlineToHtml(ent) + + MaterializedLink(inlineToHtml(unset.title), inlineToHtml(el)) + } else rv.returnValue + } + } } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala index f95829caf..d8abb0319 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/MemberLookup.scala @@ -30,7 +30,12 @@ trait MemberLookup { /** Looks for the specified entity among `ent`'s members */ def localLookup(ent: Entity with Members, searchStr: String): LinkTo = - ent.members.find(_.name == searchStr).fold(notFound)(e => LinkToEntity(e)) + ent + .members + .collect { case x if x.name == searchStr => x } + .sortBy(_.path.last) + .headOption + .fold(notFound)(e => LinkToEntity(e)) /** Looks for an entity down in the structure, if the search list is Nil, * the search stops @@ -43,8 +48,8 @@ trait MemberLookup { case x :: xs => ent .members - .collect { case e: Entity with Members => e } - .find(_.name == x) + .collect { case e: Entity with Members if e.name == x => e } + .headOption .fold(notFound)(e => downwardLookup(e, xs)) } @@ -71,8 +76,10 @@ trait MemberLookup { localLookup(e, x) case (x :: _, e: Entity with Members) if x == entity.name => downwardLookup(e, querys) - case _ => - globalLookup + case (x :: xs, _) => + if (xs.nonEmpty) + globalLookup + else lookup(entity, packages, "scala." + query, pos) } } @@ -82,5 +89,5 @@ trait MemberLookup { title: Inline, pos: Position, query: String - ): Inline = EntityLink(title, lookup(entity, packages, query, pos)) + ): EntityLink = EntityLink(title, lookup(entity, packages, query, pos)) } diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala index 798d54041..bbef32474 100644 --- a/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala +++ b/dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala @@ -4,8 +4,8 @@ package internal object setters { import model._ - import model.comment.Comment - import model.internal._ + import comment.{ Comment, MaterializableLink } + import internal._ def setComment(ent: Entity, to: Option[Comment]) = ent match { case x: PackageImpl => x.comment = to @@ -17,6 +17,13 @@ object setters { case x: ValImpl => x.comment = to } + + def setReturnValue(ent: Entity, to: MaterializableLink) = ent match { + case x: DefImpl => x.returnValue = to + case x: ValImpl => x.returnValue = to + case _ => () + } + def setParent(ent: Entity, to: Entity): Unit = ent match { case e: ClassImpl => e.parent = to |