@@ -82,7 +82,9 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
8282
8383 def apply (idx : Int ): Char = content().apply(idx)
8484
85- def length : Int = content().length
85+ def length : Int =
86+ if lineIndicesCache ne null then lineIndicesCache.last
87+ else content().length
8688
8789 /** true for all source files except `NoSource` */
8890 def exists : Boolean = true
@@ -105,7 +107,8 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
105107 def positionInUltimateSource (position : SourcePosition ): SourcePosition =
106108 SourcePosition (underlying, position.span shift start)
107109
108- private def calculateLineIndices (cs : Array [Char ]) = {
110+ private def calculateLineIndicesFromContents () = {
111+ val cs = content()
109112 val buf = new ArrayBuffer [Int ]
110113 buf += 0
111114 var i = 0
@@ -120,7 +123,22 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
120123 buf += cs.length // sentinel, so that findLine below works smoother
121124 buf.toArray
122125 }
123- private lazy val lineIndices : Array [Int ] = calculateLineIndices(content())
126+
127+ private var lineIndicesCache : Array [Int ] = _
128+ private def lineIndices : Array [Int ] =
129+ if lineIndicesCache eq null then
130+ lineIndicesCache = calculateLineIndicesFromContents()
131+ lineIndicesCache
132+ def setLineIndicesFromLineSizes (sizes : Array [Int ]): Unit =
133+ val lines = sizes.length
134+ val indices = new Array [Int ](lines + 1 )
135+ var i = 0
136+ val penultimate = lines - 1
137+ while i < penultimate do
138+ indices(i + 1 ) = indices(i) + sizes(i) + 1 // `+1` for the '\n' at the end of the line
139+ i += 1
140+ indices(lines) = indices(penultimate) + sizes(penultimate) // last line does not end with '\n'
141+ lineIndicesCache = indices
124142
125143 /** Map line to offset of first character in line */
126144 def lineToOffset (index : Int ): Int = lineIndices(index)
0 commit comments