Skip to content

Commit 73cf7d5

Browse files
petebacondarwinmatsko
authored andcommitted
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
1 parent 72c4fda commit 73cf7d5

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

packages/compiler-cli/ngcc/src/sourcemaps/source_file.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ export class SourceFile {
4949
const sources: SourceFile[] = [];
5050
const names: string[] = [];
5151

52-
// Ensure a mapping line array for each line in the generated source.
53-
const mappings: SourceMapMappings = this.lineLengths.map(() => []);
52+
const mappings: SourceMapMappings = [];
5453

5554
for (const mapping of this.flattenedMappings) {
56-
const mappingLine = mappings[mapping.generatedSegment.line];
5755
const sourceIndex = findIndexOrAdd(sources, mapping.originalSource);
5856
const mappingArray: SourceMapSegment = [
5957
mapping.generatedSegment.column,
@@ -65,7 +63,14 @@ export class SourceFile {
6563
const nameIndex = findIndexOrAdd(names, mapping.name);
6664
mappingArray.push(nameIndex);
6765
}
68-
mappingLine.push(mappingArray);
66+
67+
// Ensure a mapping line array for this mapping.
68+
const line = mapping.generatedSegment.line;
69+
while (line >= mappings.length) {
70+
mappings.push([]);
71+
}
72+
// Add this mapping to the line
73+
mappings[line].push(mappingArray);
6974
}
7075

7176
const sourcePathDir = dirname(this.sourcePath);

packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ runInEachFileSystem(() => {
174174
[5, 0, 1, 20], [7, 0, 1, 22], [12, 0, 1, 27], [14, 0, 1, 28], [15, 0, 1, 29],
175175
[9, 0, 2, 13], [10, 0, 2, 14]
176176
],
177-
[],
178177
];
179178

180179
JS_CONTENT_MAP = fromObject({
@@ -196,15 +195,12 @@ runInEachFileSystem(() => {
196195
'file': 'file.js',
197196
'sources': ['file.js'],
198197
'names': [],
199-
'mappings': encode([
200-
[], [], [], [], [], [], [], [], [], [], [], [], [[0, 0, 0, 0]],
201-
[], [], [], [], [], [], [], [], []
202-
]),
198+
'mappings': encode([[], [], [], [], [], [], [], [], [], [], [], [], [[0, 0, 0, 0]]]),
203199
'sourcesContent': [JS_CONTENT.contents],
204200
});
205201

206202
const MERGED_OUTPUT_PROGRAM_MAPPINGS: SourceMapMappings =
207-
[[], [], [], [], [], [], [], [], [], [], [], [], ...JS_CONTENT_MAPPINGS, []];
203+
[[], [], [], [], [], [], [], [], [], [], [], [], ...JS_CONTENT_MAPPINGS];
208204

209205
MERGED_OUTPUT_PROGRAM_MAP = fromObject({
210206
'version': 3,

packages/compiler-cli/ngcc/test/sourcemaps/source_file_spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,32 @@ runInEachFileSystem(() => {
229229
[[1, 0, 0, 0], [2, 0, 0, 2], [3, 0, 0, 3], [3, 0, 0, 6], [4, 0, 0, 1], [5, 0, 0, 7]]
230230
]));
231231
});
232+
233+
it('should handle mappings that map from lines outside of the actual content lines', () => {
234+
const bSource = new SourceFile(_('/foo/src/b.js'), 'abcdef', null, false, []);
235+
const aToBSourceMap: RawSourceMap = {
236+
mappings: encode([
237+
[[0, 0, 0, 0], [2, 0, 0, 3], [4, 0, 0, 2], [5, 0, 0, 5]],
238+
[
239+
[0, 0, 0, 0], // Extra mapping from a non-existent line
240+
]
241+
]),
242+
names: [],
243+
sources: ['b.js'],
244+
version: 3
245+
};
246+
const aSource =
247+
new SourceFile(_('/foo/src/a.js'), 'abdecf', aToBSourceMap, false, [bSource]);
248+
249+
const aTocSourceMap = aSource.renderFlattenedSourceMap();
250+
expect(aTocSourceMap.version).toEqual(3);
251+
expect(aTocSourceMap.file).toEqual('a.js');
252+
expect(aTocSourceMap.names).toEqual([]);
253+
expect(aTocSourceMap.sourceRoot).toBeUndefined();
254+
expect(aTocSourceMap.sources).toEqual(['b.js']);
255+
expect(aTocSourceMap.sourcesContent).toEqual(['abcdef']);
256+
expect(aTocSourceMap.mappings).toEqual(aToBSourceMap.mappings);
257+
});
232258
});
233259
});
234260

0 commit comments

Comments
 (0)