From 1fe56e16de74c4c90eec5a4c411ba0b1adde0ee2 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Tue, 31 Jan 2017 14:24:41 +0100 Subject: Fix `setParent` for `TypeAlias` and only recurse from root Previously all packages would be iterated through on `setParent`. With this change, only the root packages will be mutated. This gives about 30% speedup for doc compile on Dotty --- .../dotty/tools/dottydoc/core/DocASTPhase.scala | 35 ++++++++++++---------- .../tools/dottydoc/core/TypeLinkingPhases.scala | 14 ++------- .../dotty/tools/dottydoc/model/references.scala | 11 ++++++- .../src/dotty/tools/dottydoc/util/mutate.scala | 4 +++ 4 files changed, 36 insertions(+), 28 deletions(-) (limited to 'doc-tool') diff --git a/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala index 72953b5a8..36b9db93c 100644 --- a/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/doc-tool/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -26,18 +26,18 @@ class DocASTPhase extends Phase { def phaseName = "docASTPhase" /** Build documentation hierarchy from existing tree */ - def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = { + def collect(tree: Tree)(implicit ctx: Context): Entity = { val implicitConversions = ctx.docbase.defs(tree.symbol) - def collectList(xs: List[Tree], ps: List[String]): List[Entity] = - xs.map(collect(_, ps)).filter(_ != NonEntity) + def collectList(xs: List[Tree]): List[Entity] = + xs.map(collect).filter(_ != NonEntity) - def collectEntityMembers(xs: List[Tree], ps: List[String]) = - collectList(xs, ps).asInstanceOf[List[Entity with Members]] + def collectEntityMembers(xs: List[Tree]) = + collectList(xs).asInstanceOf[List[Entity with Members]] - def collectMembers(tree: Tree, ps: List[String] = prev)(implicit ctx: Context): List[Entity] = { + def collectMembers(tree: Tree)(implicit ctx: Context): List[Entity] = { val defs = (tree match { - case t: Template => collectList(t.body, ps) + case t: Template => collectList(t.body) case _ => Nil }) @@ -85,8 +85,7 @@ class DocASTPhase extends Phase { tree match { /** package */ case pd @ PackageDef(pid, st) => - val pkgPath = path(pd.symbol) - addPackage(PackageImpl(pd.symbol, annotations(pd.symbol), pd.symbol.showFullName, collectEntityMembers(st, pkgPath), pkgPath)) + addPackage(PackageImpl(pd.symbol, annotations(pd.symbol), pd.symbol.showFullName, collectEntityMembers(st), path(pd.symbol))) /** type alias */ case t: TypeDef if !t.isClassDef => @@ -105,7 +104,7 @@ class DocASTPhase extends Phase { case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) => val name = o.name.show //TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well - ObjectImpl(o.symbol, annotations(o.symbol), name.dropRight(1), collectMembers(rhs, prev :+ name), flags(o), path(o.symbol).init :+ name, superTypes(o)) + ObjectImpl(o.symbol, annotations(o.symbol), name.dropRight(1), collectMembers(rhs), flags(o), path(o.symbol).init :+ name, superTypes(o)) /** class / case class */ case c @ TypeDef(n, rhs) if c.symbol.isClass => @@ -207,12 +206,17 @@ class DocASTPhase extends Phase { mergedPackages(packages(newPkg.name), newPkg) else { val root = packages.get(path.head) - - if (root.isDefined) createAndInsert(root.get, newPkg.path.drop(1)) + if (root.isDefined) + // Root ancestor of `newPkg` exists, start recursing to point of + // insertion. Point of insertion will be the parent package of `newPkg`. + // + // Which is the first element of `newPkg`'s path - thus we use the tail + // to continue traversing down the tree. + createAndInsert(root.get, path.tail) else { val newEmpty = EmptyPackage(List(path.head), path.head) packages = packages + (path.head -> newEmpty) - createAndInsert(newEmpty, newPkg.path.drop(1)) + createAndInsert(newEmpty, path.tail) } } } @@ -233,8 +237,9 @@ class DocASTPhase extends Phase { // (2) Set parents of entities, needed for linking for { - parent <- packages.values - child <- parent.children + parentName <- rootPackages(packages) + parent = packages(parentName) + child <- parent.members } setParent(child, to = parent) // (3) Update Doc AST in ctx.base diff --git a/doc-tool/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala b/doc-tool/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala index 02f6ccb97..825cdf9ad 100644 --- a/doc-tool/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala +++ b/doc-tool/src/dotty/tools/dottydoc/core/TypeLinkingPhases.scala @@ -80,18 +80,8 @@ class LinkImplicitlyAddedTypes extends DocMiniPhase with TypeLinker { trait TypeLinker extends MemberLookup { def handleEntityLink(title: String, target: Option[Entity], ent: Entity, query: String = ""): MaterializableLink = target match { - case Some(target: Package) => - MaterializedLink(title, target.path.mkString("/") + "/index.html") - case Some(target: TypeAlias) => - MaterializedLink(title, target.parent.path.mkString("/") + ".html#" + target.signature) - case Some(target: Def) => - MaterializedLink(title, target.parent.path.mkString("/") + ".html#" + target.signature) - case Some(target: Val) => - MaterializedLink(title, target.parent.path.mkString("/") + ".html#" + target.signature) - case Some(target) => - MaterializedLink(title, target.path.mkString("/") + ".html") - case none => - NoLink(title, query) + case Some(target) => new MaterializedLink(title, target) + case none => NoLink(title, query) } def linkReference(ent: Entity, ref: Reference, packs: Map[String, Package]): Reference = { diff --git a/doc-tool/src/dotty/tools/dottydoc/model/references.scala b/doc-tool/src/dotty/tools/dottydoc/model/references.scala index 02304b302..a103347c1 100644 --- a/doc-tool/src/dotty/tools/dottydoc/model/references.scala +++ b/doc-tool/src/dotty/tools/dottydoc/model/references.scala @@ -16,7 +16,16 @@ object references { /** Use MaterializableLink for entities that need be picklable */ sealed trait MaterializableLink { def title: String } final case class UnsetLink(title: String, query: String) extends MaterializableLink - final case class MaterializedLink(title: String, target: String) extends MaterializableLink + final case class MaterializedLink(title: String, target: String) extends MaterializableLink { + def this(title: String, target: Entity) = this(title, target match { + case target: Package => + target.path.mkString("/") + "/index.html" + case _: TypeAlias | _: Def | _: Val => + target.parent.path.mkString("/") + ".html#" + target.signature + case _ => + target.path.mkString("/") + ".html" + }) + } final case class NoLink(title: String, target: String) extends MaterializableLink object AndOrTypeReference { diff --git a/doc-tool/src/dotty/tools/dottydoc/util/mutate.scala b/doc-tool/src/dotty/tools/dottydoc/util/mutate.scala index 739a1e19d..4633bf257 100644 --- a/doc-tool/src/dotty/tools/dottydoc/util/mutate.scala +++ b/doc-tool/src/dotty/tools/dottydoc/util/mutate.scala @@ -16,9 +16,13 @@ object setters { case x: ObjectImpl => x.comment = to case x: DefImpl => x.comment = to case x: ValImpl => x.comment = to + case x: TypeAliasImpl => x.comment = to } def setParent(ent: Entity, to: Entity): Unit = ent match { + case e: PackageImpl => + e.parent = to + e.members.foreach(setParent(_, e)) case e: ClassImpl => e.parent = to e.members.foreach(setParent(_, e)) -- cgit v1.2.3