Skip to content

Commit 71de737

Browse files
committed
feat(espower-source): backport espowerify to support multi-stage sourcemaps
1 parent db2ea06 commit 71de737

File tree

1 file changed

+58
-15
lines changed

1 file changed

+58
-15
lines changed

Diff for: index.js

+58-15
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,74 @@
77
* Licensed under the MIT license.
88
* https://github.com/twada/espower-source/blob/master/MIT-LICENSE.txt
99
*/
10+
'use strict';
11+
1012
var espower = require('espower'),
1113
esprima = require('esprima'),
1214
escodegen = require('escodegen'),
1315
extend = require('xtend'),
14-
convert = require('convert-source-map');
16+
convert = require('convert-source-map'),
17+
transfer = require('multi-stage-sourcemap').transfer;
1518

16-
function espowerSource(jsCode, filepath, options) {
17-
'use strict';
19+
function mergeSourceMap(incomingSourceMap, outgoingSourceMap) {
20+
if (typeof outgoingSourceMap === 'string' || outgoingSourceMap instanceof String) {
21+
outgoingSourceMap = JSON.parse(outgoingSourceMap);
22+
}
23+
if (!incomingSourceMap) {
24+
return outgoingSourceMap;
25+
}
26+
return JSON.parse(transfer({fromSourceMap: outgoingSourceMap, toSourceMap: incomingSourceMap}));
27+
}
1828

19-
var jsAst, espowerOptions, modifiedAst, escodegenOutput, code, map;
29+
function handleUpstreamSourceMap (jsCode, options) {
30+
var inMap;
31+
if (options.sourceMap) {
32+
inMap = options.sourceMap;
33+
} else {
34+
var commented = convert.fromSource(jsCode);
35+
if (commented) {
36+
inMap = commented.toObject();
37+
options.sourceMap = inMap;
38+
}
39+
}
40+
return inMap;
41+
}
2042

21-
jsAst = esprima.parse(jsCode, {tolerant: true, loc: true, tokens: true, raw: true, source: filepath});
22-
espowerOptions = extend(espower.defaultOptions(), options, {
23-
destructive: true,
24-
path: filepath
25-
});
26-
modifiedAst = espower(jsAst, espowerOptions);
27-
escodegenOutput = escodegen.generate(modifiedAst, {
43+
function instrument (jsCode, filepath, options) {
44+
var jsAst = esprima.parse(jsCode, {tolerant: true, loc: true, source: filepath});
45+
var modifiedAst = espower(jsAst, options);
46+
// keep paths absolute by not using `file` and `sourceMapRoot`
47+
// paths will be resolved by mold-source-map
48+
return escodegen.generate(modifiedAst, {
2849
sourceMap: true,
2950
sourceMapWithCode: true
3051
});
31-
code = escodegenOutput.code; // Generated source code
32-
map = convert.fromJSON(escodegenOutput.map.toString());
33-
map.sourcemap.sourcesContent = [jsCode];
34-
return code + '\n' + map.toComment() + '\n';
52+
}
53+
54+
function mergeEspowerOptions (options, filepath) {
55+
return extend(espower.defaultOptions(), options, {
56+
destructive: true,
57+
path: filepath
58+
});
59+
}
60+
61+
function espowerSource(jsCode, filepath, options) {
62+
var espowerOptions = mergeEspowerOptions(options, filepath);
63+
var inMap = handleUpstreamSourceMap(jsCode, espowerOptions);
64+
var instrumented = instrument(jsCode, filepath, espowerOptions);
65+
var outMap = convert.fromJSON(instrumented.map.toString());
66+
if (inMap) {
67+
var mergedRawMap = mergeSourceMap(inMap, outMap.toObject());
68+
var reMap = convert.fromObject(mergedRawMap);
69+
reMap.setProperty('sources', inMap.sources);
70+
reMap.setProperty('sourcesContent', inMap.sourcesContent);
71+
return instrumented.code + '\n' + reMap.toComment() + '\n';
72+
} else {
73+
// Keeping paths absolute. Paths will be resolved by mold-source-map.
74+
outMap.setProperty('sources', [filepath]);
75+
outMap.setProperty('sourcesContent', [jsCode]);
76+
return instrumented.code + '\n' + outMap.toComment() + '\n';
77+
}
3578
}
3679

3780
module.exports = espowerSource;

0 commit comments

Comments
 (0)