Skip to content

[doc] Usecases with docbase as param #1502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Oct 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package dotty.tools
package dottydoc

import dotty.tools.dottydoc.util.syntax._
import core._
import core.transform._
import dotc.config.CompilerCommand
import dotc.config.Printers.dottydoc
import dotc.core.Contexts._
import dotc.core.Comments.ContextDoc
import dotc.core.Phases.Phase
import dotc.typer.FrontEnd
import dotc.{ CompilationUnit, Compiler, Driver, Run }
Expand All @@ -31,7 +33,9 @@ class DocCompiler extends Compiler {
List(new DocFrontEnd),
List(new DocImplicitsPhase),
List(new DocASTPhase),
List(DocMiniTransformations(new LinkReturnTypes,
List(DocMiniTransformations(new UsecasePhase,
new DocstringPhase,
new LinkReturnTypes,
new LinkParamListTypes,
new LinkImplicitlyAddedTypes,
new LinkSuperTypes,
Expand All @@ -54,6 +58,7 @@ abstract class DocDriver extends Driver {

ctx.setSettings(summary.sstate)
ctx.setSetting(ctx.settings.YkeepComments, true)
ctx.setProperty(ContextDoc, new ContextDottydoc)

val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx)
(fileNames, ctx)
Expand All @@ -65,7 +70,7 @@ abstract class DocDriver extends Driver {
val (fileNames, ctx) = setup(args, initCtx.fresh)
doCompile(newCompiler(ctx), fileNames)(ctx)

ctx.docbase.packages[Package]
ctx.docbase.packages
}

def compiledDocsJava(args: Array[String]): JMap[String, Package] =
Expand Down
23 changes: 23 additions & 0 deletions dottydoc/src/dotty/tools/dottydoc/core/ContextDottydoc.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package dotty.tools
package dottydoc
package core

import dotc.core.Symbols.Symbol
import dotc.core.Comments.ContextDocstrings
import model.Package

class ContextDottydoc extends ContextDocstrings {
import scala.collection.mutable

private[this] val _packages: mutable.Map[String, Package] = mutable.Map.empty
def packages: Map[String, Package] = _packages.toMap
def packagesMutable: mutable.Map[String, Package] = _packages

/** Should perhaps factorize this into caches that get flushed */
private var _defs: Map[Symbol, Set[Symbol]] = Map.empty
def defs(sym: Symbol): Set[Symbol] = _defs.get(sym).getOrElse(Set.empty)

def addDef(s: Symbol, d: Symbol): Unit = _defs = (_defs + {
s -> _defs.get(s).map(xs => xs + d).getOrElse(Set(d))
})
}
76 changes: 28 additions & 48 deletions dottydoc/src/dotty/tools/dottydoc/core/DocASTPhase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,25 @@ import dotc.ast.Trees._
import dotc.CompilationUnit
import dotc.config.Printers.dottydoc
import dotc.core.Contexts.Context
import dotc.core.Comments.ContextDocstrings
import dotc.core.Phases.Phase
import dotc.core.Symbols.{ Symbol, NoSymbol }

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._
import dotty.tools.dottydoc.util.syntax._
import util.traversing._
import util.internal.setters._

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] =
Expand All @@ -58,28 +47,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.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.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
Expand All @@ -90,38 +77,38 @@ class DocASTPhase extends Phase {
/** package */
case pd @ PackageDef(pid, st) =>
val newPath = prev :+ pid.name.toString
addEntity(PackageImpl(newPath.mkString("."), collectEntityMembers(st, newPath), newPath))
addEntity(PackageImpl(pd.symbol, newPath.mkString("."), collectEntityMembers(st, newPath), newPath))

/** trait */
case t @ TypeDef(n, rhs) if t.symbol.is(Flags.Trait) =>
val name = n.decode.toString
val newPath = prev :+ name
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
TraitImpl(name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), traitParameters(t.symbol), superTypes(t))
TraitImpl(t.symbol, name, collectMembers(rhs), flags(t), newPath, typeParams(t.symbol), traitParameters(t.symbol), superTypes(t))

/** objects, on the format "Object$" so drop the last letter */
case o @ TypeDef(n, rhs) if o.symbol.is(Flags.Module) =>
val name = n.decode.toString.dropRight(1)
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
ObjectImpl(name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o))
ObjectImpl(o.symbol, name, collectMembers(rhs, prev :+ name), flags(o), prev :+ (name + "$"), superTypes(o))

/** class / case class */
case c @ TypeDef(n, rhs) if c.symbol.isClass =>
val name = n.decode.toString
val newPath = prev :+ name
//TODO: should not `collectMember` from `rhs` - instead: get from symbol, will get inherited members as well
(name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), constructors(c.symbol), superTypes(c), None) match {
(c.symbol, name, collectMembers(rhs), flags(c), newPath, typeParams(c.symbol), constructors(c.symbol), superTypes(c), None) match {
case x if c.symbol.is(Flags.CaseClass) => CaseClassImpl.tupled(x)
case x => ClassImpl.tupled(x)
}

/** def */
case d: DefDef =>
DefImpl(d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d.symbol.info))
DefImpl(d.symbol, d.name.decode.toString, flags(d), path(d.symbol), returnType(d.tpt.tpe), typeParams(d.symbol), paramLists(d.symbol.info))

/** val */
case v: ValDef if !v.symbol.is(Flags.ModuleVal) =>
ValImpl(v.name.decode.toString, flags(v), path(v.symbol), returnType(v.tpt.tpe))
ValImpl(v.symbol, v.name.decode.toString, flags(v), path(v.symbol), returnType(v.tpt.tpe))

case x => {
//dottydoc.println(s"Found unwanted entity: $x (${x.pos},\n${x.show}")
Expand Down Expand Up @@ -175,15 +162,8 @@ 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
for (kv <- packages) ctx.docbase.packages += kv
// (3) Update Doc AST in ctx.base
for (kv <- packages) ctx.docbase.packagesMutable += kv

// Return super's result
compUnits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package core
import dotty.tools.dotc.transform.TreeTransforms.{ MiniPhaseTransform, TransformerInfo }
import dotty.tools.dotc.core.Flags
import dotc.core.Contexts.Context
import util.syntax._

class DocImplicitsPhase extends MiniPhaseTransform { thisTransformer =>
import dotty.tools.dotc.ast.tpd._
Expand Down
47 changes: 47 additions & 0 deletions dottydoc/src/dotty/tools/dottydoc/core/DocstringPhase.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package dotty.tools
package dottydoc
package core

import dotc.core.Contexts.Context
import transform.DocMiniPhase
import model._
import model.internal._
import model.comment._
import BodyParsers._
import util.syntax._

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, 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))
}
}
15 changes: 12 additions & 3 deletions dottydoc/src/dotty/tools/dottydoc/core/MiniPhaseTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ package core

import dotc.CompilationUnit
import dotc.core.Contexts.Context
import dotc.core.Comments.ContextDocstrings
import dotc.core.Phases.Phase
import model._
import model.internal._
import util.syntax._

object transform {
/**
Expand Down Expand Up @@ -43,9 +45,9 @@ object transform {
override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = {
for {
rootName <- rootPackages
pack = ctx.docbase.packages[Package](rootName)
pack = ctx.docbase.packages(rootName)
transformed = performPackageTransform(pack)
} yield ctx.docbase.packages(rootName) = transformed
} yield ctx.docbase.packagesMutable(rootName) = transformed
super.runOn(units)
}

Expand Down Expand Up @@ -77,19 +79,21 @@ object transform {
def traverse(ent: Entity): Entity = ent match {
case p: Package => transformEntity(p, _.packageTransformation) { p =>
val newPackage = PackageImpl(
p.symbol,
p.name,
p.members.map(traverse),
p.path,
p.comment
)

// Update reference in context to newPackage
ctx.docbase.packages[Package] += (newPackage.path.mkString(".") -> newPackage)
ctx.docbase.packagesMutable += (newPackage.path.mkString(".") -> newPackage)

newPackage
}
case c: Class => transformEntity(c, _.classTransformation) { cls =>
ClassImpl(
cls.symbol,
cls.name,
cls.members.map(traverse),
cls.modifiers,
Expand All @@ -102,6 +106,7 @@ object transform {
}
case cc: CaseClass => transformEntity(cc, _.caseClassTransformation) { cc =>
CaseClassImpl(
cc.symbol,
cc.name,
cc.members.map(traverse),
cc.modifiers,
Expand All @@ -114,6 +119,7 @@ object transform {
}
case trt: Trait => transformEntity(trt, _.traitTransformation) { trt =>
TraitImpl(
trt.symbol,
trt.name,
trt.members.map(traverse),
trt.modifiers,
Expand All @@ -126,6 +132,7 @@ object transform {
}
case obj: Object => transformEntity(obj, _.objectTransformation) { obj =>
ObjectImpl(
obj.symbol,
obj.name,
obj.members.map(traverse),
obj.modifiers,
Expand All @@ -136,6 +143,7 @@ object transform {
}
case df: Def => transformEntity(df, _.defTransformation) { df =>
DefImpl(
df.symbol,
df.name,
df.modifiers,
df.path,
Expand All @@ -148,6 +156,7 @@ object transform {
}
case vl: Val => transformEntity(vl, _.valTransformation) { vl =>
ValImpl(
vl.symbol,
vl.name,
vl.modifiers,
vl.path,
Expand Down
Loading