|
7 | 7 | * Licensed under the MIT license.
|
8 | 8 | * https://github.com/twada/espower-source/blob/master/MIT-LICENSE.txt
|
9 | 9 | */
|
| 10 | +'use strict'; |
| 11 | + |
10 | 12 | var espower = require('espower'),
|
11 | 13 | esprima = require('esprima'),
|
12 | 14 | escodegen = require('escodegen'),
|
13 | 15 | extend = require('xtend'),
|
14 |
| - convert = require('convert-source-map'); |
| 16 | + convert = require('convert-source-map'), |
| 17 | + transfer = require('multi-stage-sourcemap').transfer; |
15 | 18 |
|
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 | +} |
18 | 28 |
|
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 | +} |
20 | 42 |
|
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, { |
28 | 49 | sourceMap: true,
|
29 | 50 | sourceMapWithCode: true
|
30 | 51 | });
|
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 | + } |
35 | 78 | }
|
36 | 79 |
|
37 | 80 | module.exports = espowerSource;
|
0 commit comments