Skip to content

Commit 4076d3f

Browse files
committed
fix: avoid mapping to null source
In order to bypass an issue in source-map(<0.7) applySourceMap which panic about null source.
1 parent 97082df commit 4076d3f

5 files changed

Lines changed: 132 additions & 61 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const result = m.transform();
4343
version: 3,
4444
sources: [ 'optional-file-name.js' ],
4545
names: [],
46-
mappings: ';AAAA,G,CAAI,C,CAAE,C,CAAE,OAAO,CAAC,QAAG,CAAC,C,YACpB,OAAO,CAAC,G,CAAI,C,CAAE,CAAC,C',
46+
mappings: 'AAAA;AAAA,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAG,CAAC,CACpB,mBAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE',
4747
file: 'optional-file-name.js',
4848
sourcesContent: [ 'var a = require("a");\nexports.foo = a;\n' ]
4949
}

index.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ module.exports = function(code, filePath) {
5656
};
5757
modifyCode.transform = function() {
5858
var i = 0, ti = 0, ii = mutations.length, transformedTokens = [];
59-
var mutation, newValue, offset, offset2, token;
59+
var mutation, newValue, offset, offset2, token, lastToken;
6060

6161
mutations.sort(function(a, b) {return a.start - b.start;});
6262

@@ -83,8 +83,23 @@ module.exports = function(code, filePath) {
8383
if (mutation.start === mutation.end) {
8484
// an insertion
8585
if (!tokens[ti] || tokens[ti].start === mutation.start) {
86-
// append or prepend
87-
transformedTokens.push({value: mutation.value});
86+
if (!tokens[ti]) {
87+
// append
88+
lastToken = tokens[ti - 1];
89+
transformedTokens.push({
90+
value: mutation.value,
91+
line: lastToken ? lastToken.line : 1,
92+
column: lastToken ? (lastToken.column + lastToken.end - lastToken.start) : 0
93+
});
94+
} else {
95+
// prepend or insert
96+
transformedTokens.push({
97+
value: mutation.value,
98+
line: tokens[ti].line,
99+
column: tokens[ti].column
100+
});
101+
}
102+
88103
if (tokens[ti]) {
89104
transformedTokens.push(tokens[ti]);
90105
ti++;
@@ -134,14 +149,8 @@ module.exports = function(code, filePath) {
134149
ti++;
135150
}
136151

137-
// console.log('transformedTokens', transformedTokens);
138-
139152
var node = new SourceNode(null, null, null, transformedTokens.map(function(t) {
140-
if (t.line) {
141-
return new SourceNode(t.line, t.column, filePath, t.value);
142-
} else {
143-
return t.value; // no source map needed
144-
}
153+
return new SourceNode(t.line, t.column, filePath, t.value);
145154
}));
146155

147156
var result = node.toStringWithSourceMap({file: filePath});

test/modify-code.spec.js

Lines changed: 95 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ test('modify-code outputs identity map', function(t) {
1717
mappings: encode([
1818
[
1919
[0, 0, 0, 0],
20-
[3],
20+
[3, 0, 0, 3],
2121
[4, 0, 0, 4],
22-
[5],
22+
[5, 0, 0, 5],
2323
[6, 0, 0, 6],
24-
[7],
24+
[7, 0, 0, 7],
2525
[8, 0, 0, 8],
2626
[9, 0, 0, 9]
2727
]
@@ -45,11 +45,11 @@ test('modify-code replaces one token', function(t) {
4545
mappings: encode([
4646
[
4747
[0, 0, 0, 0],
48-
[3],
48+
[3, 0, 0, 3],
4949
[4, 0, 0, 4],
50-
[9],
50+
[9, 0, 0, 5],
5151
[10, 0, 0, 6],
52-
[11],
52+
[11, 0, 0, 7],
5353
[12, 0, 0, 8],
5454
[13, 0, 0, 9]
5555
]
@@ -73,11 +73,11 @@ test('modify-code deletes one token', function(t) {
7373
mappings: encode([
7474
[
7575
[0, 0, 0, 0],
76-
[3],
76+
[3, 0, 0, 3],
7777
[4, 0, 0, 4],
78-
[5],
78+
[5, 0, 0, 5],
7979
[6, 0, 0, 6],
80-
[7],
80+
[7, 0, 0, 7],
8181
[8, 0, 0, 8]
8282
]
8383
])
@@ -86,6 +86,32 @@ test('modify-code deletes one token', function(t) {
8686
t.end();
8787
});
8888

89+
test('modify-code deletes multiple tokens', function(t) {
90+
var m = modify('var a = 1;');
91+
m.delete(0, 4);
92+
t.deepEqual(m.transform(), {
93+
code: 'a = 1;',
94+
map: {
95+
version: 3,
96+
sources: ['file.js'],
97+
sourcesContent: ['var a = 1;'],
98+
file: 'file.js',
99+
names: [],
100+
mappings: encode([
101+
[
102+
[0, 0, 0, 4],
103+
[1, 0, 0, 5],
104+
[2, 0, 0, 6],
105+
[3, 0, 0, 7],
106+
[4, 0, 0, 8],
107+
[5, 0, 0, 9]
108+
]
109+
])
110+
}
111+
})
112+
t.end();
113+
});
114+
89115
test('modify-code prepends content', function(t) {
90116
var m = modify('var a = 1;');
91117
m.prepend('/* c */ ');
@@ -99,12 +125,12 @@ test('modify-code prepends content', function(t) {
99125
names: [],
100126
mappings: encode([
101127
[
102-
[8, 0, 0, 0],
103-
[11],
128+
[0, 0, 0, 0],
129+
[11, 0, 0, 3],
104130
[12, 0, 0, 4],
105-
[13],
131+
[13, 0, 0, 5],
106132
[14, 0, 0, 6],
107-
[15],
133+
[15, 0, 0, 7],
108134
[16, 0, 0, 8],
109135
[17, 0, 0, 9]
110136
]
@@ -128,12 +154,12 @@ test('modify-code prepends multiple contents', function(t) {
128154
names: [],
129155
mappings: encode([
130156
[
131-
[16, 0, 0, 0],
132-
[19],
157+
[0, 0, 0, 0],
158+
[19, 0, 0, 3],
133159
[20, 0, 0, 4],
134-
[21],
160+
[21, 0, 0, 5],
135161
[22, 0, 0, 6],
136-
[23],
162+
[23, 0, 0, 7],
137163
[24, 0, 0, 8],
138164
[25, 0, 0, 9]
139165
]
@@ -157,14 +183,14 @@ test('modify-code appends content', function(t) {
157183
mappings: encode([
158184
[
159185
[0, 0, 0, 0],
160-
[3],
186+
[3, 0, 0, 3],
161187
[4, 0, 0, 4],
162-
[5],
188+
[5, 0, 0, 5],
163189
[6, 0, 0, 6],
164-
[7],
190+
[7, 0, 0, 7],
165191
[8, 0, 0, 8],
166192
[9, 0, 0, 9],
167-
[10]
193+
[10, 0, 0, 10]
168194
]
169195
])
170196
}
@@ -187,14 +213,14 @@ test('modify-code appends multiple contents', function(t) {
187213
mappings: encode([
188214
[
189215
[0, 0, 0, 0],
190-
[3],
216+
[3, 0, 0, 3],
191217
[4, 0, 0, 4],
192-
[5],
218+
[5, 0, 0, 5],
193219
[6, 0, 0, 6],
194-
[7],
220+
[7, 0, 0, 7],
195221
[8, 0, 0, 8],
196222
[9, 0, 0, 9],
197-
[10]
223+
[10, 0, 0, 10],
198224
]
199225
])
200226
}
@@ -224,15 +250,15 @@ test('modify-code does two replacement, each for one token', function(t) {
224250
[8, 0, 0, 8],
225251
[13, 0, 0, 11],
226252
[14, 0, 0, 12],
227-
[15]
253+
[15, 0, 0, 13]
228254
],
229255
[
230256
[0, 0, 1, 0],
231257
[7, 0, 1, 7],
232258
[8, 0, 1, 8],
233259
[13, 0, 1, 11],
234260
[14, 0, 1, 12],
235-
[15]
261+
[15, 0, 1, 13]
236262
]
237263
])
238264
}
@@ -262,15 +288,15 @@ test('modify-code does two replacement, each for one token, in different order',
262288
[8, 0, 0, 8],
263289
[13, 0, 0, 11],
264290
[14, 0, 0, 12],
265-
[15]
291+
[15, 0, 0, 13]
266292
],
267293
[
268294
[0, 0, 1, 0],
269295
[7, 0, 1, 7],
270296
[8, 0, 1, 8],
271297
[13, 0, 1, 11],
272298
[14, 0, 1, 12],
273-
[15]
299+
[15, 0, 1, 13]
274300
]
275301
])
276302
}
@@ -300,12 +326,12 @@ test('modify-code replaces across multiple tokens', function(t) {
300326
[8, 0, 0, 8],
301327
[13, 0, 0, 11],
302328
[14, 0, 0, 12],
303-
[15]
329+
[15, 0, 0, 13]
304330
],
305331
[
306332
[0, 0, 1, 0],
307333
[9, 0, 1, 12],
308-
[10]
334+
[10, 0, 1, 13]
309335
]
310336
])
311337
}
@@ -333,15 +359,15 @@ test('modify-code inserts content', function(t) {
333359
[8, 0, 0, 8],
334360
[11, 0, 0, 11],
335361
[12, 0, 0, 12],
336-
[13]
362+
[13, 0, 0, 13]
337363
],
338364
[
339-
[8, 0, 1, 0],
365+
[0, 0, 1, 0],
340366
[15, 0, 1, 7],
341367
[16, 0, 1, 8],
342368
[19, 0, 1, 11],
343369
[20, 0, 1, 12],
344-
[21]
370+
[21, 0, 1, 13]
345371
]
346372
])
347373
}
@@ -369,15 +395,15 @@ test('modify-code inserts content inside a token', function(t) {
369395
[8, 0, 0, 8],
370396
[11, 0, 0, 11],
371397
[12, 0, 0, 12],
372-
[13]
398+
[13, 0, 0, 13]
373399
],
374400
[
375401
[0, 0, 1, 0],
376402
[7, 0, 1, 7],
377403
[8, 0, 1, 8],
378404
[15, 0, 1, 11],
379405
[16, 0, 1, 12],
380-
[17]
406+
[17, 0, 1, 13]
381407
]
382408
])
383409
}
@@ -442,7 +468,39 @@ test('modify-code can chain mutation calls', function(t) {
442468
version: 3,
443469
sources: [ 'optional-file-name.js' ],
444470
names: [],
445-
mappings: ';AAAA,G,CAAI,C,CAAE,C,CAAE,OAAO,CAAC,QAAG,CAAC,C,YACpB,OAAO,CAAC,G,CAAI,C,CAAE,CAAC,C',
471+
mappings: 'AAAA;AAAA,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAG,CAAC,CACpB,mBAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE',
472+
file: 'optional-file-name.js',
473+
sourcesContent: [ 'var a = require("a");\nexports.foo = a;\n' ]
474+
}
475+
});
476+
t.end();
477+
});
478+
479+
test('modify-code can chain mutation calls, in different order', function(t) {
480+
var result = modify('var a = require("a");\nexports.foo = a;\n', 'optional-file-name.js')
481+
// append some content at the end
482+
.append('/* end of modified */\n')
483+
// insert a statement after first line
484+
.insert(22, "a = '#' + a;")
485+
// prepend some content at the beginning
486+
.prepend('/* modified */\n')
487+
// modify exported name "foo" to "bar"
488+
.replace(30, 33, 'bar')
489+
// modify dependency "a" into "mock-a"
490+
.replace(17, 18, 'mock-a')
491+
// remove line breaks
492+
.delete(21, 22)
493+
.delete(38, 39)
494+
// generate code and sourcemap
495+
.transform();
496+
497+
t.deepEqual(result, {
498+
code: '/* modified */\nvar a = require("mock-a");a = \'#\' + a;exports.bar = a;/* end of modified */\n',
499+
map: {
500+
version: 3,
501+
sources: [ 'optional-file-name.js' ],
502+
names: [],
503+
mappings: 'AAAA;AAAA,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAG,CAAC,CACpB,mBAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE',
446504
file: 'optional-file-name.js',
447505
sourcesContent: [ 'var a = require("a");\nexports.foo = a;\n' ]
448506
}

test/tokenize.spec.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ test('tokenize outputs tokens', function(t) {
1212
tokens,
1313
[
1414
{ value: 'var', start: 0, line: 1, column: 0 , end: 3 },
15-
{ value: ' ', start: 3 , end: 4 },
16-
{ value: 'a', start: 4, line: 1, column: 4 , end: 5 },
17-
{ value: ' ', start: 5, end: 6 },
18-
{ value: '=', start: 6, line: 1, column: 6 , end: 7 },
19-
{ value: ' ', start: 7, end: 8 },
15+
{ value: ' ', start: 3 , end: 4, line: 1, column: 3 },
16+
{ value: 'a', start: 4, line: 1, column: 4, end: 5 },
17+
{ value: ' ', start: 5, end: 6, line: 1, column: 5 },
18+
{ value: '=', start: 6, line: 1, column: 6, end: 7 },
19+
{ value: ' ', start: 7, end: 8, line: 1, column: 7 },
2020
{ value: '1', start: 8, line: 1, column: 8 , end: 9 },
2121
{ value: ';', start: 9, line: 1, column: 9 , end: 10 }
2222
]
@@ -31,16 +31,16 @@ test('tokenize outputs tokens with leading and tailing white spaces', function(t
3131
t.deepEqual(
3232
tokens,
3333
[
34-
{ value: '// lorem\n', start: 0, end: 9 },
34+
{ value: '// lorem\n', start: 0, end: 9, line: 1, column: 0 },
3535
{ value: 'var', start: 9, line: 2, column: 0, end: 12 },
36-
{ value: ' ', start: 12, end: 13 },
36+
{ value: ' ', start: 12, end: 13, line: 2, column: 3 },
3737
{ value: 'a', start: 13, line: 2, column: 4, end: 14 },
38-
{ value: ' ', start: 14, end: 15 },
38+
{ value: ' ', start: 14, end: 15, line: 2, column: 5 },
3939
{ value: '=', start: 15, line: 2, column: 6, end: 16 },
40-
{ value: ' ', start: 16, end: 17 },
40+
{ value: ' ', start: 16, end: 17, line: 2, column: 7 },
4141
{ value: '1', start: 17, line: 2, column: 8, end: 18 },
4242
{ value: ';', start: 18, line: 2, column: 9, end: 19 },
43-
{ value: '\n\n', start: 19, end: 21 }
43+
{ value: '\n\n', start: 19, end: 21, line: 2, column: 10 }
4444
]
4545
);
4646
t.equal(tokensToCode(tokens), code);

0 commit comments

Comments
 (0)