@@ -10,6 +10,7 @@ import util.Chars._
1010import Tokens ._
1111import scala .annotation .{ switch , tailrec }
1212import scala .collection .mutable
13+ import scala .collection .immutable .SortedMap
1314import mutable .ListBuffer
1415import Utility .isNameStart
1516import 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