Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 29 additions & 17 deletions packages/metro-source-map/src/Consumer/MappingsConsumer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ import {
lookupBiasToString,
} from './constants';
import normalizeSourcePath from './normalizeSourcePath';
import {greatestLowerBound} from './search';
import invariant from 'invariant';
import {add, add0, get0, inc, sub} from 'ob1';
import {add, add0, get0, get1, inc} from 'ob1';

/* eslint-disable no-bitwise */

Expand Down Expand Up @@ -58,12 +57,16 @@ export default class MappingsConsumer
{
_sourceMap: BasicSourceMap;
_decodedMappings: ?ReadonlyArray<Mapping>;
// The index in `_decodedMappings` of the first mapping on each generated
// line (0-based), so a lookup only searches the mappings on its line.
_lineStarts: ?ReadonlyArray<number>;
_normalizedSources: ?ReadonlyArray<string>;

constructor(sourceMap: BasicSourceMap) {
super(sourceMap);
this._sourceMap = sourceMap;
this._decodedMappings = null;
this._lineStarts = null;
this._normalizedSources = null;
}

Expand All @@ -84,21 +87,27 @@ export default class MappingsConsumer
);
}
const mappings = this._decodeAndCacheMappings();
const index = greatestLowerBound(
mappings,
{line, column},
(position, mapping) => {
if (position.line === mapping.generatedLine) {
return get0(sub(position.column, mapping.generatedColumn));
}
return get0(sub(position.line, mapping.generatedLine));
},
);
if (
index != null &&
mappings[index].generatedLine === generatedPosition.line
) {
const mapping = mappings[index];
const lineStarts = this._lineStarts;
invariant(lineStarts != null, 'Expected line starts to be decoded');
const line0 = get1(line) - 1;
if (line0 < 0 || line0 >= lineStarts.length) {
return {...EMPTY_POSITION};
}
// The last mapping on the line at or before `column`.
let low = lineStarts[line0];
let high =
line0 + 1 < lineStarts.length ? lineStarts[line0 + 1] : mappings.length;
const lineStart = low;
while (low < high) {
const mid = (low + high) >>> 1;
if (get0(mappings[mid].generatedColumn) <= get0(column)) {
low = mid + 1;
} else {
high = mid;
}
}
if (low > lineStart) {
const mapping = mappings[low - 1];
return {
source: mapping.source,
name: mapping.name,
Expand All @@ -113,6 +122,7 @@ export default class MappingsConsumer
const normalizedSources = this._normalizeAndCacheSources();
const {mappings: mappingsRaw, names} = this._sourceMap;
const result: Array<Mapping> = [];
const lineStarts = [0];

let generatedLine = FIRST_LINE;
let generatedColumn = FIRST_COLUMN;
Expand Down Expand Up @@ -170,6 +180,7 @@ export default class MappingsConsumer
fieldCount = 0;
}
if (charCode === SEMICOLON && i < length) {
lineStarts.push(result.length);
generatedLine = inc(generatedLine);
generatedColumn = FIRST_COLUMN;
}
Expand All @@ -191,6 +202,7 @@ export default class MappingsConsumer
shift = 0;
}
}
this._lineStarts = lineStarts;
return result;
}

Expand Down
27 changes: 27 additions & 0 deletions packages/metro-source-map/src/__tests__/Consumer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,33 @@ describe('basic maps', () => {
}
`);
});

test('a column before the first mapping on its line is unmapped', () => {
const consumer = new Consumer({
version: 3,
mappings: 'AAAA;KAAC',
names: [],
sources: ['source0'],
});
expect(
consumer.originalPositionFor({line: add1(1), column: add0(4)}),
).toEqual({source: null, name: null, line: null, column: null});
expect(
consumer.originalPositionFor({line: add1(1), column: add0(5)}),
).toEqual({source: 'source0', name: null, line: 1, column: 1});
});

test('mappings at the same generated column resolve to the last', () => {
const consumer = new Consumer({
version: 3,
mappings: 'AAAA,AACA',
names: [],
sources: ['source0'],
});
expect(
consumer.originalPositionFor({line: add1(0), column: add0(0)}),
).toEqual({source: 'source0', name: null, line: 2, column: 0});
});
});

describe('generatedMappings()', () => {
Expand Down
Loading