diff options
author | Paul Phillips <paulp@improving.org> | 2013-02-10 10:40:27 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-02-10 10:40:27 -0800 |
commit | 0084849f7c8ab5195ffdd17c984c7738b51a1089 (patch) | |
tree | a0e298d1618eabf449844d62ecec2c45624f3269 | |
parent | 7dfbf07a89b6daac0dddf004fff512e8c9e325b4 (diff) | |
parent | f784fbfbce7c1426fe90706f11096ea1b826e88c (diff) | |
download | scala-0084849f7c8ab5195ffdd17c984c7738b51a1089.tar.gz scala-0084849f7c8ab5195ffdd17c984c7738b51a1089.tar.bz2 scala-0084849f7c8ab5195ffdd17c984c7738b51a1089.zip |
Merge commit 'f784fbfbce' into merge-210
* commit 'f784fbfbce':
Add a request to presentation compiler to fetch doc comment information.
Refactor scaladoc base functionality to allow it to be mixed in with Global in the IDE.
Conflicts:
src/compiler/scala/tools/nsc/interactive/Doc.scala
-rwxr-xr-x | src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala | 46 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/CompilerControl.scala | 22 | ||||
-rwxr-xr-x | src/compiler/scala/tools/nsc/interactive/Doc.scala | 59 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/Global.scala | 150 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/Picklers.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala | 3 | ||||
-rw-r--r--[-rwxr-xr-x] | test/files/presentation/doc.check | 1 | ||||
-rwxr-xr-x | test/files/presentation/doc/doc.scala (renamed from test/files/presentation/doc.scala) | 52 |
8 files changed, 191 insertions, 149 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala index 412dade781..c2b3c410fe 100755 --- a/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala +++ b/src/compiler/scala/tools/nsc/doc/base/CommentFactoryBase.scala @@ -97,26 +97,26 @@ trait CommentFactoryBase { this: MemberLookupBase => } - protected val endOfText = '\u0003' - protected val endOfLine = '\u000A' + private val endOfText = '\u0003' + private val endOfLine = '\u000A' /** Something that should not have happened, happened, and Scaladoc should exit. */ - protected def oops(msg: String): Nothing = + private def oops(msg: String): Nothing = throw FatalError("program logic: " + msg) /** The body of a line, dropping the (optional) start star-marker, * one leading whitespace and all trailing whitespace. */ - protected val CleanCommentLine = + private val CleanCommentLine = new Regex("""(?:\s*\*\s?)?(.*)""") /** Dangerous HTML tags that should be replaced by something safer, * such as wiki syntax, or that should be dropped. */ - protected val DangerousTags = + private val DangerousTags = new Regex("""<(/?(div|ol|ul|li|h[1-6]|p))( [^>]*)?/?>|<!--.*-->""") /** Maps a dangerous HTML tag to a safe wiki replacement, or an empty string * if it cannot be salvaged. */ - protected def htmlReplacement(mtch: Regex.Match): String = mtch.group(1) match { + private def htmlReplacement(mtch: Regex.Match): String = mtch.group(1) match { case "p" | "div" => "\n\n" case "h1" => "\n= " case "/h1" => " =\n" @@ -132,11 +132,11 @@ trait CommentFactoryBase { this: MemberLookupBase => /** Javadoc tags that should be replaced by something useful, such as wiki * syntax, or that should be dropped. */ - protected val JavadocTags = + private val JavadocTags = new Regex("""\{\@(code|docRoot|inheritDoc|link|linkplain|literal|value)([^}]*)\}""") /** Maps a javadoc tag to a useful wiki replacement, or an empty string if it cannot be salvaged. */ - protected def javadocReplacement(mtch: Regex.Match): String = mtch.group(1) match { + private def javadocReplacement(mtch: Regex.Match): String = mtch.group(1) match { case "code" => "`" + mtch.group(2) + "`" case "docRoot" => "" case "inheritDoc" => "" @@ -148,41 +148,41 @@ trait CommentFactoryBase { this: MemberLookupBase => } /** Safe HTML tags that can be kept. */ - protected val SafeTags = + private val SafeTags = new Regex("""((&\w+;)|(&#\d+;)|(</?(abbr|acronym|address|area|a|bdo|big|blockquote|br|button|b|caption|cite|code|col|colgroup|dd|del|dfn|em|fieldset|form|hr|img|input|ins|i|kbd|label|legend|link|map|object|optgroup|option|param|pre|q|samp|select|small|span|strong|sub|sup|table|tbody|td|textarea|tfoot|th|thead|tr|tt|var)( [^>]*)?/?>))""") - protected val safeTagMarker = '\u000E' + private val safeTagMarker = '\u000E' /** A Scaladoc tag not linked to a symbol and not followed by text */ - protected val SingleTag = + private val SingleTagRegex = new Regex("""\s*@(\S+)\s*""") /** A Scaladoc tag not linked to a symbol. Returns the name of the tag, and the rest of the line. */ - protected val SimpleTag = + private val SimpleTagRegex = new Regex("""\s*@(\S+)\s+(.*)""") /** A Scaladoc tag linked to a symbol. Returns the name of the tag, the name * of the symbol, and the rest of the line. */ - protected val SymbolTag = + private val SymbolTagRegex = new Regex("""\s*@(param|tparam|throws|groupdesc|groupname|groupprio)\s+(\S*)\s*(.*)""") /** The start of a scaladoc code block */ - protected val CodeBlockStart = + private val CodeBlockStartRegex = new Regex("""(.*?)((?:\{\{\{)|(?:\u000E<pre(?: [^>]*)?>\u000E))(.*)""") /** The end of a scaladoc code block */ - protected val CodeBlockEnd = + private val CodeBlockEndRegex = new Regex("""(.*?)((?:\}\}\})|(?:\u000E</pre>\u000E))(.*)""") /** A key used for a tag map. The key is built from the name of the tag and * from the linked symbol if the tag has one. * Equality on tag keys is structural. */ - protected sealed abstract class TagKey { + private sealed abstract class TagKey { def name: String } - protected final case class SimpleTagKey(name: String) extends TagKey - protected final case class SymbolTagKey(name: String, symbol: String) extends TagKey + private final case class SimpleTagKey(name: String) extends TagKey + private final case class SymbolTagKey(name: String, symbol: String) extends TagKey /** Parses a raw comment string into a `Comment` object. * @param comment The expanded comment string (including start and end markers) to be parsed. @@ -228,7 +228,7 @@ trait CommentFactoryBase { this: MemberLookupBase => inCodeBlock: Boolean ): Comment = remaining match { - case CodeBlockStart(before, marker, after) :: ls if (!inCodeBlock) => + case CodeBlockStartRegex(before, marker, after) :: ls if (!inCodeBlock) => if (!before.trim.isEmpty && !after.trim.isEmpty) parse0(docBody, tags, lastTagKey, before :: marker :: after :: ls, false) else if (!before.trim.isEmpty) @@ -247,7 +247,7 @@ trait CommentFactoryBase { this: MemberLookupBase => parse0(docBody append endOfLine append marker, tags, lastTagKey, ls, true) } - case CodeBlockEnd(before, marker, after) :: ls => + case CodeBlockEndRegex(before, marker, after) :: ls => if (!before.trim.isEmpty && !after.trim.isEmpty) parse0(docBody, tags, lastTagKey, before :: marker :: after :: ls, true) if (!before.trim.isEmpty) @@ -266,17 +266,17 @@ trait CommentFactoryBase { this: MemberLookupBase => parse0(docBody append endOfLine append marker, tags, lastTagKey, ls, false) } - case SymbolTag(name, sym, body) :: ls if (!inCodeBlock) => + case SymbolTagRegex(name, sym, body) :: ls if (!inCodeBlock) => val key = SymbolTagKey(name, sym) val value = body :: tags.getOrElse(key, Nil) parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) - case SimpleTag(name, body) :: ls if (!inCodeBlock) => + case SimpleTagRegex(name, body) :: ls if (!inCodeBlock) => val key = SimpleTagKey(name) val value = body :: tags.getOrElse(key, Nil) parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) - case SingleTag(name) :: ls if (!inCodeBlock) => + case SingleTagRegex(name) :: ls if (!inCodeBlock) => val key = SimpleTagKey(name) val value = "" :: tags.getOrElse(key, Nil) parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock) diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala index ed6b38dade..cf38c629fc 100644 --- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala +++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala @@ -159,6 +159,20 @@ trait CompilerControl { self: Global => def askLinkPos(sym: Symbol, source: SourceFile, response: Response[Position]) = postWorkItem(new AskLinkPosItem(sym, source, response)) + /** Sets sync var `response` to doc comment information for a given symbol. + * + * @param sym The symbol whose doc comment should be retrieved (might come from a classfile) + * @param site The place where sym is observed. + * @param source The source file that's supposed to contain the definition + * @param response A response that will be set to the following: + * If `source` contains a definition of a given symbol that has a doc comment, + * the (expanded, raw, position) triplet for a comment, otherwise ("", "", NoPosition). + * Note: This operation does not automatically load `source`. If `source` + * is unloaded, it stays that way. + */ + def askDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]) = + postWorkItem(new AskDocCommentItem(sym, site, source, response)) + /** Sets sync var `response` to list of members that are visible * as members of the tree enclosing `pos`, possibly reachable by an implicit. * @pre source is loaded @@ -376,6 +390,14 @@ trait CompilerControl { self: Global => response raise new MissingResponse } + case class AskDocCommentItem(val sym: Symbol, val site: Symbol, val source: SourceFile, response: Response[(String, String, Position)]) extends WorkItem { + def apply() = self.getDocComment(sym, site, source, response) + override def toString = "doc comment "+sym+" in "+source + + def raiseMissing() = + response raise new MissingResponse + } + case class AskLoadedTypedItem(val source: SourceFile, response: Response[Tree]) extends WorkItem { def apply() = self.waitLoadedTyped(source, response, this.onCompilerThread) override def toString = "wait loaded & typed "+source diff --git a/src/compiler/scala/tools/nsc/interactive/Doc.scala b/src/compiler/scala/tools/nsc/interactive/Doc.scala deleted file mode 100755 index eab3e39e14..0000000000 --- a/src/compiler/scala/tools/nsc/interactive/Doc.scala +++ /dev/null @@ -1,59 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author Eugene Vigdorchik - */ - -package scala.tools.nsc -package interactive - -import doc.base._ -import comment._ -import scala.xml.NodeSeq - -sealed trait DocResult -final case class UrlResult(url: String) extends DocResult -final case class HtmlResult(comment: Comment) extends DocResult - -abstract class Doc(val settings: doc.Settings) extends MemberLookupBase with CommentFactoryBase { - - override val global: interactive.Global - import global._ - - def chooseLink(links: List[LinkTo]): LinkTo - - override def internalLink(sym: Symbol, site: Symbol): Option[LinkTo] = - ask { () => - if (sym.isClass || sym.isModule) - Some(LinkToTpl(sym)) - else - if ((site.isClass || site.isModule) && site.info.members.toList.contains(sym)) - Some(LinkToMember(sym, site)) - else - None - } - - override def toString(link: LinkTo) = ask { () => - link match { - case LinkToMember(mbr: Symbol, site: Symbol) => - mbr.signatureString + " in " + site.toString - case LinkToTpl(sym: Symbol) => sym.toString - case _ => link.toString - } - } - - def retrieve(sym: Symbol, site: Symbol): Option[DocResult] = { - val sig = ask { () => externalSignature(sym) } - findExternalLink(sym, sig) map { link => UrlResult(link.url) } orElse { - val resp = new Response[Tree] - // Ensure docComment tree is type-checked. - val pos = ask { () => docCommentPos(sym) } - askTypeAt(pos, resp) - resp.get.left.toOption flatMap { _ => - ask { () => - val comment = parseAtSymbol(expandedDocComment(sym), rawDocComment(sym), pos, Some(site)) - Some(HtmlResult(comment)) - } - } - } - } -} diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 2f63fbbff2..31208d2ad7 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -423,6 +423,9 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") compileRunner } + private def ensureUpToDate(unit: RichCompilationUnit) = + if (!unit.isUpToDate && unit.status != JustParsed) reset(unit) // reparse previously typechecked units. + /** Compile all loaded source files in the order given by `allSources`. */ private[interactive] final def backgroundCompile() { @@ -435,7 +438,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") // ensure all loaded units are parsed for (s <- allSources; unit <- getUnit(s)) { // checkForMoreWork(NoPosition) // disabled, as any work done here would be in an inconsistent state - if (!unit.isUpToDate && unit.status != JustParsed) reset(unit) // reparse previously typechecked units. + ensureUpToDate(unit) parseAndEnter(unit) serviceParsedEntered() } @@ -688,7 +691,7 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") try { debugLog("starting targeted type check") typeCheck(unit) - println("tree not found at "+pos) +// println("tree not found at "+pos) EmptyTree } catch { case ex: TyperResult => new Locator(pos) locateIn ex.tree @@ -719,64 +722,69 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") respond(response)(typedTree(source, forceReload)) } - /** Implements CompilerControl.askLinkPos */ - private[interactive] def getLinkPos(sym: Symbol, source: SourceFile, response: Response[Position]) { + private def withTempUnit[T](source: SourceFile)(f: RichCompilationUnit => T): T = + getUnit(source) match { + case None => + reloadSources(List(source)) + try f(getUnit(source).get) + finally afterRunRemoveUnitOf(source) + case Some(unit) => + f(unit) + } - /** Find position of symbol `sym` in unit `unit`. Pre: `unit is loaded. */ - def findLinkPos(unit: RichCompilationUnit): Position = { - val originalTypeParams = sym.owner.typeParams - parseAndEnter(unit) - val pre = adaptToNewRunMap(ThisType(sym.owner)) - val rawsym = pre.typeSymbol.info.decl(sym.name) - val newsym = rawsym filter { alt => - sym.isType || { - try { - val tp1 = pre.memberType(alt) onTypeError NoType - val tp2 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, sym.owner.typeParams) - matchesType(tp1, tp2, false) || { - debugLog(s"getLinkPos matchesType($tp1, $tp2) failed") - val tp3 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, alt.owner.typeParams) - matchesType(tp1, tp3, false) || { - debugLog(s"getLinkPos fallback matchesType($tp1, $tp3) failed") - false - } - } - } - catch { - case ex: ControlThrowable => throw ex - case ex: Throwable => - println("error in hyperlinking: " + ex) - ex.printStackTrace() + /** Find a 'mirror' of symbol `sym` in unit `unit`. Pre: `unit is loaded. */ + private def findMirrorSymbol(sym: Symbol, unit: RichCompilationUnit): Symbol = { + val originalTypeParams = sym.owner.typeParams + ensureUpToDate(unit) + parseAndEnter(unit) + val pre = adaptToNewRunMap(ThisType(sym.owner)) + val rawsym = pre.typeSymbol.info.decl(sym.name) + val newsym = rawsym filter { alt => + sym.isType || { + try { + val tp1 = pre.memberType(alt) onTypeError NoType + val tp2 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, sym.owner.typeParams) + matchesType(tp1, tp2, false) || { + debugLog(s"findMirrorSymbol matchesType($tp1, $tp2) failed") + val tp3 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, alt.owner.typeParams) + matchesType(tp1, tp3, false) || { + debugLog(s"findMirrorSymbol fallback matchesType($tp1, $tp3) failed") false + } } } - } - if (newsym == NoSymbol) { - if (rawsym.exists && !rawsym.isOverloaded) rawsym.pos - else { - debugLog("link not found " + sym + " " + source + " " + pre) - NoPosition + catch { + case ex: ControlThrowable => throw ex + case ex: Throwable => + debugLog("error in findMirrorSymbol: " + ex) + ex.printStackTrace() + false } - } else if (newsym.isOverloaded) { - settings.uniqid.value = true - debugLog("link ambiguous " + sym + " " + source + " " + pre + " " + newsym.alternatives) - NoPosition - } else { - debugLog("link found for " + newsym + ": " + newsym.pos) - newsym.pos } } + if (newsym == NoSymbol) { + if (rawsym.exists && !rawsym.isOverloaded) rawsym + else { + debugLog("mirror not found " + sym + " " + unit.source + " " + pre) + NoSymbol + } + } else if (newsym.isOverloaded) { + settings.uniqid.value = true + debugLog("mirror ambiguous " + sym + " " + unit.source + " " + pre + " " + newsym.alternatives) + NoSymbol + } else { + debugLog("mirror found for " + newsym + ": " + newsym.pos) + newsym + } + } + /** Implements CompilerControl.askLinkPos */ + private[interactive] def getLinkPos(sym: Symbol, source: SourceFile, response: Response[Position]) { informIDE("getLinkPos "+sym+" "+source) respond(response) { if (sym.owner.isClass) { - getUnit(source) match { - case None => - reloadSources(List(source)) - try findLinkPos(getUnit(source).get) - finally afterRunRemoveUnitOf(source) - case Some(unit) => - findLinkPos(unit) + withTempUnit(source){ u => + findMirrorSymbol(sym, u).pos } } else { debugLog("link not in class "+sym+" "+source+" "+sym.owner) @@ -785,6 +793,50 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") } } + /** Implements CompilerControl.askDocComment */ + private[interactive] def getDocComment(sym: Symbol, site: Symbol, source: SourceFile, response: Response[(String, String, Position)]) { + informIDE("getDocComment "+sym+" "+source) + respond(response) { + withTempUnit(source){ u => + val mirror = findMirrorSymbol(sym, u) + if (mirror eq NoSymbol) + ("", "", NoPosition) + else { + forceDocComment(mirror, u) + (expandedDocComment(mirror), rawDocComment(mirror), docCommentPos(mirror)) + } + } + } + } + + private def forceDocComment(sym: Symbol, unit: RichCompilationUnit) { + // Either typer has been run and we don't find DocDef, + // or we force the targeted typecheck here. + // In both cases doc comment maps should be filled for the subject symbol. + val docTree = + unit.body find { + case DocDef(_, defn) if defn.symbol eq sym => true + case _ => false + } + + for (t <- docTree) { + debugLog("Found DocDef tree for "+sym) + // Cannot get a typed tree at position since DocDef range is transparent. + val prevPos = unit.targetPos + val prevInterruptsEnabled = interruptsEnabled + try { + unit.targetPos = t.pos + interruptsEnabled = true + typeCheck(unit) + } catch { + case _: TyperResult => // ignore since we are after the side effect. + } finally { + unit.targetPos = prevPos + interruptsEnabled = prevInterruptsEnabled + } + } + } + def stabilizedType(tree: Tree): Type = tree match { case Ident(_) if tree.symbol.isStable => singleType(NoPrefix, tree.symbol) diff --git a/src/compiler/scala/tools/nsc/interactive/Picklers.scala b/src/compiler/scala/tools/nsc/interactive/Picklers.scala index 1dc891b984..09533fdeb5 100644 --- a/src/compiler/scala/tools/nsc/interactive/Picklers.scala +++ b/src/compiler/scala/tools/nsc/interactive/Picklers.scala @@ -163,6 +163,11 @@ trait Picklers { self: Global => .wrapped { case sym ~ source => new AskLinkPosItem(sym, source, new Response) } { item => item.sym ~ item.source } .asClass (classOf[AskLinkPosItem]) + implicit def askDocCommentItem: CondPickler[AskDocCommentItem] = + (pkl[Symbol] ~ pkl[Symbol] ~ pkl[SourceFile]) + .wrapped { case sym ~ site ~ source => new AskDocCommentItem(sym, site, source, new Response) } { item => item.sym ~ item.site ~ item.source } + .asClass (classOf[AskDocCommentItem]) + implicit def askLoadedTypedItem: CondPickler[AskLoadedTypedItem] = pkl[SourceFile] .wrapped { source => new AskLoadedTypedItem(source, new Response) } { _.source } @@ -180,5 +185,5 @@ trait Picklers { self: Global => implicit def action: Pickler[() => Unit] = reloadItem | askTypeAtItem | askTypeItem | askTypeCompletionItem | askScopeCompletionItem | - askToDoFirstItem | askLinkPosItem | askLoadedTypedItem | askParsedEnteredItem | emptyAction + askToDoFirstItem | askLinkPosItem | askDocCommentItem | askLoadedTypedItem | askParsedEnteredItem | emptyAction } diff --git a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala index 11ae7c974b..034a844e2e 100644 --- a/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala +++ b/src/compiler/scala/tools/nsc/interactive/tests/core/PresentationCompilerInstance.scala @@ -7,7 +7,8 @@ import reporters.{Reporter => CompilerReporter} /** Trait encapsulating the creation of a presentation compiler's instance.*/ private[tests] trait PresentationCompilerInstance extends TestSettings { protected val settings = new Settings - protected def docSettings: doc.Settings = new doc.Settings(_ => ()) + protected val docSettings = new doc.Settings(_ => ()) + protected val compilerReporter: CompilerReporter = new InteractiveReporter { override def compiler = PresentationCompilerInstance.this.compiler } diff --git a/test/files/presentation/doc.check b/test/files/presentation/doc.check index 62b3bfc2e3..e33756773d 100755..100644 --- a/test/files/presentation/doc.check +++ b/test/files/presentation/doc.check @@ -1,3 +1,4 @@ +reload: Test.scala body:Body(List(Paragraph(Chain(List(Summary(Chain(List(Text(This is a test comment), Text(.)))), Text( )))))) @example:Body(List(Paragraph(Chain(List(Summary(Monospace(Text("abb".permutations = Iterator(abb, bab, bba))))))))) diff --git a/test/files/presentation/doc.scala b/test/files/presentation/doc/doc.scala index 4b0d6baa1f..475d92b861 100755 --- a/test/files/presentation/doc.scala +++ b/test/files/presentation/doc/doc.scala @@ -1,5 +1,5 @@ import scala.tools.nsc.doc -import scala.tools.nsc.doc.base.LinkTo +import scala.tools.nsc.doc.base._ import scala.tools.nsc.doc.base.comment._ import scala.tools.nsc.interactive._ import scala.tools.nsc.interactive.tests._ @@ -28,12 +28,33 @@ object Test extends InteractiveTest { |trait Commented {} |class User(c: %sCommented)""".stripMargin.format(comment, tags take nTags mkString "\n", caret) - override def main(args: Array[String]) { - val documenter = new Doc(settings) { - val global: compiler.type = compiler - + override lazy val compiler = { + new { + override val settings = { + prepareSettings(Test.this.settings) + Test.this.settings + } + } with Global(settings, compilerReporter) with MemberLookupBase with CommentFactoryBase { + val global: this.type = this def chooseLink(links: List[LinkTo]): LinkTo = links.head + def internalLink(sym: Symbol, site: Symbol) = None + def toString(link: LinkTo) = link.toString + + def getComment(sym: Symbol, source: SourceFile) = { + val docResponse = new Response[(String, String, Position)] + askDocComment(sym, sym.owner, source, docResponse) + docResponse.get.left.toOption flatMap { + case (expanded, raw, pos) => + if (expanded.isEmpty) + None + else + Some(ask { () => parseAtSymbol(expanded, raw, pos, Some(sym.owner)) }) + } + } } + } + + override def runDefaultTests() { for (i <- 1 to tags.length) { val markedText = text(i) val idx = markedText.indexOf(caret) @@ -52,18 +73,17 @@ object Test extends InteractiveTest { treeResponse.get.left.toOption match { case Some(tree) => val sym = tree.tpe.typeSymbol - documenter.retrieve(sym, sym.owner) match { - case Some(HtmlResult(comment)) => - import comment._ - val tags: List[(String, Iterable[Body])] = - List(("@example", example), ("@version", version), ("@since", since.toList), ("@todo", todo), ("@note", note), ("@see", see)) - val str = ("body:" + body + "\n") + - tags.map{ case (name, bodies) => name + ":" + bodies.mkString("\n") }.mkString("\n") - reporter.println(str) - case Some(_) => reporter.println("Got unexpected result") - case None => reporter.println("Got no result") + compiler.getComment(sym, batch) match { + case None => println("Got no doc comment") + case Some(comment) => + import comment._ + val tags: List[(String, Iterable[Body])] = + List(("@example", example), ("@version", version), ("@since", since.toList), ("@todo", todo), ("@note", note), ("@see", see)) + val str = ("body:" + body + "\n") + + tags.map{ case (name, bodies) => name + ":" + bodies.mkString("\n") }.mkString("\n") + println(str) } - case None => reporter.println("Couldn't find a typedTree") + case None => println("Couldn't find a typedTree") } } } |