diff options
author | odersky <odersky@gmail.com> | 2016-08-24 00:49:23 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-24 00:49:23 +0300 |
commit | 265ade02e522c89844076b5339267eac08e44c37 (patch) | |
tree | 4e1c0f808eb2dbff1a80a7920021874916c9c324 /src/dotty | |
parent | 76c3e99e33cf25a6ebccc0785212f629a3cda54e (diff) | |
parent | 0b69be68d3100103ebfd636bbc36f9cdcbd6fb28 (diff) | |
download | dotty-265ade02e522c89844076b5339267eac08e44c37.tar.gz dotty-265ade02e522c89844076b5339267eac08e44c37.tar.bz2 dotty-265ade02e522c89844076b5339267eac08e44c37.zip |
Merge pull request #1453 from felixmulder/topic/dottydoc
Add dottydoc
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/config/ScalaSettings.scala | 64 | ||||
-rw-r--r-- | src/dotty/tools/dotc/config/Settings.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 28 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/Parsers.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/Scanners.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/FrontEnd.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 |
8 files changed, 111 insertions, 23 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 20ae02994..cf11c27fa 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -15,6 +15,7 @@ import printing.Printer import util.{Stats, Attachment, DotClass} import annotation.unchecked.uncheckedVariance import language.implicitConversions +import parsing.Scanners.Comment object Trees { @@ -30,7 +31,7 @@ object Trees { @sharable var ntrees = 0 /** Attachment key for trees with documentation strings attached */ - val DocComment = new Attachment.Key[String] + val DocComment = new Attachment.Key[Comment] /** Modifiers and annotations for definitions * @param flags The set flags @@ -324,7 +325,7 @@ object Trees { private[ast] def rawMods: Modifiers[T] = if (myMods == null) genericEmptyModifiers else myMods - def rawComment: Option[String] = getAttachment(DocComment) + def rawComment: Option[Comment] = getAttachment(DocComment) def withMods(mods: Modifiers[Untyped]): ThisTree[Untyped] = { val tree = if (myMods == null || (myMods == mods)) this else clone.asInstanceOf[MemberDef[Untyped]] @@ -334,7 +335,7 @@ object Trees { def withFlags(flags: FlagSet): ThisTree[Untyped] = withMods(Modifiers(flags)) - def setComment(comment: Option[String]): ThisTree[Untyped] = { + def setComment(comment: Option[Comment]): ThisTree[Untyped] = { comment.map(putAttachment(DocComment, _)) asInstanceOf[ThisTree[Untyped]] } diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala index d0c4cc02c..5d5903584 100644 --- a/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -196,4 +196,68 @@ class ScalaSettings extends Settings.SettingGroup { val YpresentationLog = StringSetting("-Ypresentation-log", "file", "Log presentation compiler events into file", "") val YpresentationReplay = StringSetting("-Ypresentation-replay", "file", "Replay presentation compiler events from file", "") val YpresentationDelay = IntSetting("-Ypresentation-delay", "Wait number of ms after typing before starting typechecking", 0, 0 to 999) + + /** Doc specific settings */ + val template = OptionSetting[String]( + "-template", + "A mustache template for rendering each top-level entity in the API" + ) + + val resources = OptionSetting[String]( + "-resources", + "A directory containing static resources needed for the API documentation" + ) + + val DocTitle = StringSetting ( + "-Ydoc-title", + "title", + "The overall name of the Scaladoc site", + "" + ) + + val DocVersion = StringSetting ( + "-Ydoc-version", + "version", + "An optional version number, to be appended to the title", + "" + ) + + val DocOutput = StringSetting ( + "-Ydoc-output", + "outdir", + "The output directory in which to place the documentation", + "." + ) + + val DocFooter = StringSetting ( + "-Ydoc-footer", + "footer", + "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.", + "" + ) + + val DocUncompilable = StringSetting ( + "-Ydoc-no-compile", + "path", + "A directory containing sources which should be parsed, no more (e.g. AnyRef.scala)", + "" + ) + + //def DocUncompilableFiles(implicit ctx: Context) = DocUncompilable.value match { + // case "" => Nil + // case path => io.Directory(path).deepFiles.filter(_ hasExtension "scala").toList + //} + + val DocExternalDoc = MultiStringSetting ( + "-Ydoc-external-doc", + "external-doc", + "comma-separated list of classpath_entry_path#doc_URL pairs describing external dependencies." + ) + + val DocAuthor = BooleanSetting("-Ydoc-author", "Include authors.", true) + + val DocGroups = BooleanSetting ( + "-Ydoc:groups", + "Group similar functions together (based on the @group annotation)" + ) } diff --git a/src/dotty/tools/dotc/config/Settings.scala b/src/dotty/tools/dotc/config/Settings.scala index f30cedaa0..73df4e1ec 100644 --- a/src/dotty/tools/dotc/config/Settings.scala +++ b/src/dotty/tools/dotc/config/Settings.scala @@ -235,8 +235,8 @@ object Settings { setting } - def BooleanSetting(name: String, descr: String): Setting[Boolean] = - publish(Setting(name, descr, false)) + def BooleanSetting(name: String, descr: String, initialValue: Boolean = false): Setting[Boolean] = + publish(Setting(name, descr, initialValue)) def StringSetting(name: String, helpArg: String, descr: String, default: String): Setting[String] = publish(Setting(name, descr, default, helpArg)) diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 262443314..cd76fe88b 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -29,6 +29,7 @@ import printing._ import config.{Settings, ScalaSettings, Platform, JavaPlatform, SJSPlatform} import language.implicitConversions import DenotTransformers.DenotTransformer +import parsing.Scanners.Comment import xsbti.AnalysisCallback object Contexts { @@ -531,6 +532,9 @@ object Contexts { /** The symbol loaders */ val loaders = new SymbolLoaders + /** Documentation base */ + val docbase = new DocBase + /** The platform, initialized by `initPlatform()`. */ private var _platform: Platform = _ @@ -567,14 +571,32 @@ object Contexts { def squashed(p: Phase): Phase = { allPhases.find(_.period.containsPhaseId(p.id)).getOrElse(NoPhase) } + } - val _docstrings: mutable.Map[Symbol, String] = + class DocBase { + private[this] val _docstrings: mutable.Map[Symbol, Comment] = mutable.Map.empty - def docstring(sym: Symbol): Option[String] = _docstrings.get(sym) + def docstring(sym: Symbol): Option[Comment] = _docstrings.get(sym) - def addDocstring(sym: Symbol, doc: Option[String]): Unit = + def addDocstring(sym: Symbol, doc: Option[Comment]): Unit = doc.map(d => _docstrings += (sym -> d)) + + /* + * Dottydoc places instances of `Package` in this map - but we do not want + * to depend on `dottydoc` for the compiler, as such this is defined as a + * map of `String -> AnyRef` + */ + private[this] val _packages: mutable.Map[String, AnyRef] = mutable.Map.empty + def packages[A]: mutable.Map[String, A] = _packages.asInstanceOf[mutable.Map[String, A]] + + /** 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)) + }) } /** The essential mutable state of a context base, collected into a common class */ diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index 600707cbf..378aa6ed7 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -22,6 +22,7 @@ import ScriptParsers._ import scala.annotation.{tailrec, switch} import util.DotClass import rewrite.Rewrites.patch +import Scanners.Comment object Parsers { @@ -1778,13 +1779,13 @@ object Parsers { */ def defOrDcl(start: Int, mods: Modifiers): Tree = in.token match { case VAL => - patDefOrDcl(posMods(start, mods), in.getDocString(start)) + patDefOrDcl(posMods(start, mods), in.getDocComment(start)) case VAR => - patDefOrDcl(posMods(start, addFlag(mods, Mutable)), in.getDocString(start)) + patDefOrDcl(posMods(start, addFlag(mods, Mutable)), in.getDocComment(start)) case DEF => - defDefOrDcl(posMods(start, mods), in.getDocString(start)) + defDefOrDcl(posMods(start, mods), in.getDocComment(start)) case TYPE => - typeDefOrDcl(posMods(start, mods), in.getDocString(start)) + typeDefOrDcl(posMods(start, mods), in.getDocComment(start)) case _ => tmplDef(start, mods) } @@ -1794,7 +1795,7 @@ object Parsers { * ValDcl ::= Id {`,' Id} `:' Type * VarDcl ::= Id {`,' Id} `:' Type */ - def patDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = { + def patDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = { val lhs = commaSeparated(pattern2) val tpt = typedOpt() val rhs = @@ -1820,7 +1821,7 @@ object Parsers { * DefDcl ::= DefSig `:' Type * DefSig ::= id [DefTypeParamClause] ParamClauses */ - def defDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = atPos(tokenRange) { + def defDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = atPos(tokenRange) { def scala2ProcedureSyntax(resultTypeStr: String) = { val toInsert = if (in.token == LBRACE) s"$resultTypeStr =" @@ -1895,7 +1896,7 @@ object Parsers { /** TypeDef ::= type Id [TypeParamClause] `=' Type * TypeDcl ::= type Id [TypeParamClause] TypeBounds */ - def typeDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = { + def typeDefOrDcl(mods: Modifiers, docstring: Option[Comment] = None): Tree = { newLinesOpt() atPos(tokenRange) { val name = ident().toTypeName @@ -1917,7 +1918,7 @@ object Parsers { * | [`case'] `object' ObjectDef */ def tmplDef(start: Int, mods: Modifiers): Tree = { - val docstring = in.getDocString(start) + val docstring = in.getDocComment(start) in.token match { case TRAIT => classDef(posMods(start, addFlag(mods, Trait)), docstring) @@ -1938,7 +1939,7 @@ object Parsers { /** ClassDef ::= Id [ClsTypeParamClause] * [ConstrMods] ClsParamClauses TemplateOpt */ - def classDef(mods: Modifiers, docstring: Option[String]): TypeDef = atPos(tokenRange) { + def classDef(mods: Modifiers, docstring: Option[Comment]): TypeDef = atPos(tokenRange) { val name = ident().toTypeName val constr = atPos(in.offset) { val tparams = typeParamClauseOpt(ParamOwner.Class) @@ -1965,7 +1966,7 @@ object Parsers { /** ObjectDef ::= Id TemplateOpt */ - def objectDef(mods: Modifiers, docstring: Option[String] = None): ModuleDef = { + def objectDef(mods: Modifiers, docstring: Option[Comment] = None): ModuleDef = { val name = ident() val template = templateOpt(emptyConstructor()) @@ -2190,7 +2191,7 @@ object Parsers { if (in.token == PACKAGE) { in.nextToken() if (in.token == OBJECT) { - val docstring = in.getDocString(start) + val docstring = in.getDocComment(start) ts += objectDef(atPos(start, in.skipToken()) { Modifiers(Package) }, docstring) if (in.token != EOF) { acceptStatSep() diff --git a/src/dotty/tools/dotc/parsing/Scanners.scala b/src/dotty/tools/dotc/parsing/Scanners.scala index 1355ea386..b46ab6348 100644 --- a/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/src/dotty/tools/dotc/parsing/Scanners.scala @@ -193,7 +193,7 @@ object Scanners { } /** Returns the closest docstring preceding the position supplied */ - def getDocString(pos: Int): Option[String] = { + def getDocComment(pos: Int): Option[Comment] = { def closest(c: Comment, docstrings: List[Comment]): Comment = docstrings match { case x :: xs if (c.pos.end < x.pos.end && x.pos.end <= pos) => closest(x, xs) case Nil => c @@ -203,7 +203,7 @@ object Scanners { case (list @ (x :: xs)) :: _ => { val c = closest(x, xs) docsPerBlockStack = list.dropWhile(_ != c).tail :: docsPerBlockStack.tail - Some(c.chrs) + Some(c) } case _ => None } diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala index c5c6aec3c..e193b126a 100644 --- a/src/dotty/tools/dotc/typer/FrontEnd.scala +++ b/src/dotty/tools/dotc/typer/FrontEnd.scala @@ -57,7 +57,7 @@ class FrontEnd extends Phase { case _ => NoSymbol } - private def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) = + protected def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) = unit.isJava || firstTopLevelDef(unit.tpdTree :: Nil).isPrimitiveValueClass override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = { diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 698f7e9a9..b8e75664c 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -426,7 +426,7 @@ class Namer { typer: Typer => } def setDocstring(sym: Symbol, tree: Tree)(implicit ctx: Context) = tree match { - case t: MemberDef => ctx.base.addDocstring(sym, t.rawComment) + case t: MemberDef => ctx.docbase.addDocstring(sym, t.rawComment) case _ => () } |