@@ -137,12 +137,12 @@ class SourceMap {
137137
138138 async extendSourceMap ( original , extension ) {
139139 if ( ! ( extension instanceof SourceMap ) ) {
140- throw new Error (
141- '[SOURCEMAP] Type of extension should be a SourceMap instance!'
142- ) ;
140+ extension = await new SourceMap ( ) . addMap ( extension ) ;
141+ }
142+ if ( ! ( original instanceof SourceMap ) ) {
143+ original = await this . getConsumer ( original ) ;
143144 }
144145
145- original = await this . getConsumer ( original ) ;
146146 extension . eachMapping ( mapping => {
147147 let originalMapping = original . originalPositionFor ( {
148148 line : mapping . original . line ,
@@ -182,6 +182,90 @@ class SourceMap {
182182 return this ;
183183 }
184184
185+ findClosest ( line , column , key = 'original' ) {
186+ if ( line < 1 ) {
187+ throw new Error ( 'Line numbers must be >= 1' ) ;
188+ }
189+
190+ if ( column < 0 ) {
191+ throw new Error ( 'Column numbers must be >= 0' ) ;
192+ }
193+
194+ if ( this . mappings . length < 1 ) {
195+ return undefined ;
196+ }
197+
198+ let startIndex = 0 ;
199+ let stopIndex = this . mappings . length - 1 ;
200+ let middleIndex = Math . floor ( ( stopIndex + startIndex ) / 2 ) ;
201+
202+ while (
203+ startIndex < stopIndex &&
204+ this . mappings [ middleIndex ] [ key ] . line !== line
205+ ) {
206+ if ( line < this . mappings [ middleIndex ] [ key ] . line ) {
207+ stopIndex = middleIndex - 1 ;
208+ } else if ( line > this . mappings [ middleIndex ] [ key ] . line ) {
209+ startIndex = middleIndex + 1 ;
210+ }
211+ middleIndex = Math . floor ( ( stopIndex + startIndex ) / 2 ) ;
212+ }
213+
214+ let mapping = this . mappings [ middleIndex ] ;
215+ if ( ! mapping || mapping [ key ] . line !== line ) {
216+ return this . mappings . length - 1 ;
217+ }
218+
219+ while (
220+ middleIndex >= 1 &&
221+ this . mappings [ middleIndex - 1 ] [ key ] . line === line
222+ ) {
223+ middleIndex -- ;
224+ }
225+
226+ while (
227+ middleIndex < this . mappings . length - 1 &&
228+ this . mappings [ middleIndex + 1 ] [ key ] . line === line &&
229+ column > this . mappings [ middleIndex ] [ key ] . column
230+ ) {
231+ middleIndex ++ ;
232+ }
233+
234+ return middleIndex ;
235+ }
236+
237+ originalPositionFor ( generatedPosition ) {
238+ let index = this . findClosest (
239+ generatedPosition . line ,
240+ generatedPosition . column ,
241+ 'generated'
242+ ) ;
243+ return {
244+ source : this . mappings [ index ] . source ,
245+ name : this . mappings [ index ] . name ,
246+ line : this . mappings [ index ] . original . line ,
247+ column : this . mappings [ index ] . original . column
248+ } ;
249+ }
250+
251+ generatedPositionFor ( originalPosition ) {
252+ let index = this . findClosest (
253+ originalPosition . line ,
254+ originalPosition . column ,
255+ 'original'
256+ ) ;
257+ return {
258+ source : this . mappings [ index ] . source ,
259+ name : this . mappings [ index ] . name ,
260+ line : this . mappings [ index ] . generated . line ,
261+ column : this . mappings [ index ] . generated . column
262+ } ;
263+ }
264+
265+ sourceContentFor ( fileName ) {
266+ return this . sources [ fileName ] ;
267+ }
268+
185269 offset ( lineOffset = 0 , columnOffset = 0 ) {
186270 this . mappings . map ( mapping => {
187271 mapping . generated . line = mapping . generated . line + lineOffset ;
0 commit comments