Skip to content

Commit

Permalink
fix: handle last empty line correctly when using update/overwrite
Browse files Browse the repository at this point in the history
When the string passed to update or overwrite ends with a new line, the mappings will contain two entries for column zero. This happens because the loop does not bail if the last line is empty, filling two lines with the same mapping. This commit fixes that.
Fixes #273
  • Loading branch information
dummdidumm committed Feb 28, 2024
1 parent ebca2ec commit e672108
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/utils/Mappings.js
Expand Up @@ -12,9 +12,12 @@ export default class Mappings {

addEdit(sourceIndex, content, loc, nameIndex) {
if (content.length) {
const contentLengthMinusOne = content.length - 1;
let contentLineEnd = content.indexOf('\n', 0);
let previousContentLineEnd = -1;
while (contentLineEnd >= 0) {
// Loop through each line in the content and add a segment, but stop if the last line is empty,
// else code afterwards would fill one line too many
while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {
const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
if (nameIndex >= 0) {
segment.push(nameIndex);
Expand Down
37 changes: 37 additions & 0 deletions test/MagicString.js
Expand Up @@ -491,6 +491,43 @@ describe('MagicString', () => {
assert.equal(loc4.line, 1);
assert.equal(loc4.column, 4);
});

it('generates a correct source map with update using content ending with a new line', () => {
const s = new MagicString('foobar');
s.update(2, 3, 'od\n');
s.update(4, 5, 'a\nnd\n');
assert.equal(s.toString(), 'food\nba\nnd\nr');

const map = s.generateMap({ hires: true });
const smc = new SourceMapConsumer(map);

// od\n
const loc = smc.originalPositionFor({ line: 1, column: 3 });
assert.equal(loc.line, 1);
assert.equal(loc.column, 2);
const loc2 = smc.originalPositionFor({ line: 1, column: 4 });
assert.equal(loc2.line, 1);
assert.equal(loc2.column, 2);
const loc3 = smc.originalPositionFor({ line: 2, column: 0 });
assert.equal(loc3.line, 1);
assert.equal(loc3.column, 3);
const loc4 = smc.originalPositionFor({ line: 2, column: 1 });
assert.equal(loc4.line, 1);
assert.equal(loc4.column, 4);
// a\nnd\n
const loc5 = smc.originalPositionFor({ line: 2, column: 2 });
assert.equal(loc5.line, 1);
assert.equal(loc5.column, 4);
const loc6 = smc.originalPositionFor({ line: 2, column: 3 });
assert.equal(loc6.line, 1);
assert.equal(loc6.column, 4);
const loc7 = smc.originalPositionFor({ line: 3, column: 0 });
assert.equal(loc7.line, 1);
assert.equal(loc7.column, 4);
const loc8 = smc.originalPositionFor({ line: 4, column: 0 });
assert.equal(loc8.line, 1);
assert.equal(loc8.column, 5);
});
});

describe('getIndentString', () => {
Expand Down

0 comments on commit e672108

Please sign in to comment.