Skip to content

Commit

Permalink
DevTools: Lazily parse indexed map sections (facebook#22415)
Browse files Browse the repository at this point in the history
Indexed maps divide nested source maps into sections, annotated with a line and column offset. Since these sections are JSON and can be quickly parsed, we can easily separate them without doing the heavier base64 and VLQ decoding process. This PR updates our sourcemap parsing code to defer parsing of an indexed map section until we actually need to retrieve mappings from it.
  • Loading branch information
Brian Vaughn authored and zhengjitf committed Apr 15, 2022
1 parent 6c049f2 commit b273b18
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions packages/react-devtools-shared/src/hooks/SourceMapConsumer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {decode} from 'sourcemap-codec';

import type {
IndexSourceMap,
IndexSourceMapSection,
BasicSourceMap,
MixedSourceMap,
} from './SourceMapTypes';
Expand All @@ -34,7 +35,7 @@ export type SourceMapConsumerType = {|
type Mappings = Array<Array<Array<number>>>;

export default function SourceMapConsumer(
sourceMapJSON: MixedSourceMap,
sourceMapJSON: MixedSourceMap | IndexSourceMapSection,
): SourceMapConsumerType {
if (sourceMapJSON.sections != null) {
return IndexedSourceMapConsumer(((sourceMapJSON: any): IndexSourceMap));
Expand Down Expand Up @@ -137,13 +138,22 @@ function BasicSourceMapConsumer(sourceMapJSON: BasicSourceMap) {
}: any): SourceMapConsumerType);
}

type Section = {|
+generatedColumn: number,
+generatedLine: number,
+map: MixedSourceMap,

// Lazily parsed only when/as the section is needed.
sourceMapConsumer: SourceMapConsumerType | null,
|};

function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
let lastOffset = {
line: -1,
column: 0,
};

const sections = sourceMapJSON.sections.map(section => {
const sections: Array<Section> = sourceMapJSON.sections.map(section => {
const offset = section.offset;
const offsetLine = offset.line;
const offsetColumn = offset.column;
Expand All @@ -161,7 +171,8 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
// The offset fields are 0-based, but we use 1-based indices when encoding/decoding from VLQ.
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1,
sourceMapConsumer: new SourceMapConsumer(section.map),
map: section.map,
sourceMapConsumer: null,
};
});

Expand Down Expand Up @@ -229,6 +240,11 @@ function IndexedSourceMapConsumer(sourceMapJSON: IndexSourceMap) {
);
}

if (section.sourceMapConsumer === null) {
// Lazily parse the section only when it's needed.
section.sourceMapConsumer = new SourceMapConsumer(section.map);
}

return section.sourceMapConsumer.originalPositionFor({
columnNumber,
lineNumber,
Expand Down

0 comments on commit b273b18

Please sign in to comment.