fix(ngcc): handle mappings outside the content when flattening source-maps (#35718)
Previously when rendering flattened source-maps, it was assumed that no mapping would come from a line that is outside the lines of the actual source content. It turns out this is not a valid assumption. Now the code that renders flattened source-maps will handle such mappings, with the additional benefit that the rendered source-map will only contain mapping lines up to the last mapping, rather than a mapping line for every content line. Fixes #35709 PR Close #35718
This commit is contained in:
		
							parent
							
								
									72c4fda613
								
							
						
					
					
						commit
						73cf7d5cb4
					
				| @ -49,11 +49,9 @@ export class SourceFile { | |||||||
|     const sources: SourceFile[] = []; |     const sources: SourceFile[] = []; | ||||||
|     const names: string[] = []; |     const names: string[] = []; | ||||||
| 
 | 
 | ||||||
|     // Ensure a mapping line array for each line in the generated source.
 |     const mappings: SourceMapMappings = []; | ||||||
|     const mappings: SourceMapMappings = this.lineLengths.map(() => []); |  | ||||||
| 
 | 
 | ||||||
|     for (const mapping of this.flattenedMappings) { |     for (const mapping of this.flattenedMappings) { | ||||||
|       const mappingLine = mappings[mapping.generatedSegment.line]; |  | ||||||
|       const sourceIndex = findIndexOrAdd(sources, mapping.originalSource); |       const sourceIndex = findIndexOrAdd(sources, mapping.originalSource); | ||||||
|       const mappingArray: SourceMapSegment = [ |       const mappingArray: SourceMapSegment = [ | ||||||
|         mapping.generatedSegment.column, |         mapping.generatedSegment.column, | ||||||
| @ -65,7 +63,14 @@ export class SourceFile { | |||||||
|         const nameIndex = findIndexOrAdd(names, mapping.name); |         const nameIndex = findIndexOrAdd(names, mapping.name); | ||||||
|         mappingArray.push(nameIndex); |         mappingArray.push(nameIndex); | ||||||
|       } |       } | ||||||
|       mappingLine.push(mappingArray); | 
 | ||||||
|  |       // Ensure a mapping line array for this mapping.
 | ||||||
|  |       const line = mapping.generatedSegment.line; | ||||||
|  |       while (line >= mappings.length) { | ||||||
|  |         mappings.push([]); | ||||||
|  |       } | ||||||
|  |       // Add this mapping to the line
 | ||||||
|  |       mappings[line].push(mappingArray); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const sourcePathDir = dirname(this.sourcePath); |     const sourcePathDir = dirname(this.sourcePath); | ||||||
|  | |||||||
| @ -174,7 +174,6 @@ runInEachFileSystem(() => { | |||||||
|           [5, 0, 1, 20], [7, 0, 1, 22], [12, 0, 1, 27], [14, 0, 1, 28], [15, 0, 1, 29], |           [5, 0, 1, 20], [7, 0, 1, 22], [12, 0, 1, 27], [14, 0, 1, 28], [15, 0, 1, 29], | ||||||
|           [9, 0, 2, 13], [10, 0, 2, 14] |           [9, 0, 2, 13], [10, 0, 2, 14] | ||||||
|         ], |         ], | ||||||
|         [], |  | ||||||
|       ]; |       ]; | ||||||
| 
 | 
 | ||||||
|       JS_CONTENT_MAP = fromObject({ |       JS_CONTENT_MAP = fromObject({ | ||||||
| @ -196,15 +195,12 @@ runInEachFileSystem(() => { | |||||||
|         'file': 'file.js', |         'file': 'file.js', | ||||||
|         'sources': ['file.js'], |         'sources': ['file.js'], | ||||||
|         'names': [], |         'names': [], | ||||||
|         'mappings': encode([ |         'mappings': encode([[], [], [], [], [], [], [], [], [], [], [], [], [[0, 0, 0, 0]]]), | ||||||
|           [], [], [], [], [], [], [], [], [], [], [], [], [[0, 0, 0, 0]], |  | ||||||
|           [], [], [], [], [], [], [], [], [] |  | ||||||
|         ]), |  | ||||||
|         'sourcesContent': [JS_CONTENT.contents], |         'sourcesContent': [JS_CONTENT.contents], | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       const MERGED_OUTPUT_PROGRAM_MAPPINGS: SourceMapMappings = |       const MERGED_OUTPUT_PROGRAM_MAPPINGS: SourceMapMappings = | ||||||
|           [[], [], [], [], [], [], [], [], [], [], [], [], ...JS_CONTENT_MAPPINGS, []]; |           [[], [], [], [], [], [], [], [], [], [], [], [], ...JS_CONTENT_MAPPINGS]; | ||||||
| 
 | 
 | ||||||
|       MERGED_OUTPUT_PROGRAM_MAP = fromObject({ |       MERGED_OUTPUT_PROGRAM_MAP = fromObject({ | ||||||
|         'version': 3, |         'version': 3, | ||||||
|  | |||||||
| @ -229,6 +229,32 @@ runInEachFileSystem(() => { | |||||||
|             [[1, 0, 0, 0], [2, 0, 0, 2], [3, 0, 0, 3], [3, 0, 0, 6], [4, 0, 0, 1], [5, 0, 0, 7]] |             [[1, 0, 0, 0], [2, 0, 0, 2], [3, 0, 0, 3], [3, 0, 0, 6], [4, 0, 0, 1], [5, 0, 0, 7]] | ||||||
|           ])); |           ])); | ||||||
|         }); |         }); | ||||||
|  | 
 | ||||||
|  |         it('should handle mappings that map from lines outside of the actual content lines', () => { | ||||||
|  |           const bSource = new SourceFile(_('/foo/src/b.js'), 'abcdef', null, false, []); | ||||||
|  |           const aToBSourceMap: RawSourceMap = { | ||||||
|  |             mappings: encode([ | ||||||
|  |               [[0, 0, 0, 0], [2, 0, 0, 3], [4, 0, 0, 2], [5, 0, 0, 5]], | ||||||
|  |               [ | ||||||
|  |                 [0, 0, 0, 0],  // Extra mapping from a non-existent line
 | ||||||
|  |               ] | ||||||
|  |             ]), | ||||||
|  |             names: [], | ||||||
|  |             sources: ['b.js'], | ||||||
|  |             version: 3 | ||||||
|  |           }; | ||||||
|  |           const aSource = | ||||||
|  |               new SourceFile(_('/foo/src/a.js'), 'abdecf', aToBSourceMap, false, [bSource]); | ||||||
|  | 
 | ||||||
|  |           const aTocSourceMap = aSource.renderFlattenedSourceMap(); | ||||||
|  |           expect(aTocSourceMap.version).toEqual(3); | ||||||
|  |           expect(aTocSourceMap.file).toEqual('a.js'); | ||||||
|  |           expect(aTocSourceMap.names).toEqual([]); | ||||||
|  |           expect(aTocSourceMap.sourceRoot).toBeUndefined(); | ||||||
|  |           expect(aTocSourceMap.sources).toEqual(['b.js']); | ||||||
|  |           expect(aTocSourceMap.sourcesContent).toEqual(['abcdef']); | ||||||
|  |           expect(aTocSourceMap.mappings).toEqual(aToBSourceMap.mappings); | ||||||
|  |         }); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user