perf(ngcc): store the position of SegmentMarkers to avoid unnecessary computation (#36027)
Previously, calculations related to the position of and difference between SegmentMarkers required extensive computation based around the line, line start positions and columns of each segment. PR Close #36027
This commit is contained in:

committed by
Andrew Kushnir

parent
47025e07ce
commit
772bb5e742
@ -16,6 +16,7 @@
|
||||
export interface SegmentMarker {
|
||||
readonly line: number;
|
||||
readonly column: number;
|
||||
readonly position: number;
|
||||
next: SegmentMarker|undefined;
|
||||
}
|
||||
|
||||
@ -26,20 +27,7 @@ export interface SegmentMarker {
|
||||
* and zero if they are at the same position.
|
||||
*/
|
||||
export function compareSegments(a: SegmentMarker, b: SegmentMarker): number {
|
||||
return a.line === b.line ? a.column - b.column : a.line - b.line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the difference between two segment markers in a source file.
|
||||
*
|
||||
* @param startOfLinePositions the position of the start of each line of content of the source file
|
||||
* where we are computing the difference
|
||||
* @param a the start marker
|
||||
* @param b the end marker
|
||||
* @returns the number of characters between the two segments `a` and `b`
|
||||
*/
|
||||
export function segmentDiff(startOfLinePositions: number[], a: SegmentMarker, b: SegmentMarker) {
|
||||
return startOfLinePositions[b.line] - startOfLinePositions[a.line] + b.column - a.column;
|
||||
return a.position - b.position;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,19 +39,19 @@ export function segmentDiff(startOfLinePositions: number[], a: SegmentMarker, b:
|
||||
* @param offset the number of character to offset by.
|
||||
*/
|
||||
export function offsetSegment(
|
||||
startOfLinePositions: number[], marker: SegmentMarker, offset: number) {
|
||||
startOfLinePositions: number[], marker: SegmentMarker, offset: number): SegmentMarker {
|
||||
if (offset === 0) {
|
||||
return marker;
|
||||
}
|
||||
|
||||
let line = marker.line;
|
||||
const newPos = startOfLinePositions[line] + marker.column + offset;
|
||||
while (line < startOfLinePositions.length - 1 && startOfLinePositions[line + 1] <= newPos) {
|
||||
const position = marker.position + offset;
|
||||
while (line < startOfLinePositions.length - 1 && startOfLinePositions[line + 1] <= position) {
|
||||
line++;
|
||||
}
|
||||
while (line > 0 && startOfLinePositions[line] > newPos) {
|
||||
while (line > 0 && startOfLinePositions[line] > position) {
|
||||
line--;
|
||||
}
|
||||
const column = newPos - startOfLinePositions[line];
|
||||
return {line, column, next: undefined};
|
||||
const column = position - startOfLinePositions[line];
|
||||
return {line, column, position, next: undefined};
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import {removeComments, removeMapFileComments} from 'convert-source-map';
|
||||
import {SourceMapMappings, SourceMapSegment, decode, encode} from 'sourcemap-codec';
|
||||
import {AbsoluteFsPath, dirname, relative} from '../../../src/ngtsc/file_system';
|
||||
import {RawSourceMap} from './raw_source_map';
|
||||
import {SegmentMarker, compareSegments, offsetSegment, segmentDiff} from './segment_marker';
|
||||
import {SegmentMarker, compareSegments, offsetSegment} from './segment_marker';
|
||||
|
||||
export function removeSourceMapComments(contents: string): string {
|
||||
return removeMapFileComments(removeComments(contents)).replace(/\n\n$/, '\n');
|
||||
@ -89,7 +89,7 @@ export class SourceFile {
|
||||
* source files with no transitive source maps.
|
||||
*/
|
||||
private flattenMappings(): Mapping[] {
|
||||
const mappings = parseMappings(this.rawMap, this.sources);
|
||||
const mappings = parseMappings(this.rawMap, this.sources, this.startOfLinePositions);
|
||||
ensureOriginalSegmentLinks(mappings);
|
||||
const flattenedMappings: Mapping[] = [];
|
||||
for (let mappingIndex = 0; mappingIndex < mappings.length; mappingIndex++) {
|
||||
@ -277,8 +277,7 @@ export function mergeMappings(generatedSource: SourceFile, ab: Mapping, bc: Mapp
|
||||
// segment-marker" of B->C (4*): `1 - 4 = -3`.
|
||||
// Since it is negative we must increment the "generated segment-marker" with `3` to give [3,2].
|
||||
|
||||
const diff =
|
||||
segmentDiff(ab.originalSource.startOfLinePositions, ab.originalSegment, bc.generatedSegment);
|
||||
const diff = compareSegments(bc.generatedSegment, ab.originalSegment);
|
||||
if (diff > 0) {
|
||||
return {
|
||||
name,
|
||||
@ -303,7 +302,8 @@ export function mergeMappings(generatedSource: SourceFile, ab: Mapping, bc: Mapp
|
||||
* in the `sources` parameter.
|
||||
*/
|
||||
export function parseMappings(
|
||||
rawMap: RawSourceMap | null, sources: (SourceFile | null)[]): Mapping[] {
|
||||
rawMap: RawSourceMap | null, sources: (SourceFile | null)[],
|
||||
generatedSourceStartOfLinePositions: number[]): Mapping[] {
|
||||
if (rawMap === null) {
|
||||
return [];
|
||||
}
|
||||
@ -330,11 +330,13 @@ export function parseMappings(
|
||||
const generatedSegment: SegmentMarker = {
|
||||
line: generatedLine,
|
||||
column: generatedColumn,
|
||||
position: generatedSourceStartOfLinePositions[generatedLine] + generatedColumn,
|
||||
next: undefined,
|
||||
};
|
||||
const originalSegment: SegmentMarker = {
|
||||
line,
|
||||
column,
|
||||
position: originalSource.startOfLinePositions[line] + column,
|
||||
next: undefined,
|
||||
};
|
||||
mappings.push({name, generatedSegment, originalSegment, originalSource});
|
||||
|
Reference in New Issue
Block a user