aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-08-27 00:30:07 +0200
committerFelix Mulder <felix.mulder@gmail.com>2016-10-06 17:45:12 +0200
commit5463b7a9d42ece31409526ce192d263f7f55e047 (patch)
treebbdacab4ef724e42a45f3e59c0fa8acdf3ba3b3e /src/dotty/tools/dotc
parentea24c55fdc7b3310a7f9911b408647701b5799fa (diff)
downloaddotty-5463b7a9d42ece31409526ce192d263f7f55e047.tar.gz
dotty-5463b7a9d42ece31409526ce192d263f7f55e047.tar.bz2
dotty-5463b7a9d42ece31409526ce192d263f7f55e047.zip
Fix cooking of docstrings
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/config/ScalaSettings.scala1
-rw-r--r--src/dotty/tools/dotc/core/Comments.scala10
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala6
-rw-r--r--src/dotty/tools/dotc/parsing/Scanners.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala11
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala45
7 files changed, 48 insertions, 29 deletions
diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala
index ff17a9939..9304daf98 100644
--- a/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -171,6 +171,7 @@ class ScalaSettings extends Settings.SettingGroup {
val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.")
val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.")
val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.")
+ val Ydocrun = BooleanSetting("-Ydoc-run", "Current run should be treated as a docrun, enables `@usecase` annotations in comments")
val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.")
val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.")
val Yissuedebug = BooleanSetting("-Yissue-debug", "Print stack traces when a context issues an error.")
diff --git a/src/dotty/tools/dotc/core/Comments.scala b/src/dotty/tools/dotc/core/Comments.scala
index 1d9d53bac..ea5726fa0 100644
--- a/src/dotty/tools/dotc/core/Comments.scala
+++ b/src/dotty/tools/dotc/core/Comments.scala
@@ -15,6 +15,7 @@ import dotty.tools.dottydoc.model.comment.CommentUtils._
object Comments {
case class Comment(pos: Position, raw: String)(implicit ctx: Context) {
+
val isDocComment = raw.startsWith("/**")
private[this] lazy val sections = tagIndex(raw)
@@ -41,10 +42,10 @@ object Comments {
val code = raw.substring(codeStart, codeEnd) + " = ???"
val codePos = subPos(codeStart, codeEnd)
val commentStart = skipLineLead(raw, codeEnd + 1) min end
- val comment = "/** " + raw.substring(commentStart, end) + "*/"
+ val commentStr = "/** " + raw.substring(commentStart, end) + "*/"
val commentPos = subPos(commentStart, end)
- UseCase(Comment(commentPos, comment), code, codePos)
+ UseCase(Comment(commentPos, commentStr), code, codePos)
}
private def subPos(start: Int, end: Int) =
@@ -57,9 +58,6 @@ object Comments {
}
case class UseCase(comment: Comment, code: String, codePos: Position)(implicit ctx: Context) {
- /** Entered by Namer */
- var symbol: Symbol = _
-
/** Set by typer */
var tpdCode: tpd.DefDef = _
@@ -68,7 +66,7 @@ object Comments {
tree match {
case tree: untpd.DefDef =>
- val newName = (tree.name.show + "$" + codePos.start).toTermName
+ val newName = (tree.name.show + "$" + codePos + "$doc").toTermName
untpd.DefDef(newName, tree.tparams, tree.vparamss, tree.tpt, tree.rhs)
case _ =>
ctx.error("proper definition was not found in `@usecase`", codePos)
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 429b95c1e..a37e367fa 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -582,6 +582,8 @@ object Contexts {
private[this] val _docstrings: mutable.Map[Symbol, Comment] =
mutable.Map.empty
+ def docstrings: Map[Symbol, Comment] = _docstrings.toMap
+
def docstring(sym: Symbol): Option[Comment] = _docstrings.get(sym)
def addDocstring(sym: Symbol, doc: Option[Comment]): Unit =
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 969d09c3e..34612e83d 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -1541,13 +1541,15 @@ object SymDenotations {
/** Enter a symbol in given `scope` without potentially replacing the old copy. */
def enterNoReplace(sym: Symbol, scope: MutableScope)(implicit ctx: Context): Unit = {
-
+ lazy val isUsecase = ctx.settings.Ydocrun.value && sym.name.show.takeRight(4) == "$doc"
require(
(sym.denot.flagsUNSAFE is Private) ||
!(this is Frozen) ||
(scope ne this.unforcedDecls) ||
sym.hasAnnotation(defn.ScalaStaticAnnot) ||
- sym.name.isInlineAccessor)
+ sym.name.isInlineAccessor ||
+ isUsecase)
+
scope.enter(sym)
if (myMemberFingerPrint != FingerPrint.unknown)
diff --git a/src/dotty/tools/dotc/parsing/Scanners.scala b/src/dotty/tools/dotc/parsing/Scanners.scala
index 60003d098..8aee757ce 100644
--- a/src/dotty/tools/dotc/parsing/Scanners.scala
+++ b/src/dotty/tools/dotc/parsing/Scanners.scala
@@ -172,7 +172,7 @@ object Scanners {
}
class Scanner(source: SourceFile, override val startFrom: Offset = 0)(implicit ctx: Context) extends ScannerCommon(source)(ctx) {
- val keepComments = ctx.settings.YkeepComments.value
+ val keepComments = ctx.settings.YkeepComments.value || ctx.settings.Ydocrun.value
/** All doc comments as encountered, each list contains doc comments from
* the same block level. Starting with the deepest level and going upward
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index b34eaa605..1d2d59208 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -4,7 +4,7 @@ package typer
import core._
import ast._
-import Trees._, Constants._, StdNames._, Scopes._, Denotations._
+import Trees._, Constants._, StdNames._, Scopes._, Denotations._, Comments._
import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._
import ast.desugar, ast.desugar._
import ProtoTypes._
@@ -456,14 +456,7 @@ class Namer { typer: Typer =>
def setDocstring(sym: Symbol, tree: Tree)(implicit ctx: Context) = tree match {
- case t: MemberDef if t.rawComment.isDefined =>
- val cmt = t.rawComment
- ctx.docbase.addDocstring(sym, cmt)
-
- cmt.get.usecases.foreach { usecase =>
- usecase.symbol = enterSymbol(createSymbol(usecase.untpdCode))
- }
-
+ case t: MemberDef if t.rawComment.isDefined => ctx.docbase.addDocstring(sym, t.rawComment)
case _ => ()
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 181f5bd7c..2a8e7da9a 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -11,6 +11,7 @@ import Scopes._
import Denotations._
import ProtoTypes._
import Contexts._
+import Comments._
import Symbols._
import Types._
import SymDenotations._
@@ -1246,7 +1247,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val dummy = localDummy(cls, impl)
val body1 = typedStats(impl.body, dummy)(inClassContext(self1.symbol))
- typedUsecases(body1.map(_.symbol), self1.symbol)
+ if (ctx.settings.Ydocrun.value)
+ typedUsecases(body1.map(_.symbol), self1.symbol)
checkNoDoubleDefs(cls)
val impl1 = cpy.Template(impl)(constr1, parents1, self1, body1)
@@ -1536,16 +1538,37 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
tpd.cpy.DefDef(mdef)(rhs = Inliner.bodyToInline(mdef.symbol)) ::
Inliner.removeInlineAccessors(mdef.symbol)
- def typedUsecases(syms: List[Symbol], owner: Symbol)(implicit ctx: Context): Unit =
- for {
- sym <- syms
- usecase <- ctx.docbase.docstring(sym).map(_.usecases).getOrElse(Nil)
- List(tpdTree) = typedStats(usecase.untpdCode :: Nil, owner)
- } yield {
- if (tpdTree.isInstanceOf[tpd.DefDef])
- usecase.tpdCode = tpdTree.asInstanceOf[tpd.DefDef]
- else
- ctx.error("Couldn't compile `@usecase`", usecase.codePos)
+ def typedUsecases(syms: List[Symbol], owner: Symbol)(implicit ctx: Context): Unit = {
+ val relevantSyms = syms.filter(ctx.docbase.docstring(_).isDefined)
+ relevantSyms.foreach { sym =>
+ expandParentDocs(sym)
+ val usecases = ctx.docbase.docstring(sym).map(_.usecases).getOrElse(Nil)
+
+ usecases.foreach { usecase =>
+ enterSymbol(createSymbol(usecase.untpdCode))
+
+ typedStats(usecase.untpdCode :: Nil, owner) match {
+ case List(df: tpd.DefDef) => usecase.tpdCode = df
+ case _ => ctx.error("`@usecase` was not a valid definition", usecase.codePos)
+ }
+ }
+ }
+ }
+
+ import dotty.tools.dottydoc.model.comment.CommentExpander
+ val expander = new CommentExpander {}
+ def expandParentDocs(sym: Symbol)(implicit ctx: Context): Unit =
+ ctx.docbase.docstring(sym).foreach { cmt =>
+ def expandDoc(owner: Symbol): Unit = {
+ expander.defineVariables(sym)
+ val newCmt = Comment(cmt.pos, expander.expandedDocComment(sym, owner, cmt.raw))
+ ctx.docbase.addDocstring(sym, Some(newCmt))
+ }
+
+ if (sym ne NoSymbol) {
+ expandParentDocs(sym.owner)
+ expandDoc(sym.owner)
+ }
}
def typedExpr(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree =