From 8be7177a5f2f369b4932e54ee888c36544e9d3a5 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Sat, 27 Aug 2016 15:37:11 +0200 Subject: Move docstring parser to dottydoc miniphase --- dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala | 1 + .../dotty/tools/dottydoc/core/DocASTPhase.scala | 62 +++++--------- .../dotty/tools/dottydoc/core/DocstringPhase.scala | 50 +++++++++++ .../src/dotty/tools/dottydoc/model/parsers.scala | 98 ---------------------- 4 files changed, 70 insertions(+), 141 deletions(-) create mode 100644 dottydoc/src/dotty/tools/dottydoc/core/DocstringPhase.scala delete mode 100644 dottydoc/src/dotty/tools/dottydoc/model/parsers.scala (limited to 'dottydoc/src') diff --git a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala index dc051279a..380d8fda2 100644 --- a/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala +++ b/dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala @@ -32,6 +32,7 @@ class DocCompiler extends Compiler { List(new DocImplicitsPhase), List(new DocASTPhase), List(DocMiniTransformations(new UsecasePhase, + new DocstringPhase, new LinkReturnTypes, new LinkParamListTypes, new LinkImplicitlyAddedTypes, diff --git a/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala index 8df00d894..617afec51 100644 --- a/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala +++ b/dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala @@ -14,7 +14,6 @@ class DocASTPhase extends Phase { import model._ import model.factories._ import model.internal._ - import model.parsers.WikiParser import model.comment.Comment import dotty.tools.dotc.core.Flags import dotty.tools.dotc.ast.tpd._ @@ -23,20 +22,8 @@ class DocASTPhase extends Phase { def phaseName = "docphase" - private[this] val commentParser = new WikiParser - - /** Saves the commentParser function for later evaluation, for when the AST has been filled */ - def track(symbol: Symbol, ctx: Context, parent: Symbol = NoSymbol)(op: => Entity) = { - val entity = op - - if (entity != NonEntity) - commentParser += (entity, symbol, parent, ctx) - - entity - } - /** Build documentation hierarchy from existing tree */ - def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = track(tree.symbol, ctx) { + def collect(tree: Tree, prev: List[String] = Nil)(implicit ctx: Context): Entity = { val implicitConversions = ctx.docbase.defs(tree.symbol) def collectList(xs: List[Tree], ps: List[String]): List[Entity] = @@ -58,30 +45,26 @@ class DocASTPhase extends Phase { val defs = sym.info.bounds.hi.membersBasedOnFlags(Flags.Method, Flags.Synthetic | Flags.Private) .filterNot(_.symbol.owner.name.show == "Any") .map { meth => - track(meth.symbol, ctx, tree.symbol) { - DefImpl( - meth.symbol, - meth.symbol.name.show, - Nil, - path(meth.symbol), - returnType(meth.info), - typeParams(meth.symbol), - paramLists(meth.info), - implicitlyAddedFrom = Some(returnType(meth.symbol.owner.info)) - ) - } + DefImpl( + meth.symbol, + meth.symbol.name.show, + Nil, + path(meth.symbol), + returnType(meth.info), + typeParams(meth.symbol), + paramLists(meth.info), + implicitlyAddedFrom = Some(returnType(meth.symbol.owner.info)) + ) }.toList val vals = sym.info.fields.filterNot(_.symbol.is(Flags.Private | Flags.Synthetic)).map { value => - track(value.symbol, ctx, tree.symbol) { - ValImpl( - value.symbol, - value.symbol.name.show, - Nil, path(value.symbol), - returnType(value.info), - implicitlyAddedFrom = Some(returnType(value.symbol.owner.info)) - ) - } + ValImpl( + value.symbol, + value.symbol.name.show, + Nil, path(value.symbol), + returnType(value.info), + implicitlyAddedFrom = Some(returnType(value.symbol.owner.info)) + ) } defs ++ vals @@ -177,14 +160,7 @@ class DocASTPhase extends Phase { child <- parent.children } setParent(child, to = parent) - // (3) Create documentation template from docstrings, with internal links - println("Generating documentation, this might take a while...") - commentParser.parse(packages) - - // (4) Clear caches - commentParser.clear() - - // (5) Update Doc AST in ctx.base + // (3) Update Doc AST in ctx.base for (kv <- packages) ctx.docbase.packages += kv // Return super's result diff --git a/dottydoc/src/dotty/tools/dottydoc/core/DocstringPhase.scala b/dottydoc/src/dotty/tools/dottydoc/core/DocstringPhase.scala new file mode 100644 index 000000000..830336ba1 --- /dev/null +++ b/dottydoc/src/dotty/tools/dottydoc/core/DocstringPhase.scala @@ -0,0 +1,50 @@ +package dotty.tools +package dottydoc +package core + +import dotc.core.Contexts.Context +import dotc.ast.tpd + +import transform.DocMiniPhase +import model._ +import model.internal._ +import model.factories._ +import model.comment._ +import dotty.tools.dotc.core.Symbols.Symbol +import BodyParsers._ + +class DocstringPhase extends DocMiniPhase with CommentParser with CommentCleaner { + private def parsedComment[E <: Entity](ent: E)(implicit ctx: Context): Option[Comment] = + ctx.docbase.docstring(ent.symbol).map { cmt => + parse(ent, ctx.docbase.packages[Package].toMap, clean(cmt.raw), cmt.raw, cmt.pos) + .toComment(_.toHtml(ent)) + } + + override def transformPackage(implicit ctx: Context) = { case ent: PackageImpl => + ent.copy(comment = parsedComment(ent)) + } + + override def transformClass(implicit ctx: Context) = { case ent: ClassImpl => + ent.copy(comment = parsedComment(ent)) + } + + override def transformCaseClass(implicit ctx: Context) = { case ent: CaseClassImpl => + ent.copy(comment = parsedComment(ent)) + } + + override def transformTrait(implicit ctx: Context) = { case ent: TraitImpl => + ent.copy(comment = parsedComment(ent)) + } + + override def transformObject(implicit ctx: Context) = { case ent: ObjectImpl => + ent.copy(comment = parsedComment(ent)) + } + + override def transformDef(implicit ctx: Context) = { case ent: DefImpl => + ent.copy(comment = parsedComment(ent)) + } + + override def transformVal(implicit ctx: Context) = { case ent: ValImpl => + ent.copy(comment = parsedComment(ent)) + } +} diff --git a/dottydoc/src/dotty/tools/dottydoc/model/parsers.scala b/dottydoc/src/dotty/tools/dottydoc/model/parsers.scala deleted file mode 100644 index fa54163e5..000000000 --- a/dottydoc/src/dotty/tools/dottydoc/model/parsers.scala +++ /dev/null @@ -1,98 +0,0 @@ -package dotty.tools -package dottydoc -package model - -import dotc.core.Symbols.Symbol -import dotc.core.Contexts.Context -import dotc.util.Positions.NoPosition - -object parsers { - import comment._ - import BodyParsers._ - import model.internal._ - import util.MemberLookup - import util.traversing._ - import util.internal.setters._ - - class WikiParser extends CommentCleaner with CommentParser with CommentExpander { - private[this] var commentCache: Map[String, (Entity, Map[String, Package]) => Option[Comment]] = Map.empty - - /** Parses comment and returns the path to the entity with an optional comment - * - * The idea here is to use this fact to create `Future[Seq[(String, Option[Comment]]]` - * which can then be awaited near the end of the run - before the pickling. - */ - 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) - parse(entity, packages, clean(expanded), expanded, d.pos).toComment(_.toHtml(entity)) - } - - (entity.path.mkString("."), cmt) - } - - - def add(entity: Entity, symbol: Symbol, parent: Symbol, ctx: Context): Unit = { - val commentParser = { (entity: Entity, packs: Map[String, Package]) => - parseHtml(symbol, parent, entity, packs)(ctx)._2 - } - - /** TODO: this if statement searches for doc comments in parent - * definitions if one is not defined for the current symbol. - * - * It might be a good idea to factor this out of the WikiParser - since - * it mutates the state of docbase sort of silently. - */ - implicit val implCtx = ctx - if (!ctx.docbase.docstring(symbol).isDefined) { - val parentCmt = - symbol.extendedOverriddenSymbols - .find(ctx.docbase.docstring(_).isDefined) - .flatMap(p => ctx.docbase.docstring(p)) - - ctx.docbase.addDocstring(symbol, parentCmt) - } - - - val path = entity.path.mkString(".") - if (!commentCache.contains(path) || ctx.docbase.docstring(symbol).isDefined) - commentCache = commentCache + (path -> commentParser) - } - - def +=(entity: Entity, symbol: Symbol, parent: Symbol, ctx: Context) = add(entity, symbol, parent, ctx) - - def size: Int = commentCache.size - - private def parse(entity: Entity, packs: Map[String, Package]): Option[Comment] = - commentCache(entity.path.mkString("."))(entity, packs) - - def parse(packs: Map[String, Package]): Unit = { - def rootPackages: List[String] = { - var currentDepth = Int.MaxValue - var packages: List[String] = Nil - - for (key <- packs.keys) { - val keyDepth = key.split("\\.").length - packages = - if (keyDepth < currentDepth) { - currentDepth = keyDepth - key :: Nil - } else if (keyDepth == currentDepth) { - key :: packages - } else packages - } - - packages - } - - for (pack <- rootPackages) { - mutateEntities(packs(pack)) { e => - val comment = parse(e, packs) - setComment(e, to = comment) - } - } - } - - def clear(): Unit = commentCache = Map.empty - } -} -- cgit v1.2.3