@@ -99,10 +99,6 @@ namespace ts {
9999 let sourceMapDataList : SourceMapData [ ] | undefined ;
100100 let disabled : boolean = ! ( compilerOptions . sourceMap || compilerOptions . inlineSourceMap ) ;
101101
102- let completedSections : SourceMapSectionDefinition [ ] ;
103- let sectionStartLine : number ;
104- let sectionStartColumn : number ;
105-
106102 return {
107103 initialize,
108104 reset,
@@ -150,9 +146,6 @@ namespace ts {
150146 lastEncodedNameIndex = 0 ;
151147
152148 // Initialize source map data
153- completedSections = [ ] ;
154- sectionStartLine = 1 ;
155- sectionStartColumn = 1 ;
156149 sourceMapData = {
157150 sourceMapFilePath,
158151 jsSourceMappingURL : ! compilerOptions . inlineSourceMap ? getBaseFileName ( normalizeSlashes ( sourceMapFilePath ) ) : undefined ! , // TODO: GH#18217
@@ -221,9 +214,6 @@ namespace ts {
221214 lastEncodedNameIndex = undefined ;
222215 sourceMapData = undefined ! ;
223216 sourceMapDataList = undefined ! ;
224- completedSections = undefined ! ;
225- sectionStartLine = undefined ! ;
226- sectionStartColumn = undefined ! ;
227217 }
228218
229219 interface SourceMapSection {
@@ -233,7 +223,7 @@ namespace ts {
233223 sources : string [ ] ;
234224 names ?: string [ ] ;
235225 mappings : string ;
236- sourcesContent ?: string [ ] ;
226+ sourcesContent ?: ( string | null ) [ ] ;
237227 sections ?: undefined ;
238228 }
239229
@@ -261,26 +251,6 @@ namespace ts {
261251 } ;
262252 }
263253
264- function resetSectionalData ( ) : void {
265- sourceMapData . sourceMapSources = [ ] ;
266- sourceMapData . sourceMapNames = [ ] ;
267- sourceMapData . sourceMapMappings = "" ;
268- sourceMapData . sourceMapSourcesContent = compilerOptions . inlineSources ? [ ] : undefined ;
269- }
270-
271- function generateMap ( ) : SourceMap {
272- if ( completedSections . length ) {
273- captureSectionalSpanIfNeeded ( /*reset*/ false ) ;
274- return {
275- version : 3 ,
276- file : sourceMapData . sourceMapFile ,
277- sections : completedSections
278- } ;
279- }
280- else {
281- return captureSection ( ) ;
282- }
283- }
284254
285255 // Encoding for sourcemap span
286256 function encodeLastRecordedSourceMapSpan ( ) {
@@ -350,8 +320,8 @@ namespace ts {
350320 sourceLinePos . line ++ ;
351321 sourceLinePos . character ++ ;
352322
353- const emittedLine = writer . getLine ( ) - sectionStartLine + 1 ;
354- const emittedColumn = emittedLine === 0 ? ( writer . getColumn ( ) - sectionStartColumn + 1 ) : writer . getColumn ( ) ;
323+ const emittedLine = writer . getLine ( ) ;
324+ const emittedColumn = writer . getColumn ( ) ;
355325
356326 // If this location wasn't recorded or the location in source is going backwards, record the span
357327 if ( ! lastRecordedSourceMapSpan ||
@@ -386,13 +356,8 @@ namespace ts {
386356 }
387357 }
388358
389- function captureSectionalSpanIfNeeded ( reset : boolean ) {
390- if ( lastRecordedSourceMapSpan && lastRecordedSourceMapSpan === lastEncodedSourceMapSpan ) { // If we've recorded some spans, save them
391- completedSections . push ( { offset : { line : sectionStartLine - 1 , column : sectionStartColumn - 1 } , map : captureSection ( ) } ) ;
392- if ( reset ) {
393- resetSectionalData ( ) ;
394- }
395- }
359+ function isPossiblySourceMap ( x : { } ) : x is SourceMapSection {
360+ return typeof x === "object" && ! ! ( x as any ) . mappings && typeof ( x as any ) . mappings === "string" && ! ! ( x as any ) . sources ;
396361 }
397362
398363 /**
@@ -409,7 +374,6 @@ namespace ts {
409374
410375 if ( node ) {
411376 if ( isUnparsedSource ( node ) && node . sourceMapText !== undefined ) {
412- captureSectionalSpanIfNeeded ( /*reset*/ true ) ;
413377 const text = node . sourceMapText ;
414378 let parsed : { } | undefined ;
415379 try {
@@ -418,24 +382,41 @@ namespace ts {
418382 catch {
419383 // empty
420384 }
421- const offset = { line : writer . getLine ( ) - 1 , column : writer . getColumn ( ) - 1 } ;
422- completedSections . push ( parsed
423- ? {
424- offset,
425- map : parsed as SourceMap
426- }
427- : {
428- offset,
429- // This is just passes the buck on sourcemaps we don't really understand, instead of issuing an error (which would be difficult this late)
430- url : `data:application/json;charset=utf-8;base64,${ base64encode ( sys , text ) } `
431- }
432- ) ;
433- const emitResult = emitCallback ( hint , node ) ;
434- sectionStartLine = writer . getLine ( ) ;
435- sectionStartColumn = writer . getColumn ( ) ;
436- lastRecordedSourceMapSpan = undefined ! ;
437- lastEncodedSourceMapSpan = defaultLastEncodedSourceMapSpan ;
438- return emitResult ;
385+ if ( ! parsed || ! isPossiblySourceMap ( parsed ) ) {
386+ return emitCallback ( hint , node ) ;
387+ }
388+ const offsetLine = writer . getLine ( ) ;
389+ const firstLineColumnOffset = writer . getColumn ( ) ;
390+ // First, decode the old component sourcemap
391+ const originalMap = parsed ;
392+ sourcemaps . calculateDecodedMappings ( originalMap , ( raw ) : void => {
393+ // Apply offsets to each position and fixup source entries
394+ const rawPath = originalMap . sources [ raw . sourceIndex ] ;
395+ const relativePath = originalMap . sourceRoot ? combinePaths ( originalMap . sourceRoot , rawPath ) : rawPath ;
396+ const combinedPath = combinePaths ( getDirectoryPath ( node . sourceMapPath ! ) , relativePath ) ;
397+ const sourcesDirectoryPath = compilerOptions . sourceRoot ? host . getCommonSourceDirectory ( ) : sourceMapDir ;
398+ const resolvedPath = getRelativePathToDirectoryOrUrl (
399+ sourcesDirectoryPath ,
400+ combinedPath ,
401+ host . getCurrentDirectory ( ) ,
402+ host . getCanonicalFileName ,
403+ /*isAbsolutePathAnUrl*/ true
404+ ) ;
405+ const absolutePath = toPath ( resolvedPath , sourcesDirectoryPath , host . getCanonicalFileName ) ;
406+ // tslint:disable-next-line:no-null-keyword
407+ setupSourceEntry ( absolutePath , originalMap . sourcesContent ? originalMap . sourcesContent [ raw . sourceIndex ] : null ) ; // TODO: Lookup content for inlining?
408+ const newIndex = sourceMapData . sourceMapSources . indexOf ( resolvedPath ) ;
409+ // Then reencode all the updated spans into the overall map
410+ encodeLastRecordedSourceMapSpan ( ) ;
411+ lastRecordedSourceMapSpan = {
412+ ...raw ,
413+ emittedLine : raw . emittedLine + offsetLine - 1 ,
414+ emittedColumn : raw . emittedLine === 0 ? ( raw . emittedColumn + firstLineColumnOffset - 1 ) : raw . emittedColumn ,
415+ sourceIndex : newIndex ,
416+ } ;
417+ } ) ;
418+ // And actually emit the text these sourcemaps are for
419+ return emitCallback ( hint , node ) ;
439420 }
440421 const emitNode = node . emitNode ;
441422 const emitFlags = emitNode && emitNode . flags || EmitFlags . None ;
@@ -529,13 +510,17 @@ namespace ts {
529510 return ;
530511 }
531512
513+ setupSourceEntry ( sourceFile . fileName , sourceFile . text ) ;
514+ }
515+
516+ function setupSourceEntry ( fileName : string , content : string | null ) {
532517 // Add the file to tsFilePaths
533518 // If sourceroot option: Use the relative path corresponding to the common directory path
534519 // otherwise source locations relative to map file location
535520 const sourcesDirectoryPath = compilerOptions . sourceRoot ? host . getCommonSourceDirectory ( ) : sourceMapDir ;
536521
537522 const source = getRelativePathToDirectoryOrUrl ( sourcesDirectoryPath ,
538- currentSource . fileName ,
523+ fileName ,
539524 host . getCurrentDirectory ( ) ,
540525 host . getCanonicalFileName ,
541526 /*isAbsolutePathAnUrl*/ true ) ;
@@ -546,10 +531,10 @@ namespace ts {
546531 sourceMapData . sourceMapSources . push ( source ) ;
547532
548533 // The one that can be used from program to get the actual source file
549- sourceMapData . inputSourceFileNames . push ( currentSource . fileName ) ;
534+ sourceMapData . inputSourceFileNames . push ( fileName ) ;
550535
551536 if ( compilerOptions . inlineSources ) {
552- sourceMapData . sourceMapSourcesContent ! . push ( currentSource . text ) ;
537+ sourceMapData . sourceMapSourcesContent ! . push ( content ) ;
553538 }
554539 }
555540 }
@@ -564,7 +549,7 @@ namespace ts {
564549
565550 encodeLastRecordedSourceMapSpan ( ) ;
566551
567- return JSON . stringify ( generateMap ( ) ) ;
552+ return JSON . stringify ( captureSection ( ) ) ;
568553 }
569554
570555 /**
0 commit comments