Skip to content

Commit

Permalink
Moved scaladoc code into src/scaladoc.
Browse files Browse the repository at this point in the history
This leverages the preceding several commits to push scaladoc
specific code into src/scaladoc. It also renders some scanner
code more comprehensible.
  • Loading branch information
paulp authored and adriaanm committed Mar 9, 2013
1 parent 9604770 commit 3d5c675
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 223 deletions.
29 changes: 4 additions & 25 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -650,31 +650,10 @@ self =>

/* --------- COMMENT AND ATTRIBUTE COLLECTION ----------------------------- */

/** Join the comment associated with a definition. */
def joinComment(trees: => List[Tree]): List[Tree] = {
val doc = in.flushDoc
if ((doc ne null) && doc.raw.length > 0) {
val joined = trees map {
t =>
DocDef(doc, t) setPos {
if (t.pos.isDefined) {
val pos = doc.pos.withEnd(t.pos.endOrPoint)
// always make the position transparent
pos.makeTransparent
} else {
t.pos
}
}
}
joined.find(_.pos.isOpaqueRange) foreach {
main =>
val mains = List(main)
joined foreach { t => if (t ne main) ensureNonOverlapping(t, mains) }
}
joined
}
else trees
}
/** A hook for joining the comment associated with a definition.
* Overridden by scaladoc.
*/
def joinComment(trees: => List[Tree]): List[Tree] = trees

/* ---------- TREE CONSTRUCTION ------------------------------------------- */

