f0ee9bba7f4e5fdb9a1b3c28c9a963aae9c9022e27a50c292b8d4470de651d142c754eec8b0e732ddaf5c239bdc5f3c929386371f142e40492a1e906f4fe25 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. "use strict";
  2. exports.__esModule = true;
  3. exports.File = undefined;
  4. var _getIterator2 = require("babel-runtime/core-js/get-iterator");
  5. var _getIterator3 = _interopRequireDefault(_getIterator2);
  6. var _create = require("babel-runtime/core-js/object/create");
  7. var _create2 = _interopRequireDefault(_create);
  8. var _assign = require("babel-runtime/core-js/object/assign");
  9. var _assign2 = _interopRequireDefault(_assign);
  10. var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
  11. var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
  12. var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn");
  13. var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
  14. var _inherits2 = require("babel-runtime/helpers/inherits");
  15. var _inherits3 = _interopRequireDefault(_inherits2);
  16. var _babelHelpers = require("babel-helpers");
  17. var _babelHelpers2 = _interopRequireDefault(_babelHelpers);
  18. var _metadata = require("./metadata");
  19. var metadataVisitor = _interopRequireWildcard(_metadata);
  20. var _convertSourceMap = require("convert-source-map");
  21. var _convertSourceMap2 = _interopRequireDefault(_convertSourceMap);
  22. var _optionManager = require("./options/option-manager");
  23. var _optionManager2 = _interopRequireDefault(_optionManager);
  24. var _pluginPass = require("../plugin-pass");
  25. var _pluginPass2 = _interopRequireDefault(_pluginPass);
  26. var _babelTraverse = require("babel-traverse");
  27. var _babelTraverse2 = _interopRequireDefault(_babelTraverse);
  28. var _babelGenerator = require("babel-generator");
  29. var _babelGenerator2 = _interopRequireDefault(_babelGenerator);
  30. var _babelCodeFrame = require("babel-code-frame");
  31. var _babelCodeFrame2 = _interopRequireDefault(_babelCodeFrame);
  32. var _defaults = require("lodash/defaults");
  33. var _defaults2 = _interopRequireDefault(_defaults);
  34. var _logger = require("./logger");
  35. var _logger2 = _interopRequireDefault(_logger);
  36. var _store = require("../../store");
  37. var _store2 = _interopRequireDefault(_store);
  38. var _babylon = require("babylon");
  39. var _util = require("../../util");
  40. var util = _interopRequireWildcard(_util);
  41. var _path = require("path");
  42. var _path2 = _interopRequireDefault(_path);
  43. var _babelTypes = require("babel-types");
  44. var t = _interopRequireWildcard(_babelTypes);
  45. var _mergeMap = require("./merge-map");
  46. var _mergeMap2 = _interopRequireDefault(_mergeMap);
  47. var _resolve = require("../../helpers/resolve");
  48. var _resolve2 = _interopRequireDefault(_resolve);
  49. var _blockHoist = require("../internal-plugins/block-hoist");
  50. var _blockHoist2 = _interopRequireDefault(_blockHoist);
  51. var _shadowFunctions = require("../internal-plugins/shadow-functions");
  52. var _shadowFunctions2 = _interopRequireDefault(_shadowFunctions);
  53. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  54. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  55. var shebangRegex = /^#!.*/;
  56. var INTERNAL_PLUGINS = [[_blockHoist2.default], [_shadowFunctions2.default]];
  57. var errorVisitor = {
  58. enter: function enter(path, state) {
  59. var loc = path.node.loc;
  60. if (loc) {
  61. state.loc = loc;
  62. path.stop();
  63. }
  64. }
  65. };
  66. var File = function (_Store) {
  67. (0, _inherits3.default)(File, _Store);
  68. function File() {
  69. var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  70. var pipeline = arguments[1];
  71. (0, _classCallCheck3.default)(this, File);
  72. var _this = (0, _possibleConstructorReturn3.default)(this, _Store.call(this));
  73. _this.pipeline = pipeline;
  74. _this.log = new _logger2.default(_this, opts.filename || "unknown");
  75. _this.opts = _this.initOptions(opts);
  76. _this.parserOpts = {
  77. sourceType: _this.opts.sourceType,
  78. sourceFileName: _this.opts.filename,
  79. plugins: []
  80. };
  81. _this.pluginVisitors = [];
  82. _this.pluginPasses = [];
  83. _this.buildPluginsForOptions(_this.opts);
  84. if (_this.opts.passPerPreset) {
  85. _this.perPresetOpts = [];
  86. _this.opts.presets.forEach(function (presetOpts) {
  87. var perPresetOpts = (0, _assign2.default)((0, _create2.default)(_this.opts), presetOpts);
  88. _this.perPresetOpts.push(perPresetOpts);
  89. _this.buildPluginsForOptions(perPresetOpts);
  90. });
  91. }
  92. _this.metadata = {
  93. usedHelpers: [],
  94. marked: [],
  95. modules: {
  96. imports: [],
  97. exports: {
  98. exported: [],
  99. specifiers: []
  100. }
  101. }
  102. };
  103. _this.dynamicImportTypes = {};
  104. _this.dynamicImportIds = {};
  105. _this.dynamicImports = [];
  106. _this.declarations = {};
  107. _this.usedHelpers = {};
  108. _this.path = null;
  109. _this.ast = {};
  110. _this.code = "";
  111. _this.shebang = "";
  112. _this.hub = new _babelTraverse.Hub(_this);
  113. return _this;
  114. }
  115. File.prototype.getMetadata = function getMetadata() {
  116. var has = false;
  117. for (var _iterator = this.ast.program.body, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, _getIterator3.default)(_iterator);;) {
  118. var _ref;
  119. if (_isArray) {
  120. if (_i >= _iterator.length) break;
  121. _ref = _iterator[_i++];
  122. } else {
  123. _i = _iterator.next();
  124. if (_i.done) break;
  125. _ref = _i.value;
  126. }
  127. var node = _ref;
  128. if (t.isModuleDeclaration(node)) {
  129. has = true;
  130. break;
  131. }
  132. }
  133. if (has) {
  134. this.path.traverse(metadataVisitor, this);
  135. }
  136. };
  137. File.prototype.initOptions = function initOptions(opts) {
  138. opts = new _optionManager2.default(this.log, this.pipeline).init(opts);
  139. if (opts.inputSourceMap) {
  140. opts.sourceMaps = true;
  141. }
  142. if (opts.moduleId) {
  143. opts.moduleIds = true;
  144. }
  145. opts.basename = _path2.default.basename(opts.filename, _path2.default.extname(opts.filename));
  146. opts.ignore = util.arrayify(opts.ignore, util.regexify);
  147. if (opts.only) opts.only = util.arrayify(opts.only, util.regexify);
  148. (0, _defaults2.default)(opts, {
  149. moduleRoot: opts.sourceRoot
  150. });
  151. (0, _defaults2.default)(opts, {
  152. sourceRoot: opts.moduleRoot
  153. });
  154. (0, _defaults2.default)(opts, {
  155. filenameRelative: opts.filename
  156. });
  157. var basenameRelative = _path2.default.basename(opts.filenameRelative);
  158. (0, _defaults2.default)(opts, {
  159. sourceFileName: basenameRelative,
  160. sourceMapTarget: basenameRelative
  161. });
  162. return opts;
  163. };
  164. File.prototype.buildPluginsForOptions = function buildPluginsForOptions(opts) {
  165. if (!Array.isArray(opts.plugins)) {
  166. return;
  167. }
  168. var plugins = opts.plugins.concat(INTERNAL_PLUGINS);
  169. var currentPluginVisitors = [];
  170. var currentPluginPasses = [];
  171. for (var _iterator2 = plugins, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : (0, _getIterator3.default)(_iterator2);;) {
  172. var _ref2;
  173. if (_isArray2) {
  174. if (_i2 >= _iterator2.length) break;
  175. _ref2 = _iterator2[_i2++];
  176. } else {
  177. _i2 = _iterator2.next();
  178. if (_i2.done) break;
  179. _ref2 = _i2.value;
  180. }
  181. var ref = _ref2;
  182. var plugin = ref[0],
  183. pluginOpts = ref[1];
  184. currentPluginVisitors.push(plugin.visitor);
  185. currentPluginPasses.push(new _pluginPass2.default(this, plugin, pluginOpts));
  186. if (plugin.manipulateOptions) {
  187. plugin.manipulateOptions(opts, this.parserOpts, this);
  188. }
  189. }
  190. this.pluginVisitors.push(currentPluginVisitors);
  191. this.pluginPasses.push(currentPluginPasses);
  192. };
  193. File.prototype.getModuleName = function getModuleName() {
  194. var opts = this.opts;
  195. if (!opts.moduleIds) {
  196. return null;
  197. }
  198. if (opts.moduleId != null && !opts.getModuleId) {
  199. return opts.moduleId;
  200. }
  201. var filenameRelative = opts.filenameRelative;
  202. var moduleName = "";
  203. if (opts.moduleRoot != null) {
  204. moduleName = opts.moduleRoot + "/";
  205. }
  206. if (!opts.filenameRelative) {
  207. return moduleName + opts.filename.replace(/^\//, "");
  208. }
  209. if (opts.sourceRoot != null) {
  210. var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
  211. filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
  212. }
  213. filenameRelative = filenameRelative.replace(/\.(\w*?)$/, "");
  214. moduleName += filenameRelative;
  215. moduleName = moduleName.replace(/\\/g, "/");
  216. if (opts.getModuleId) {
  217. return opts.getModuleId(moduleName) || moduleName;
  218. } else {
  219. return moduleName;
  220. }
  221. };
  222. File.prototype.resolveModuleSource = function resolveModuleSource(source) {
  223. var resolveModuleSource = this.opts.resolveModuleSource;
  224. if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
  225. return source;
  226. };
  227. File.prototype.addImport = function addImport(source, imported) {
  228. var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : imported;
  229. var alias = source + ":" + imported;
  230. var id = this.dynamicImportIds[alias];
  231. if (!id) {
  232. source = this.resolveModuleSource(source);
  233. id = this.dynamicImportIds[alias] = this.scope.generateUidIdentifier(name);
  234. var specifiers = [];
  235. if (imported === "*") {
  236. specifiers.push(t.importNamespaceSpecifier(id));
  237. } else if (imported === "default") {
  238. specifiers.push(t.importDefaultSpecifier(id));
  239. } else {
  240. specifiers.push(t.importSpecifier(id, t.identifier(imported)));
  241. }
  242. var declar = t.importDeclaration(specifiers, t.stringLiteral(source));
  243. declar._blockHoist = 3;
  244. this.path.unshiftContainer("body", declar);
  245. }
  246. return id;
  247. };
  248. File.prototype.addHelper = function addHelper(name) {
  249. var declar = this.declarations[name];
  250. if (declar) return declar;
  251. if (!this.usedHelpers[name]) {
  252. this.metadata.usedHelpers.push(name);
  253. this.usedHelpers[name] = true;
  254. }
  255. var generator = this.get("helperGenerator");
  256. var runtime = this.get("helpersNamespace");
  257. if (generator) {
  258. var res = generator(name);
  259. if (res) return res;
  260. } else if (runtime) {
  261. return t.memberExpression(runtime, t.identifier(name));
  262. }
  263. var ref = (0, _babelHelpers2.default)(name);
  264. var uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
  265. if (t.isFunctionExpression(ref) && !ref.id) {
  266. ref.body._compact = true;
  267. ref._generated = true;
  268. ref.id = uid;
  269. ref.type = "FunctionDeclaration";
  270. this.path.unshiftContainer("body", ref);
  271. } else {
  272. ref._compact = true;
  273. this.scope.push({
  274. id: uid,
  275. init: ref,
  276. unique: true
  277. });
  278. }
  279. return uid;
  280. };
  281. File.prototype.addTemplateObject = function addTemplateObject(helperName, strings, raw) {
  282. var stringIds = raw.elements.map(function (string) {
  283. return string.value;
  284. });
  285. var name = helperName + "_" + raw.elements.length + "_" + stringIds.join(",");
  286. var declar = this.declarations[name];
  287. if (declar) return declar;
  288. var uid = this.declarations[name] = this.scope.generateUidIdentifier("templateObject");
  289. var helperId = this.addHelper(helperName);
  290. var init = t.callExpression(helperId, [strings, raw]);
  291. init._compact = true;
  292. this.scope.push({
  293. id: uid,
  294. init: init,
  295. _blockHoist: 1.9 });
  296. return uid;
  297. };
  298. File.prototype.buildCodeFrameError = function buildCodeFrameError(node, msg) {
  299. var Error = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : SyntaxError;
  300. var loc = node && (node.loc || node._loc);
  301. var err = new Error(msg);
  302. if (loc) {
  303. err.loc = loc.start;
  304. } else {
  305. (0, _babelTraverse2.default)(node, errorVisitor, this.scope, err);
  306. err.message += " (This is an error on an internal node. Probably an internal error";
  307. if (err.loc) {
  308. err.message += ". Location has been estimated.";
  309. }
  310. err.message += ")";
  311. }
  312. return err;
  313. };
  314. File.prototype.mergeSourceMap = function mergeSourceMap(map) {
  315. var inputMap = this.opts.inputSourceMap;
  316. if (inputMap && map) {
  317. return (0, _mergeMap2.default)(inputMap, map);
  318. } else {
  319. return map;
  320. }
  321. };
  322. File.prototype.parse = function parse(code) {
  323. var parseCode = _babylon.parse;
  324. var parserOpts = this.opts.parserOpts;
  325. if (parserOpts) {
  326. parserOpts = (0, _assign2.default)({}, this.parserOpts, parserOpts);
  327. if (parserOpts.parser) {
  328. if (typeof parserOpts.parser === "string") {
  329. var dirname = _path2.default.dirname(this.opts.filename) || process.cwd();
  330. var parser = (0, _resolve2.default)(parserOpts.parser, dirname);
  331. if (parser) {
  332. parseCode = require(parser).parse;
  333. } else {
  334. throw new Error("Couldn't find parser " + parserOpts.parser + " with \"parse\" method " + ("relative to directory " + dirname));
  335. }
  336. } else {
  337. parseCode = parserOpts.parser;
  338. }
  339. parserOpts.parser = {
  340. parse: function parse(source) {
  341. return (0, _babylon.parse)(source, parserOpts);
  342. }
  343. };
  344. }
  345. }
  346. this.log.debug("Parse start");
  347. var ast = parseCode(code, parserOpts || this.parserOpts);
  348. this.log.debug("Parse stop");
  349. return ast;
  350. };
  351. File.prototype._addAst = function _addAst(ast) {
  352. this.path = _babelTraverse.NodePath.get({
  353. hub: this.hub,
  354. parentPath: null,
  355. parent: ast,
  356. container: ast,
  357. key: "program"
  358. }).setContext();
  359. this.scope = this.path.scope;
  360. this.ast = ast;
  361. this.getMetadata();
  362. };
  363. File.prototype.addAst = function addAst(ast) {
  364. this.log.debug("Start set AST");
  365. this._addAst(ast);
  366. this.log.debug("End set AST");
  367. };
  368. File.prototype.transform = function transform() {
  369. for (var i = 0; i < this.pluginPasses.length; i++) {
  370. var pluginPasses = this.pluginPasses[i];
  371. this.call("pre", pluginPasses);
  372. this.log.debug("Start transform traverse");
  373. var visitor = _babelTraverse2.default.visitors.merge(this.pluginVisitors[i], pluginPasses, this.opts.wrapPluginVisitorMethod);
  374. (0, _babelTraverse2.default)(this.ast, visitor, this.scope);
  375. this.log.debug("End transform traverse");
  376. this.call("post", pluginPasses);
  377. }
  378. return this.generate();
  379. };
  380. File.prototype.wrap = function wrap(code, callback) {
  381. code = code + "";
  382. try {
  383. if (this.shouldIgnore()) {
  384. return this.makeResult({ code: code, ignored: true });
  385. } else {
  386. return callback();
  387. }
  388. } catch (err) {
  389. if (err._babel) {
  390. throw err;
  391. } else {
  392. err._babel = true;
  393. }
  394. var message = err.message = this.opts.filename + ": " + err.message;
  395. var loc = err.loc;
  396. if (loc) {
  397. err.codeFrame = (0, _babelCodeFrame2.default)(code, loc.line, loc.column + 1, this.opts);
  398. message += "\n" + err.codeFrame;
  399. }
  400. if (process.browser) {
  401. err.message = message;
  402. }
  403. if (err.stack) {
  404. var newStack = err.stack.replace(err.message, message);
  405. err.stack = newStack;
  406. }
  407. throw err;
  408. }
  409. };
  410. File.prototype.addCode = function addCode(code) {
  411. code = (code || "") + "";
  412. code = this.parseInputSourceMap(code);
  413. this.code = code;
  414. };
  415. File.prototype.parseCode = function parseCode() {
  416. this.parseShebang();
  417. var ast = this.parse(this.code);
  418. this.addAst(ast);
  419. };
  420. File.prototype.shouldIgnore = function shouldIgnore() {
  421. var opts = this.opts;
  422. return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
  423. };
  424. File.prototype.call = function call(key, pluginPasses) {
  425. for (var _iterator3 = pluginPasses, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : (0, _getIterator3.default)(_iterator3);;) {
  426. var _ref3;
  427. if (_isArray3) {
  428. if (_i3 >= _iterator3.length) break;
  429. _ref3 = _iterator3[_i3++];
  430. } else {
  431. _i3 = _iterator3.next();
  432. if (_i3.done) break;
  433. _ref3 = _i3.value;
  434. }
  435. var pass = _ref3;
  436. var plugin = pass.plugin;
  437. var fn = plugin[key];
  438. if (fn) fn.call(pass, this);
  439. }
  440. };
  441. File.prototype.parseInputSourceMap = function parseInputSourceMap(code) {
  442. var opts = this.opts;
  443. if (opts.inputSourceMap !== false) {
  444. var inputMap = _convertSourceMap2.default.fromSource(code);
  445. if (inputMap) {
  446. opts.inputSourceMap = inputMap.toObject();
  447. code = _convertSourceMap2.default.removeComments(code);
  448. }
  449. }
  450. return code;
  451. };
  452. File.prototype.parseShebang = function parseShebang() {
  453. var shebangMatch = shebangRegex.exec(this.code);
  454. if (shebangMatch) {
  455. this.shebang = shebangMatch[0];
  456. this.code = this.code.replace(shebangRegex, "");
  457. }
  458. };
  459. File.prototype.makeResult = function makeResult(_ref4) {
  460. var code = _ref4.code,
  461. map = _ref4.map,
  462. ast = _ref4.ast,
  463. ignored = _ref4.ignored;
  464. var result = {
  465. metadata: null,
  466. options: this.opts,
  467. ignored: !!ignored,
  468. code: null,
  469. ast: null,
  470. map: map || null
  471. };
  472. if (this.opts.code) {
  473. result.code = code;
  474. }
  475. if (this.opts.ast) {
  476. result.ast = ast;
  477. }
  478. if (this.opts.metadata) {
  479. result.metadata = this.metadata;
  480. }
  481. return result;
  482. };
  483. File.prototype.generate = function generate() {
  484. var opts = this.opts;
  485. var ast = this.ast;
  486. var result = { ast: ast };
  487. if (!opts.code) return this.makeResult(result);
  488. var gen = _babelGenerator2.default;
  489. if (opts.generatorOpts.generator) {
  490. gen = opts.generatorOpts.generator;
  491. if (typeof gen === "string") {
  492. var dirname = _path2.default.dirname(this.opts.filename) || process.cwd();
  493. var generator = (0, _resolve2.default)(gen, dirname);
  494. if (generator) {
  495. gen = require(generator).print;
  496. } else {
  497. throw new Error("Couldn't find generator " + gen + " with \"print\" method relative " + ("to directory " + dirname));
  498. }
  499. }
  500. }
  501. this.log.debug("Generation start");
  502. var _result = gen(ast, opts.generatorOpts ? (0, _assign2.default)(opts, opts.generatorOpts) : opts, this.code);
  503. result.code = _result.code;
  504. result.map = _result.map;
  505. this.log.debug("Generation end");
  506. if (this.shebang) {
  507. result.code = this.shebang + "\n" + result.code;
  508. }
  509. if (result.map) {
  510. result.map = this.mergeSourceMap(result.map);
  511. }
  512. if (opts.sourceMaps === "inline" || opts.sourceMaps === "both") {
  513. result.code += "\n" + _convertSourceMap2.default.fromObject(result.map).toComment();
  514. }
  515. if (opts.sourceMaps === "inline") {
  516. result.map = null;
  517. }
  518. return this.makeResult(result);
  519. };
  520. return File;
  521. }(_store2.default);
  522. exports.default = File;
  523. exports.File = File;