@@ -148,8 +148,16 @@ namespace ts.sourcemaps {
148
148
}
149
149
}
150
150
151
- export function calculateDecodedMappings < T > ( map : SourceMapData , processPosition : ( position : RawSourceMapPosition ) => T , host ?: { log ?( s : string ) : void } ) : T [ ] {
152
- const state : DecoderState < T > = {
151
+ /*@internal */
152
+ export interface MappingsDecoder extends Iterator < SourceMapSpan > {
153
+ readonly decodingIndex : number ;
154
+ readonly error : string | undefined ;
155
+ readonly lastSpan : SourceMapSpan ;
156
+ }
157
+
158
+ /*@internal */
159
+ export function decodeMappings ( map : SourceMapData ) : MappingsDecoder {
160
+ const state : DecoderState = {
153
161
encodedText : map . mappings ,
154
162
currentNameIndex : undefined ,
155
163
sourceMapNamesLength : map . names ? map . names . length : undefined ,
@@ -158,20 +166,40 @@ namespace ts.sourcemaps {
158
166
currentSourceColumn : 0 ,
159
167
currentSourceLine : 0 ,
160
168
currentSourceIndex : 0 ,
161
- positions : [ ] ,
162
- decodingIndex : 0 ,
163
- processPosition,
169
+ decodingIndex : 0
164
170
} ;
165
- while ( ! hasCompletedDecoding ( state ) ) {
166
- decodeSinglePosition ( state ) ;
167
- if ( state . error ) {
168
- if ( host && host . log ) {
169
- host . log ( `Encountered error while decoding sourcemap: ${ state . error } ` ) ;
170
- }
171
- return [ ] ;
171
+ function captureSpan ( ) : SourceMapSpan {
172
+ return {
173
+ emittedColumn : state . currentEmittedColumn ,
174
+ emittedLine : state . currentEmittedLine ,
175
+ sourceColumn : state . currentSourceColumn ,
176
+ sourceIndex : state . currentSourceIndex ,
177
+ sourceLine : state . currentSourceLine ,
178
+ nameIndex : state . currentNameIndex
179
+ } ;
180
+ }
181
+ return {
182
+ get decodingIndex ( ) { return state . decodingIndex ; } ,
183
+ get error ( ) { return state . error ; } ,
184
+ get lastSpan ( ) { return captureSpan ( ) ; } ,
185
+ next ( ) {
186
+ if ( hasCompletedDecoding ( state ) || state . error ) return { done : true , value : undefined as never } ;
187
+ if ( ! decodeSinglePosition ( state ) ) return { done : true , value : undefined as never } ;
188
+ return { done : false , value : captureSpan ( ) } ;
172
189
}
190
+ } ;
191
+ }
192
+
193
+ export function calculateDecodedMappings < T > ( map : SourceMapData , processPosition : ( position : RawSourceMapPosition ) => T , host ?: { log ?( s : string ) : void } ) : T [ ] {
194
+ const decoder = decodeMappings ( map ) ;
195
+ const positions = arrayFrom ( decoder , processPosition ) ;
196
+ if ( decoder . error ) {
197
+ if ( host && host . log ) {
198
+ host . log ( `Encountered error while decoding sourcemap: ${ decoder . error } ` ) ;
199
+ }
200
+ return [ ] ;
173
201
}
174
- return state . positions ;
202
+ return positions ;
175
203
}
176
204
177
205
interface ProcessedSourceMapPosition {
@@ -189,7 +217,7 @@ namespace ts.sourcemaps {
189
217
nameIndex ?: number ;
190
218
}
191
219
192
- interface DecoderState < T > {
220
+ interface DecoderState {
193
221
decodingIndex : number ;
194
222
currentEmittedLine : number ;
195
223
currentEmittedColumn : number ;
@@ -200,15 +228,13 @@ namespace ts.sourcemaps {
200
228
encodedText : string ;
201
229
sourceMapNamesLength ?: number ;
202
230
error ?: string ;
203
- positions : T [ ] ;
204
- processPosition : ( position : RawSourceMapPosition ) => T ;
205
231
}
206
232
207
- function hasCompletedDecoding ( state : DecoderState < any > ) {
233
+ function hasCompletedDecoding ( state : DecoderState ) {
208
234
return state . decodingIndex === state . encodedText . length ;
209
235
}
210
236
211
- function decodeSinglePosition < T > ( state : DecoderState < T > ) : void {
237
+ function decodeSinglePosition ( state : DecoderState ) : boolean {
212
238
while ( state . decodingIndex < state . encodedText . length ) {
213
239
const char = state . encodedText . charCodeAt ( state . decodingIndex ) ;
214
240
if ( char === CharacterCodes . semicolon ) {
@@ -230,40 +256,40 @@ namespace ts.sourcemaps {
230
256
state . currentEmittedColumn += base64VLQFormatDecode ( ) ;
231
257
// Incorrect emittedColumn dont support this map
232
258
if ( createErrorIfCondition ( state . currentEmittedColumn < 0 , "Invalid emittedColumn found" ) ) {
233
- return ;
259
+ return false ;
234
260
}
235
261
// Dont support reading mappings that dont have information about original source and its line numbers
236
262
if ( createErrorIfCondition ( isSourceMappingSegmentEnd ( state . encodedText , state . decodingIndex ) , "Unsupported Error Format: No entries after emitted column" ) ) {
237
- return ;
263
+ return false ;
238
264
}
239
265
240
266
// 2. Relative sourceIndex
241
267
state . currentSourceIndex += base64VLQFormatDecode ( ) ;
242
268
// Incorrect sourceIndex dont support this map
243
269
if ( createErrorIfCondition ( state . currentSourceIndex < 0 , "Invalid sourceIndex found" ) ) {
244
- return ;
270
+ return false ;
245
271
}
246
272
// Dont support reading mappings that dont have information about original source position
247
273
if ( createErrorIfCondition ( isSourceMappingSegmentEnd ( state . encodedText , state . decodingIndex ) , "Unsupported Error Format: No entries after sourceIndex" ) ) {
248
- return ;
274
+ return false ;
249
275
}
250
276
251
277
// 3. Relative sourceLine 0 based
252
278
state . currentSourceLine += base64VLQFormatDecode ( ) ;
253
279
// Incorrect sourceLine dont support this map
254
280
if ( createErrorIfCondition ( state . currentSourceLine < 0 , "Invalid sourceLine found" ) ) {
255
- return ;
281
+ return false ;
256
282
}
257
283
// Dont support reading mappings that dont have information about original source and its line numbers
258
284
if ( createErrorIfCondition ( isSourceMappingSegmentEnd ( state . encodedText , state . decodingIndex ) , "Unsupported Error Format: No entries after emitted Line" ) ) {
259
- return ;
285
+ return false ;
260
286
}
261
287
262
288
// 4. Relative sourceColumn 0 based
263
289
state . currentSourceColumn += base64VLQFormatDecode ( ) ;
264
290
// Incorrect sourceColumn dont support this map
265
291
if ( createErrorIfCondition ( state . currentSourceColumn < 0 , "Invalid sourceLine found" ) ) {
266
- return ;
292
+ return false ;
267
293
}
268
294
// 5. Check if there is name:
269
295
if ( ! isSourceMappingSegmentEnd ( state . encodedText , state . decodingIndex ) ) {
@@ -279,27 +305,15 @@ namespace ts.sourcemaps {
279
305
}
280
306
// Dont support reading mappings that dont have information about original source and its line numbers
281
307
if ( createErrorIfCondition ( ! isSourceMappingSegmentEnd ( state . encodedText , state . decodingIndex ) , "Unsupported Error Format: There are more entries after " + ( state . currentNameIndex === undefined ? "sourceColumn" : "nameIndex" ) ) ) {
282
- return ;
308
+ return false ;
283
309
}
284
310
285
311
// Entry should be complete
286
- capturePosition ( ) ;
287
- return ;
312
+ return true ;
288
313
}
289
314
290
315
createErrorIfCondition ( /*condition*/ true , "No encoded entry found" ) ;
291
- return ;
292
-
293
- function capturePosition ( ) {
294
- state . positions . push ( state . processPosition ( {
295
- emittedColumn : state . currentEmittedColumn ,
296
- emittedLine : state . currentEmittedLine ,
297
- sourceColumn : state . currentSourceColumn ,
298
- sourceIndex : state . currentSourceIndex ,
299
- sourceLine : state . currentSourceLine ,
300
- nameIndex : state . currentNameIndex
301
- } ) ) ;
302
- }
316
+ return false ;
303
317
304
318
function createErrorIfCondition ( condition : boolean , errormsg : string ) {
305
319
if ( state . error ) {
0 commit comments