aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-05-30 17:45:32 +0200
committerFelix Mulder <felix.mulder@gmail.com>2016-08-19 15:37:24 +0200
commit59055f28c7f6f3b01216ccbbd701e138101912d3 (patch)
treec5aee716316c5d34bb215a5a2f4eec22afc90a42
parent926a81c358b58ea09de86f8d55519cc38bc97034 (diff)
downloaddotty-59055f28c7f6f3b01216ccbbd701e138101912d3.tar.gz
dotty-59055f28c7f6f3b01216ccbbd701e138101912d3.tar.bz2
dotty-59055f28c7f6f3b01216ccbbd701e138101912d3.zip
Add basic member-lookup for result types
-rw-r--r--dottydoc/js/src/html/Member.scala11
-rw-r--r--dottydoc/jvm/src/dotty/tools/dottydoc/core/Phases.scala11
-rw-r--r--dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyParsers.scala68
-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.scala19
-rw-r--r--dottydoc/jvm/src/dotty/tools/dottydoc/util/mutate.scala11
-rw-r--r--dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala (renamed from dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala)11
-rw-r--r--dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala4
-rw-r--r--dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala22
-rw-r--r--dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala6
-rw-r--r--dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala16
-rw-r--r--dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala10
12 files changed, 155 insertions, 56 deletions
diff --git a/dottydoc/js/src/html/Member.scala b/dottydoc/js/src/html/Member.scala
index a862ffea4..ff16631c5 100644
--- a/dottydoc/js/src/html/Member.scala
+++ b/dottydoc/js/src/html/Member.scala
@@ -9,6 +9,7 @@ import org.scalajs.dom.html.{Anchor, Div}
trait MemberLayout {
import model._
+ import comment._
def member(m: Entity, parent: Entity) = {
def toggleBetween(short: Div, and: Div): Unit =
@@ -66,9 +67,15 @@ trait MemberLayout {
case xs => s
}
+ def link(rv: MaterializableLink) = rv match {
+ case ml: MaterializedLink =>
+ span(cls := "return-value", ": ", raw(ml.target))
+ case un: UnsetLink =>
+ span(cls := "return-value", ": " + shorten(un.query))
+ }
+
m match {
- case v: Val => span(cls := "return-value", ": " + shorten(v.returnValue))
- case d: Def => span(cls := "return-value", ": " + shorten(d.returnValue))
+ case rv: ReturnValue => link(rv.returnValue)
case _ => span()
}
}
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/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
diff --git a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala
index f423cf8de..c22d7a82f 100644
--- a/dottydoc/jvm/src/dotty/tools/dottydoc/model/comment/BodyEntities.scala
+++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/comment/BodyEntities.scala
@@ -87,6 +87,15 @@ final case class HtmlTag(data: String) extends Inline {
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
+
+/** Linking directly to entities is not picklable because of cyclic references */
+final case class LinkToEntity(entity: Entity) extends LinkTo
+
+/** Use MaterializableLink for entities that need be picklable */
+sealed trait MaterializableLink {
+ def title: Any
+}
+final case class UnsetLink(title: Inline, query: String) extends MaterializableLink
+final case class MaterializedLink(title: String, target: String) extends MaterializableLink
diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala
index e62b8573a..0ecfd04be 100644
--- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala
+++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/entities.scala
@@ -1,7 +1,7 @@
package dotty.tools.dottydoc
package model
-import comment.Comment
+import comment.{ Comment, MaterializableLink }
trait Entity {
def name: String
@@ -40,7 +40,7 @@ trait Modifiers {
}
trait ReturnValue {
- def returnValue: String
+ def returnValue: MaterializableLink
}
trait Package extends Entity with Members {
diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala
index 4707fccff..ab6ff86d1 100644
--- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala
+++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/factories.scala
@@ -1,6 +1,7 @@
package dotty.tools.dottydoc
package model
+import comment._
import dotty.tools.dotc
import dotc.core.Types._
import dotc.core.Contexts.Context
@@ -8,10 +9,13 @@ import dotc.core.Symbols.Symbol
import dotc.core.{ Flags => DottyFlags }
import dotc.ast.Trees._
+
object factories {
import dotty.tools.dotc.ast.tpd._
import DottyFlags._
+ type TypeTree = dotty.tools.dotc.ast.Trees.Tree[Type]
+
def flags(t: Tree)(implicit ctx: Context): List[String] =
(t.symbol.flags & SourceModifierFlags)
.flagStrings.toList
@@ -37,11 +41,23 @@ object factories {
pathList(ref)
}
- // TODO: should be updated to link to local entities
- def returnType(t: Tree)(implicit ctx: Context): String =
- t.show
+ def returnType(t: Tree, tpt: TypeTree)(implicit ctx: Context): MaterializableLink = {
+ def cleanTitle(title: String): String = title match {
+ case x if x matches "[^\\[]+\\.this\\..+" => x.split("\\.").last
+ case _ => title
+ }
+
+ def cleanQuery(query: String): String = query match {
+ case x if x matches "[^\\[]+\\[[^\\]]+\\]" => x.takeWhile(_ != '[')
+ case _ => query
+ }
+
+ UnsetLink(Text(cleanTitle(tpt.show)), cleanQuery(tpt.show))
+ }
def filteredName(str: String) = str
.replaceAll("\\$colon", ":")
.replaceAll("\\$plus", "+")
+ .replaceAll("\\$less", "<")
+ .replaceAll("\\$eq", "=")
}
diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala
index 147523662..7535504b6 100644
--- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala
+++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/internal.scala
@@ -1,7 +1,7 @@
package dotty.tools.dottydoc
package model
-import comment.Comment
+import comment.{ Comment, MaterializableLink }
object internal {
@@ -55,7 +55,7 @@ object internal {
name: String,
modifiers: List[String],
path: List[String],
- returnValue: String,
+ var returnValue: MaterializableLink,
var comment: Option[Comment] = None
) extends Def with Impl
@@ -63,7 +63,7 @@ object internal {
name: String,
modifiers: List[String],
path: List[String],
- returnValue: String,
+ var returnValue: MaterializableLink,
var comment: Option[Comment] = None
) extends Val with Impl
}
diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala
index ea33a05fd..75741bb6b 100644
--- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala
+++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/model/pickling.scala
@@ -4,6 +4,22 @@ package model
object pickling {
import internal._
import prickle._
+ import comment._
+
+ implicit val inlinePickler: PicklerPair[Inline] = CompositePickler[Inline]
+ .concreteType[Chain]
+ .concreteType[Italic]
+ .concreteType[Bold]
+ .concreteType[Underline]
+ .concreteType[Superscript]
+ .concreteType[Subscript]
+ .concreteType[Link]
+ .concreteType[Monospace]
+ .concreteType[Text]
+
+ implicit val entityLinkPicker: PicklerPair[MaterializableLink] = CompositePickler[MaterializableLink]
+ .concreteType[UnsetLink]
+ .concreteType[MaterializedLink]
implicit val entityPickler: PicklerPair[Entity] = CompositePickler[Entity]
.concreteType[NonEntity.type]
diff --git a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala
index aca5f41ea..2ac8eae4f 100644
--- a/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala
+++ b/dottydoc/shared/src/main/scala/dotty/tools/dottydoc/util/Traversing.scala
@@ -11,7 +11,13 @@ object traversing {
case e: Entity => trans(e)
}
- def relativePath(from: Entity, to: Entity) =
- "../" * (from.path.length - 1) +
+ def relativePath(from: Entity, to: Entity) = {
+ val offset = from match {
+ case _: Val | _: Def => 2
+ case _ => 1
+ }
+
+ "../" * (from.path.length - offset) +
to.path.mkString("", "/", ".html")
+ }
}