Expand Down
155 changes: 69 additions & 86 deletions src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,69 @@ trait Scanners extends ScannersCommon {
abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon {
private def isDigit(c: Char) = java.lang.Character isDigit c

private var openComments = 0
protected def putCommentChar(): Unit = nextChar()

@tailrec private def skipLineComment(): Unit = ch match {
case SU | CR | LF =>
case _ => nextChar() ; skipLineComment()
}
private def maybeOpen() {
putCommentChar()
if (ch == '*') {
putCommentChar()
openComments += 1
}
}
private def maybeClose(): Boolean = {
putCommentChar()
(ch == '/') && {
putCommentChar()
openComments -= 1
openComments == 0
}
}
@tailrec final def skipNestedComments(): Unit = ch match {
case '/' => maybeOpen() ; skipNestedComments()
case '*' => if (!maybeClose()) skipNestedComments()
case SU => incompleteInputError("unclosed comment")
case _ => putCommentChar() ; skipNestedComments()
}
def skipDocComment(): Unit = skipNestedComments()
def skipBlockComment(): Unit = skipNestedComments()

private def skipToCommentEnd(isLineComment: Boolean) {
nextChar()
if (isLineComment) skipLineComment()
else {
openComments = 1
val isDocComment = (ch == '*') && { nextChar(); true }
if (isDocComment) {
// Check for the amazing corner case of /**/
if (ch == '/')
nextChar()
else
skipDocComment()
}
else skipBlockComment()
}
}

/** @pre ch == '/'
* Returns true if a comment was skipped.
*/
def skipComment(): Boolean = ch match {
case '/' | '*' => skipToCommentEnd(isLineComment = ch == '/') ; true
case _ => false
}
def flushDoc(): DocComment = null

/** To prevent doc comments attached to expressions from leaking out of scope
* onto the next documentable entity, they are discarded upon passing a right
* brace, bracket, or parenthesis.
*/
def discardDocBuffer(): Unit = ()

def isAtEnd = charOffset >= buf.length

def resume(lastCode: Int) = {
Expand Down Expand Up @@ -130,22 +193,6 @@ trait Scanners extends ScannersCommon {
cbuf.clear()
}

/** Should doc comments be built? */
def buildDocs: Boolean = forScaladoc

/** holder for the documentation comment
*/
var docComment: DocComment = null

def flushDoc: DocComment = {
val ret = docComment
docComment = null
ret
}

protected def foundComment(value: String, start: Int, end: Int) = ()
protected def foundDocComment(value: String, start: Int, end: Int) = ()

private class TokenData0 extends TokenData

/** we need one token lookahead and one token history
Expand Down Expand Up @@ -218,12 +265,15 @@ trait Scanners extends ScannersCommon {
case RBRACE =>
while (!sepRegions.isEmpty && sepRegions.head != RBRACE)
sepRegions = sepRegions.tail
if (!sepRegions.isEmpty) sepRegions = sepRegions.tail
docComment = null
if (!sepRegions.isEmpty)
sepRegions = sepRegions.tail

discardDocBuffer()
case RBRACKET | RPAREN =>
if (!sepRegions.isEmpty && sepRegions.head == lastToken)
sepRegions = sepRegions.tail
docComment = null

discardDocBuffer()
case ARROW =>
if (!sepRegions.isEmpty && sepRegions.head == lastToken)
sepRegions = sepRegions.tail
Expand Down Expand Up @@ -516,62 +566,6 @@ trait Scanners extends ScannersCommon {
}
}

private def skipComment(): Boolean = {

if (ch == '/' || ch == '*') {

val comment = new StringBuilder("/")
def appendToComment() = comment.append(ch)

if (ch == '/') {
do {
appendToComment()
nextChar()
} while ((ch != CR) && (ch != LF) && (ch != SU))
} else {
docComment = null
var openComments = 1
appendToComment()
nextChar()
appendToComment()
var buildingDocComment = false
if (ch == '*' && buildDocs) {
buildingDocComment = true
}
while (openComments > 0) {
do {
do {
if (ch == '/') {
nextChar(); appendToComment()
if (ch == '*') {
nextChar(); appendToComment()
openComments += 1
}
}
if (ch != '*' && ch != SU) {
nextChar(); appendToComment()
}
} while (ch != '*' && ch != SU)
while (ch == '*') {
nextChar(); appendToComment()
}
} while (ch != '/' && ch != SU)
if (ch == '/') nextChar()
else incompleteInputError("unclosed comment")
openComments -= 1
}

if (buildingDocComment)
foundDocComment(comment.toString, offset, charOffset - 2)
}

foundComment(comment.toString, offset, charOffset - 2)
true
} else {
false
}
}

/** Can token start a statement? */
def inFirstOfStat(token: Int) = token match {
case EOF | CATCH | ELSE | EXTENDS | FINALLY | FORSOME | MATCH | WITH | YIELD |
Expand Down Expand Up @@ -1281,17 +1275,6 @@ trait Scanners extends ScannersCommon {
}
}
}

override def foundComment(value: String, start: Int, end: Int) {
val pos = new RangePosition(unit.source, start, start, end)
unit.comment(pos, value)
}

override def foundDocComment(value: String, start: Int, end: Int) {
val docPos = new RangePosition(unit.source, start, start, end)
docComment = new DocComment(value, docPos)
unit.comment(docPos, value)
}
}

class ParensAnalyzer(unit: CompilationUnit, patches: List[BracePatch]) extends UnitScanner(unit, patches) {
Expand Down
10 changes: 0 additions & 10 deletions src/compiler/scala/tools/nsc/javac/JavaScanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,6 @@ trait JavaScanners extends ast.parser.ScannersCommon {
cbuf.setLength(0)
}

/** buffer for the documentation comment
*/
var docBuffer: StringBuilder = null

/** add the given character to the documentation buffer
*/
protected def putDocChar(c: Char) {
if (docBuffer ne null) docBuffer.append(c)
}

private class JavaTokenData0 extends JavaTokenData

/** we need one token lookahead
Expand Down
12 changes: 4 additions & 8 deletions src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,10 @@ abstract class SymbolLoaders {

protected def signalError(root: Symbol, ex: Throwable) {
if (settings.debug.value) ex.printStackTrace()
// SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented
// therefore, it will rummage through the classpath triggering errors whenever it encounters package objects
// that are not in their correct place (see bug for details)
if (!settings.isScaladoc)
globalError(ex.getMessage() match {
case null => "i/o error while loading " + root.name
case msg => "error while loading " + root.name + ", " + msg
})
globalError(ex.getMessage() match {
case null => "i/o error while loading " + root.name
case msg => "error while loading " + root.name + ", " + msg
})
}

/** Enter class with given `name` into scope of `root`
Expand Down
12 changes: 0 additions & 12 deletions src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,6 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
log("Expanded '%s' to '%s' in %s".format(savedName, s.name, sym))
}
}
if (settings.verbose.value && forScaladoc && !sym.isAnonymousClass) {
println("========== scaladoc of "+sym+" =============================")
println(toJavaDoc(expandedDocComment(sym)))
for (member <- sym.info.members) {
println(member+":"+sym.thisType.memberInfo(member)+"\n"+
toJavaDoc(expandedDocComment(member, sym)))
for ((useCase, comment, pos) <- useCases(member, sym)) {
println("usecase "+useCase+":"+useCase.info)
println(toJavaDoc(comment))
}
}
}
super.transform(tree)
}
transformClassDef
Expand Down

0 comments on commit 3d5c675

Please sign in to comment.