Skip to content

Commit

Permalink
Fix column offset calculation in sectioned source maps
Browse files Browse the repository at this point in the history
Summary:
Fixes a bug in `metro-source-map`'s source map consumer implementation, where positions inside a section with a nonzero column offset would be incorrectly shifted during lookup.

If `A` represents characters mapped by one section and `B` represents characters mapped by another section:
```
// Generated code

1 | AAAAAAAAAA
2 | AAAAABBBBB
         ^
        (i)
3 | BBBBBBBBBB
          ^
         (ii)
```

Then in order to perform a look up in the source map for section B, the positions marked above should be translated to:
```
// "B" part of generated code

1 | BBBBB
    ^
   (i)
2 | BBBBBBBBBB
          ^
         (ii)
```

But with the bug we instead translated them to:

```
// "B" part of generated code

1 | BBBBB
    ^
   (i - correct)
2 | BBBBBBBBBB
     ^
    (ii - incorrect)
```

Reviewed By: MichaReiser

Differential Revision: D26166640

fbshipit-source-id: db510bf7e20b9eb9e67e06cc3dedcab95410b79b
  • Loading branch information
motiz88 authored and facebook-github-bot committed Feb 2, 2021
1 parent eb06fbd commit 2cc5aa8
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
10 changes: 8 additions & 2 deletions packages/metro-source-map/src/Consumer/positionMath.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

'use strict';

const {add, neg} = require('ob1');
const {add, neg, add0, add1} = require('ob1');

import type {GeneratedOffset} from './types.flow';
import type {Number0, Number1} from 'ob1';
Expand All @@ -36,9 +36,15 @@ function subtractOffsetFromPosition<
...
},
>(pos: T, offset: GeneratedOffset): T {
if (pos.line === add1(offset.lines)) {
return shiftPositionByOffset(pos, {
lines: neg(offset.lines),
columns: neg(offset.columns),
});
}
return shiftPositionByOffset(pos, {
lines: neg(offset.lines),
columns: neg(offset.columns),
columns: add0(0),
});
}

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

test('column offset only applies to first line of section', () => {
const consumer = new Consumer({
version: 3,
sections: [
{
offset: {line: 5, column: 1000},
map: {
version: 3,
names: ['section0_name0', 'section0_name1'],
sources: ['section0_source0', 'section0_source1'],
mappings: 'AAEEA,G;ECAAC,C;C',
},
},
],
});
expect(consumer.originalPositionFor({line: add1(5), column: add0(1002)}))
.toMatchInlineSnapshot(`
Object {
"column": 2,
"line": 3,
"name": "section0_name0",
"source": "section0_source0",
}
`);
expect(consumer.originalPositionFor({line: add1(5), column: add0(1003)}))
.toMatchInlineSnapshot(`
Object {
"column": null,
"line": null,
"name": null,
"source": null,
}
`);
expect(consumer.originalPositionFor({line: add1(6), column: add0(2)}))
.toMatchInlineSnapshot(`
Object {
"column": 2,
"line": 3,
"name": "section0_name1",
"source": "section0_source1",
}
`);
expect(consumer.originalPositionFor({line: add1(6), column: add0(3)}))
.toMatchInlineSnapshot(`
Object {
"column": null,
"line": null,
"name": null,
"source": null,
}
`);
expect(consumer.originalPositionFor({line: add1(6), column: add0(1002)}))
.toMatchInlineSnapshot(`
Object {
"column": null,
"line": null,
"name": null,
"source": null,
}
`);
});

test('unmapped regions', () => {
const consumer = new Consumer({
version: 3,
Expand Down

0 comments on commit 2cc5aa8

Please sign in to comment.