Skip to content

Commit ce40517

Browse files
committed
Make getDocComment referentially transparent
1 parent a51a963 commit ce40517

File tree

1 file changed

+12
-36
lines changed

1 file changed

+12
-36
lines changed

Diff for: compiler/src/dotty/tools/dotc/parsing/Scanners.scala

+12-36
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import scala.reflect.internal.Chars._
1010
import Tokens._
1111
import scala.annotation.{ switch, tailrec }
1212
import scala.collection.mutable
13+
import scala.collection.immutable.SortedMap
1314
import mutable.ListBuffer
1415
import Utility.isNameStart
1516
import rewrite.Rewrites.patch
@@ -174,39 +175,15 @@ object Scanners {
174175
class Scanner(source: SourceFile, override val startFrom: Offset = 0)(implicit ctx: Context) extends ScannerCommon(source)(ctx) {
175176
val keepComments = ctx.settings.YkeepComments.value
176177

177-
/** All doc comments as encountered, each list contains doc comments from
178-
* the same block level. Starting with the deepest level and going upward
179-
*/
180-
private[this] var docsPerBlockStack: List[List[Comment]] = List(Nil)
181-
182-
/** Adds level of nesting to docstrings */
183-
def enterBlock(): Unit =
184-
docsPerBlockStack = List(Nil) ::: docsPerBlockStack
178+
/** All doc comments kept by their end position in a `Map` */
179+
private[this] var docstringMap: SortedMap[Int, Comment] = SortedMap.empty
185180

186-
/** Removes level of nesting for docstrings */
187-
def exitBlock(): Unit = docsPerBlockStack = docsPerBlockStack match {
188-
case x :: Nil => List(Nil)
189-
case _ => docsPerBlockStack.tail
190-
}
181+
private[this] def addComment(comment: Comment): Unit =
182+
docstringMap = docstringMap + (comment.pos.end -> comment)
191183

192184
/** Returns the closest docstring preceding the position supplied */
193-
def getDocComment(pos: Int): Option[Comment] = {
194-
def closest(c: Comment, docstrings: List[Comment]): Comment = docstrings match {
195-
case x :: xs =>
196-
if (c.pos.end < x.pos.end && x.pos.end <= pos) closest(x, xs)
197-
else closest(c, xs)
198-
case Nil => c
199-
}
200-
201-
docsPerBlockStack match {
202-
case (list @ (x :: xs)) :: _ => {
203-
val c = closest(x, xs)
204-
docsPerBlockStack = list.dropWhile(_ != c).tail :: docsPerBlockStack.tail
205-
Some(c)
206-
}
207-
case _ => None
208-
}
209-
}
185+
def getDocComment(pos: Int): Option[Comment] =
186+
docstringMap.to(pos).lastOption.map(_._2)
210187

211188
/** A buffer for comments */
212189
val commentBuf = new StringBuilder
@@ -541,13 +518,13 @@ object Scanners {
541518
case ',' =>
542519
nextChar(); token = COMMA
543520
case '(' =>
544-
enterBlock(); nextChar(); token = LPAREN
521+
nextChar(); token = LPAREN
545522
case '{' =>
546-
enterBlock(); nextChar(); token = LBRACE
523+
nextChar(); token = LBRACE
547524
case ')' =>
548-
exitBlock(); nextChar(); token = RPAREN
525+
nextChar(); token = RPAREN
549526
case '}' =>
550-
exitBlock(); nextChar(); token = RBRACE
527+
nextChar(); token = RBRACE
551528
case '[' =>
552529
nextChar(); token = LBRACKET
553530
case ']' =>
@@ -615,8 +592,7 @@ object Scanners {
615592
val pos = Position(start, charOffset, start)
616593
val comment = Comment(pos, flushBuf(commentBuf))
617594

618-
if (comment.isDocComment)
619-
docsPerBlockStack = (docsPerBlockStack.head :+ comment) :: docsPerBlockStack.tail
595+
if (comment.isDocComment) addComment(comment)
620596
}
621597

622598
true

0 commit comments

Comments
 (0)