@@ -82,7 +82,9 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
82
82
83
83
def apply (idx : Int ): Char = content().apply(idx)
84
84
85
- def length : Int = content().length
85
+ def length : Int =
86
+ if lineIndicesCache ne null then lineIndicesCache.last
87
+ else content().length
86
88
87
89
/** true for all source files except `NoSource` */
88
90
def exists : Boolean = true
@@ -105,7 +107,8 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
105
107
def positionInUltimateSource (position : SourcePosition ): SourcePosition =
106
108
SourcePosition (underlying, position.span shift start)
107
109
108
- private def calculateLineIndices (cs : Array [Char ]) = {
110
+ private def calculateLineIndicesFromContents () = {
111
+ val cs = content()
109
112
val buf = new ArrayBuffer [Int ]
110
113
buf += 0
111
114
var i = 0
@@ -120,7 +123,22 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
120
123
buf += cs.length // sentinel, so that findLine below works smoother
121
124
buf.toArray
122
125
}
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
124
142
125
143
/** Map line to offset of first character in line */
126
144
def lineToOffset (index : Int ): Int = lineIndices(index)
0 commit comments