@@ -10,6 +10,7 @@ import scala.reflect.internal.Chars._
10
10
import Tokens ._
11
11
import scala .annotation .{ switch , tailrec }
12
12
import scala .collection .mutable
13
+ import scala .collection .immutable .SortedMap
13
14
import mutable .ListBuffer
14
15
import Utility .isNameStart
15
16
import rewrite .Rewrites .patch
@@ -174,39 +175,15 @@ object Scanners {
174
175
class Scanner (source : SourceFile , override val startFrom : Offset = 0 )(implicit ctx : Context ) extends ScannerCommon (source)(ctx) {
175
176
val keepComments = ctx.settings.YkeepComments .value
176
177
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
185
180
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)
191
183
192
184
/** 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)
210
187
211
188
/** A buffer for comments */
212
189
val commentBuf = new StringBuilder
@@ -541,13 +518,13 @@ object Scanners {
541
518
case ',' =>
542
519
nextChar(); token = COMMA
543
520
case '(' =>
544
- enterBlock(); nextChar(); token = LPAREN
521
+ nextChar(); token = LPAREN
545
522
case '{' =>
546
- enterBlock(); nextChar(); token = LBRACE
523
+ nextChar(); token = LBRACE
547
524
case ')' =>
548
- exitBlock(); nextChar(); token = RPAREN
525
+ nextChar(); token = RPAREN
549
526
case '}' =>
550
- exitBlock(); nextChar(); token = RBRACE
527
+ nextChar(); token = RBRACE
551
528
case '[' =>
552
529
nextChar(); token = LBRACKET
553
530
case ']' =>
@@ -615,8 +592,7 @@ object Scanners {
615
592
val pos = Position (start, charOffset, start)
616
593
val comment = Comment (pos, flushBuf(commentBuf))
617
594
618
- if (comment.isDocComment)
619
- docsPerBlockStack = (docsPerBlockStack.head :+ comment) :: docsPerBlockStack.tail
595
+ if (comment.isDocComment) addComment(comment)
620
596
}
621
597
622
598
true
0 commit comments