Skip to content

Commit

Permalink
SI-7376 Unmoored doc has correct position
Browse files Browse the repository at this point in the history
The unmoored DocComment is created more eagerly so that its position
is correct despite subsequent line comments. (Previously, skipComment
would advance docPos.)

It looks like the error caret is still off by one when a doc comment
shows up in the middle of an operator, and who doesn't scaladoc the
interior of expressions?

Another bug fixed by Paul's refactor is that additional comments
between the doc and the entity no longer breaks the scaladoc.
Test added.
  • Loading branch information
som-snytt committed Apr 17, 2013
1 parent 0fde95e commit 3f0a90b
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 25 deletions.
41 changes: 17 additions & 24 deletions src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala
Expand Up @@ -149,9 +149,9 @@ abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends Syntax

class ScaladocUnitScanner(unit0: CompilationUnit, patches0: List[BracePatch]) extends UnitScanner(unit0, patches0) {

private var docBuffer: StringBuilder = null // buffer for comments
private var docPos: Position = NoPosition // last doc comment position
private var inDocComment = false
private var docBuffer: StringBuilder = null // buffer for comments (non-null while scanning)
private var inDocComment = false // if buffer contains double-star doc comment
private var lastDoc: DocComment = null // last comment if it was double-star doc

private lazy val unmooredParser = { // minimalist comment parser
import scala.tools.nsc.doc.base.{comment => _, _}
Expand Down Expand Up @@ -180,7 +180,7 @@ abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends Syntax
* Also warn under -Xlint, but otherwise only warn in the presence of suspicious
* tags that appear to be documenting API. Warnings are suppressed while parsing
* the local comment so that comments of the form `[at] Martin` will not trigger a warning.
* In addition, tags for `todo`, `note` and `example` are ignored.
* By omission, tags for `see`, `todo`, `note` and `example` are ignored.
*/
override def discardDocBuffer() = {
import scala.tools.nsc.doc.base.comment.Comment
Expand All @@ -193,13 +193,10 @@ abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends Syntax
}
def isDirty = unclean(unmooredParser parseComment doc)
if ((doc ne null) && (settings.lint || isDirty))
unit.warning(docPos, "discarding unmoored doc comment")
unit.warning(doc.pos, "discarding unmoored doc comment")
}

override def flushDoc(): DocComment = {
if (docBuffer eq null) null
else try DocComment(docBuffer.toString, docPos) finally docBuffer = null
}
override def flushDoc(): DocComment = (try lastDoc finally lastDoc = null)

override protected def putCommentChar() {
if (inDocComment)
Expand All @@ -218,23 +215,19 @@ abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends Syntax
super.skipBlockComment()
}
override def skipComment(): Boolean = {
super.skipComment() && {
if (docBuffer ne null) {
if (inDocComment)
foundDocComment(docBuffer.toString, offset, charOffset - 2)
else
try foundComment(docBuffer.toString, offset, charOffset - 2) finally docBuffer = null
}
// emit a block comment; if it's double-star, make Doc at this pos
def foundStarComment(start: Int, end: Int) = try {
val str = docBuffer.toString
val pos = new RangePosition(unit.source, start, start, end)
unit.comment(pos, str)
if (inDocComment)
lastDoc = DocComment(str, pos)
true
} finally {
docBuffer = null
inDocComment = false
}
}
def foundComment(value: String, start: Int, end: Int) {
val pos = new RangePosition(unit.source, start, start, end)
unit.comment(pos, value)
}
def foundDocComment(value: String, start: Int, end: Int) {
docPos = new RangePosition(unit.source, start, start, end)
unit.comment(docPos, value)
super.skipComment() && ((docBuffer eq null) || foundStarComment(offset, charOffset - 2))
}
}
class ScaladocUnitParser(unit: CompilationUnit, patches: List[BracePatch]) extends UnitParser(unit, patches) {
Expand Down
20 changes: 19 additions & 1 deletion test/scaladoc/run/t5527.check
@@ -1,6 +1,12 @@
newSource1:47: warning: discarding unmoored doc comment
/** Document this crucial constant for posterity.
^
newSource1:64: warning: discarding unmoored doc comment
/*************************\
^
newSource1:73: warning: discarding unmoored doc comment
val i = 10 */** Important!
^
[[syntax trees at end of parser]] // newSource1
package <empty> {
object UselessComments extends scala.AnyRef {
Expand Down Expand Up @@ -54,6 +60,14 @@ package <empty> {
def test7 = {
val u = 4;
0.to(u).foreach(((i) => println(i)))
};
def test8 = {
val z = "fancy";
z.replace("fanc", "arts")
};
def test9 = {
val i = 10.$times(10);
assert(i.$eq$eq(100))
}
};
/** comments that we should keep */
Expand Down Expand Up @@ -108,7 +122,11 @@ package <empty> {
super.<init>();
()
}
}
};
/** Get the simple value.
* @return the default value
*/
def value: Int = 7
}
}

25 changes: 25 additions & 0 deletions test/scaladoc/run/t5527.scala
Expand Up @@ -72,6 +72,24 @@ object Test extends DirectTest {
for (i <- 0 to u)
println(i)
}
def test8 = {
/*************************\
* Fancy ASCII Art Block *
* @author som-snytt *
\*************************/
// this is just a local
val z = "fancy"
z replace ("fanc", "arts")
}
def test9 = {
val i = 10 */** Important!
* We have to multiply here!
* @author community
* @see SI-1234
*/
10
assert(i == 100)
}
}
/** comments that we should keep */
Expand Down Expand Up @@ -108,6 +126,13 @@ object Test extends DirectTest {
/** class D */
@deprecated("use ... instead", "2.10.0")
class D
/** Get the simple value.
* @return the default value
*/
// an intervening line comment
/* I had more to say, but didn't want to pollute the scaladoc. */
def value: Int = 7
}
""".trim

Expand Down

0 comments on commit 3f0a90b

Please sign in to comment.