Compare commits

...

76 Commits

Author SHA1 Message Date
Sebastian McKenzie
09e68d8d46 v4.6.2 2015-03-01 10:12:43 +11:00
Sebastian McKenzie
ee850c3aeb merge fix for #917 with #918 2015-03-01 10:09:03 +11:00
Sebastian McKenzie
ff5a149cec Merge branch 'master' of github.com:babel/babel
# Conflicts:
#	src/babel/transformation/transformers/es6/parameters.rest.js
2015-03-01 10:04:52 +11:00
Sebastian McKenzie
957118fb41 delay rest optimisation, deopt on unoptimisable references - fixes #918 2015-03-01 10:04:16 +11:00
Sebastian McKenzie
e7ad0a9741 Merge pull request #919 from neVERberleRfellerER/rest-args-optimization-fix
fix rest optimization in arrow functions
2015-03-01 09:38:00 +11:00
Ondrej Kraus
24f4b041c7 fix rest optimization in arrow functions and add advanced test 2015-02-28 23:28:21 +01:00
Sebastian McKenzie
4c77d04b56 more es6 modules 2015-03-01 01:01:51 +11:00
Sebastian McKenzie
e945f0d10f add support for outputting flow types - fixes #665 2015-03-01 00:32:36 +11:00
Sebastian McKenzie
fb04b2561f copy over files in watch mode 2015-02-28 21:39:40 +11:00
Sebastian McKenzie
a4f8b41507 4.6.1 2015-02-28 11:56:46 +11:00
Sebastian McKenzie
1fb6018e9c v4.6.1 2015-02-28 11:55:47 +11:00
Sebastian McKenzie
bca233d22c add 4.6.1 changelog 2015-02-28 11:52:21 +11:00
Sebastian McKenzie
c78703e194 blacklist regenerator from templates directory - fixes #912 2015-02-28 11:47:18 +11:00
Sebastian McKenzie
43fdbe3d6c fix whitespace 2015-02-28 11:31:43 +11:00
Sebastian McKenzie
8650ca7d55 properly expose util - fixes #52 2015-02-28 11:24:51 +11:00
Sebastian McKenzie
3a0c226a34 upgrade babel 2015-02-28 00:31:35 +11:00
Sebastian McKenzie
73e8bdd048 update 4.6.0 changelog 2015-02-28 00:31:28 +11:00
Sebastian McKenzie
e7c52a734e 4.6.0 2015-02-27 21:14:20 +11:00
Sebastian McKenzie
5a81b02569 v4.6.0 2015-02-27 21:09:17 +11:00
Sebastian McKenzie
999baf2888 fix regex tests 2015-02-27 21:01:13 +11:00
Sebastian McKenzie
70b25e8942 add sticky regex desugaring #904 2015-02-27 20:51:48 +11:00
Sebastian McKenzie
2ddbd4eecc fix es for of break test expected 2015-02-27 20:33:42 +11:00
Sebastian McKenzie
7520807df3 move eslint out of the core into a separate plugin 2015-02-27 16:30:53 +11:00
Sebastian McKenzie
974b71bcc3 flesh out eslint support 2015-02-27 16:11:47 +11:00
Sebastian McKenzie
0aee3c06ec add noCheckAst option to enforce newline test 2015-02-27 15:45:09 +11:00
Sebastian McKenzie
a4382580fc ignore user whitespace when splitting up module declaration - fixes #906 2015-02-27 15:25:13 +11:00
Sebastian McKenzie
166b2eda87 remove rogue export in node api 2015-02-27 15:08:01 +11:00
Sebastian McKenzie
83c23d266f add eslint with an acorn-babel compatibility layer, yay! coming soon to a production release near you 2015-02-27 13:17:22 +11:00
Sebastian McKenzie
a9db70b60d close iterators on abrupt completion - google/traceur-compiler#1773 #838 2015-02-27 11:44:13 +11:00
Sebastian McKenzie
5d90c442cb fix es6 rest parameters transformer comment 2015-02-26 23:25:48 +11:00
Sebastian McKenzie
32606ddb93 remove linting mention from contributing guide 2015-02-26 22:34:54 +11:00
Sebastian McKenzie
330f6910c6 remove unnecessary exception catch and process.exit - fixes #901 2015-02-26 22:33:36 +11:00
Sebastian McKenzie
4ca8a0e6e2 bump browserify 2015-02-26 21:41:15 +11:00
Sebastian McKenzie
f097ddeac3 bump source-map dependency 2015-02-26 21:39:54 +11:00
Sebastian McKenzie
1eb53dd13a add try-catch to bin watching compilation - fixes #901 2015-02-26 21:28:54 +11:00
Sebastian McKenzie
75b5f32e7a make js-tokens version fixed - explanation in #900 2015-02-26 21:15:54 +11:00
Sebastian McKenzie
f753cf4845 Merge pull request #900 from lydell/js-tokens-1.0
Upgrade to js-tokens@1.0.0
2015-02-26 21:13:55 +11:00
Simon Lydell
9a569f64da Upgrade to js-tokens@1.0.0
This commit also adds syntax highlighting for `null`, `false` and `true`.
2015-02-26 11:11:23 +01:00
Sebastian McKenzie
8efeae80af remove export function Function 2015-02-26 20:39:30 +11:00
Sebastian McKenzie
4df9cf6c05 add missing transform import and change babel import to a wildcard 2015-02-26 20:26:08 +11:00
Sebastian McKenzie
7729cb4b68 start using es6 modules 2015-02-26 20:13:00 +11:00
Sebastian McKenzie
307ffcd107 correctly get old extension handler in registerExtension 2015-02-26 16:00:06 +11:00
Sebastian McKenzie
751557aef1 make #889 more efficient and flexible 2015-02-26 15:24:12 +11:00
Sebastian McKenzie
3f146b54ff Merge branch 'master' of github.com:6to5/6to5 2015-02-26 15:04:21 +11:00
Sebastian McKenzie
19a173c622 Merge pull request #899 from xjamundx/patch-1
feat(6to5/register) don't override uncaughtException handler
2015-02-26 15:04:02 +11:00
Sebastian McKenzie
89bcb307a2 Merge pull request #889 from neVERberleRfellerER/rest-args-optimization-v2
Add rest parameters optimization
2015-02-26 15:03:51 +11:00
Sebastian McKenzie
ded1e02da7 move buildHelpers require down a slot 2015-02-26 13:06:15 +11:00
Sebastian McKenzie
564ba67190 4.5.5 2015-02-26 13:06:08 +11:00
Sebastian McKenzie
00c964ed19 v4.5.5 2015-02-26 13:03:02 +11:00
Sebastian McKenzie
3ab88e02c7 delete from require.extensions when old extension handler is undefined 2015-02-26 12:58:01 +11:00
Sebastian McKenzie
bb2fc830eb use some spreads 2015-02-26 12:57:43 +11:00
Sebastian McKenzie
c6a542fd1d finish remaining class conversion 2015-02-26 12:34:05 +11:00
Sebastian McKenzie
553eb2d45e more classes! 2015-02-26 12:19:28 +11:00
Ondrej Kraus
b5f3c3f4cc stop traversal when it is clear that optimization is impossible 2015-02-26 02:05:26 +01:00
Ondrej Kraus
5d83638583 set literal MemberExpression as computed in rest array destructuring 2015-02-26 01:22:00 +01:00
Sebastian McKenzie
f7186980e5 add external helpers test #898 2015-02-26 09:24:28 +11:00
Sebastian McKenzie
0eaaaa503e 4.5.4 2015-02-26 09:24:10 +11:00
Sebastian McKenzie
51dff364db v4.5.4 2015-02-26 09:21:55 +11:00
Sebastian McKenzie
dc6129eb6a fix helper whitelist in build script 2015-02-26 09:19:49 +11:00
Sebastian McKenzie
5b84b9c867 4.5.3 2015-02-26 09:11:15 +11:00
Jamund Ferguson
24ace3c8c2 feat(6to5/register) don't override uncaughtException handler
Maybe we could do this by default or even make it configurable?
2015-02-25 13:51:26 -08:00
Ondrej Kraus
687b0f3180 remove unused function argument 2015-02-25 15:38:32 +01:00
Ondrej Kraus
e6855b974b update tests 2015-02-25 15:30:22 +01:00
Ondrej Kraus
a808742c19 remove strict-mode specific optimizations due to unsolvable ambiguities 2015-02-25 15:24:45 +01:00
Ondrej Kraus
c3f4091b6d replace for-of with with for for performance reasons 2015-02-25 14:41:20 +01:00
Ondrej Kraus
edb880f87c add tests 2015-02-25 14:26:28 +01:00
Ondrej Kraus
e8741daee3 use some ES6 to simplify code 2015-02-25 14:13:15 +01:00
Ondrej Kraus
c5913564f8 replace quotes to conform to coding style 2015-02-25 13:34:18 +01:00
Ondrej Kraus
662bddbaca simplify optimization code 2015-02-25 13:34:17 +01:00
Ondrej Kraus
8f540dfff3 call non-strict mode optimizer before strict mode one to simplify literals 2015-02-25 13:34:17 +01:00
Ondrej Kraus
1265bc5a92 add better optimization when strictMode transformer is enabled 2015-02-25 13:34:15 +01:00
Ondrej Kraus
e677c72d58 add patterns support 2015-02-25 13:34:15 +01:00
Ondrej Kraus
8ca854156a simplify and optimize local binding handling 2015-02-25 13:34:14 +01:00
Ondrej Kraus
81ae656358 remove unused function 2015-02-25 13:34:13 +01:00
Ondrej Kraus
f2981b7e95 replace direct node type checking with helper functions 2015-02-25 13:34:12 +01:00
Ondrej Kraus
99b2e00d33 add rest parameters optimization 2015-02-25 13:34:11 +01:00
239 changed files with 5598 additions and 3972 deletions

1
.eslintignore Normal file
View File

@@ -0,0 +1 @@
src/babel/transformation/templates

22
.eslintrc Normal file
View File

@@ -0,0 +1,22 @@
{
"parser": "babel-eslint",
"rules": {
"strict": 0,
"no-underscore-dangle": 0,
"no-unused-vars": 0,
"curly": 0,
"no-multi-spaces": 0,
"key-spacing": 0,
"no-return-assign": 0,
"consistent-return": 0,
"no-shadow": 0,
"no-comma-dangle": 0,
"no-use-before-define": 0,
"no-empty": 0,
"new-parens": 0,
"no-cond-assign": 0
},
"env": {
"node": true
}
}

View File

@@ -13,6 +13,36 @@ _Note: Gaps between patch versions are faulty/broken releases._
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog. See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
## 4.6.1
* **Bug Fix**
* Fix generators in template directory being transformed.
* Fix exposure of `util` for plugins.
## 4.6.0
* **New Feature**
* Desugar sticky regexes to a new constructor expression so it can be handled by a polyfill.
* **Spec Compliancy**
* `for...of` now outputs in a lengthy `try...catch` this is to ensure spec compliancy in regards to iterator returns and abrupt completions. See [google/traceur-compiler#1773](https://github.com/google/traceur-compiler/issues/1773) and [babel/babel/#838](https://github.com/babel/babel/issues/838) for more information.
* **Polish**
* Rest parameters that are only refered to via number properties on member expressions are desugared into a direct `arguments` reference. Thanks [@neVERberleRfellerER](https://github.com/neVERberleRfellerER)!
* `$ babel` no longer exits on syntax errors.
* **Internal**
* Upgrade `browserify`.
* Upgrade `source-map`.
* Publicly expose more internals.
## 4.5.5
* **Polish**
* Delete old extensions when overriding them in `babel/register`.
## 4.5.3
* **Bug Fix**
* Fix whitelisting logic for helper build script.
## 4.5.2 ## 4.5.2
* **New Feature** * **New Feature**

View File

@@ -4,10 +4,6 @@ Contributions are always welcome, no matter how large or small. Before
contributing, please read the contributing, please read the
[code of conduct](https://github.com/babel/babel/blob/master/CODE_OF_CONDUCT.md). [code of conduct](https://github.com/babel/babel/blob/master/CODE_OF_CONDUCT.md).
**NOTE:** Please do not send pull requests that fix linting issues. It's highly
likely that they've already been fixed by the time it's submitted and it just
pollutes the git tree.
## Developing ## Developing
#### Setup #### Setup
@@ -44,15 +40,6 @@ running them with `mocha`:
$ mocha test/transformation.js $ mocha test/transformation.js
``` ```
#### Linting
Please follow the correct code style, this ensures that the code is consistent
and increases maintainability.
```sh
$ make lint
```
#### Workflow #### Workflow
* Fork the repository * Fork the repository

View File

@@ -31,6 +31,14 @@ module.exports = function (commander, filenames, opts) {
console.log(src + " -> " + dest); console.log(src + " -> " + dest);
}; };
var handleFile = function (src, filename) {
if (util.canCompile(filename)) {
write(src, filename);
} else if (commander.copyFiles) {
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
}
};
var handle = function (filename) { var handle = function (filename) {
if (!fs.existsSync(filename)) return; if (!fs.existsSync(filename)) return;
@@ -41,11 +49,7 @@ module.exports = function (commander, filenames, opts) {
_.each(util.readdir(dirname), function (filename) { _.each(util.readdir(dirname), function (filename) {
var src = path.join(dirname, filename); var src = path.join(dirname, filename);
if (util.canCompile(filename)) { handleFile(src, filename);
write(src, filename);
} else if (commander.copyFiles) {
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
}
}); });
} else { } else {
write(filename, filename); write(filename, filename);
@@ -64,7 +68,11 @@ module.exports = function (commander, filenames, opts) {
_.each(["add", "change"], function (type) { _.each(["add", "change"], function (type) {
watcher.on(type, function (filename) { watcher.on(type, function (filename) {
var relative = path.relative(dirname, filename) || filename; var relative = path.relative(dirname, filename) || filename;
if (util.canCompile(filename)) write(filename, relative); try {
handleFile(filename, relative);
} catch (err) {
console.error(err.stack);
}
}); });
}); });
}); });

View File

@@ -119,7 +119,11 @@ module.exports = function (commander, filenames) {
}).on("all", function (type, filename) { }).on("all", function (type, filename) {
if (type === "add" || type === "change") { if (type === "add" || type === "change") {
console.log(type, filename); console.log(type, filename);
walk(); try {
walk();
} catch (err) {
console.error(err.stack);
}
} }
}); });
} }

View File

@@ -26,17 +26,7 @@ exports.transform = function (filename, code, opts) {
opts.filename = filename; opts.filename = filename;
resolveRc(filename, opts); resolveRc(filename, opts);
var result; var result = babel.transform(code, opts);
try {
result = babel.transform(code, opts);
} catch (e) {
if (e instanceof SyntaxError) {
console.error("SyntaxError:", e.message);
process.exit(1);
} else {
throw e;
}
}
result.filename = filename; result.filename = filename;
result.actual = code; result.actual = code;
return result; return result;

View File

@@ -1,7 +1,7 @@
{ {
"name": "babel", "name": "babel",
"description": "Turn ES6 code into readable vanilla ES5 with source maps", "description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "4.5.3", "version": "4.6.2",
"author": "Sebastian McKenzie <sebmck@gmail.com>", "author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/", "homepage": "https://babeljs.io/",
"repository": "babel/babel", "repository": "babel/babel",
@@ -36,7 +36,7 @@
"test": "make test" "test": "make test"
}, },
"dependencies": { "dependencies": {
"acorn-babel": "0.11.1-35", "acorn-babel": "0.11.1-37",
"ast-types": "~0.6.1", "ast-types": "~0.6.1",
"chalk": "^1.0.0", "chalk": "^1.0.0",
"chokidar": "^0.12.6", "chokidar": "^0.12.6",
@@ -49,7 +49,7 @@
"fs-readdir-recursive": "^0.1.0", "fs-readdir-recursive": "^0.1.0",
"globals": "^6.2.0", "globals": "^6.2.0",
"is-integer": "^1.0.4", "is-integer": "^1.0.4",
"js-tokens": "0.4.1", "js-tokens": "1.0.0",
"leven": "^1.0.1", "leven": "^1.0.1",
"line-numbers": "0.2.0", "line-numbers": "0.2.0",
"lodash": "^3.2.0", "lodash": "^3.2.0",
@@ -61,15 +61,17 @@
"repeating": "^1.1.2", "repeating": "^1.1.2",
"shebang-regex": "^1.0.0", "shebang-regex": "^1.0.0",
"slash": "^1.0.0", "slash": "^1.0.0",
"source-map": "^0.1.43", "source-map": "^0.4.0",
"source-map-support": "^0.2.9", "source-map-support": "^0.2.9",
"source-map-to-comment": "^1.0.0", "source-map-to-comment": "^1.0.0",
"trim-right": "^1.0.0" "trim-right": "^1.0.0"
}, },
"devDependencies": { "devDependencies": {
"babel": "4.5.1", "babel": "4.6.0",
"browserify": "^8.1.3", "browserify": "^9.0.3",
"chai": "^2.0.0", "chai": "^2.0.0",
"eslint": "^0.15.1",
"babel-eslint": "^1.0.1",
"esvalid": "^1.1.0", "esvalid": "^1.1.0",
"istanbul": "^0.3.5", "istanbul": "^0.3.5",
"matcha": "^0.6.0", "matcha": "^0.6.0",

View File

@@ -1,7 +1,7 @@
{ {
"name": "babel-runtime", "name": "babel-runtime",
"description": "babel selfContained runtime", "description": "babel selfContained runtime",
"version": "4.5.2", "version": "4.6.1",
"repository": "babel/babel", "repository": "babel/babel",
"author": "Sebastian McKenzie <sebmck@gmail.com>" "author": "Sebastian McKenzie <sebmck@gmail.com>"
} }

View File

@@ -1,7 +1,7 @@
"use strict"; "use strict";
var buildHelpers = require("../lib/babel/build-helpers");
var transform = require("../lib/babel/transformation"); var transform = require("../lib/babel/transformation");
var buildHelpers = require("../lib/babel/build-helpers");
var util = require("../lib/babel/util"); var util = require("../lib/babel/util");
var fs = require("fs"); var fs = require("fs");
var t = require("../lib/babel/types"); var t = require("../lib/babel/types");

View File

@@ -4,14 +4,12 @@ transform.version = require("../../../package").version;
transform.transform = transform; transform.transform = transform;
transform.run = function (code, opts) { transform.run = function (code, opts = {}) {
opts ||= {};
opts.sourceMap = "inline"; opts.sourceMap = "inline";
return new Function(transform(code, opts).code)(); return new Function(transform(code, opts).code)();
}; };
transform.load = function (url, callback, opts, hold) { transform.load = function (url, callback, opts = {}, hold) {
opts ||= {};
opts.filename ||= url; opts.filename ||= url;
var xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest(); var xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest();

View File

@@ -1,32 +1,29 @@
var isFunction = require("lodash/lang/isFunction"); import isFunction from "lodash/lang/isFunction";
var transform = require("../transformation"); import transform from "../transformation";
var util = require("../util"); import fs from "fs";
var fs = require("fs");
exports.version = require("../../../package").version; import * as util from "../util";
export { util as _util };
export { canCompile } from "../util";
exports.buildExternalHelpers = require("../build-external-helpers"); export { default as acorn } from "acorn-babel";
export { default as transform } from "../transformation";
export { default as traverse } from "../traversal";
export { default as buildExternalHelpers } from "../build-external-helpers";
export { default as types } from "../types";
export { version } from "../../../package";
exports.types = require("../types"); export function register(opts) {
var callback = require("./register/node");
if (opts != null) callback(opts);
return callback;
}
exports.register = function (opts) { export function polyfill() {
var register = require("./register/node");
if (opts != null) register(opts);
return register;
};
exports.polyfill = function () {
require("../polyfill"); require("../polyfill");
}; }
exports.canCompile = util.canCompile; export function transformFile(filename, opts, callback) {
// do not use this - this is for use by official maintained babel plugins
exports._util = util;
exports.transform = transform;
exports.transformFile = function (filename, opts, callback) {
if (isFunction(opts)) { if (isFunction(opts)) {
callback = opts; callback = opts;
opts = {}; opts = {};
@@ -47,10 +44,9 @@ exports.transformFile = function (filename, opts, callback) {
callback(null, result); callback(null, result);
}); });
}; }
exports.transformFileSync = function (filename, opts) { export function transformFileSync(filename, opts = {}) {
opts ||= {};
opts.filename = filename; opts.filename = filename;
return transform(fs.readFileSync(filename), opts); return transform(fs.readFileSync(filename), opts);
}; }

View File

@@ -1,5 +1,5 @@
// required to safely use babel/register within a browserify codebase // required to safely use babel/register within a browserify codebase
module.exports = function () {}; export default function () {};
require("../../polyfill"); import "../../polyfill";

View File

@@ -1,22 +1,22 @@
var path = require("path"); import path from "path";
var os = require("os"); import os from "os";
var fs = require("fs"); import fs from "fs";
var FILENAME = process.env.BABEL_CACHE_PATH || path.join(os.tmpdir(), "babel.json"); var FILENAME = process.env.BABEL_CACHE_PATH || path.join(os.tmpdir(), "babel.json");
var data = {}; var data = {};
exports.save = function () { export function save() {
fs.writeFileSync(FILENAME, JSON.stringify(data, null, " ")); fs.writeFileSync(FILENAME, JSON.stringify(data, null, " "));
}; }
exports.load = function () { export function load() {
if (process.env.BABEL_DISABLE_CACHE) return; if (process.env.BABEL_DISABLE_CACHE) return;
process.on("exit", exports.save); process.on("exit", save);
var sigint = function () { var sigint = function () {
process.removeListener("SIGINT", sigint); process.removeListener("SIGINT", sigint);
exports.save(); save();
process.kill(process.pid, "SIGINT"); process.kill(process.pid, "SIGINT");
}; };
@@ -29,8 +29,8 @@ exports.load = function () {
} catch (err) { } catch (err) {
return; return;
} }
}; }
exports.get = function () { export function get() {
return data; return data;
}; }

View File

@@ -1,15 +1,15 @@
require("../../polyfill"); import "../../polyfill";
import sourceMapSupport from "source-map-support";
var sourceMapSupport = require("source-map-support"); import * as registerCache from "./cache";
var registerCache = require("./cache"); import resolveRc from "./resolve-rc";
var resolveRc = require("./resolve-rc"); import extend from "lodash/object/extend";
var extend = require("lodash/object/extend"); import * as babel from "../node";
var babel = require("../node"); import each from "lodash/collection/each";
var each = require("lodash/collection/each"); import * as util from "../../util";
var util = require("../../util"); import fs from "fs";
var fs = require("fs");
sourceMapSupport.install({ sourceMapSupport.install({
handleUncaughtExceptions: false,
retrieveSourceMap(source) { retrieveSourceMap(source) {
var map = maps && maps[source]; var map = maps && maps[source];
if (map) { if (map) {
@@ -33,7 +33,7 @@ var cache = registerCache.get();
var transformOpts = {}; var transformOpts = {};
var ignoreRegex = /node_modules/; var ignoreRegex = /node_modules/;
var onlyRegex; var onlyRegex;
var exts = {}; var oldHandlers = {};
var maps = {}; var maps = {};
var mtime = function (filename) { var mtime = function (filename) {
@@ -105,7 +105,7 @@ var normalLoader = function (m, filename) {
}; };
var registerExtension = function (ext) { var registerExtension = function (ext) {
var old = require.extensions[ext]; var old = oldHandlers[ext] || oldHandlers[".js"];
var loader = normalLoader; var loader = normalLoader;
if (process.env.running_under_istanbul) loader = istanbulLoader; // jshint ignore:line if (process.env.running_under_istanbul) loader = istanbulLoader; // jshint ignore:line
@@ -120,24 +120,25 @@ var registerExtension = function (ext) {
}; };
var hookExtensions = function (_exts) { var hookExtensions = function (_exts) {
each(exts, function (old, ext) { each(oldHandlers, function (old, ext) {
require.extensions[ext] = old; if (old === undefined) {
delete require.extensions[ext];
} else {
require.extensions[ext] = old;
}
}); });
exts = {}; oldHandlers = {};
each(_exts, function (ext) { each(_exts, function (ext) {
exts[ext] = require.extensions[ext]; oldHandlers[ext] = require.extensions[ext];
registerExtension(ext); registerExtension(ext);
}); });
}; };
hookExtensions(util.canCompile.EXTENSIONS); hookExtensions(util.canCompile.EXTENSIONS);
module.exports = function (opts) { export default function (opts = {}) {
// normalize options
opts ||= {};
if (opts.only != null) onlyRegex = util.regexify(opts.only); if (opts.only != null) onlyRegex = util.regexify(opts.only);
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore); if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);

View File

@@ -1,6 +1,6 @@
var merge = require("lodash/object/merge"); import merge from "lodash/object/merge";
var path = require("path"); import path from "path";
var fs = require("fs"); import fs from "fs";
var cache = {}; var cache = {};
@@ -10,9 +10,8 @@ function exists(filename) {
return cache[filename] = fs.existsSync(filename); return cache[filename] = fs.existsSync(filename);
} }
module.exports = function (loc, opts) { export default function (loc, opts = {}) {
var rel = ".babelrc"; var rel = ".babelrc";
opts ||= {};
function find(start, rel) { function find(start, rel) {
var file = path.join(start, rel); var file = path.join(start, rel);

View File

@@ -1,9 +1,9 @@
var buildHelpers = require("./build-helpers"); import buildHelpers from "./build-helpers";
var generator = require("./generation"); import generator from "./generation";
var util = require("./util"); import * as util from "./util";
var t = require("./types"); import t from "./types";
module.exports = function (whitelist) { export default function (whitelist) {
var namespace = t.identifier("babelHelpers"); var namespace = t.identifier("babelHelpers");
var body = []; var body = [];

View File

@@ -1,11 +1,11 @@
var File = require("./transformation/file"); import File from "./transformation/file";
var util = require("./util"); import * as util from "./util";
var each = require("lodash/collection/each"); import each from "lodash/collection/each";
var t = require("./types"); import t from "./types";
module.exports = function (body, namespace, whitelist = []) { export default function (body, namespace, whitelist = []) {
each(File.helpers, function (name) { each(File.helpers, function (name) {
if (whitelist.length && whitelist.indexOf(key) >= 0) return; if (whitelist.length && whitelist.indexOf(name) === -1) return;
var key = t.identifier(t.toIdentifier(name)); var key = t.identifier(t.toIdentifier(name));
body.push(t.expressionStatement( body.push(t.expressionStatement(

View File

@@ -1,10 +1,9 @@
module.exports = detect; import SYNTAX_KEYS from "./syntax-keys";
import traverse from "../traversal";
var SYNTAX_KEYS = require("./syntax-keys"); var visitors = traverse.explode(require("./visitors"));
var traverse = require("../traversal");
var visitors = traverse.explode(require("./visitors"));
function detect(ast) { export default function (ast) {
var stats = { var stats = {
syntax: {}, syntax: {},
builtins: {} builtins: {}
@@ -26,4 +25,4 @@ function detect(ast) {
}); });
return stats; return stats;
} };

View File

@@ -1,19 +1,19 @@
var t = require("../types"); import includes from "lodash/collection/includes";
var includes = require("lodash/collection/includes"); import t from "../types";
exports.AssignmentExpression = function (node, parent, detected) { export function AssignmentExpression(node, parent, detected) {
if (node.operator === "**=") { if (node.operator === "**=") {
detected("es6.exponentation"); detected("es6.exponentation");
} }
}; }
exports.BinaryExpression = function (node, parent, detected) { export function BinaryExpression(node, parent, detected) {
if (node.operator === "**") { if (node.operator === "**") {
detected("es6.exponentation"); detected("es6.exponentation");
} }
}; }
exports.VariableDeclaration = function (node, parent, detected) { export function VariableDeclaration(node, parent, detected) {
if (node.kind === "let" || node.kind === "const") { if (node.kind === "let" || node.kind === "const") {
detected("es6.blockScoping"); detected("es6.blockScoping");
} }
@@ -21,9 +21,9 @@ exports.VariableDeclaration = function (node, parent, detected) {
if (node.kind === "const") { if (node.kind === "const") {
detected("es6.constants"); detected("es6.constants");
} }
}; }
exports.Property = function (node, parent, detected) { export function Property(node, parent, detected) {
if (node.shorthand || node.method) { if (node.shorthand || node.method) {
detected("es6.properties.shorthand"); detected("es6.properties.shorthand");
} }
@@ -35,13 +35,13 @@ exports.Property = function (node, parent, detected) {
if (node.computed) { if (node.computed) {
detected("es6.properties.computed"); detected("es6.properties.computed");
} }
}; }
exports.AssignmentPattern = function (node, parent, detected) { export function AssignmentPattern(node, parent, detected) {
if (t.isFunction(parent) && includes(parent.params, node)) { if (t.isFunction(parent) && includes(parent.params, node)) {
detected("es6.parameters.default"); detected("es6.parameters.default");
} }
}; }
exports.Function = function (node, parent, detected) { exports.Function = function (node, parent, detected) {
if (node.generator) { if (node.generator) {

View File

@@ -1,173 +1,173 @@
module.exports = Buffer; import repeating from "repeating";
import trimRight from "trim-right";
import isBoolean from "lodash/lang/isBoolean";
import includes from "lodash/collection/includes";
import isNumber from "lodash/lang/isNumber";
var repeating = require("repeating"); export default class Buffer {
var trimRight = require("trim-right"); constructor(position, format) {
var isBoolean = require("lodash/lang/isBoolean"); this.position = position;
var includes = require("lodash/collection/includes"); this._indent = format.indent.base;
var isNumber = require("lodash/lang/isNumber"); this.format = format;
this.buf = "";
function Buffer(position, format) {
this.position = position;
this._indent = format.indent.base;
this.format = format;
this.buf = "";
}
Buffer.prototype.get = function () {
return trimRight(this.buf);
};
Buffer.prototype.getIndent = function () {
if (this.format.compact || this.format.concise) {
return "";
} else {
return repeating(this.format.indent.style, this._indent);
} }
};
Buffer.prototype.indentSize = function () { get() {
return this.getIndent().length; return trimRight(this.buf);
};
Buffer.prototype.indent = function () {
this._indent++;
};
Buffer.prototype.dedent = function () {
this._indent--;
};
Buffer.prototype.semicolon = function () {
this.push(";");
};
Buffer.prototype.ensureSemicolon = function () {
if (!this.isLast(";")) this.semicolon();
};
Buffer.prototype.rightBrace = function () {
this.newline(true);
this.push("}");
};
Buffer.prototype.keyword = function (name) {
this.push(name);
this.space();
};
Buffer.prototype.space = function () {
if (this.format.compact) return;
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) {
this.push(" ");
} }
};
Buffer.prototype.removeLast = function (cha) { getIndent() {
if (this.format.compact) return; if (this.format.compact || this.format.concise) {
if (!this.isLast(cha)) return; return "";
} else {
return repeating(this.format.indent.style, this._indent);
}
}
this.buf = this.buf.substr(0, this.buf.length - 1); indentSize() {
this.position.unshift(cha); return this.getIndent().length;
}; }
Buffer.prototype.newline = function (i, removeLast) { indent() {
if (this.format.compact) return; this._indent++;
}
if (this.format.concise) { dedent() {
this._indent--;
}
semicolon() {
this.push(";");
}
ensureSemicolon() {
if (!this.isLast(";")) this.semicolon();
}
rightBrace() {
this.newline(true);
this.push("}");
}
keyword(name) {
this.push(name);
this.space(); this.space();
return;
} }
removeLast ||= false; space() {
if (this.format.compact) return;
if (isNumber(i)) { if (this.buf && !this.isLast(" ") && !this.isLast("\n")) {
i = Math.min(2, i); this.push(" ");
if (this.endsWith("{\n") || this.endsWith(":\n")) i--;
if (i <= 0) return;
while (i > 0) {
this._newline(removeLast);
i--;
} }
return;
} }
if (isBoolean(i)) { removeLast(cha) {
removeLast = i; if (this.format.compact) return;
if (!this.isLast(cha)) return;
this.buf = this.buf.substr(0, this.buf.length - 1);
this.position.unshift(cha);
} }
this._newline(removeLast); newline(i, removeLast) {
}; if (this.format.compact) return;
Buffer.prototype._newline = function (removeLast) { if (this.format.concise) {
// never allow more than two lines this.space();
if (this.endsWith("\n\n")) return; return;
// remove the last newline
if (removeLast && this.isLast("\n")) this.removeLast("\n");
this.removeLast(" ");
this._removeSpacesAfterLastNewline();
this._push("\n");
};
/**
* If buffer ends with a newline and some spaces after it, trim those spaces.
*/
Buffer.prototype._removeSpacesAfterLastNewline = function () {
var lastNewlineIndex = this.buf.lastIndexOf("\n");
if (lastNewlineIndex === -1)
return;
var index = this.buf.length - 1;
while (index > lastNewlineIndex) {
if (this.buf[index] !== " ") {
break;
} }
index--; removeLast ||= false;
if (isNumber(i)) {
i = Math.min(2, i);
if (this.endsWith("{\n") || this.endsWith(":\n")) i--;
if (i <= 0) return;
while (i > 0) {
this._newline(removeLast);
i--;
}
return;
}
if (isBoolean(i)) {
removeLast = i;
}
this._newline(removeLast);
} }
if (index === lastNewlineIndex) { _newline(removeLast) {
this.buf = this.buf.substring(0, index + 1); // never allow more than two lines
} if (this.endsWith("\n\n")) return;
};
Buffer.prototype.push = function (str, noIndent) { // remove the last newline
if (!this.format.compact && this._indent && !noIndent && str !== "\n") { if (removeLast && this.isLast("\n")) this.removeLast("\n");
// we have an indent level and we aren't pushing a newline
var indent = this.getIndent();
// replace all newlines with newlines with the indentation this.removeLast(" ");
str = str.replace(/\n/g, "\n" + indent); this._removeSpacesAfterLastNewline();
this._push("\n");
// we've got a newline before us so prepend on the indentation
if (this.isLast("\n")) this._push(indent);
} }
this._push(str); /**
}; * If buffer ends with a newline and some spaces after it, trim those spaces.
*/
Buffer.prototype._push = function (str) { _removeSpacesAfterLastNewline() {
this.position.push(str); var lastNewlineIndex = this.buf.lastIndexOf("\n");
this.buf += str; if (lastNewlineIndex === -1)
}; return;
Buffer.prototype.endsWith = function (str) { var index = this.buf.length - 1;
return this.buf.slice(-str.length) === str; while (index > lastNewlineIndex) {
}; if (this.buf[index] !== " ") {
break;
}
Buffer.prototype.isLast = function (cha) { index--;
if (this.format.compact) return false; }
var buf = this.buf; if (index === lastNewlineIndex) {
var last = buf[buf.length - 1]; this.buf = this.buf.substring(0, index + 1);
}
if (Array.isArray(cha)) {
return includes(cha, last);
} else {
return cha === last;
} }
};
push(str, noIndent) {
if (!this.format.compact && this._indent && !noIndent && str !== "\n") {
// we have an indent level and we aren't pushing a newline
var indent = this.getIndent();
// replace all newlines with newlines with the indentation
str = str.replace(/\n/g, "\n" + indent);
// we've got a newline before us so prepend on the indentation
if (this.isLast("\n")) this._push(indent);
}
this._push(str);
}
_push(str) {
this.position.push(str);
this.buf += str;
}
endsWith(str) {
return this.buf.slice(-str.length) === str;
}
isLast(cha) {
if (this.format.compact) return false;
var buf = this.buf;
var last = buf[buf.length - 1];
if (Array.isArray(cha)) {
return includes(cha, last);
} else {
return cha === last;
}
}
}

View File

@@ -1,12 +1,12 @@
exports.File = function (node, print) { export function File(node, print) {
print(node.program); print(node.program);
}; }
exports.Program = function (node, print) { export function Program(node, print) {
print.sequence(node.body); print.sequence(node.body);
}; }
exports.BlockStatement = function (node, print) { export function BlockStatement(node, print) {
if (node.body.length === 0) { if (node.body.length === 0) {
this.push("{}"); this.push("{}");
} else { } else {
@@ -16,4 +16,4 @@ exports.BlockStatement = function (node, print) {
this.removeLast("\n"); this.removeLast("\n");
this.rightBrace(); this.rightBrace();
} }
}; }

View File

@@ -1,5 +1,4 @@
exports.ClassExpression = export function ClassDeclaration(node, print) {
exports.ClassDeclaration = function (node, print) {
this.push("class"); this.push("class");
if (node.id) { if (node.id) {
@@ -7,16 +6,26 @@ exports.ClassDeclaration = function (node, print) {
print(node.id); print(node.id);
} }
print(node.typeParameters);
if (node.superClass) { if (node.superClass) {
this.push(" extends "); this.push(" extends ");
print(node.superClass); print(node.superClass);
print(node.superTypeParameters);
}
if (node.implements) {
this.push(" implements ");
print.join(node.implements, { separator: ", " });
} }
this.space(); this.space();
print(node.body); print(node.body);
}; }
exports.ClassBody = function (node, print) { export { ClassDeclaration as ClassExpression };
export function ClassBody(node, print) {
if (node.body.length === 0) { if (node.body.length === 0) {
this.push("{}"); this.push("{}");
} else { } else {
@@ -29,12 +38,12 @@ exports.ClassBody = function (node, print) {
this.rightBrace(); this.rightBrace();
} }
}; }
exports.MethodDefinition = function (node, print) { export function MethodDefinition(node, print) {
if (node.static) { if (node.static) {
this.push("static "); this.push("static ");
} }
this._method(node, print); this._method(node, print);
}; }

View File

@@ -1,13 +1,13 @@
exports.ComprehensionBlock = function (node, print) { export function ComprehensionBlock(node, print) {
this.keyword("for"); this.keyword("for");
this.push("("); this.push("(");
print(node.left); print(node.left);
this.push(" of "); this.push(" of ");
print(node.right); print(node.right);
this.push(")"); this.push(")");
}; }
exports.ComprehensionExpression = function (node, print) { export function ComprehensionExpression(node, print) {
this.push(node.generator ? "(" : "["); this.push(node.generator ? "(" : "[");
print.join(node.blocks, { separator: " " }); print.join(node.blocks, { separator: " " });
@@ -24,4 +24,4 @@ exports.ComprehensionExpression = function (node, print) {
print(node.body); print(node.body);
this.push(node.generator ? ")" : "]"); this.push(node.generator ? ")" : "]");
}; }

View File

@@ -1,8 +1,8 @@
var isInteger = require("is-integer"); import isInteger from "is-integer";
var isNumber = require("lodash/lang/isNumber"); import isNumber from "lodash/lang/isNumber";
var t = require("../../types"); import t from "../../types";
exports.UnaryExpression = function (node, print) { export function UnaryExpression(node, print) {
var hasSpace = /[a-z]$/.test(node.operator); var hasSpace = /[a-z]$/.test(node.operator);
var arg = node.argument; var arg = node.argument;
@@ -17,9 +17,9 @@ exports.UnaryExpression = function (node, print) {
this.push(node.operator); this.push(node.operator);
if (hasSpace) this.push(" "); if (hasSpace) this.push(" ");
print(node.argument); print(node.argument);
}; }
exports.UpdateExpression = function (node, print) { export function UpdateExpression(node, print) {
if (node.prefix) { if (node.prefix) {
this.push(node.operator); this.push(node.operator);
print(node.argument); print(node.argument);
@@ -27,9 +27,9 @@ exports.UpdateExpression = function (node, print) {
print(node.argument); print(node.argument);
this.push(node.operator); this.push(node.operator);
} }
}; }
exports.ConditionalExpression = function (node, print) { export function ConditionalExpression(node, print) {
print(node.test); print(node.test);
this.space(); this.space();
this.push("?"); this.push("?");
@@ -39,25 +39,25 @@ exports.ConditionalExpression = function (node, print) {
this.push(":"); this.push(":");
this.space(); this.space();
print(node.alternate); print(node.alternate);
}; }
exports.NewExpression = function (node, print) { export function NewExpression(node, print) {
this.push("new "); this.push("new ");
print(node.callee); print(node.callee);
this.push("("); this.push("(");
print.list(node.arguments); print.list(node.arguments);
this.push(")"); this.push(")");
}; }
exports.SequenceExpression = function (node, print) { export function SequenceExpression(node, print) {
print.list(node.expressions); print.list(node.expressions);
}; }
exports.ThisExpression = function () { export function ThisExpression() {
this.push("this"); this.push("this");
}; }
exports.CallExpression = function (node, print) { export function CallExpression(node, print) {
print(node.callee); print(node.callee);
this.push("("); this.push("(");
@@ -80,7 +80,7 @@ exports.CallExpression = function (node, print) {
} }
this.push(")"); this.push(")");
}; }
var buildYieldAwait = function (keyword) { var buildYieldAwait = function (keyword) {
return function (node, print) { return function (node, print) {
@@ -97,17 +97,17 @@ var buildYieldAwait = function (keyword) {
}; };
}; };
exports.YieldExpression = buildYieldAwait("yield"); export var YieldExpression = buildYieldAwait("yield");
exports.AwaitExpression = buildYieldAwait("await"); export var AwaitExpression = buildYieldAwait("await");
exports.EmptyStatement = function () { export function EmptyStatement() {
this.semicolon(); this.semicolon();
}; }
exports.ExpressionStatement = function (node, print) { export function ExpressionStatement(node, print) {
print(node.expression); print(node.expression);
this.semicolon(); this.semicolon();
}; }
exports.BinaryExpression = exports.BinaryExpression =
exports.LogicalExpression = exports.LogicalExpression =
@@ -123,7 +123,7 @@ exports.AssignmentExpression = function (node, print) {
var SCIENTIFIC_NOTATION = /e/i; var SCIENTIFIC_NOTATION = /e/i;
exports.MemberExpression = function (node, print) { export function MemberExpression(node, print) {
var obj = node.object; var obj = node.object;
print(obj); print(obj);
@@ -149,4 +149,4 @@ exports.MemberExpression = function (node, print) {
this.push("."); this.push(".");
print(node.property); print(node.property);
} }
}; }

View File

@@ -1,34 +1,226 @@
exports.AnyTypeAnnotation = import t from "../../types";
exports.ArrayTypeAnnotation =
exports.BooleanTypeAnnotation = export function AnyTypeAnnotation() {
exports.ClassProperty = this.push("any");
exports.DeclareClass = }
exports.DeclareFunction =
exports.DeclareModule = export function ArrayTypeAnnotation(node, print) {
exports.DeclareVariable = print(node.elementType);
exports.FunctionTypeAnnotation = this.push("[");
exports.FunctionTypeParam = this.push("]");
exports.GenericTypeAnnotation = }
exports.InterfaceExtends =
exports.InterfaceDeclaration = export function BooleanTypeAnnotation(node) {
exports.IntersectionTypeAnnotation = this.push("bool");
exports.NullableTypeAnnotation = }
exports.NumberTypeAnnotation =
exports.StringLiteralTypeAnnotation = export function ClassProperty(node, print) {
exports.StringTypeAnnotation = if (node.static) this.push("static ");
exports.TupleTypeAnnotation = print(node.key);
exports.TypeofTypeAnnotation = print(node.typeAnnotation);
exports.TypeAlias = this.semicolon();
exports.TypeAnnotation = }
exports.TypeParameterDeclaration =
exports.TypeParameterInstantiation = export function DeclareClass(node, print) {
exports.ObjectTypeAnnotation = this.push("declare class ");
exports.ObjectTypeCallProperty = this._interfaceish(node, print);
exports.ObjectTypeIndexer = }
exports.ObjectTypeProperty =
exports.QualifiedTypeIdentifier = export function DeclareFunction(node, print) {
exports.UnionTypeAnnotation = this.push("declare function ");
exports.TypeCastExpression = print(node.id);
exports.VoidTypeAnnotation = function () { print(node.id.typeAnnotation.typeAnnotation);
// todo: implement these once we have a `--keep-types` option this.semicolon();
}; }
export function DeclareModule(node, print) {
this.push("declare module ");
print(node.id);
this.space();
print(node.body);
}
export function DeclareVariable(node, print) {
this.push("declare var ");
print(node.id);
print(node.id.typeAnnotation);
this.semicolon();
}
export function FunctionTypeAnnotation(node, print, parent) {
print(node.typeParameters);
this.push("(");
print.list(node.params);
if (node.rest) {
if (node.params.length) {
this.push(",");
this.space();
}
this.push("...");
print(node.rest);
}
this.push(")");
// this node type is overloaded, not sure why but it makes it EXTREMELY annoying
if (parent.type === "ObjectTypeProperty" || parent.type === "ObjectTypeCallProperty" || parent.type === "DeclareFunction") {
this.push(":");
} else {
this.space();
this.push("=>");
}
this.space();
print(node.returnType);
}
export function FunctionTypeParam(node, print) {
print(node.name);
if (node.optional) this.push("?");
this.push(":");
this.space();
print(node.typeAnnotation);
}
export function InterfaceExtends(node, print) {
print(node.id);
print(node.typeParameters);
}
export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation };
export function _interfaceish(node, print) {
print(node.id);
print(node.typeParameters);
if (node.extends.length) {
this.push(" extends ");
print.join(node.extends, { separator: ", " });
}
this.space();
print(node.body);
}
export function InterfaceDeclaration(node, print) {
this.push("interface ");
this._interfaceish(node, print);
}
export function IntersectionTypeAnnotation(node, print) {
print.join(node.types, { separator: " & " });
}
export function NullableTypeAnnotation(node, print) {
this.push("?");
print(node.typeAnnotation);
}
export function NumberTypeAnnotation() {
this.push("number");
}
export function StringLiteralTypeAnnotation(node) {
this._stringLiteral(node.value);
}
export function StringTypeAnnotation() {
this.push("string");
}
export function TupleTypeAnnotation(node, print) {
this.push("[");
print.join(node.types, { separator: ", " });
this.push("]");
}
export function TypeofTypeAnnotation(node, print) {
this.push("typeof ");
print(node.argument);
}
export function TypeAlias(node, print) {
this.push("type ");
print(node.id);
print(node.typeParameters);
this.space();
this.push("=");
this.space();
print(node.right);
this.semicolon();
}
export function TypeAnnotation(node, print) {
this.push(":");
this.space();
if (node.optional) this.push("?");
print(node.typeAnnotation);
}
export function TypeParameterInstantiation(node, print) {
this.push("<");
print.join(node.params, { separator: ", " });
this.push(">");
}
export { TypeParameterInstantiation as TypeParameterDeclaration };
export function ObjectTypeAnnotation(node, print) {
this.push("{");
var props = node.properties.concat(node.callProperties, node.indexers);
if (props.length) {
this.space();
print.list(props, { indent: true, separator: "; " });
this.space();
}
this.push("}");
}
export function ObjectTypeCallProperty(node, print) {
if (node.static) this.push("static ");
print(node.value);
}
export function ObjectTypeIndexer(node, print) {
if (node.static) this.push("static ");
this.push("[");
print(node.id);
this.push(":");
this.space();
print(node.key);
this.push("]");
this.push(":");
this.space();
print(node.value);
}
export function ObjectTypeProperty(node, print) {
if (node.static) this.push("static ");
print(node.key);
if (node.optional) this.push("?");
if (!t.isFunctionTypeAnnotation(node.value)) {
this.push(":");
this.space();
}
print(node.value);
}
export function QualifiedTypeIdentifier(node, print) {
print(node.qualification);
this.push(".");
print(node.id);
}
export function UnionTypeAnnotation(node, print) {
print.join(node.types, { separator: " | " });
}
export function TypeCastExpression(node, print) {
this.push("(");
print(node.expression);
print(node.typeAnnotation);
this.push(")");
}
export function VoidTypeAnnotation(node) {
this.push("void");
}

View File

@@ -1,43 +1,43 @@
var t = require("../../types"); import each from "lodash/collection/each";
var each = require("lodash/collection/each"); import t from "../../types";
exports.JSXAttribute = function (node, print) { export function JSXAttribute(node, print) {
print(node.name); print(node.name);
if (node.value) { if (node.value) {
this.push("="); this.push("=");
print(node.value); print(node.value);
} }
}; }
exports.JSXIdentifier = function (node) { export function JSXIdentifier(node) {
this.push(node.name); this.push(node.name);
}; }
exports.JSXNamespacedName = function (node, print) { export function JSXNamespacedName(node, print) {
print(node.namespace); print(node.namespace);
this.push(":"); this.push(":");
print(node.name); print(node.name);
}; }
exports.JSXMemberExpression = function (node, print) { export function JSXMemberExpression(node, print) {
print(node.object); print(node.object);
this.push("."); this.push(".");
print(node.property); print(node.property);
}; }
exports.JSXSpreadAttribute = function (node, print) { export function JSXSpreadAttribute(node, print) {
this.push("{..."); this.push("{...");
print(node.argument); print(node.argument);
this.push("}"); this.push("}");
}; }
exports.JSXExpressionContainer = function (node, print) { export function JSXExpressionContainer(node, print) {
this.push("{"); this.push("{");
print(node.expression); print(node.expression);
this.push("}"); this.push("}");
}; }
exports.JSXElement = function (node, print) { export function JSXElement(node, print) {
var open = node.openingElement; var open = node.openingElement;
print(open); print(open);
if (open.selfClosing) return; if (open.selfClosing) return;
@@ -53,9 +53,9 @@ exports.JSXElement = function (node, print) {
this.dedent(); this.dedent();
print(node.closingElement); print(node.closingElement);
}; }
exports.JSXOpeningElement = function (node, print) { export function JSXOpeningElement(node, print) {
this.push("<"); this.push("<");
print(node.name); print(node.name);
if (node.attributes.length > 0) { if (node.attributes.length > 0) {
@@ -63,12 +63,12 @@ exports.JSXOpeningElement = function (node, print) {
print.join(node.attributes, { separator: " " }); print.join(node.attributes, { separator: " " });
} }
this.push(node.selfClosing ? " />" : ">"); this.push(node.selfClosing ? " />" : ">");
}; }
exports.JSXClosingElement = function (node, print) { export function JSXClosingElement(node, print) {
this.push("</"); this.push("</");
print(node.name); print(node.name);
this.push(">"); this.push(">");
}; }
exports.JSXEmptyExpression = function () {}; export function JSXEmptyExpression() {}

View File

@@ -1,12 +1,22 @@
var t = require("../../types"); import t from "../../types";
exports._params = function (node, print) { export function _params(node, print) {
print(node.typeParameters);
this.push("("); this.push("(");
print.list(node.params); print.list(node.params, {
iterator: (node) =>{
if (node.optional) this.push("?");
print(node.typeAnnotation);
}
});
this.push(")"); this.push(")");
};
exports._method = function (node, print) { if (node.returnType) {
print(node.returnType);
}
}
export function _method(node, print) {
var value = node.value; var value = node.value;
var kind = node.kind; var kind = node.kind;
var key = node.key; var key = node.key;
@@ -32,7 +42,7 @@ exports._method = function (node, print) {
this._params(value, print); this._params(value, print);
this.push(" "); this.push(" ");
print(value.body); print(value.body);
}; }
exports.FunctionDeclaration = exports.FunctionDeclaration =
exports.FunctionExpression = function (node, print) { exports.FunctionExpression = function (node, print) {
@@ -52,7 +62,7 @@ exports.FunctionExpression = function (node, print) {
print(node.body); print(node.body);
}; };
exports.ArrowFunctionExpression = function (node, print) { export function ArrowFunctionExpression(node, print) {
if (node.async) this.push("async "); if (node.async) this.push("async ");
if (node.params.length === 1 && t.isIdentifier(node.params[0])) { if (node.params.length === 1 && t.isIdentifier(node.params[0])) {
@@ -63,4 +73,4 @@ exports.ArrowFunctionExpression = function (node, print) {
this.push(" => "); this.push(" => ");
print(node.body); print(node.body);
}; }

View File

@@ -1,27 +1,27 @@
var t = require("../../types"); import each from "lodash/collection/each";
var each = require("lodash/collection/each"); import t from "../../types";
exports.ImportSpecifier = function (node, print) { export function ImportSpecifier(node, print) {
if (t.isSpecifierDefault(node)) { if (t.isSpecifierDefault(node)) {
print(t.getSpecifierName(node)); print(t.getSpecifierName(node));
} else { } else {
return exports.ExportSpecifier.apply(this, arguments); return exports.ExportSpecifier.apply(this, arguments);
} }
}; }
exports.ExportSpecifier = function (node, print) { export function ExportSpecifier(node, print) {
print(node.id); print(node.id);
if (node.name) { if (node.name) {
this.push(" as "); this.push(" as ");
print(node.name); print(node.name);
} }
}; }
exports.ExportBatchSpecifier = function () { export function ExportBatchSpecifier() {
this.push("*"); this.push("*");
}; }
exports.ExportDeclaration = function (node, print) { export function ExportDeclaration(node, print) {
this.push("export "); this.push("export ");
var specifiers = node.specifiers; var specifiers = node.specifiers;
@@ -53,9 +53,9 @@ exports.ExportDeclaration = function (node, print) {
} }
this.ensureSemicolon(); this.ensureSemicolon();
}; }
exports.ImportDeclaration = function (node, print) { export function ImportDeclaration(node, print) {
this.push("import "); this.push("import ");
if (node.isType) { if (node.isType) {
@@ -90,9 +90,9 @@ exports.ImportDeclaration = function (node, print) {
print(node.source); print(node.source);
this.semicolon(); this.semicolon();
}; }
exports.ImportBatchSpecifier = function (node, print) { export function ImportBatchSpecifier(node, print) {
this.push("* as "); this.push("* as ");
print(node.name); print(node.name);
}; }

View File

@@ -1,4 +1,4 @@
var each = require("lodash/collection/each"); import each from "lodash/collection/each";
each(["BindMemberExpression", "BindFunctionExpression"], function (type) { each(["BindMemberExpression", "BindFunctionExpression"], function (type) {
exports[type] = function () { exports[type] = function () {

View File

@@ -1,15 +1,15 @@
var repeating = require("repeating"); import repeating from "repeating";
var t = require("../../types"); import t from "../../types";
exports.WithStatement = function (node, print) { export function WithStatement(node, print) {
this.keyword("with"); this.keyword("with");
this.push("("); this.push("(");
print(node.object); print(node.object);
this.push(")"); this.push(")");
print.block(node.body); print.block(node.body);
}; }
exports.IfStatement = function (node, print) { export function IfStatement(node, print) {
this.keyword("if"); this.keyword("if");
this.push("("); this.push("(");
print(node.test); print(node.test);
@@ -23,9 +23,9 @@ exports.IfStatement = function (node, print) {
this.push("else "); this.push("else ");
print.indentOnComments(node.alternate); print.indentOnComments(node.alternate);
} }
}; }
exports.ForStatement = function (node, print) { export function ForStatement(node, print) {
this.keyword("for"); this.keyword("for");
this.push("("); this.push("(");
@@ -45,15 +45,15 @@ exports.ForStatement = function (node, print) {
this.push(")"); this.push(")");
print.block(node.body); print.block(node.body);
}; }
exports.WhileStatement = function (node, print) { export function WhileStatement(node, print) {
this.keyword("while"); this.keyword("while");
this.push("("); this.push("(");
print(node.test); print(node.test);
this.push(")"); this.push(")");
print.block(node.body); print.block(node.body);
}; }
var buildForXStatement = function (op) { var buildForXStatement = function (op) {
return function (node, print) { return function (node, print) {
@@ -67,10 +67,10 @@ var buildForXStatement = function (op) {
}; };
}; };
exports.ForInStatement = buildForXStatement("in"); export var ForInStatement = buildForXStatement("in");
exports.ForOfStatement = buildForXStatement("of"); export var ForOfStatement = buildForXStatement("of");
exports.DoWhileStatement = function (node, print) { export function DoWhileStatement(node, print) {
this.keyword("do"); this.keyword("do");
print(node.body); print(node.body);
this.space(); this.space();
@@ -78,7 +78,7 @@ exports.DoWhileStatement = function (node, print) {
this.push("("); this.push("(");
print(node.test); print(node.test);
this.push(");"); this.push(");");
}; }
var buildLabelStatement = function (prefix, key) { var buildLabelStatement = function (prefix, key) {
return function (node, print) { return function (node, print) {
@@ -94,17 +94,17 @@ var buildLabelStatement = function (prefix, key) {
}; };
}; };
exports.ContinueStatement = buildLabelStatement("continue"); export var ContinueStatement = buildLabelStatement("continue");
exports.ReturnStatement = buildLabelStatement("return", "argument"); export var ReturnStatement = buildLabelStatement("return", "argument");
exports.BreakStatement = buildLabelStatement("break"); export var BreakStatement = buildLabelStatement("break");
exports.LabeledStatement = function (node, print) { export function LabeledStatement(node, print) {
print(node.label); print(node.label);
this.push(": "); this.push(": ");
print(node.body); print(node.body);
}; }
exports.TryStatement = function (node, print) { export function TryStatement(node, print) {
this.keyword("try"); this.keyword("try");
print(node.block); print(node.block);
this.space(); this.space();
@@ -123,23 +123,23 @@ exports.TryStatement = function (node, print) {
this.push("finally "); this.push("finally ");
print(node.finalizer); print(node.finalizer);
} }
}; }
exports.CatchClause = function (node, print) { export function CatchClause(node, print) {
this.keyword("catch"); this.keyword("catch");
this.push("("); this.push("(");
print(node.param); print(node.param);
this.push(") "); this.push(") ");
print(node.body); print(node.body);
}; }
exports.ThrowStatement = function (node, print) { export function ThrowStatement(node, print) {
this.push("throw "); this.push("throw ");
print(node.argument); print(node.argument);
this.semicolon(); this.semicolon();
}; }
exports.SwitchStatement = function (node, print) { export function SwitchStatement(node, print) {
this.keyword("switch"); this.keyword("switch");
this.push("("); this.push("(");
print(node.discriminant); print(node.discriminant);
@@ -155,9 +155,9 @@ exports.SwitchStatement = function (node, print) {
}); });
this.push("}"); this.push("}");
}; }
exports.SwitchCase = function (node, print) { export function SwitchCase(node, print) {
if (node.test) { if (node.test) {
this.push("case "); this.push("case ");
print(node.test); print(node.test);
@@ -170,13 +170,13 @@ exports.SwitchCase = function (node, print) {
this.newline(); this.newline();
print.sequence(node.consequent, { indent: true }); print.sequence(node.consequent, { indent: true });
} }
}; }
exports.DebuggerStatement = function () { export function DebuggerStatement() {
this.push("debugger;"); this.push("debugger;");
}; }
exports.VariableDeclaration = function (node, print, parent) { export function VariableDeclaration(node, print, parent) {
this.push(node.kind + " "); this.push(node.kind + " ");
var hasInits = false; var hasInits = false;
@@ -202,22 +202,21 @@ exports.VariableDeclaration = function (node, print, parent) {
if (!t.isFor(parent)) { if (!t.isFor(parent)) {
this.semicolon(); this.semicolon();
} }
}; }
exports.PrivateDeclaration = function (node, print) { export function PrivateDeclaration(node, print) {
this.push("private "); this.push("private ");
print.join(node.declarations, { separator: ", " }); print.join(node.declarations, { separator: ", " });
this.semicolon(); this.semicolon();
}; }
exports.VariableDeclarator = function (node, print) { export function VariableDeclarator(node, print) {
print(node.id);
print(node.id.typeAnnotation);
if (node.init) { if (node.init) {
print(node.id);
this.space(); this.space();
this.push("="); this.push("=");
this.space(); this.space();
print(node.init); print(node.init);
} else {
print(node.id);
} }
}; }

View File

@@ -1,15 +1,15 @@
var each = require("lodash/collection/each"); import each from "lodash/collection/each";
exports.TaggedTemplateExpression = function (node, print) { export function TaggedTemplateExpression(node, print) {
print(node.tag); print(node.tag);
print(node.quasi); print(node.quasi);
}; }
exports.TemplateElement = function (node) { export function TemplateElement(node) {
this._push(node.value.raw); this._push(node.value.raw);
}; }
exports.TemplateLiteral = function (node, print) { export function TemplateLiteral(node, print) {
this.push("`"); this.push("`");
var quasis = node.quasis; var quasis = node.quasis;
@@ -26,4 +26,4 @@ exports.TemplateLiteral = function (node, print) {
}); });
this._push("`"); this._push("`");
}; }

View File

@@ -1,8 +1,8 @@
var each = require("lodash/collection/each"); import each from "lodash/collection/each";
exports.Identifier = function (node) { export function Identifier(node) {
this.push(node.name); this.push(node.name);
}; }
exports.RestElement = exports.RestElement =
exports.SpreadElement = exports.SpreadElement =
@@ -11,11 +11,11 @@ exports.SpreadProperty = function (node, print) {
print(node.argument); print(node.argument);
}; };
exports.VirtualPropertyExpression = function (node, print) { export function VirtualPropertyExpression(node, print) {
print(node.object); print(node.object);
this.push("::"); this.push("::");
print(node.property); print(node.property);
}; }
exports.ObjectExpression = exports.ObjectExpression =
exports.ObjectPattern = function (node, print) { exports.ObjectPattern = function (node, print) {
@@ -34,7 +34,7 @@ exports.ObjectPattern = function (node, print) {
} }
}; };
exports.Property = function (node, print) { export function Property(node, print) {
if (node.method || node.kind === "get" || node.kind === "set") { if (node.method || node.kind === "get" || node.kind === "set") {
this._method(node, print); this._method(node, print);
} else { } else {
@@ -51,7 +51,7 @@ exports.Property = function (node, print) {
this.space(); this.space();
print(node.value); print(node.value);
} }
}; }
exports.ArrayExpression = exports.ArrayExpression =
exports.ArrayPattern = function (node, print) { exports.ArrayPattern = function (node, print) {
@@ -78,19 +78,12 @@ exports.ArrayPattern = function (node, print) {
this.push("]"); this.push("]");
}; };
exports.Literal = function (node) { export function Literal(node) {
var val = node.value; var val = node.value;
var type = typeof val; var type = typeof val;
if (type === "string") { if (type === "string") {
val = JSON.stringify(val); this._stringLiteral(val);
// escape illegal js but valid json unicode characters
val = val.replace(/[\u000A\u000D\u2028\u2029]/g, function (c) {
return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4);
});
this.push(val);
} else if (type === "number") { } else if (type === "number") {
this.push(val + ""); this.push(val + "");
} else if (type === "boolean") { } else if (type === "boolean") {
@@ -100,4 +93,15 @@ exports.Literal = function (node) {
} else if (val === null) { } else if (val === null) {
this.push("null"); this.push("null");
} }
}; }
export function _stringLiteral(val) {
val = JSON.stringify(val);
// escape illegal js but valid json unicode characters
val = val.replace(/[\u000A\u000D\u2028\u2029]/g, function (c) {
return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4);
});
this.push(val);
}

View File

@@ -1,35 +1,339 @@
module.exports = function (ast, opts, code) { import detectIndent from "detect-indent";
var gen = new CodeGenerator(ast, opts, code); import Whitespace from "./whitespace";
return gen.generate(); import repeating from "repeating";
}; import SourceMap from "./source-map";
import Position from "./position";
import * as messages from "../messages";
import Buffer from "./buffer";
import extend from "lodash/object/extend";
import each from "lodash/collection/each";
import n from "./node";
import t from "../types";
module.exports.CodeGenerator = CodeGenerator; class CodeGenerator {
constructor(ast, opts, code) {
opts ||= {};
var detectIndent = require("detect-indent"); this.comments = ast.comments || [];
var Whitespace = require("./whitespace"); this.tokens = ast.tokens || [];
var repeating = require("repeating"); this.format = CodeGenerator.normalizeOptions(code, opts);
var SourceMap = require("./source-map"); this.opts = opts;
var Position = require("./position"); this.ast = ast;
var messages = require("../messages");
var Buffer = require("./buffer");
var extend = require("lodash/object/extend");
var each = require("lodash/collection/each");
var n = require("./node");
var t = require("../types");
function CodeGenerator(ast, opts, code) { this.whitespace = new Whitespace(this.tokens, this.comments, this.format);
opts ||= {}; this.position = new Position;
this.map = new SourceMap(this.position, opts, code);
this.buffer = new Buffer(this.position, this.format);
}
this.comments = ast.comments || []; static normalizeOptions(code, opts) {
this.tokens = ast.tokens || []; var style = " ";
this.format = CodeGenerator.normalizeOptions(code, opts); if (code) {
this.opts = opts; var indent = detectIndent(code).indent;
this.ast = ast; if (indent && indent !== " ") style = indent;
}
this.whitespace = new Whitespace(this.tokens, this.comments, this.format); var format = {
this.position = new Position; comments: opts.comments == null || opts.comments,
this.map = new SourceMap(this.position, opts, code); compact: opts.compact,
this.buffer = new Buffer(this.position, this.format); indent: {
adjustMultilineComment: true,
style: style,
base: 0
}
};
if (format.compact === "auto") {
format.compact = code.length > 100000; // 100KB
if (format.compact) {
console.error(messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
}
}
return format;
}
static generators = {
templateLiterals: require("./generators/template-literals"),
comprehensions: require("./generators/comprehensions"),
expressions: require("./generators/expressions"),
statements: require("./generators/statements"),
playground: require("./generators/playground"),
classes: require("./generators/classes"),
methods: require("./generators/methods"),
modules: require("./generators/modules"),
types: require("./generators/types"),
flow: require("./generators/flow"),
base: require("./generators/base"),
jsx: require("./generators/jsx")
};
generate() {
var ast = this.ast;
this.print(ast);
var comments = [];
each(ast.comments, function (comment) {
if (!comment._displayed) comments.push(comment);
});
this._printComments(comments);
return {
map: this.map.get(),
code: this.buffer.get()
};
}
buildPrint(parent) {
var print = (node, opts) => {
return this.print(node, parent, opts);
};
print.sequence = (nodes, opts = {}) => {
opts.statement = true;
return this.printJoin(print, nodes, opts);
};
print.join = (nodes, opts) => {
return this.printJoin(print, nodes, opts);
};
print.list = function (items, opts = {}) {
opts.separator ||= ", ";
print.join(items, opts);
};
print.block = (node) => {
return this.printBlock(print, node);
};
print.indentOnComments = (node) => {
return this.printAndIndentOnComments(print, node);
};
return print;
}
print(node, parent, opts = {}) {
if (!node) return;
if (parent && parent._compact) {
node._compact = true;
}
var oldConcise = this.format.concise;
if (node._compact) {
this.format.concise = true;
}
var newline = (leading) => {
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
return;
}
var lines = 0;
if (node.start != null && !node._ignoreUserWhitespace) {
// user node
if (leading) {
lines = this.whitespace.getNewlinesBefore(node);
} else {
lines = this.whitespace.getNewlinesAfter(node);
}
} else {
// generated node
if (!leading) lines++; // always include at least a single line after
if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;
var needs = n.needsWhitespaceAfter;
if (leading) needs = n.needsWhitespaceBefore;
if (needs(node, parent)) lines++;
// generated nodes can't add starting file whitespace
if (!this.buffer.buf) lines = 0;
}
this.newline(lines);
};
if (this[node.type]) {
var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent);
var needsParens = needsNoLineTermParens || n.needsParens(node, parent);
if (needsParens) this.push("(");
if (needsNoLineTermParens) this.indent();
this.printLeadingComments(node, parent);
newline(true);
if (opts.before) opts.before();
this.map.mark(node, "start");
this[node.type](node, this.buildPrint(node), parent);
if (needsNoLineTermParens) {
this.newline();
this.dedent();
}
if (needsParens) this.push(")");
this.map.mark(node, "end");
if (opts.after) opts.after();
newline(false);
this.printTrailingComments(node, parent);
} else {
throw new ReferenceError("unknown node of type " + JSON.stringify(node.type) + " with constructor " + JSON.stringify(node && node.constructor.name));
}
this.format.concise = oldConcise;
}
printJoin(print, nodes, opts = {}) {
if (!nodes || !nodes.length) return;
var len = nodes.length;
if (opts.indent) this.indent();
each(nodes, (node, i) => {
print(node, {
statement: opts.statement,
addNewlines: opts.addNewlines,
after: () => {
if (opts.iterator) {
opts.iterator(node, i);
}
if (opts.separator && i < len - 1) {
this.push(opts.separator);
}
}
});
});
if (opts.indent) this.dedent();
}
printAndIndentOnComments(print, node) {
var indent = !!node.leadingComments;
if (indent) this.indent();
print(node);
if (indent) this.dedent();
}
printBlock(print, node) {
if (t.isEmptyStatement(node)) {
this.semicolon();
} else {
this.push(" ");
print(node);
}
}
generateComment(comment) {
var val = comment.value;
if (comment.type === "Line") {
val = "//" + val;
} else {
val = "/*" + val + "*/";
}
return val;
}
printTrailingComments(node, parent) {
this._printComments(this.getComments("trailingComments", node, parent));
}
printLeadingComments(node, parent) {
this._printComments(this.getComments("leadingComments", node, parent));
}
getComments(key, node, parent) {
if (t.isExpressionStatement(parent)) {
return [];
}
var comments = [];
var nodes = [node];
if (t.isExpressionStatement(node)) {
nodes.push(node.argument);
}
each(nodes, (node) => {
comments = comments.concat(this._getComments(key, node));
});
return comments;
}
_getComments(key, node) {
return (node && node[key]) || [];
}
_printComments(comments) {
if (this.format.compact) return;
if (!this.format.comments) return;
if (!comments || !comments.length) return;
each(comments, (comment) => {
var skip = false;
// find the original comment in the ast and set it as displayed
each(this.ast.comments, function (origComment) {
if (origComment.start === comment.start) {
// comment has already been output
if (origComment._displayed) skip = true;
origComment._displayed = true;
return false;
}
});
if (skip) return;
// whitespace before
this.newline(this.whitespace.getNewlinesBefore(comment));
var column = this.position.column;
var val = this.generateComment(comment);
if (column && !this.isLast(["\n", " ", "[", "{"])) {
this._push(" ");
column++;
}
//
if (comment.type === "Block" && this.format.indent.adjustMultilineComment) {
var offset = comment.loc.start.column;
if (offset) {
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
val = val.replace(newlineRegex, "\n");
}
var indent = Math.max(this.indentSize(), column);
val = val.replace(/\n/g, "\n" + repeating(" ", indent));
}
if (column === 0) {
val = this.getIndent() + val;
}
//
this._push(val);
// whitespace after
this.newline(this.whitespace.getNewlinesAfter(comment));
});
}
} }
each(Buffer.prototype, function (fn, key) { each(Buffer.prototype, function (fn, key) {
@@ -38,321 +342,13 @@ each(Buffer.prototype, function (fn, key) {
}; };
}); });
CodeGenerator.normalizeOptions = function (code, opts) {
var style = " ";
if (code) {
var indent = detectIndent(code).indent;
if (indent && indent !== " ") style = indent;
}
var format = {
comments: opts.comments == null || opts.comments,
compact: opts.compact,
indent: {
adjustMultilineComment: true,
style: style,
base: 0
}
};
if (format.compact === "auto") {
format.compact = code.length > 100000; // 100KB
if (format.compact) {
console.error(messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
}
}
return format;
};
CodeGenerator.generators = {
templateLiterals: require("./generators/template-literals"),
comprehensions: require("./generators/comprehensions"),
expressions: require("./generators/expressions"),
statements: require("./generators/statements"),
playground: require("./generators/playground"),
classes: require("./generators/classes"),
methods: require("./generators/methods"),
modules: require("./generators/modules"),
types: require("./generators/types"),
flow: require("./generators/flow"),
base: require("./generators/base"),
jsx: require("./generators/jsx")
};
each(CodeGenerator.generators, function (generator) { each(CodeGenerator.generators, function (generator) {
extend(CodeGenerator.prototype, generator); extend(CodeGenerator.prototype, generator);
}); });
CodeGenerator.prototype.generate = function () { module.exports = function (ast, opts, code) {
var ast = this.ast; var gen = new CodeGenerator(ast, opts, code);
return gen.generate();
this.print(ast);
var comments = [];
each(ast.comments, function (comment) {
if (!comment._displayed) comments.push(comment);
});
this._printComments(comments);
return {
map: this.map.get(),
code: this.buffer.get()
};
}; };
CodeGenerator.prototype.buildPrint = function (parent) { module.exports.CodeGenerator = CodeGenerator;
var print = (node, opts) => {
return this.print(node, parent, opts);
};
print.sequence = (nodes, opts) => {
opts ||= {};
opts.statement = true;
return this.printJoin(print, nodes, opts);
};
print.join = (nodes, opts) => {
return this.printJoin(print, nodes, opts);
};
print.list = function (items, opts) {
opts ||= {};
opts.separator ||= ", ";
print.join(items, opts);
};
print.block = (node) => {
return this.printBlock(print, node);
};
print.indentOnComments = (node) => {
return this.printAndIndentOnComments(print, node);
};
return print;
};
CodeGenerator.prototype.print = function (node, parent, opts) {
if (!node) return "";
if (parent && parent._compact) {
node._compact = true;
}
var oldConcise = this.format.concise;
if (node._compact) {
this.format.concise = true;
}
opts ||= {};
var newline = (leading) => {
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
return;
}
var lines = 0;
if (node.start != null && !node._ignoreUserWhitespace) {
// user node
if (leading) {
lines = this.whitespace.getNewlinesBefore(node);
} else {
lines = this.whitespace.getNewlinesAfter(node);
}
} else {
// generated node
if (!leading) lines++; // always include at least a single line after
if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;
var needs = n.needsWhitespaceAfter;
if (leading) needs = n.needsWhitespaceBefore;
if (needs(node, parent)) lines++;
// generated nodes can't add starting file whitespace
if (!this.buffer.buf) lines = 0;
}
this.newline(lines);
};
if (this[node.type]) {
var needsNoLineTermParens = n.needsParensNoLineTerminator(node, parent);
var needsParens = needsNoLineTermParens || n.needsParens(node, parent);
if (needsParens) this.push("(");
if (needsNoLineTermParens) this.indent();
this.printLeadingComments(node, parent);
newline(true);
if (opts.before) opts.before();
this.map.mark(node, "start");
this[node.type](node, this.buildPrint(node), parent);
if (needsNoLineTermParens) {
this.newline();
this.dedent();
}
if (needsParens) this.push(")");
this.map.mark(node, "end");
if (opts.after) opts.after();
newline(false);
this.printTrailingComments(node, parent);
} else {
throw new ReferenceError("unknown node of type " + JSON.stringify(node.type) + " with constructor " + JSON.stringify(node && node.constructor.name));
}
this.format.concise = oldConcise;
};
CodeGenerator.prototype.printJoin = function (print, nodes, opts) {
if (!nodes || !nodes.length) return;
opts ||= {};
var len = nodes.length;
if (opts.indent) this.indent();
each(nodes, (node, i) => {
print(node, {
statement: opts.statement,
addNewlines: opts.addNewlines,
after: () => {
if (opts.iterator) {
opts.iterator(node, i);
}
if (opts.separator && i < len - 1) {
this.push(opts.separator);
}
}
});
});
if (opts.indent) this.dedent();
};
CodeGenerator.prototype.printAndIndentOnComments = function (print, node) {
var indent = !!node.leadingComments;
if (indent) this.indent();
print(node);
if (indent) this.dedent();
};
CodeGenerator.prototype.printBlock = function (print, node) {
if (t.isEmptyStatement(node)) {
this.semicolon();
} else {
this.push(" ");
print(node);
}
};
CodeGenerator.prototype.generateComment = function (comment) {
var val = comment.value;
if (comment.type === "Line") {
val = "//" + val;
} else {
val = "/*" + val + "*/";
}
return val;
};
CodeGenerator.prototype.printTrailingComments = function (node, parent) {
this._printComments(this.getComments("trailingComments", node, parent));
};
CodeGenerator.prototype.printLeadingComments = function (node, parent) {
this._printComments(this.getComments("leadingComments", node, parent));
};
CodeGenerator.prototype.getComments = function (key, node, parent) {
if (t.isExpressionStatement(parent)) {
return [];
}
var comments = [];
var nodes = [node];
if (t.isExpressionStatement(node)) {
nodes.push(node.argument);
}
each(nodes, (node) => {
comments = comments.concat(this._getComments(key, node));
});
return comments;
};
CodeGenerator.prototype._getComments = function (key, node) {
return (node && node[key]) || [];
};
CodeGenerator.prototype._printComments = function (comments) {
if (this.format.compact) return;
if (!this.format.comments) return;
if (!comments || !comments.length) return;
each(comments, (comment) => {
var skip = false;
// find the original comment in the ast and set it as displayed
each(this.ast.comments, function (origComment) {
if (origComment.start === comment.start) {
// comment has already been output
if (origComment._displayed) skip = true;
origComment._displayed = true;
return false;
}
});
if (skip) return;
// whitespace before
this.newline(this.whitespace.getNewlinesBefore(comment));
var column = this.position.column;
var val = this.generateComment(comment);
if (column && !this.isLast(["\n", " ", "[", "{"])) {
this._push(" ");
column++;
}
//
if (comment.type === "Block" && this.format.indent.adjustMultilineComment) {
var offset = comment.loc.start.column;
if (offset) {
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
val = val.replace(newlineRegex, "\n");
}
var indent = Math.max(this.indentSize(), column);
val = val.replace(/\n/g, "\n" + repeating(" ", indent));
}
if (column === 0) {
val = this.getIndent() + val;
}
//
this._push(val);
// whitespace after
this.newline(this.whitespace.getNewlinesAfter(comment));
});
};

View File

@@ -1,10 +1,8 @@
module.exports = Node; import whitespace from "./whitespace";
import * as parens from "./parentheses";
var whitespace = require("./whitespace"); import each from "lodash/collection/each";
var parens = require("./parentheses"); import some from "lodash/collection/some";
var each = require("lodash/collection/each"); import t from "../../types";
var some = require("lodash/collection/some");
var t = require("../../types");
var find = function (obj, node, parent) { var find = function (obj, node, parent) {
if (!obj) return; if (!obj) return;
@@ -24,79 +22,81 @@ var find = function (obj, node, parent) {
return result; return result;
}; };
function Node(node, parent) { export default class Node {
this.parent = parent; constructor(node, parent) {
this.node = node; this.parent = parent;
} this.node = node;
Node.isUserWhitespacable = function (node) {
return t.isUserWhitespacable(node);
};
Node.needsWhitespace = function (node, parent, type) {
if (!node) return 0;
if (t.isExpressionStatement(node)) {
node = node.expression;
} }
var linesInfo = find(whitespace.nodes, node, parent); static isUserWhitespacable(node) {
return t.isUserWhitespacable(node);
}
if (!linesInfo) { static needsWhitespace(node, parent, type) {
var items = find(whitespace.list, node, parent); if (!node) return 0;
if (items) {
for (var i = 0; i < items.length; i++) { if (t.isExpressionStatement(node)) {
linesInfo = Node.needsWhitespace(items[i], node, type); node = node.expression;
if (linesInfo) break; }
var linesInfo = find(whitespace.nodes, node, parent);
if (!linesInfo) {
var items = find(whitespace.list, node, parent);
if (items) {
for (var i = 0; i < items.length; i++) {
linesInfo = Node.needsWhitespace(items[i], node, type);
if (linesInfo) break;
}
} }
} }
return (linesInfo && linesInfo[type]) || 0;
} }
return (linesInfo && linesInfo[type]) || 0; static needsWhitespaceBefore(node, parent) {
}; return Node.needsWhitespace(node, parent, "before");
Node.needsWhitespaceBefore = function (node, parent) {
return Node.needsWhitespace(node, parent, "before");
};
Node.needsWhitespaceAfter = function (node, parent) {
return Node.needsWhitespace(node, parent, "after");
};
Node.needsParens = function (node, parent) {
if (!parent) return false;
if (t.isNewExpression(parent) && parent.callee === node) {
if (t.isCallExpression(node)) return true;
var hasCall = some(node, function (val) {
return t.isCallExpression(val);
});
if (hasCall) return true;
} }
return find(parens, node, parent); static needsWhitespaceAfter(node, parent) {
}; return Node.needsWhitespace(node, parent, "after");
}
Node.needsParensNoLineTerminator = function (node, parent) { static needsParens(node, parent) {
if (!parent) return false; if (!parent) return false;
if (t.isNewExpression(parent) && parent.callee === node) {
if (t.isCallExpression(node)) return true;
var hasCall = some(node, function (val) {
return t.isCallExpression(val);
});
if (hasCall) return true;
}
return find(parens, node, parent);
}
static needsParensNoLineTerminator(node, parent) {
if (!parent) return false;
// no comments
if (!node.leadingComments || !node.leadingComments.length) {
return false;
}
if (t.isYieldExpression(parent) || t.isAwaitExpression(parent)) {
return true;
}
if (t.isContinueStatement(parent) || t.isBreakStatement(parent) ||
t.isReturnStatement(parent) || t.isThrowStatement(parent)) {
return true;
}
// no comments
if (!node.leadingComments || !node.leadingComments.length) {
return false; return false;
} }
}
if (t.isYieldExpression(parent) || t.isAwaitExpression(parent)) {
return true;
}
if (t.isContinueStatement(parent) || t.isBreakStatement(parent) ||
t.isReturnStatement(parent) || t.isThrowStatement(parent)) {
return true;
}
return false;
};
each(Node, function (fn, key) { each(Node, function (fn, key) {
Node.prototype[key] = function () { Node.prototype[key] = function () {

View File

@@ -1,5 +1,5 @@
var t = require("../../types"); import each from "lodash/collection/each";
var each = require("lodash/collection/each"); import t from "../../types";
var PRECEDENCE = {}; var PRECEDENCE = {};
@@ -21,14 +21,20 @@ each([
}); });
}); });
exports.UpdateExpression = function (node, parent) { export function NullableTypeAnnotation(node, parent) {
return t.isArrayTypeAnnotation(parent);
}
export { NullableTypeAnnotation as FunctionTypeAnnotation };
export function UpdateExpression(node, parent) {
if (t.isMemberExpression(parent) && parent.object === node) { if (t.isMemberExpression(parent) && parent.object === node) {
// (foo++).test() // (foo++).test()
return true; return true;
} }
}; }
exports.ObjectExpression = function (node, parent) { export function ObjectExpression(node, parent) {
if (t.isExpressionStatement(parent)) { if (t.isExpressionStatement(parent)) {
// ({ foo: "bar" }); // ({ foo: "bar" });
return true; return true;
@@ -40,9 +46,9 @@ exports.ObjectExpression = function (node, parent) {
} }
return false; return false;
}; }
exports.Binary = function (node, parent) { export function Binary(node, parent) {
if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) { if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) {
return true; return true;
} }
@@ -70,9 +76,9 @@ exports.Binary = function (node, parent) {
return true; return true;
} }
} }
}; }
exports.BinaryExpression = function (node, parent) { export function BinaryExpression(node, parent) {
if (node.operator === "in") { if (node.operator === "in") {
// var i = (1 in []); // var i = (1 in []);
if (t.isVariableDeclarator(parent)) { if (t.isVariableDeclarator(parent)) {
@@ -84,9 +90,9 @@ exports.BinaryExpression = function (node, parent) {
return true; return true;
} }
} }
}; }
exports.SequenceExpression = function (node, parent) { export function SequenceExpression(node, parent) {
if (t.isForStatement(parent)) { if (t.isForStatement(parent)) {
// Although parentheses wouldn't hurt around sequence // Although parentheses wouldn't hurt around sequence
// expressions in the head of for loops, traditional style // expressions in the head of for loops, traditional style
@@ -102,9 +108,9 @@ exports.SequenceExpression = function (node, parent) {
// Otherwise err on the side of overparenthesization, adding // Otherwise err on the side of overparenthesization, adding
// explicit exceptions above if this proves overzealous. // explicit exceptions above if this proves overzealous.
return true; return true;
}; }
exports.YieldExpression = function (node, parent) { export function YieldExpression(node, parent) {
return t.isBinary(parent) || return t.isBinary(parent) ||
t.isUnaryLike(parent) || t.isUnaryLike(parent) ||
t.isCallExpression(parent) || t.isCallExpression(parent) ||
@@ -112,17 +118,17 @@ exports.YieldExpression = function (node, parent) {
t.isNewExpression(parent) || t.isNewExpression(parent) ||
t.isConditionalExpression(parent) || t.isConditionalExpression(parent) ||
t.isYieldExpression(parent); t.isYieldExpression(parent);
}; }
exports.ClassExpression = function (node, parent) { export function ClassExpression(node, parent) {
return t.isExpressionStatement(parent); return t.isExpressionStatement(parent);
}; }
exports.UnaryLike = function (node, parent) { export function UnaryLike(node, parent) {
return t.isMemberExpression(parent) && parent.object === node; return t.isMemberExpression(parent) && parent.object === node;
}; }
exports.FunctionExpression = function (node, parent) { export function FunctionExpression(node, parent) {
// function () {}; // function () {};
if (t.isExpressionStatement(parent)) { if (t.isExpressionStatement(parent)) {
return true; return true;
@@ -137,10 +143,9 @@ exports.FunctionExpression = function (node, parent) {
if (t.isCallExpression(parent) && parent.callee === node) { if (t.isCallExpression(parent) && parent.callee === node) {
return true; return true;
} }
}; }
exports.AssignmentExpression = export function ConditionalExpression(node, parent) {
exports.ConditionalExpression = function (node, parent) {
if (t.isUnaryLike(parent)) { if (t.isUnaryLike(parent)) {
return true; return true;
} }
@@ -164,4 +169,6 @@ exports.ConditionalExpression = function (node, parent) {
} }
return false; return false;
}; }
export { ConditionalExpression as AssignmentExpression };

View File

@@ -1,11 +1,9 @@
var isBoolean = require("lodash/lang/isBoolean"); import isBoolean from "lodash/lang/isBoolean";
var each = require("lodash/collection/each"); import each from "lodash/collection/each";
var map = require("lodash/collection/map"); import map from "lodash/collection/map";
var t = require("../../types"); import t from "../../types";
var crawl = function (node, state) {
state ||= {};
function crawl(node, state = {}) {
if (t.isMemberExpression(node)) { if (t.isMemberExpression(node)) {
crawl(node.object, state); crawl(node.object, state);
if (node.computed) crawl(node.property, state); if (node.computed) crawl(node.property, state);
@@ -22,9 +20,9 @@ var crawl = function (node, state) {
} }
return state; return state;
}; }
var isHelper = function (node) { function isHelper(node) {
if (t.isMemberExpression(node)) { if (t.isMemberExpression(node)) {
return isHelper(node.object) || isHelper(node.property); return isHelper(node.object) || isHelper(node.property);
} else if (t.isIdentifier(node)) { } else if (t.isIdentifier(node)) {
@@ -36,12 +34,12 @@ var isHelper = function (node) {
} else { } else {
return false; return false;
} }
}; }
var isType = function (node) { function isType(node) {
return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) || return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) ||
t.isIdentifier(node) || t.isMemberExpression(node); t.isIdentifier(node) || t.isMemberExpression(node);
}; }
exports.nodes = { exports.nodes = {
AssignmentExpression(node) { AssignmentExpression(node) {

View File

@@ -1,27 +1,27 @@
module.exports = Position; export default class Position {
constructor() {
this.line = 1;
this.column = 0;
}
function Position() { push(str) {
this.line = 1; for (var i = 0; i < str.length; i++) {
this.column = 0; if (str[i] === "\n") {
this.line++;
this.column = 0;
} else {
this.column++;
}
}
}
unshift(str) {
for (var i = 0; i < str.length; i++) {
if (str[i] === "\n") {
this.line--;
} else {
this.column--;
}
}
}
} }
Position.prototype.push = function (str) {
for (var i = 0; i < str.length; i++) {
if (str[i] === "\n") {
this.line++;
this.column = 0;
} else {
this.column++;
}
}
};
Position.prototype.unshift = function (str) {
for (var i = 0; i < str.length; i++) {
if (str[i] === "\n") {
this.line--;
} else {
this.column--;
}
}
};

View File

@@ -1,54 +1,54 @@
module.exports = SourceMap; import sourceMap from "source-map";
import t from "../types";
var sourceMap = require("source-map"); export default class SourceMap {
var t = require("../types"); constructor(position, opts, code) {
this.position = position;
this.opts = opts;
function SourceMap(position, opts, code) { if (opts.sourceMap) {
this.position = position; this.map = new sourceMap.SourceMapGenerator({
this.opts = opts; file: opts.sourceMapName,
sourceRoot: opts.sourceRoot
});
if (opts.sourceMap) { this.map.setSourceContent(opts.sourceFileName, code);
this.map = new sourceMap.SourceMapGenerator({ } else {
file: opts.sourceMapName, this.map = null;
sourceRoot: opts.sourceRoot }
}
get() {
var map = this.map;
if (map) {
return map.toJSON();
} else {
return map;
}
}
mark(node, type) {
var loc = node.loc;
if (!loc) return; // no location info
var map = this.map;
if (!map) return; // no source map
if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes
var position = this.position;
var generated = {
line: position.line,
column: position.column
};
var original = loc[type];
map.addMapping({
source: this.opts.sourceFileName,
generated: generated,
original: original
}); });
this.map.setSourceContent(opts.sourceFileName, code);
} else {
this.map = null;
} }
} }
SourceMap.prototype.get = function () {
var map = this.map;
if (map) {
return map.toJSON();
} else {
return map;
}
};
SourceMap.prototype.mark = function (node, type) {
var loc = node.loc;
if (!loc) return; // no location info
var map = this.map;
if (!map) return; // no source map
if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes
var position = this.position;
var generated = {
line: position.line,
column: position.column
};
var original = loc[type];
map.addMapping({
source: this.opts.sourceFileName,
generated: generated,
original: original
});
};

View File

@@ -1,6 +1,4 @@
module.exports = Whitespace; import sortBy from "lodash/collection/sortBy";
var sortBy = require("lodash/collection/sortBy");
/** /**
* Returns `i`th number from `base`, continuing from 0 when `max` is reached. * Returns `i`th number from `base`, continuing from 0 when `max` is reached.
@@ -22,92 +20,94 @@ function getLookupIndex(i, base, max) {
return i; return i;
} }
function Whitespace(tokens, comments) { export default class Whitespace {
this.tokens = sortBy(tokens.concat(comments), "start"); constructor(tokens, comments) {
this.used = {}; this.tokens = sortBy(tokens.concat(comments), "start");
this.used = {};
// Profiling this code shows that while generator passes over it, indexes // Profiling this code shows that while generator passes over it, indexes
// returned by `getNewlinesBefore` and `getNewlinesAfter` are always increasing. // returned by `getNewlinesBefore` and `getNewlinesAfter` are always increasing.
// We use this implementation detail for an optimization: instead of always // We use this implementation detail for an optimization: instead of always
// starting to look from `this.tokens[0]`, we will start `for` loops from the // starting to look from `this.tokens[0]`, we will start `for` loops from the
// previous successful match. We will enumerate all tokens—but the common // previous successful match. We will enumerate all tokens—but the common
// case will be much faster. // case will be much faster.
this._lastFoundIndex = 0; this._lastFoundIndex = 0;
}
Whitespace.prototype.getNewlinesBefore = function (node) {
var startToken;
var endToken;
var tokens = this.tokens;
var token;
for (var j = 0; j < tokens.length; j++) {
// optimize for forward traversal by shifting for loop index
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length);
token = tokens[i];
// this is the token this node starts with
if (node.start === token.start) {
startToken = tokens[i - 1];
endToken = token;
this._lastFoundIndex = i;
break;
}
} }
return this.getNewlinesBetween(startToken, endToken); getNewlinesBefore(node) {
}; var startToken;
var endToken;
var tokens = this.tokens;
var token;
Whitespace.prototype.getNewlinesAfter = function (node) { for (var j = 0; j < tokens.length; j++) {
var startToken; // optimize for forward traversal by shifting for loop index
var endToken; var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length);
var tokens = this.tokens; token = tokens[i];
var token;
for (var j = 0; j < tokens.length; j++) { // this is the token this node starts with
// optimize for forward traversal by shifting for loop index if (node.start === token.start) {
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length); startToken = tokens[i - 1];
token = tokens[i]; endToken = token;
// this is the token this node ends with this._lastFoundIndex = i;
if (node.end === token.end) { break;
startToken = token; }
endToken = tokens[i + 1];
this._lastFoundIndex = i;
break;
} }
return this.getNewlinesBetween(startToken, endToken);
} }
if (endToken && endToken.type.type === "eof") { getNewlinesAfter(node) {
return 1; var startToken;
} else { var endToken;
var lines = this.getNewlinesBetween(startToken, endToken); var tokens = this.tokens;
if (node.type === "Line" && !lines) { var token;
// line comment
for (var j = 0; j < tokens.length; j++) {
// optimize for forward traversal by shifting for loop index
var i = getLookupIndex(j, this._lastFoundIndex, this.tokens.length);
token = tokens[i];
// this is the token this node ends with
if (node.end === token.end) {
startToken = token;
endToken = tokens[i + 1];
this._lastFoundIndex = i;
break;
}
}
if (endToken && endToken.type.type === "eof") {
return 1; return 1;
} else { } else {
return lines; var lines = this.getNewlinesBetween(startToken, endToken);
} if (node.type === "Line" && !lines) {
} // line comment
}; return 1;
} else {
Whitespace.prototype.getNewlinesBetween = function (startToken, endToken) { return lines;
if (!endToken || !endToken.loc) return 0; }
var start = startToken ? startToken.loc.end.line : 1;
var end = endToken.loc.start.line;
var lines = 0;
for (var line = start; line < end; line++) {
if (typeof this.used[line] === "undefined") {
this.used[line] = true;
lines++;
} }
} }
return lines; getNewlinesBetween(startToken, endToken) {
}; if (!endToken || !endToken.loc) return 0;
var start = startToken ? startToken.loc.end.line : 1;
var end = endToken.loc.start.line;
var lines = 0;
for (var line = start; line < end; line++) {
if (typeof this.used[line] === "undefined") {
this.used[line] = true;
lines++;
}
}
return lines;
}
}

View File

@@ -1,23 +1,22 @@
var lineNumbers = require("line-numbers"); import lineNumbers from "line-numbers";
var repeating = require("repeating"); import repeating from "repeating";
var jsTokens = require("js-tokens"); import jsTokens from "js-tokens";
var esutils = require("esutils"); import esutils from "esutils";
var chalk = require("chalk"); import chalk from "chalk";
var ary = require("lodash/function/ary"); import ary from "lodash/function/ary";
var defs = { var defs = {
string: chalk.red, string: chalk.red,
punctuation: chalk.white.bold, punctuator: chalk.white.bold,
operator: chalk.white.bold, curly: chalk.green,
curly: chalk.green, parens: chalk.blue.bold,
parens: chalk.blue.bold, square: chalk.yellow,
square: chalk.yellow, name: chalk.white,
name: chalk.white, keyword: chalk.cyan,
keyword: chalk.cyan, number: chalk.magenta,
number: chalk.magenta, regex: chalk.magenta,
regex: chalk.magenta, comment: chalk.grey,
comment: chalk.grey, invalid: chalk.inverse
invalid: chalk.inverse
}; };
var newline = /\r\n|[\n\r\u2028\u2029]/; var newline = /\r\n|[\n\r\u2028\u2029]/;
@@ -25,11 +24,11 @@ var newline = /\r\n|[\n\r\u2028\u2029]/;
var highlight = function (text) { var highlight = function (text) {
var tokenType = function (match) { var tokenType = function (match) {
var token = jsTokens.matchToToken(match); var token = jsTokens.matchToToken(match);
if (token.type === "name" && esutils.keyword.isKeywordES6(token.value)) { if (token.type === "name" && esutils.keyword.isReservedWordES6(token.value)) {
return "keyword"; return "keyword";
} }
if (token.type === "punctuation") { if (token.type === "punctuator") {
switch (token.value) { switch (token.value) {
case "{": case "{":
case "}": case "}":

View File

@@ -1,4 +1,4 @@
var t = require("../types"); import t from "../types";
module.exports = function (ast, comments, tokens) { module.exports = function (ast, comments, tokens) {
if (ast && ast.type === "Program") { if (ast && ast.type === "Program") {

View File

@@ -1,7 +1,7 @@
var normalizeAst = require("./normalize-ast"); import normalizeAst from "./normalize-ast";
var estraverse = require("estraverse"); import estraverse from "estraverse";
var codeFrame = require("./code-frame"); import codeFrame from "./code-frame";
var acorn = require("acorn-babel"); import acorn from "acorn-babel";
module.exports = function (opts, code, callback) { module.exports = function (opts, code, callback) {
try { try {

View File

@@ -1,6 +1,6 @@
var util = require("util"); import * as util from "util";
exports.messages = { export var messages = {
tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence", tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence",
JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.", JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.",
classesIllegalBareSuper: "Illegal use of bare super", classesIllegalBareSuper: "Illegal use of bare super",
@@ -21,7 +21,7 @@ exports.messages = {
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2." codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2."
}; };
exports.get = function (key) { export function get(key) {
var msg = exports.messages[key]; var msg = exports.messages[key];
if (!msg) throw new ReferenceError("Unknown message `" + key + "`"); if (!msg) throw new ReferenceError("Unknown message `" + key + "`");
@@ -34,9 +34,9 @@ exports.get = function (key) {
return msg.replace(/\$(\d+)/g, function (str, i) { return msg.replace(/\$(\d+)/g, function (str, i) {
return args[--i]; return args[--i];
}); });
}; }
exports.parseArgs = function (args) { export function parseArgs(args) {
return args.map(function (val) { return args.map(function (val) {
if (val != null && val.inspect) { if (val != null && val.inspect) {
return val.inspect(); return val.inspect();
@@ -48,4 +48,4 @@ exports.parseArgs = function (args) {
} }
} }
}); });
}; }

View File

@@ -1,14 +1,14 @@
var extend = require("lodash/object/extend"); import estraverse from "estraverse";
var t = require("./types"); import extend from "lodash/object/extend";
import types from "ast-types";
import t from "./types";
// estraverse // estraverse
var estraverse = require("estraverse");
extend(estraverse.VisitorKeys, t.VISITOR_KEYS); extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
// regenerator-babel/ast-types // regenerator-babel/ast-types
var types = require("ast-types");
var def = types.Type.def; var def = types.Type.def;
var or = types.Type.or; var or = types.Type.or;

View File

@@ -3,5 +3,5 @@ if (global._babelPolyfill) {
} }
global._babelPolyfill = true; global._babelPolyfill = true;
require("core-js/shim"); import "core-js/shim";
require("regenerator-babel/runtime"); import "regenerator-babel/runtime";

View File

@@ -1,423 +1,18 @@
module.exports = File; import sourceMapToComment from "source-map-to-comment";
import shebangRegex from "shebang-regex";
var sourceMapToComment = require("source-map-to-comment"); import isFunction from "lodash/lang/isFunction";
var shebangRegex = require("shebang-regex"); import transform from "./index";
var isFunction = require("lodash/lang/isFunction"); import generate from "../generation";
var transform = require("./index"); import defaults from "lodash/object/defaults";
var generate = require("../generation"); import includes from "lodash/collection/includes";
var defaults = require("lodash/object/defaults"); import assign from "lodash/object/assign";
var includes = require("lodash/collection/includes"); import parse from "../helpers/parse";
var assign = require("lodash/object/assign"); import Scope from "../traversal/scope";
var parse = require("../helpers/parse"); import slash from "slash";
var Scope = require("../traversal/scope"); import * as util from "../util";
var slash = require("slash"); import path from "path";
var util = require("../util"); import each from "lodash/collection/each";
var path = require("path"); import t from "../types";
var each = require("lodash/collection/each");
var t = require("../types");
function File(opts) {
this.dynamicImportedNoDefault = [];
this.dynamicImportIds = {};
this.dynamicImported = [];
this.dynamicImports = [];
this.usedHelpers = {};
this.dynamicData = {};
this.data = {};
this.lastStatements = [];
this.opts = this.normalizeOptions(opts);
this.ast = {};
this.buildTransformers();
}
File.helpers = [
"inherits",
"defaults",
"prototype-properties",
"apply-constructor",
"tagged-template-literal",
"tagged-template-literal-loose",
"interop-require",
"to-array",
"to-consumable-array",
"sliced-to-array",
"object-without-properties",
"has-own",
"slice",
"bind",
"define-property",
"async-to-generator",
"interop-require-wildcard",
"typeof",
"extends",
"get",
"set",
"class-call-check",
"object-destructuring-empty",
"temporal-undefined",
"temporal-assert-defined",
"self-global"
];
File.validOptions = [
"filename",
"filenameRelative",
"blacklist",
"whitelist",
"loose",
"optional",
"modules",
"sourceMap",
"sourceMapName",
"sourceFileName",
"sourceRoot",
"moduleRoot",
"moduleIds",
"comments",
"reactCompat",
"keepModuleIdExtensions",
"code",
"ast",
"playground",
"experimental",
"externalHelpers",
"auxiliaryComment",
"compact",
"returnUsedHelpers",
"resolveModuleSource",
"moduleId",
// legacy
"format",
// these are used by plugins
"ignore",
"only",
"extensions",
"accept"
];
File.prototype.normalizeOptions = function (opts) {
opts = assign({}, opts);
for (var key in opts) {
if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) {
throw new ReferenceError("Unknown option: " + key);
}
}
defaults(opts, {
keepModuleIdExtensions: false,
resolveModuleSource: null,
returnUsedHelpers: false,
externalHelpers: false,
auxilaryComment: "",
experimental: false,
reactCompat: false,
playground: false,
moduleIds: false,
blacklist: [],
whitelist: [],
sourceMap: false,
optional: [],
comments: true,
filename: "unknown",
modules: "common",
compact: "auto",
loose: [],
code: true,
ast: true
});
// normalize windows path separators to unix
opts.filename = slash(opts.filename);
if (opts.sourceRoot) {
opts.sourceRoot = slash(opts.sourceRoot);
}
if (opts.moduleId) {
opts.moduleIds = true;
}
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
opts.blacklist = util.arrayify(opts.blacklist);
opts.whitelist = util.arrayify(opts.whitelist);
opts.optional = util.arrayify(opts.optional);
opts.compact = util.booleanify(opts.compact);
opts.loose = util.arrayify(opts.loose);
if (includes(opts.loose, "all") || includes(opts.loose, true)) {
opts.loose = Object.keys(transform.transformers);
}
defaults(opts, {
moduleRoot: opts.sourceRoot
});
defaults(opts, {
sourceRoot: opts.moduleRoot
});
defaults(opts, {
filenameRelative: opts.filename
});
defaults(opts, {
sourceFileName: opts.filenameRelative,
sourceMapName: opts.filenameRelative
});
if (opts.playground) {
opts.experimental = true;
}
if (opts.externalHelpers) {
this.set("helpersNamespace", t.identifier("babelHelpers"));
}
opts.blacklist = transform._ensureTransformerNames("blacklist", opts.blacklist);
opts.whitelist = transform._ensureTransformerNames("whitelist", opts.whitelist);
opts.optional = transform._ensureTransformerNames("optional", opts.optional);
opts.loose = transform._ensureTransformerNames("loose", opts.loose);
if (opts.reactCompat) {
opts.optional.push("reactCompat");
console.error("The reactCompat option has been moved into the optional transformer `reactCompat`");
}
var ensureEnabled = function (key) {
var namespace = transform.transformerNamespaces[key];
if (namespace === "es7") opts.experimental = true;
if (namespace === "playground") opts.playground = true;
};
each(opts.whitelist, ensureEnabled);
each(opts.optional, ensureEnabled);
return opts;
};
File.prototype.isLoose = function (key) {
return includes(this.opts.loose, key);
};
File.prototype.buildTransformers = function () {
var file = this;
var transformers = {};
var secondaryStack = [];
var stack = [];
each(transform.transformers, function (transformer, key) {
var pass = transformers[key] = transformer.buildPass(file);
if (pass.canRun(file)) {
stack.push(pass);
if (transformer.secondPass) {
secondaryStack.push(pass);
}
if (transformer.manipulateOptions) {
transformer.manipulateOptions(file.opts, file);
}
}
});
this.transformerStack = stack.concat(secondaryStack);
this.transformers = transformers;
};
File.prototype.debug = function (msg) {
var parts = this.opts.filename;
if (msg) parts += ": " + msg;
util.debug(parts);
};
File.prototype.getModuleFormatter = function (type) {
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
if (!ModuleFormatter) {
var loc = util.resolve(type);
if (loc) ModuleFormatter = require(loc);
}
if (!ModuleFormatter) {
throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type));
}
return new ModuleFormatter(this);
};
File.prototype.parseShebang = function (code) {
var shebangMatch = shebangRegex.exec(code);
if (shebangMatch) {
this.shebang = shebangMatch[0];
// remove shebang
code = code.replace(shebangRegex, "");
}
return code;
};
File.prototype.set = function (key, val) {
return this.data[key] = val;
};
File.prototype.setDynamic = function (key, fn) {
this.dynamicData[key] = fn;
};
File.prototype.get = function (key) {
var data = this.data[key];
if (data) {
return data;
} else {
var dynamic = this.dynamicData[key];
if (dynamic) {
return this.set(key, dynamic());
}
}
};
File.prototype.addImport = function (source, name, noDefault) {
name ||= source;
var id = this.dynamicImportIds[name];
if (!id) {
id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(name);
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
var declar = t.importDeclaration(specifiers, t.literal(source));
declar._blockHoist = 3;
this.dynamicImported.push(declar);
if (noDefault) this.dynamicImportedNoDefault.push(declar);
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
}
return id;
};
File.prototype.isConsequenceExpressionStatement = function (node) {
return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0;
};
File.prototype.attachAuxiliaryComment = function (node) {
var comment = this.opts.auxiliaryComment;
if (comment) {
node.leadingComments ||= [];
node.leadingComments.push({
type: "Line",
value: " " + comment
});
}
return node;
};
File.prototype.addHelper = function (name) {
if (!includes(File.helpers, name)) {
throw new ReferenceError("Unknown helper " + name);
}
var program = this.ast.program;
var declar = program._declarations && program._declarations[name];
if (declar) return declar.id;
this.usedHelpers[name] = true;
var runtime = this.get("helpersNamespace");
if (runtime) {
name = t.identifier(t.toIdentifier(name));
return t.memberExpression(runtime, name);
} else {
var ref = util.template(name);
ref._compact = true;
var uid = this.scope.generateUidIdentifier(name);
this.scope.push({
key: name,
id: uid,
init: ref
});
return uid;
}
};
File.prototype.logDeopt = function () {
// todo, (node, msg)
};
File.prototype.errorWithNode = function (node, msg, Error) {
Error ||= SyntaxError;
var loc = node.loc.start;
var err = new Error("Line " + loc.line + ": " + msg);
err.loc = loc;
return err;
};
File.prototype.addCode = function (code) {
code = (code || "") + "";
this.code = code;
return this.parseShebang(code);
};
File.prototype.parse = function (code) {
code = this.addCode(code);
var opts = this.opts;
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
opts.strictMode = this.transformers.useStrict.canRun();
return parse(opts, code, (tree) => {
this.transform(tree);
return this.generate();
});
};
File.prototype.transform = function (ast) {
this.debug();
this.ast = ast;
this.lastStatements = t.getLastStatements(ast.program);
this.scope = new Scope(ast.program, ast, null, this);
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
if (modFormatter.init && this.transformers["es6.modules"].canRun()) {
modFormatter.init();
}
this.checkNode(ast);
this.call("pre");
each(this.transformerStack, function (pass) {
pass.transform();
});
this.call("post");
};
File.prototype.call = function (key) {
var stack = this.transformerStack;
for (var i = 0; i < stack.length; i++) {
var transformer = stack[i].transformer;
if (transformer[key]) {
transformer[key](this);
}
}
};
var checkTransformerVisitor = { var checkTransformerVisitor = {
enter(node, parent, scope, state) { enter(node, parent, scope, state) {
@@ -425,54 +20,457 @@ var checkTransformerVisitor = {
} }
}; };
var checkNode = function (stack, node, scope) { function checkNode(stack, node, scope) {
each(stack, function (pass) { each(stack, function (pass) {
if (pass.shouldRun) return; if (pass.shouldRun) return;
pass.checkNode(node, scope); pass.checkNode(node, scope);
}); });
}; }
File.prototype.checkNode = function (node, scope) { export default class File {
var stack = this.transformerStack; constructor(opts) {
scope ||= this.scope; this.dynamicImportedNoDefault = [];
this.dynamicImportIds = {};
this.dynamicImported = [];
this.dynamicImports = [];
checkNode(stack, node, scope); this.usedHelpers = {};
this.dynamicData = {};
this.data = {};
scope.traverse(node, checkTransformerVisitor, { this.lastStatements = [];
stack: stack this.opts = this.normalizeOptions(opts);
}); this.ast = {};
};
File.prototype.generate = function () { this.buildTransformers();
var opts = this.opts; }
var ast = this.ast;
var result = { static helpers = [
code: "", "inherits",
map: null, "defaults",
ast: null "prototype-properties",
"apply-constructor",
"tagged-template-literal",
"tagged-template-literal-loose",
"interop-require",
"to-array",
"to-consumable-array",
"sliced-to-array",
"object-without-properties",
"has-own",
"slice",
"bind",
"define-property",
"async-to-generator",
"interop-require-wildcard",
"typeof",
"extends",
"get",
"set",
"class-call-check",
"object-destructuring-empty",
"temporal-undefined",
"temporal-assert-defined",
"self-global"
];
static validOptions = [
"filename",
"filenameRelative",
"blacklist",
"whitelist",
"loose",
"optional",
"modules",
"sourceMap",
"sourceMapName",
"sourceFileName",
"sourceRoot",
"moduleRoot",
"moduleIds",
"comments",
"reactCompat",
"keepModuleIdExtensions",
"code",
"ast",
"playground",
"experimental",
"externalHelpers",
"auxiliaryComment",
"compact",
"returnUsedHelpers",
"resolveModuleSource",
"moduleId",
// legacy
"format",
// these are used by plugins
"ignore",
"only",
"extensions",
"accept"
];
normalizeOptions(opts) {
opts = assign({}, opts);
for (var key in opts) {
if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) {
throw new ReferenceError("Unknown option: " + key);
}
}
defaults(opts, {
keepModuleIdExtensions: false,
resolveModuleSource: null,
returnUsedHelpers: false,
externalHelpers: false,
auxilaryComment: "",
experimental: false,
reactCompat: false,
playground: false,
moduleIds: false,
blacklist: [],
whitelist: [],
sourceMap: false,
optional: [],
comments: true,
filename: "unknown",
modules: "common",
compact: "auto",
loose: [],
code: true,
ast: true
});
// normalize windows path separators to unix
opts.filename = slash(opts.filename);
if (opts.sourceRoot) {
opts.sourceRoot = slash(opts.sourceRoot);
}
if (opts.moduleId) {
opts.moduleIds = true;
}
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
opts.blacklist = util.arrayify(opts.blacklist);
opts.whitelist = util.arrayify(opts.whitelist);
opts.optional = util.arrayify(opts.optional);
opts.compact = util.booleanify(opts.compact);
opts.loose = util.arrayify(opts.loose);
if (includes(opts.loose, "all") || includes(opts.loose, true)) {
opts.loose = Object.keys(transform.transformers);
}
defaults(opts, {
moduleRoot: opts.sourceRoot
});
defaults(opts, {
sourceRoot: opts.moduleRoot
});
defaults(opts, {
filenameRelative: opts.filename
});
defaults(opts, {
sourceFileName: opts.filenameRelative,
sourceMapName: opts.filenameRelative
});
if (opts.playground) {
opts.experimental = true;
}
if (opts.externalHelpers) {
this.set("helpersNamespace", t.identifier("babelHelpers"));
}
opts.blacklist = transform._ensureTransformerNames("blacklist", opts.blacklist);
opts.whitelist = transform._ensureTransformerNames("whitelist", opts.whitelist);
opts.optional = transform._ensureTransformerNames("optional", opts.optional);
opts.loose = transform._ensureTransformerNames("loose", opts.loose);
if (opts.reactCompat) {
opts.optional.push("reactCompat");
console.error("The reactCompat option has been moved into the optional transformer `reactCompat`");
}
var ensureEnabled = function (key) {
var namespace = transform.transformerNamespaces[key];
if (namespace === "es7") opts.experimental = true;
if (namespace === "playground") opts.playground = true;
};
each(opts.whitelist, ensureEnabled);
each(opts.optional, ensureEnabled);
return opts;
}; };
if (this.opts.returnUsedHelpers) { isLoose(key) {
result.usedHelpers = Object.keys(this.usedHelpers); return includes(this.opts.loose, key);
} }
if (opts.ast) result.ast = ast; buildTransformers() {
if (!opts.code) return result; var file = this;
var _result = generate(ast, opts, this.code); var transformers = {};
result.code = _result.code;
result.map = _result.map;
if (this.shebang) { var secondaryStack = [];
// add back shebang var stack = [];
result.code = this.shebang + "\n" + result.code;
each(transform.transformers, function (transformer, key) {
var pass = transformers[key] = transformer.buildPass(file);
if (pass.canRun(file)) {
stack.push(pass);
if (transformer.secondPass) {
secondaryStack.push(pass);
}
if (transformer.manipulateOptions) {
transformer.manipulateOptions(file.opts, file);
}
}
});
this.transformerStack = stack.concat(secondaryStack);
this.transformers = transformers;
} }
if (opts.sourceMap === "inline") { debug(msg) {
result.code += "\n" + sourceMapToComment(result.map); var parts = this.opts.filename;
result.map = null; if (msg) parts += ": " + msg;
util.debug(parts);
} }
return result; getModuleFormatter(type) {
}; var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
if (!ModuleFormatter) {
var loc = util.resolve(type);
if (loc) ModuleFormatter = require(loc);
}
if (!ModuleFormatter) {
throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type));
}
return new ModuleFormatter(this);
}
parseShebang(code) {
var shebangMatch = shebangRegex.exec(code);
if (shebangMatch) {
this.shebang = shebangMatch[0];
// remove shebang
code = code.replace(shebangRegex, "");
}
return code;
}
set(key, val) {
return this.data[key] = val;
};
setDynamic(key, fn) {
this.dynamicData[key] = fn;
}
get(key) {
var data = this.data[key];
if (data) {
return data;
} else {
var dynamic = this.dynamicData[key];
if (dynamic) {
return this.set(key, dynamic());
}
}
}
addImport(source, name, noDefault) {
name ||= source;
var id = this.dynamicImportIds[name];
if (!id) {
id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(name);
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
var declar = t.importDeclaration(specifiers, t.literal(source));
declar._blockHoist = 3;
this.dynamicImported.push(declar);
if (noDefault) this.dynamicImportedNoDefault.push(declar);
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
}
return id;
}
isConsequenceExpressionStatement(node) {
return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0;
}
attachAuxiliaryComment(node) {
var comment = this.opts.auxiliaryComment;
if (comment) {
node.leadingComments ||= [];
node.leadingComments.push({
type: "Line",
value: " " + comment
});
}
return node;
}
addHelper(name) {
if (!includes(File.helpers, name)) {
throw new ReferenceError("Unknown helper " + name);
}
var program = this.ast.program;
var declar = program._declarations && program._declarations[name];
if (declar) return declar.id;
this.usedHelpers[name] = true;
var runtime = this.get("helpersNamespace");
if (runtime) {
name = t.identifier(t.toIdentifier(name));
return t.memberExpression(runtime, name);
} else {
var ref = util.template(name);
ref._compact = true;
var uid = this.scope.generateUidIdentifier(name);
this.scope.push({
key: name,
id: uid,
init: ref
});
return uid;
}
}
logDeopt() {
// todo, (node, msg)
}
errorWithNode(node, msg, Error = SyntaxError) {
var loc = node.loc.start;
var err = new Error("Line " + loc.line + ": " + msg);
err.loc = loc;
return err;
}
addCode(code) {
code = (code || "") + "";
this.code = code;
return this.parseShebang(code);
}
parse(code) {
code = this.addCode(code);
var opts = this.opts;
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
opts.strictMode = this.transformers.useStrict.canRun();
return parse(opts, code, (tree) => {
this.transform(tree);
return this.generate();
});
}
transform(ast) {
this.debug();
this.ast = ast;
this.lastStatements = t.getLastStatements(ast.program);
this.scope = new Scope(ast.program, ast, null, this);
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
if (modFormatter.init && this.transformers["es6.modules"].canRun()) {
modFormatter.init();
}
this.checkNode(ast);
this.call("pre");
each(this.transformerStack, function (pass) {
pass.transform();
});
this.call("post");
}
call(key) {
var stack = this.transformerStack;
for (var i = 0; i < stack.length; i++) {
var transformer = stack[i].transformer;
if (transformer[key]) {
transformer[key](this);
}
}
}
checkNode(node, scope) {
var stack = this.transformerStack;
scope ||= this.scope;
checkNode(stack, node, scope);
scope.traverse(node, checkTransformerVisitor, {
stack: stack
});
}
generate() {
var opts = this.opts;
var ast = this.ast;
var result = {
code: "",
map: null,
ast: null
};
if (this.opts.returnUsedHelpers) {
result.usedHelpers = Object.keys(this.usedHelpers);
}
if (opts.ast) result.ast = ast;
if (!opts.code) return result;
var _result = generate(ast, opts, this.code);
result.code = _result.code;
result.map = _result.map;
if (this.shebang) {
// add back shebang
result.code = this.shebang + "\n" + result.code;
}
if (opts.sourceMap === "inline") {
result.code += "\n" + sourceMapToComment(result.map);
result.map = null;
}
return result;
}
}

View File

@@ -1,5 +1,5 @@
var explode = require("./explode-assignable-expression"); import explode from "./explode-assignable-expression";
var t = require("../../types"); import t from "../../types";
module.exports = function (exports, opts) { module.exports = function (exports, opts) {
var isAssignment = function (node) { var isAssignment = function (node) {

View File

@@ -1,4 +1,4 @@
var t = require("../../types"); import t from "../../types";
module.exports = function build(node, buildBody) { module.exports = function build(node, buildBody) {
var self = node.blocks.shift(); var self = node.blocks.shift();

View File

@@ -1,5 +1,5 @@
var explode = require("./explode-assignable-expression"); import explode from "./explode-assignable-expression";
var t = require("../../types"); import t from "../../types";
module.exports = function (exports, opts) { module.exports = function (exports, opts) {
var buildAssignment = function (left, right) { var buildAssignment = function (left, right) {

View File

@@ -3,11 +3,11 @@
// jsx // jsx
var isString = require("lodash/lang/isString"); import isString from "lodash/lang/isString";
var messages = require("../../messages"); import * as messages from "../../messages";
var esutils = require("esutils"); import esutils from "esutils";
var react = require("./react"); import * as react from "./react";
var t = require("../../types"); import t from "../../types";
module.exports = function (exports, opts) { module.exports = function (exports, opts) {
exports.check = function (node) { exports.check = function (node) {

View File

@@ -1,11 +1,11 @@
var cloneDeep = require("lodash/lang/cloneDeep"); import cloneDeep from "lodash/lang/cloneDeep";
var traverse = require("../../traversal"); import traverse from "../../traversal";
var clone = require("lodash/lang/clone"); import clone from "lodash/lang/clone";
var each = require("lodash/collection/each"); import each from "lodash/collection/each";
var has = require("lodash/object/has"); import has from "lodash/object/has";
var t = require("../../types"); import t from "../../types";
exports.push = function (mutatorMap, key, kind, computed, value) { export function push(mutatorMap, key, kind, computed, value) {
var alias; var alias;
if (t.isIdentifier(key)) { if (t.isIdentifier(key)) {
@@ -31,9 +31,9 @@ exports.push = function (mutatorMap, key, kind, computed, value) {
} }
map[kind] = value; map[kind] = value;
}; }
exports.build = function (mutatorMap) { export function build(mutatorMap) {
var objExpr = t.objectExpression([]); var objExpr = t.objectExpression([]);
each(mutatorMap, function (map) { each(mutatorMap, function (map) {
@@ -70,4 +70,4 @@ exports.build = function (mutatorMap) {
}); });
return objExpr; return objExpr;
}; }

View File

@@ -1,4 +1,4 @@
var t = require("../../types"); import t from "../../types";
var getObjRef = function (node, nodes, file, scope) { var getObjRef = function (node, nodes, file, scope) {
var ref; var ref;

View File

@@ -1,4 +1,4 @@
var t = require("../../types"); import t from "../../types";
module.exports = function (node) { module.exports = function (node) {
var lastNonDefault = 0; var lastNonDefault = 0;

View File

@@ -1,6 +1,6 @@
var getFunctionArity = require("./get-function-arity"); import getFunctionArity from "./get-function-arity";
var util = require("../../util"); import * as util from "../../util";
var t = require("../../types"); import t from "../../types";
var visitor = { var visitor = {
enter(node, parent, scope, state) { enter(node, parent, scope, state) {
@@ -49,7 +49,7 @@ var visit = function (node, name, scope) {
selfReference: false, selfReference: false,
outerDeclar: scope.getBindingIdentifier(name), outerDeclar: scope.getBindingIdentifier(name),
references: [], references: [],
name: name, name: name
}; };
// check to see if we have a local binding of the id we're setting inside of // check to see if we have a local binding of the id we're setting inside of
@@ -89,7 +89,7 @@ var visit = function (node, name, scope) {
return state; return state;
}; };
exports.property = function (node, file, scope) { export function property(node, file, scope) {
var key = t.toComputedKey(node, node.key); var key = t.toComputedKey(node, node.key);
if (!t.isLiteral(key)) return node; // we can't set a function id with this if (!t.isLiteral(key)) return node; // we can't set a function id with this
@@ -99,9 +99,9 @@ exports.property = function (node, file, scope) {
var method = node.value; var method = node.value;
var state = visit(method, name, scope); var state = visit(method, name, scope);
node.value = wrap(state, method, id, scope); node.value = wrap(state, method, id, scope);
}; }
exports.bare = function (node, parent, scope) { export function bare(node, parent, scope) {
// has an `id` so we don't need to infer one // has an `id` so we don't need to infer one
if (node.id) return; if (node.id) return;
@@ -123,4 +123,4 @@ exports.bare = function (node, parent, scope) {
var state = visit(node, name, scope); var state = visit(node, name, scope);
return wrap(state, node, id, scope); return wrap(state, node, id, scope);
}; }

View File

@@ -1,8 +1,8 @@
var t = require("../../types"); import t from "../../types";
var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass"); var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass");
exports.isCreateClass = function (node) { export function isCreateClass(node) {
if (!node || !t.isCallExpression(node)) return false; if (!node || !t.isCallExpression(node)) return false;
// not React.createClass call member object // not React.createClass call member object
@@ -17,10 +17,10 @@ exports.isCreateClass = function (node) {
if (!t.isObjectExpression(first)) return false; if (!t.isObjectExpression(first)) return false;
return true; return true;
}; }
exports.isReactComponent = t.buildMatchMemberExpression("React.Component"); export var isReactComponent = t.buildMatchMemberExpression("React.Component");
exports.isCompatTag = function (tagName) { export function isCompatTag(tagName) {
return tagName && /^[a-z]|\-/.test(tagName); return tagName && /^[a-z]|\-/.test(tagName);
}; }

View File

@@ -0,0 +1,13 @@
import pull from "lodash/array/pull";
import t from "../../types";
export function is(node, flag) {
return t.isLiteral(node) && node.regex && node.regex.flags.indexOf(flag) >= 0;
}
export function pullFlag(node, flag) {
var flags = node.regex.flags.split("");
if (node.regex.flags.indexOf("u") < 0) return;
pull(flags, "u");
node.regex.flags = flags.join("");
}

View File

@@ -1,4 +1,4 @@
var t = require("../../types"); import t from "../../types";
var visitor = { var visitor = {
enter(node) { enter(node) {

View File

@@ -1,97 +1,19 @@
module.exports = ReplaceSupers; module.exports = ReplaceSupers;
var messages = require("../../messages"); import * as messages from "../../messages";
var t = require("../../types"); import t from "../../types";
/**
* Description
*
* @param {Object} opts
* @param {Boolean} [inClass]
*/
function ReplaceSupers(opts, inClass) { function isIllegalBareSuper(node, parent) {
this.topLevelThisReference = opts.topLevelThisReference; if (!isSuper(node, parent)) return false;
this.methodNode = opts.methodNode; if (t.isMemberExpression(parent, { computed: false })) return false;
this.className = opts.className; if (t.isCallExpression(parent, { callee: node })) return false;
this.superName = opts.superName; return true;
this.isStatic = opts.isStatic;
this.hasSuper = false;
this.inClass = inClass;
this.isLoose = opts.isLoose;
this.scope = opts.scope;
this.file = opts.file;
} }
/** function isSuper(node, parent) {
* Sets a super class value of the named property. return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent);
* }
* @example
*
* _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this)
*
* @param {Node} property
* @param {Node} value
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
ReplaceSupers.prototype.setSuperProperty = function (property, value, isComputed, thisExpression) {
return t.callExpression(
this.file.addHelper("set"),
[
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
value,
thisExpression
]
);
};
/**
* Gets a node representing the super class value of the named property.
*
* @example
*
* _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
*
* @param {Node} property
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
ReplaceSupers.prototype.getSuperProperty = function (property, isComputed, thisExpression) {
return t.callExpression(
this.file.addHelper("get"),
[
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
thisExpression
]
);
};
/**
* Description
*/
ReplaceSupers.prototype.replace = function () {
this.traverseLevel(this.methodNode.value, true);
};
var visitor = { var visitor = {
enter(node, parent, scope, state) { enter(node, parent, scope, state) {
@@ -121,181 +43,263 @@ var visitor = {
} }
}; };
/** export default class ReplaceSupers {
* Description
*
* @param {Object} node
* @param {Boolean} topLevel
*/
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) { /**
var state = { self: this, topLevel: topLevel }; * Description
this.scope.traverse(node, visitor, state); *
}; * @param {Object} opts
* @param {Boolean} [inClass]
*/
/** constructor(opts, inClass) {
* Description this.topLevelThisReference = opts.topLevelThisReference;
*/ this.methodNode = opts.methodNode;
this.className = opts.className;
ReplaceSupers.prototype.getThisReference = function () { this.superName = opts.superName;
if (this.topLevelThisReference) { this.isStatic = opts.isStatic;
return this.topLevelThisReference; this.hasSuper = false;
} else { this.inClass = inClass;
var ref = this.topLevelThisReference = this.scope.generateUidIdentifier("this"); this.isLoose = opts.isLoose;
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [ this.scope = opts.scope;
t.variableDeclarator(this.topLevelThisReference, t.thisExpression()) this.file = opts.file;
]));
return ref;
} }
};
/** /**
* Description * Sets a super class value of the named property.
* *
* @param {Object} node * @example
* @param {Object} id *
* @param {Object} parent * _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this)
* @returns {Object} *
*/ * @param {Node} property
* @param {Node} value
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
ReplaceSupers.prototype.getLooseSuperProperty = function (id, parent) { setSuperProperty(property, value, isComputed, thisExpression) {
var methodNode = this.methodNode; return t.callExpression(
var methodName = methodNode.key; this.file.addHelper("set"),
var superName = this.superName || t.identifier("Function"); [
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
value,
thisExpression
]
);
}
if (parent.property === id) { /**
return; * Gets a node representing the super class value of the named property.
} else if (t.isCallExpression(parent, { callee: id })) { *
// super(); -> ClassName.prototype.MethodName.call(this); * @example
parent.arguments.unshift(t.thisExpression()); *
* _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
*
* @param {Node} property
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
if (methodName.name === "constructor") { getSuperProperty(property, isComputed, thisExpression) {
// constructor() { super(); } return t.callExpression(
return t.memberExpression(superName, t.identifier("call")); this.file.addHelper("get"),
[
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
thisExpression
]
);
}
/**
* Description
*/
replace() {
this.traverseLevel(this.methodNode.value, true);
}
/**
* Description
*
* @param {Object} node
* @param {Boolean} topLevel
*/
traverseLevel(node, topLevel) {
var state = { self: this, topLevel: topLevel };
this.scope.traverse(node, visitor, state);
}
/**
* Description
*/
getThisReference() {
if (this.topLevelThisReference) {
return this.topLevelThisReference;
} else { } else {
id = superName; var ref = this.topLevelThisReference = this.scope.generateUidIdentifier("this");
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
// foo() { super(); } t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
if (!methodNode.static) { ]));
id = t.memberExpression(id, t.identifier("prototype")); return ref;
}
id = t.memberExpression(id, methodName, methodNode.computed);
return t.memberExpression(id, t.identifier("call"));
} }
} else if (t.isMemberExpression(parent) && !methodNode.static) {
// super.test -> ClassName.prototype.test
return t.memberExpression(superName, t.identifier("prototype"));
} else {
return superName;
}
};
/**
* Description
*
* @param {Function} getThisReference
* @param {Object} node
* @param {Object} parent
*/
ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) {
if (t.isIdentifier(node, { name: "super" })) {
this.hasSuper = true;
return this.getLooseSuperProperty(node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
// super.test(); -> ClassName.prototype.MethodName.call(this);
this.hasSuper = true;
t.appendToMemberExpression(callee, t.identifier("call"));
node.arguments.unshift(getThisReference());
}
};
/**
* Description
*
* @param {Function} getThisReference
* @param {Object} node
* @param {Object} parent
*/
ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
var methodNode = this.methodNode;
var property;
var computed;
var args;
var thisReference;
if (isIllegalBareSuper(node, parent)) {
throw this.file.errorWithNode(node, messages.get("classesIllegalBareSuper"));
} }
if (t.isCallExpression(node)) { /**
var callee = node.callee; * Description
if (isSuper(callee, node)) { *
// super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this); * @param {Object} node
property = methodNode.key; * @param {Object} id
computed = methodNode.computed; * @param {Object} parent
args = node.arguments; * @returns {Object}
*/
// bare `super` call is illegal inside non-constructors getLooseSuperProperty(id, parent) {
// - https://esdiscuss.org/topic/super-call-in-methods var methodNode = this.methodNode;
// - https://twitter.com/wycats/status/544553184396836864 var methodName = methodNode.key;
if (methodNode.key.name !== "constructor" || !this.inClass) { var superName = this.superName || t.identifier("Function");
var methodName = methodNode.key.name || "METHOD_NAME";
throw this.file.errorWithNode(node, messages.get("classesIllegalSuperCall", methodName)); if (parent.property === id) {
return;
} else if (t.isCallExpression(parent, { callee: id })) {
// super(); -> ClassName.prototype.MethodName.call(this);
parent.arguments.unshift(t.thisExpression());
if (methodName.name === "constructor") {
// constructor() { super(); }
return t.memberExpression(superName, t.identifier("call"));
} else {
id = superName;
// foo() { super(); }
if (!methodNode.static) {
id = t.memberExpression(id, t.identifier("prototype"));
}
id = t.memberExpression(id, methodName, methodNode.computed);
return t.memberExpression(id, t.identifier("call"));
} }
} else if (t.isMemberExpression(callee) && isSuper(callee.object, callee)) { } else if (t.isMemberExpression(parent) && !methodNode.static) {
// super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this); // super.test -> ClassName.prototype.test
property = callee.property; return t.memberExpression(superName, t.identifier("prototype"));
computed = callee.computed;
args = node.arguments;
}
} else if (t.isMemberExpression(node) && isSuper(node.object, node)) {
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
property = node.property;
computed = node.computed;
} else if (t.isAssignmentExpression(node) && isSuper(node.left.object, node.left) && methodNode.kind === "set") {
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
this.hasSuper = true;
return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference());
}
if (!property) return;
this.hasSuper = true;
thisReference = getThisReference();
var superProperty = this.getSuperProperty(property, computed, thisReference);
if (args) {
if (args.length === 1 && t.isSpreadElement(args[0])) {
// super(...arguments);
return t.callExpression(
t.memberExpression(superProperty, t.identifier("apply")),
[thisReference, args[0].argument]
);
} else { } else {
return t.callExpression( return superName;
t.memberExpression(superProperty, t.identifier("call")),
[thisReference].concat(args)
);
} }
} else {
return superProperty;
} }
};
var isIllegalBareSuper = function (node, parent) { /**
if (!isSuper(node, parent)) return false; * Description
if (t.isMemberExpression(parent, { computed: false })) return false; *
if (t.isCallExpression(parent, { callee: node })) return false; * @param {Function} getThisReference
return true; * @param {Object} node
}; * @param {Object} parent
*/
var isSuper = function (node, parent) { looseHandle(getThisReference, node, parent) {
return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent); if (t.isIdentifier(node, { name: "super" })) {
}; this.hasSuper = true;
return this.getLooseSuperProperty(node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
// super.test(); -> ClassName.prototype.MethodName.call(this);
this.hasSuper = true;
t.appendToMemberExpression(callee, t.identifier("call"));
node.arguments.unshift(getThisReference());
}
}
/**
* Description
*
* @param {Function} getThisReference
* @param {Object} node
* @param {Object} parent
*/
specHandle(getThisReference, node, parent) {
var methodNode = this.methodNode;
var property;
var computed;
var args;
var thisReference;
if (isIllegalBareSuper(node, parent)) {
throw this.file.errorWithNode(node, messages.get("classesIllegalBareSuper"));
}
if (t.isCallExpression(node)) {
var callee = node.callee;
if (isSuper(callee, node)) {
// super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
property = methodNode.key;
computed = methodNode.computed;
args = node.arguments;
// bare `super` call is illegal inside non-constructors
// - https://esdiscuss.org/topic/super-call-in-methods
// - https://twitter.com/wycats/status/544553184396836864
if (methodNode.key.name !== "constructor" || !this.inClass) {
var methodName = methodNode.key.name || "METHOD_NAME";
throw this.file.errorWithNode(node, messages.get("classesIllegalSuperCall", methodName));
}
} else if (t.isMemberExpression(callee) && isSuper(callee.object, callee)) {
// super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
property = callee.property;
computed = callee.computed;
args = node.arguments;
}
} else if (t.isMemberExpression(node) && isSuper(node.object, node)) {
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
property = node.property;
computed = node.computed;
} else if (t.isAssignmentExpression(node) && isSuper(node.left.object, node.left) && methodNode.kind === "set") {
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
this.hasSuper = true;
return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference());
}
if (!property) return;
this.hasSuper = true;
thisReference = getThisReference();
var superProperty = this.getSuperProperty(property, computed, thisReference);
if (args) {
if (args.length === 1 && t.isSpreadElement(args[0])) {
// super(...arguments);
return t.callExpression(
t.memberExpression(superProperty, t.identifier("apply")),
[thisReference, args[0].argument]
);
} else {
return t.callExpression(
t.memberExpression(superProperty, t.identifier("call")),
[thisReference, ...args]
);
}
} else {
return superProperty;
}
}
}

View File

@@ -1,11 +1,11 @@
var t = require("../../types"); import t from "../../types";
exports.has = function (node) { export function has(node) {
var first = node.body[0]; var first = node.body[0];
return t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" }); return t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" });
}; }
exports.wrap = function (node, callback) { export function wrap(node, callback) {
var useStrictNode; var useStrictNode;
if (exports.has(node)) { if (exports.has(node)) {
useStrictNode = node.body.shift(); useStrictNode = node.body.shift();
@@ -16,4 +16,4 @@ exports.wrap = function (node, callback) {
if (useStrictNode) { if (useStrictNode) {
node.body.unshift(useStrictNode); node.body.unshift(useStrictNode);
} }
}; }

View File

@@ -1,12 +1,10 @@
module.exports = transform; import normalizeAst from "../helpers/normalize-ast";
import Transformer from "./transformer";
import object from "../helpers/object";
import File from "./file";
import each from "lodash/collection/each";
var normalizeAst = require("../helpers/normalize-ast"); export default function transform(code, opts) {
var Transformer = require("./transformer");
var object = require("../helpers/object");
var File = require("./file");
var each = require("lodash/collection/each");
function transform(code, opts) {
var file = new File(opts); var file = new File(opts);
return file.parse(code); return file.parse(code);
} }
@@ -53,7 +51,7 @@ transform.namespaces = object();
transform.deprecatedTransformerMap = require("./transformers/deprecated"); transform.deprecatedTransformerMap = require("./transformers/deprecated");
transform.moduleFormatters = require("./modules"); transform.moduleFormatters = require("./modules");
var rawTransformers = require("./transformers"); import rawTransformers from "./transformers";
each(rawTransformers, function (transformer, key) { each(rawTransformers, function (transformer, key) {
var namespace = key.split(".")[0]; var namespace = key.split(".")[0];

View File

@@ -1,80 +1,8 @@
module.exports = DefaultFormatter; import * as messages from "../../messages";
import extend from "lodash/object/extend";
var messages = require("../../messages"); import object from "../../helpers/object";
var extend = require("lodash/object/extend"); import * as util from "../../util";
var object = require("../../helpers/object"); import t from "../../types";
var util = require("../../util");
var t = require("../../types");
function DefaultFormatter(file) {
this.scope = file.scope;
this.file = file;
this.ids = object();
this.hasNonDefaultExports = false;
this.hasLocalExports = false;
this.hasLocalImports = false;
this.localImportOccurences = object();
this.localExports = object();
this.localImports = object();
this.getLocalExports();
this.getLocalImports();
this.remapAssignments();
}
DefaultFormatter.prototype.doDefaultExportInterop = function (node) {
return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports;
};
DefaultFormatter.prototype.bumpImportOccurences = function (node) {
var source = node.source.value;
var occurs = this.localImportOccurences;
occurs[source] ||= 0;
occurs[source] += node.specifiers.length;
};
var exportsVisitor = {
enter(node, parent, scope, formatter) {
var declar = node && node.declaration;
if (t.isExportDeclaration(node)) {
formatter.hasLocalImports = true;
if (declar && t.isStatement(declar)) {
extend(formatter.localExports, t.getBindingIdentifiers(declar));
}
if (!node.default) {
formatter.hasNonDefaultExports = true;
}
if (node.source) {
formatter.bumpImportOccurences(node);
}
}
}
};
DefaultFormatter.prototype.getLocalExports = function () {
this.file.scope.traverse(this.file.ast, exportsVisitor, this);
};
var importsVisitor = {
enter(node, parent, scope, formatter) {
if (t.isImportDeclaration(node)) {
formatter.hasLocalImports = true;
extend(formatter.localImports, t.getBindingIdentifiers(node));
formatter.bumpImportOccurences(node);
}
}
};
DefaultFormatter.prototype.getLocalImports = function () {
this.file.scope.traverse(this.file.ast, importsVisitor, this);
};
var remapVisitor = { var remapVisitor = {
enter(node, parent, scope, formatter) { enter(node, parent, scope, formatter) {
@@ -113,181 +41,253 @@ var remapVisitor = {
} }
}; };
DefaultFormatter.prototype.remapAssignments = function () { var importsVisitor = {
if (this.hasLocalImports) { enter(node, parent, scope, formatter) {
this.file.scope.traverse(this.file.ast, remapVisitor, this); if (t.isImportDeclaration(node)) {
} formatter.hasLocalImports = true;
}; extend(formatter.localImports, t.getBindingIdentifiers(node));
formatter.bumpImportOccurences(node);
DefaultFormatter.prototype.isLocalReference = function (node) {
var localImports = this.localImports;
return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node;
};
DefaultFormatter.prototype.remapExportAssignment = function (node) {
return t.assignmentExpression(
"=",
node.left,
t.assignmentExpression(
node.operator,
t.memberExpression(t.identifier("exports"), node.left),
node.right
)
);
};
DefaultFormatter.prototype.isLocalReference = function (node, scope) {
var localExports = this.localExports;
var name = node.name;
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name);
};
DefaultFormatter.prototype.getModuleName = function () {
var opts = this.file.opts;
if (opts.moduleId) return opts.moduleId;
var filenameRelative = opts.filenameRelative;
var moduleName = "";
if (opts.moduleRoot) {
moduleName = opts.moduleRoot + "/";
}
if (!opts.filenameRelative) {
return moduleName + opts.filename.replace(/^\//, "");
}
if (opts.sourceRoot) {
// remove sourceRoot from filename
var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
}
if (!opts.keepModuleIdExtensions) {
// remove extension
filenameRelative = filenameRelative.replace(/\.(\w*?)$/, "");
}
moduleName += filenameRelative;
// normalize path separators
moduleName = moduleName.replace(/\\/g, "/");
return moduleName;
};
DefaultFormatter.prototype._pushStatement = function (ref, nodes) {
if (t.isClass(ref) || t.isFunction(ref)) {
if (ref.id) {
nodes.push(t.toStatement(ref));
ref = ref.id;
} }
} }
return ref;
}; };
DefaultFormatter.prototype._hoistExport = function (declar, assign, priority) { var exportsVisitor = {
if (t.isFunctionDeclaration(declar)) { enter(node, parent, scope, formatter) {
assign._blockHoist = priority || 2; var declar = node && node.declaration;
} if (t.isExportDeclaration(node)) {
formatter.hasLocalImports = true;
return assign; if (declar && t.isStatement(declar)) {
}; extend(formatter.localExports, t.getBindingIdentifiers(declar));
DefaultFormatter.prototype.getExternalReference = function (node, nodes) {
var ids = this.ids;
var id = node.source.value;
if (ids[id]) {
return ids[id];
} else {
return this.ids[id] = this._getExternalReference(node, nodes);
}
};
DefaultFormatter.prototype.checkExportIdentifier = function (node) {
if (t.isIdentifier(node, { name: "__esModule" })) {
throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name));
}
};
DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
if (node.source) {
var ref = this.getExternalReference(node, nodes);
if (t.isExportBatchSpecifier(specifier)) {
// export * from "foo";
nodes.push(this.buildExportsWildcard(ref, node));
} else {
if (t.isSpecifierDefault(specifier) && !this.noInteropRequireExport) {
// importing a default so we need to normalize it
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {
ref = t.memberExpression(ref, t.getSpecifierId(specifier));
} }
// export { foo } from "test"; if (!node.default) {
nodes.push(this.buildExportsAssignment( formatter.hasNonDefaultExports = true;
t.getSpecifierName(specifier), }
ref,
node if (node.source) {
)); formatter.bumpImportOccurences(node);
}
} }
} else {
// export { foo };
nodes.push(this.buildExportsAssignment(t.getSpecifierName(specifier), specifier.id, node));
} }
}; };
DefaultFormatter.prototype.buildExportsWildcard = function (objectIdentifier) { export default class DefaultFormatter {
return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [ constructor(file) {
t.identifier("exports"), this.scope = file.scope;
t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier]) this.file = file;
])); this.ids = object();
};
DefaultFormatter.prototype.buildExportsAssignment = function (id, init) { this.hasNonDefaultExports = false;
this.checkExportIdentifier(id);
return util.template("exports-assign", {
VALUE: init,
KEY: id
}, true);
};
DefaultFormatter.prototype.exportDeclaration = function (node, nodes) { this.hasLocalExports = false;
var declar = node.declaration; this.hasLocalImports = false;
var id = declar.id; this.localImportOccurences = object();
this.localExports = object();
this.localImports = object();
if (node.default) { this.getLocalExports();
id = t.identifier("default"); this.getLocalImports();
this.remapAssignments();
} }
var assign; doDefaultExportInterop(node) {
return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports;
if (t.isVariableDeclaration(declar)) {
for (var i = 0; i < declar.declarations.length; i++) {
var decl = declar.declarations[i];
decl.init = this.buildExportsAssignment(decl.id, decl.init, node).expression;
var newDeclar = t.variableDeclaration(declar.kind, [decl]);
if (i === 0) t.inherits(newDeclar, declar);
nodes.push(newDeclar);
}
} else {
var ref = declar;
if (t.isFunctionDeclaration(declar) || t.isClassDeclaration(declar)) {
ref = declar.id;
nodes.push(declar);
}
assign = this.buildExportsAssignment(id, ref, node);
nodes.push(assign);
this._hoistExport(declar, assign);
} }
};
bumpImportOccurences(node) {
var source = node.source.value;
var occurs = this.localImportOccurences;
occurs[source] ||= 0;
occurs[source] += node.specifiers.length;
}
getLocalExports() {
this.file.scope.traverse(this.file.ast, exportsVisitor, this);
}
getLocalImports() {
this.file.scope.traverse(this.file.ast, importsVisitor, this);
}
remapAssignments() {
if (this.hasLocalImports) {
this.file.scope.traverse(this.file.ast, remapVisitor, this);
}
}
isLocalReference(node) {
var localImports = this.localImports;
return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node;
}
remapExportAssignment(node) {
return t.assignmentExpression(
"=",
node.left,
t.assignmentExpression(
node.operator,
t.memberExpression(t.identifier("exports"), node.left),
node.right
)
);
}
isLocalReference(node, scope) {
var localExports = this.localExports;
var name = node.name;
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name);
}
getModuleName() {
var opts = this.file.opts;
if (opts.moduleId) return opts.moduleId;
var filenameRelative = opts.filenameRelative;
var moduleName = "";
if (opts.moduleRoot) {
moduleName = opts.moduleRoot + "/";
}
if (!opts.filenameRelative) {
return moduleName + opts.filename.replace(/^\//, "");
}
if (opts.sourceRoot) {
// remove sourceRoot from filename
var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
}
if (!opts.keepModuleIdExtensions) {
// remove extension
filenameRelative = filenameRelative.replace(/\.(\w*?)$/, "");
}
moduleName += filenameRelative;
// normalize path separators
moduleName = moduleName.replace(/\\/g, "/");
return moduleName;
}
_pushStatement(ref, nodes) {
if (t.isClass(ref) || t.isFunction(ref)) {
if (ref.id) {
nodes.push(t.toStatement(ref));
ref = ref.id;
}
}
return ref;
}
_hoistExport(declar, assign, priority) {
if (t.isFunctionDeclaration(declar)) {
assign._blockHoist = priority || 2;
}
return assign;
}
getExternalReference(node, nodes) {
var ids = this.ids;
var id = node.source.value;
if (ids[id]) {
return ids[id];
} else {
return this.ids[id] = this._getExternalReference(node, nodes);
}
}
checkExportIdentifier(node) {
if (t.isIdentifier(node, { name: "__esModule" })) {
throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name));
}
}
exportSpecifier(specifier, node, nodes) {
if (node.source) {
var ref = this.getExternalReference(node, nodes);
if (t.isExportBatchSpecifier(specifier)) {
// export * from "foo";
nodes.push(this.buildExportsWildcard(ref, node));
} else {
if (t.isSpecifierDefault(specifier) && !this.noInteropRequireExport) {
// importing a default so we need to normalize it
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {
ref = t.memberExpression(ref, t.getSpecifierId(specifier));
}
// export { foo } from "test";
nodes.push(this.buildExportsAssignment(
t.getSpecifierName(specifier),
ref,
node
));
}
} else {
// export { foo };
nodes.push(this.buildExportsAssignment(t.getSpecifierName(specifier), specifier.id, node));
}
}
buildExportsWildcard(objectIdentifier) {
return t.expressionStatement(t.callExpression(this.file.addHelper("defaults"), [
t.identifier("exports"),
t.callExpression(this.file.addHelper("interop-require-wildcard"), [objectIdentifier])
]));
}
buildExportsAssignment(id, init) {
this.checkExportIdentifier(id);
return util.template("exports-assign", {
VALUE: init,
KEY: id
}, true);
}
exportDeclaration(node, nodes) {
var declar = node.declaration;
var id = declar.id;
if (node.default) {
id = t.identifier("default");
}
var assign;
if (t.isVariableDeclaration(declar)) {
for (var i = 0; i < declar.declarations.length; i++) {
var decl = declar.declarations[i];
decl.init = this.buildExportsAssignment(decl.id, decl.init, node).expression;
var newDeclar = t.variableDeclaration(declar.kind, [decl]);
if (i === 0) t.inherits(newDeclar, declar);
nodes.push(newDeclar);
}
} else {
var ref = declar;
if (t.isFunctionDeclaration(declar) || t.isClassDeclaration(declar)) {
ref = declar.id;
nodes.push(declar);
}
assign = this.buildExportsAssignment(id, ref, node);
nodes.push(assign);
this._hoistExport(declar, assign);
}
}
}

View File

@@ -1,6 +1,6 @@
var util = require("../../util"); import * as util from "../../util";
module.exports = function (Parent) { export default function (Parent) {
var Constructor = function () { var Constructor = function () {
this.noInteropRequireImport = true; this.noInteropRequireImport = true;
this.noInteropRequireExport = true; this.noInteropRequireExport = true;

View File

@@ -1,106 +1,100 @@
module.exports = AMDFormatter; import DefaultFormatter from "./_default";
import CommonFormatter from "./common";
import includes from "lodash/collection/includes";
import values from "lodash/object/values";
import * as util from "../../util";
import t from "../../types";
var DefaultFormatter = require("./_default"); export default class AMDFormatter extends DefaultFormatter {
var CommonFormatter = require("./common"); init = CommonFormatter.prototype.init;
var includes = require("lodash/collection/includes");
var values = require("lodash/object/values");
var util = require("../../util");
var t = require("../../types");
function AMDFormatter() { buildDependencyLiterals() {
CommonFormatter.apply(this, arguments); var names = [];
for (var name in this.ids) {
names.push(t.literal(name));
}
return names;
}
/**
* Wrap the entire body in a `define` wrapper.
*/
transform(program) {
var body = program.body;
// build an array of module names
var names = [t.literal("exports")];
if (this.passModuleArg) names.push(t.literal("module"));
names = names.concat(this.buildDependencyLiterals());
names = t.arrayExpression(names);
// build up define container
var params = values(this.ids);
if (this.passModuleArg) params.unshift(t.identifier("module"));
params.unshift(t.identifier("exports"));
var container = t.functionExpression(null, params, t.blockStatement(body));
var defineArgs = [names, container];
var moduleName = this.getModuleName();
if (moduleName) defineArgs.unshift(t.literal(moduleName));
var call = t.callExpression(t.identifier("define"), defineArgs);
program.body = [t.expressionStatement(call)];
}
/**
* Get the AMD module name that we'll prepend to the wrapper
* to define this module
*/
getModuleName() {
if (this.file.opts.moduleIds) {
return DefaultFormatter.prototype.getModuleName.apply(this, arguments);
} else {
return null;
}
}
_getExternalReference(node) {
return this.scope.generateUidIdentifier(node.source.value);
}
importDeclaration(node) {
this.getExternalReference(node);
}
importSpecifier(specifier, node, nodes) {
var key = t.getSpecifierName(specifier);
var ref = this.getExternalReference(node);
if (includes(this.file.dynamicImportedNoDefault, node)) {
// Prevent unnecessary renaming of dynamic imports.
this.ids[node.source.value] = ref;
} else if (t.isImportBatchSpecifier(specifier)) {
// import * as bar from "foo";
} else if (!includes(this.file.dynamicImported, node) && t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) {
// import foo from "foo";
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {
// import {foo} from "foo";
ref = t.memberExpression(ref, t.getSpecifierId(specifier), false);
}
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(key, ref)
]));
}
exportDeclaration(node) {
if (this.doDefaultExportInterop(node)) {
this.passModuleArg = true;
}
CommonFormatter.prototype.exportDeclaration.apply(this, arguments);
}
} }
util.inherits(AMDFormatter, DefaultFormatter);
AMDFormatter.prototype.init = CommonFormatter.prototype.init;
AMDFormatter.prototype.buildDependencyLiterals = function () {
var names = [];
for (var name in this.ids) {
names.push(t.literal(name));
}
return names;
};
/**
* Wrap the entire body in a `define` wrapper.
*/
AMDFormatter.prototype.transform = function (program) {
var body = program.body;
// build an array of module names
var names = [t.literal("exports")];
if (this.passModuleArg) names.push(t.literal("module"));
names = names.concat(this.buildDependencyLiterals());
names = t.arrayExpression(names);
// build up define container
var params = values(this.ids);
if (this.passModuleArg) params.unshift(t.identifier("module"));
params.unshift(t.identifier("exports"));
var container = t.functionExpression(null, params, t.blockStatement(body));
var defineArgs = [names, container];
var moduleName = this.getModuleName();
if (moduleName) defineArgs.unshift(t.literal(moduleName));
var call = t.callExpression(t.identifier("define"), defineArgs);
program.body = [t.expressionStatement(call)];
};
/**
* Get the AMD module name that we'll prepend to the wrapper
* to define this module
*/
AMDFormatter.prototype.getModuleName = function () {
if (this.file.opts.moduleIds) {
return DefaultFormatter.prototype.getModuleName.apply(this, arguments);
} else {
return null;
}
};
AMDFormatter.prototype._getExternalReference = function (node) {
return this.scope.generateUidIdentifier(node.source.value);
};
AMDFormatter.prototype.importDeclaration = function (node) {
this.getExternalReference(node);
};
AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var key = t.getSpecifierName(specifier);
var ref = this.getExternalReference(node);
if (includes(this.file.dynamicImportedNoDefault, node)) {
// Prevent unnecessary renaming of dynamic imports.
this.ids[node.source.value] = ref;
} else if (t.isImportBatchSpecifier(specifier)) {
// import * as bar from "foo";
} else if (!includes(this.file.dynamicImported, node) && t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) {
// import foo from "foo";
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {
// import {foo} from "foo";
ref = t.memberExpression(ref, t.getSpecifierId(specifier), false);
}
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(key, ref)
]));
};
AMDFormatter.prototype.exportDeclaration = function (node) {
if (this.doDefaultExportInterop(node)) {
this.passModuleArg = true;
}
CommonFormatter.prototype.exportDeclaration.apply(this, arguments);
};

View File

@@ -1,104 +1,98 @@
module.exports = CommonJSFormatter; import DefaultFormatter from "./_default";
import includes from "lodash/collection/includes";
import * as util from "../../util";
import t from "../../types";
var DefaultFormatter = require("./_default"); export default class CommonJSFormatter extends DefaultFormatter {
var includes = require("lodash/collection/includes"); init() {
var util = require("../../util"); var file = this.file;
var t = require("../../types"); var scope = file.scope;
function CommonJSFormatter() { scope.rename("module");
DefaultFormatter.apply(this, arguments);
}
util.inherits(CommonJSFormatter, DefaultFormatter); if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
var templateName = "exports-module-declaration";
CommonJSFormatter.prototype.init = function () { if (this.file.isLoose("es6.modules")) templateName += "-loose";
var file = this.file; file.ast.program.body.push(util.template(templateName, true));
var scope = file.scope;
scope.rename("module");
if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
var templateName = "exports-module-declaration";
if (this.file.isLoose("es6.modules")) templateName += "-loose";
file.ast.program.body.push(util.template(templateName, true));
}
};
CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var variableName = t.getSpecifierName(specifier);
var ref = this.getExternalReference(node, nodes);
// import foo from "foo";
if (t.isSpecifierDefault(specifier)) {
if (!includes(this.file.dynamicImportedNoDefault, node)) {
if (this.noInteropRequireImport || includes(this.file.dynamicImported, node)) {
ref = t.memberExpression(ref, t.identifier("default"));
} else {
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
}
} }
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)])); };
} else {
if (specifier.type === "ImportBatchSpecifier") {
if (!this.noInteropRequireImport) { importSpecifier(specifier, node, nodes) {
ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]); var variableName = t.getSpecifierName(specifier);
var ref = this.getExternalReference(node, nodes);
// import foo from "foo";
if (t.isSpecifierDefault(specifier)) {
if (!includes(this.file.dynamicImportedNoDefault, node)) {
if (this.noInteropRequireImport || includes(this.file.dynamicImported, node)) {
ref = t.memberExpression(ref, t.identifier("default"));
} else {
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
}
} }
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)]));
// import * as bar from "foo";
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(variableName, ref)
]));
} else { } else {
// import { foo } from "foo"; if (specifier.type === "ImportBatchSpecifier") {
if (!this.noInteropRequireImport) {
ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]);
}
// import * as bar from "foo";
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(variableName, ref)
]));
} else {
// import { foo } from "foo";
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(
variableName,
t.memberExpression(ref, t.getSpecifierId(specifier))
)
]));
}
}
}
importDeclaration(node, nodes) {
// import "foo";
nodes.push(util.template("require", {
MODULE_NAME: node.source
}, true));
}
exportDeclaration(node, nodes) {
if (this.doDefaultExportInterop(node)) {
var declar = node.declaration;
var assign = util.template("exports-default-assign", {
VALUE: this._pushStatement(declar, nodes)
}, true);
if (t.isFunctionDeclaration(declar)) {
// we can hoist this assignment to the top of the file
assign._blockHoist = 3;
}
nodes.push(assign);
return;
}
DefaultFormatter.prototype.exportDeclaration.apply(this, arguments);
}
_getExternalReference(node, nodes) {
var source = node.source.value;
var call = t.callExpression(t.identifier("require"), [node.source]);
if (this.localImportOccurences[source] > 1) {
var uid = this.scope.generateUidIdentifier(source);
nodes.push(t.variableDeclaration("var", [ nodes.push(t.variableDeclaration("var", [
t.variableDeclarator( t.variableDeclarator(uid, call)
variableName,
t.memberExpression(ref, t.getSpecifierId(specifier))
)
])); ]));
return uid;
} else {
return call;
} }
} }
}; }
CommonJSFormatter.prototype.importDeclaration = function (node, nodes) {
// import "foo";
nodes.push(util.template("require", {
MODULE_NAME: node.source
}, true));
};
CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) {
if (this.doDefaultExportInterop(node)) {
var declar = node.declaration;
var assign = util.template("exports-default-assign", {
VALUE: this._pushStatement(declar, nodes)
}, true);
if (t.isFunctionDeclaration(declar)) {
// we can hoist this assignment to the top of the file
assign._blockHoist = 3;
}
nodes.push(assign);
return;
}
DefaultFormatter.prototype.exportDeclaration.apply(this, arguments);
};
CommonJSFormatter.prototype._getExternalReference = function (node, nodes) {
var source = node.source.value;
var call = t.callExpression(t.identifier("require"), [node.source]);
if (this.localImportOccurences[source] > 1) {
var uid = this.scope.generateUidIdentifier(source);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(uid, call)
]));
return uid;
} else {
return call;
}
};

View File

@@ -1,18 +1,12 @@
module.exports = IgnoreFormatter; import t from "../../types";
var t = require("../../types"); export default class IgnoreFormatter {
exportDeclaration(node, nodes) {
function IgnoreFormatter() { var declar = t.toStatement(node.declaration, true);
if (declar) nodes.push(t.inherits(declar, node));
}
importDeclaration() {}
importSpecifier() {}
exportSpecifier() {}
} }
IgnoreFormatter.prototype.exportDeclaration = function (node, nodes) {
var declar = t.toStatement(node.declaration, true);
if (declar) nodes.push(t.inherits(declar, node));
};
IgnoreFormatter.prototype.importDeclaration =
IgnoreFormatter.prototype.importSpecifier =
IgnoreFormatter.prototype.exportSpecifier = function () {
};

View File

@@ -1,104 +1,10 @@
module.exports = SystemFormatter; import DefaultFormatter from "./_default";
import AMDFormatter from "./amd";
var DefaultFormatter = require("./_default"); import * as util from "../../util";
var AMDFormatter = require("./amd"); import last from "lodash/array/last";
var util = require("../../util"); import each from "lodash/collection/each";
var last = require("lodash/array/last"); import map from "lodash/collection/map";
var each = require("lodash/collection/each"); import t from "../../types";
var map = require("lodash/collection/map");
var t = require("../../types");
function SystemFormatter(file) {
this.exportIdentifier = file.scope.generateUidIdentifier("export");
this.noInteropRequireExport = true;
this.noInteropRequireImport = true;
DefaultFormatter.apply(this, arguments);
}
util.inherits(SystemFormatter, AMDFormatter);
SystemFormatter.prototype.init = function () {};
SystemFormatter.prototype._addImportSource = function (node, exportNode) {
node._importSource = exportNode.source && exportNode.source.value;
return node;
};
SystemFormatter.prototype.buildExportsWildcard = function (objectIdentifier, node) {
var leftIdentifier = this.scope.generateUidIdentifier("key");
var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true);
var left = t.variableDeclaration("var", [
t.variableDeclarator(leftIdentifier)
]);
var right = objectIdentifier;
var block = t.blockStatement([
t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier))
]);
return this._addImportSource(t.forInStatement(left, right, block), node);
};
SystemFormatter.prototype.buildExportsAssignment = function (id, init, node) {
var call = this.buildExportCall(t.literal(id.name), init, true);
return this._addImportSource(call, node);
};
SystemFormatter.prototype.remapExportAssignment = function (node) {
return this.buildExportCall(t.literal(node.left.name), node);
};
SystemFormatter.prototype.buildExportCall = function (id, init, isStatement) {
var call = t.callExpression(this.exportIdentifier, [id, init]);
if (isStatement) {
return t.expressionStatement(call);
} else {
return call;
}
};
SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
AMDFormatter.prototype.importSpecifier.apply(this, arguments);
this._addImportSource(last(nodes), node);
};
var runnerSettersVisitor = {
enter(node, parent, scope, state) {
if (node._importSource === state.source) {
if (t.isVariableDeclaration(node)) {
each(node.declarations, function (declar) {
state.hoistDeclarators.push(t.variableDeclarator(declar.id));
state.nodes.push(t.expressionStatement(
t.assignmentExpression("=", declar.id, declar.init)
));
});
} else {
state.nodes.push(node);
}
this.remove();
}
}
};
SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators) {
var scope = this.file.scope;
return t.arrayExpression(map(this.ids, function (uid, source) {
var state = {
source: source,
nodes: [],
hoistDeclarators: hoistDeclarators
};
scope.traverse(block, runnerSettersVisitor, state);
return t.functionExpression(null, [uid], t.blockStatement(state.nodes));
}));
};
var hoistVariablesVisitor = { var hoistVariablesVisitor = {
enter(node, parent, scope, hoistDeclarators) { enter(node, parent, scope, hoistDeclarators) {
@@ -156,39 +62,131 @@ var hoistFunctionsVisitor = {
} }
}; };
SystemFormatter.prototype.transform = function (program) { var runnerSettersVisitor = {
var hoistDeclarators = []; enter(node, parent, scope, state) {
var moduleName = this.getModuleName(); if (node._importSource === state.source) {
var moduleNameLiteral = t.literal(moduleName); if (t.isVariableDeclaration(node)) {
each(node.declarations, function (declar) {
state.hoistDeclarators.push(t.variableDeclarator(declar.id));
state.nodes.push(t.expressionStatement(
t.assignmentExpression("=", declar.id, declar.init)
));
});
} else {
state.nodes.push(node);
}
var block = t.blockStatement(program.body); this.remove();
}
}
};
var runner = util.template("system", { export default class SystemFormatter extends AMDFormatter {
MODULE_NAME: moduleNameLiteral, constructor(file) {
MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()), this.exportIdentifier = file.scope.generateUidIdentifier("export");
EXPORT_IDENTIFIER: this.exportIdentifier, this.noInteropRequireExport = true;
SETTERS: this.buildRunnerSetters(block, hoistDeclarators), this.noInteropRequireImport = true;
EXECUTE: t.functionExpression(null, [], block)
}, true);
var handlerBody = runner.expression.arguments[2].body.body; DefaultFormatter.apply(this, arguments);
if (!moduleName) runner.expression.arguments.shift();
var returnStatement = handlerBody.pop();
// hoist up all variable declarations
this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators);
if (hoistDeclarators.length) {
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators);
hoistDeclar._blockHoist = true;
handlerBody.unshift(hoistDeclar);
} }
// hoist up function declarations for circular references init() {}
this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody);
handlerBody.push(returnStatement); _addImportSource(node, exportNode) {
node._importSource = exportNode.source && exportNode.source.value;
return node;
}
program.body = [runner]; buildExportsWildcard(objectIdentifier, node) {
}; var leftIdentifier = this.scope.generateUidIdentifier("key");
var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true);
var left = t.variableDeclaration("var", [
t.variableDeclarator(leftIdentifier)
]);
var right = objectIdentifier;
var block = t.blockStatement([
t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier))
]);
return this._addImportSource(t.forInStatement(left, right, block), node);
}
buildExportsAssignment(id, init, node) {
var call = this.buildExportCall(t.literal(id.name), init, true);
return this._addImportSource(call, node);
}
remapExportAssignment(node) {
return this.buildExportCall(t.literal(node.left.name), node);
}
buildExportCall(id, init, isStatement) {
var call = t.callExpression(this.exportIdentifier, [id, init]);
if (isStatement) {
return t.expressionStatement(call);
} else {
return call;
}
}
importSpecifier(specifier, node, nodes) {
AMDFormatter.prototype.importSpecifier.apply(this, arguments);
this._addImportSource(last(nodes), node);
}
buildRunnerSetters(block, hoistDeclarators) {
var scope = this.file.scope;
return t.arrayExpression(map(this.ids, function (uid, source) {
var state = {
source: source,
nodes: [],
hoistDeclarators: hoistDeclarators
};
scope.traverse(block, runnerSettersVisitor, state);
return t.functionExpression(null, [uid], t.blockStatement(state.nodes));
}));
}
transform(program) {
var hoistDeclarators = [];
var moduleName = this.getModuleName();
var moduleNameLiteral = t.literal(moduleName);
var block = t.blockStatement(program.body);
var runner = util.template("system", {
MODULE_NAME: moduleNameLiteral,
MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()),
EXPORT_IDENTIFIER: this.exportIdentifier,
SETTERS: this.buildRunnerSetters(block, hoistDeclarators),
EXECUTE: t.functionExpression(null, [], block)
}, true);
var handlerBody = runner.expression.arguments[2].body.body;
if (!moduleName) runner.expression.arguments.shift();
var returnStatement = handlerBody.pop();
// hoist up all variable declarations
this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators);
if (hoistDeclarators.length) {
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators);
hoistDeclar._blockHoist = true;
handlerBody.unshift(hoistDeclar);
}
// hoist up function declarations for circular references
this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody);
handlerBody.push(returnStatement);
program.body = [runner];
}
}

View File

@@ -1,71 +1,65 @@
module.exports = UMDFormatter; import AMDFormatter from "./amd";
import values from "lodash/object/values";
import * as util from "../../util";
import t from "../../types";
var AMDFormatter = require("./amd"); export default class UMDFormatter extends AMDFormatter {
var util = require("../../util"); transform(program) {
var t = require("../../types"); var body = program.body;
var values = require("lodash/object/values");
function UMDFormatter() { // build an array of module names
AMDFormatter.apply(this, arguments);
}
util.inherits(UMDFormatter, AMDFormatter); var names = [];
for (var name in this.ids) {
names.push(t.literal(name));
}
UMDFormatter.prototype.transform = function (program) { // factory
var body = program.body;
// build an array of module names var ids = values(this.ids);
var args = [t.identifier("exports")];
if (this.passModuleArg) args.push(t.identifier("module"));
args = args.concat(ids);
var names = []; var factory = t.functionExpression(null, args, t.blockStatement(body));
for (var name in this.ids) {
names.push(t.literal(name)); // amd
var defineArgs = [t.literal("exports")];
if (this.passModuleArg) defineArgs.push(t.literal("module"));
defineArgs = defineArgs.concat(names);
defineArgs = [t.arrayExpression(defineArgs)];
// common
var testExports = util.template("test-exports");
var testModule = util.template("test-module");
var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports;
var commonArgs = [t.identifier("exports")];
if (this.passModuleArg) commonArgs.push(t.identifier("module"));
commonArgs = commonArgs.concat(names.map(function (name) {
return t.callExpression(t.identifier("require"), [name]);
}));
// globals
//var umdArgs = [];
//
var moduleName = this.getModuleName();
if (moduleName) defineArgs.unshift(t.literal(moduleName));
var runner = util.template("umd-runner-body", {
AMD_ARGUMENTS: defineArgs,
COMMON_TEST: commonTests,
COMMON_ARGUMENTS: commonArgs
});
//
var call = t.callExpression(runner, [factory]);
program.body = [t.expressionStatement(call)];
} }
}
// factory
var ids = values(this.ids);
var args = [t.identifier("exports")];
if (this.passModuleArg) args.push(t.identifier("module"));
args = args.concat(ids);
var factory = t.functionExpression(null, args, t.blockStatement(body));
// amd
var defineArgs = [t.literal("exports")];
if (this.passModuleArg) defineArgs.push(t.literal("module"));
defineArgs = defineArgs.concat(names);
defineArgs = [t.arrayExpression(defineArgs)];
// common
var testExports = util.template("test-exports");
var testModule = util.template("test-module");
var commonTests = this.passModuleArg ? t.logicalExpression("&&", testExports, testModule) : testExports;
var commonArgs = [t.identifier("exports")];
if (this.passModuleArg) commonArgs.push(t.identifier("module"));
commonArgs = commonArgs.concat(names.map(function (name) {
return t.callExpression(t.identifier("require"), [name]);
}));
// globals
//var umdArgs = [];
//
var moduleName = this.getModuleName();
if (moduleName) defineArgs.unshift(t.literal(moduleName));
var runner = util.template("umd-runner-body", {
AMD_ARGUMENTS: defineArgs,
COMMON_TEST: commonTests,
COMMON_ARGUMENTS: commonArgs
});
//
var call = t.callExpression(runner, [factory]);
program.body = [t.expressionStatement(call)];
};

View File

@@ -1,3 +1,3 @@
{ {
"blacklist": ["useStrict", "es6.blockScoping"] "blacklist": ["useStrict", "es6.blockScoping", "regenerator"]
} }

View File

@@ -1,3 +1,21 @@
for (var ITERATOR_KEY = OBJECT[Symbol.iterator](), STEP_KEY; !(STEP_KEY = ITERATOR_KEY.next()).done; ) { var ITERATOR_COMPLETION = true;
var ITERATOR_HAD_ERROR_KEY = false;
var ITERATOR_ERROR_KEY = undefined;
try {
for (var ITERATOR_KEY = OBJECT[Symbol.iterator](), STEP_KEY; !(ITERATOR_COMPLETION = (STEP_KEY = ITERATOR_KEY.next()).done); ITERATOR_COMPLETION = true) {
}
} catch (err) {
ITERATOR_HAD_ERROR_KEY = true;
ITERATOR_ERROR_KEY = err;
} finally {
try {
if (!ITERATOR_COMPLETION && ITERATOR_KEY.return) {
ITERATOR_KEY.return();
}
} finally {
if (ITERATOR_HAD_ERROR_KEY) {
throw ITERATOR_ERROR_KEY;
}
}
} }

View File

@@ -1,63 +1,63 @@
module.exports = TransformerPass; import includes from "lodash/collection/includes";
var includes = require("lodash/collection/includes");
/** /**
* This class is responsible for traversing over the provided `File`s * This class is responsible for traversing over the provided `File`s
* AST and running it's parent transformers handlers over it. * AST and running it's parent transformers handlers over it.
*/ */
function TransformerPass(file, transformer) { export default class TransformerPass {
this.transformer = transformer; constructor(file, transformer) {
this.shouldRun = !transformer.check; this.transformer = transformer;
this.handlers = transformer.handlers; this.shouldRun = !transformer.check;
this.file = file; this.handlers = transformer.handlers;
} this.file = file;
}
TransformerPass.prototype.canRun = function () { canRun() {
var transformer = this.transformer; var transformer = this.transformer;
var opts = this.file.opts; var opts = this.file.opts;
var key = transformer.key; var key = transformer.key;
// internal // internal
if (key[0] === "_") return true; if (key[0] === "_") return true;
// blacklist // blacklist
var blacklist = opts.blacklist; var blacklist = opts.blacklist;
if (blacklist.length && includes(blacklist, key)) return false; if (blacklist.length && includes(blacklist, key)) return false;
// whitelist // whitelist
var whitelist = opts.whitelist; var whitelist = opts.whitelist;
if (whitelist.length) return includes(whitelist, key); if (whitelist.length) return includes(whitelist, key);
// optional // optional
if (transformer.optional && !includes(opts.optional, key)) return false; if (transformer.optional && !includes(opts.optional, key)) return false;
// experimental // experimental
if (transformer.experimental && !opts.experimental) return false; if (transformer.experimental && !opts.experimental) return false;
// playground // playground
if (transformer.playground && !opts.playground) return false; if (transformer.playground && !opts.playground) return false;
return true;
};
TransformerPass.prototype.checkNode = function (node) {
var check = this.transformer.check;
if (check) {
return this.shouldRun = check(node);
} else {
return true; return true;
} }
};
TransformerPass.prototype.transform = function () { checkNode(node) {
if (!this.shouldRun) return; var check = this.transformer.check;
if (check) {
return this.shouldRun = check(node);
} else {
return true;
}
}
var file = this.file; transform() {
if (!this.shouldRun) return;
file.debug("Running transformer " + this.transformer.key); var file = this.file;
file.scope.traverse(file.ast, this.handlers, file); file.debug("Running transformer " + this.transformer.key);
};
file.scope.traverse(file.ast, this.handlers, file);
}
}

View File

@@ -1,11 +1,9 @@
module.exports = Transformer; import TransformerPass from "./transformer-pass";
import isFunction from "lodash/lang/isFunction";
var TransformerPass = require("./transformer-pass"); import traverse from "../traversal";
var isFunction = require("lodash/lang/isFunction"); import isObject from "lodash/lang/isObject";
var traverse = require("../traversal"); import assign from "lodash/object/assign";
var isObject = require("lodash/lang/isObject"); import each from "lodash/collection/each";
var assign = require("lodash/object/assign");
var each = require("lodash/collection/each");
/** /**
* This is the class responsible for normalising a transformers handlers * This is the class responsible for normalising a transformers handlers
@@ -13,59 +11,61 @@ var each = require("lodash/collection/each");
* actually running the transformer over the provided `File`. * actually running the transformer over the provided `File`.
*/ */
function Transformer(key, transformer, opts) { export default class Transformer {
transformer = assign({}, transformer); constructor(transformerKey, transformer, opts) {
transformer = assign({}, transformer);
var take = function (key) { var take = function (key) {
var val = transformer[key]; var val = transformer[key];
delete transformer[key]; delete transformer[key];
return val; return val;
}; };
this.manipulateOptions = take("manipulateOptions"); this.manipulateOptions = take("manipulateOptions");
this.check = take("check"); this.check = take("check");
this.post = take("post"); this.post = take("post");
this.pre = take("pre"); this.pre = take("pre");
this.experimental = !!take("experimental"); this.experimental = !!take("experimental");
this.playground = !!take("playground"); this.playground = !!take("playground");
this.secondPass = !!take("secondPass"); this.secondPass = !!take("secondPass");
this.optional = !!take("optional"); this.optional = !!take("optional");
this.handlers = this.normalize(transformer); this.handlers = this.normalize(transformer);
this.opts ||= {}; this.opts ||= {};
this.key = key; this.key = transformerKey;
}
Transformer.prototype.normalize = function (transformer) {
if (isFunction(transformer)) {
transformer = { ast: transformer };
} }
traverse.explode(transformer); normalize(transformer) {
if (isFunction(transformer)) {
each(transformer, (fns, type) => { transformer = { ast: transformer };
// hidden property
if (type[0] === "_") {
this[type] = fns;
return;
} }
if (type === "enter" || type === "exit") return; traverse.explode(transformer);
if (isFunction(fns)) fns = { enter: fns }; each(transformer, (fns, type) => {
// hidden property
if (type[0] === "_") {
this[type] = fns;
return;
}
if (!isObject(fns)) return; if (type === "enter" || type === "exit") return;
if (!fns.enter) fns.enter = function () { }; if (isFunction(fns)) fns = { enter: fns };
if (!fns.exit) fns.exit = function () { };
transformer[type] = fns; if (!isObject(fns)) return;
});
return transformer; if (!fns.enter) fns.enter = function () { };
}; if (!fns.exit) fns.exit = function () { };
Transformer.prototype.buildPass = function (file) { transformer[type] = fns;
return new TransformerPass(file, this); });
};
return transformer;
}
buildPass(file) {
return new TransformerPass(file, this);
}
}

View File

@@ -1,3 +1,4 @@
{ {
"selfContained": "runtime" "selfContained": "runtime",
"unicode-regex": "regex.unicode"
} }

View File

@@ -1,6 +1,6 @@
var t = require("../../../types"); import t from "../../../types";
exports.MemberExpression = function (node) { export function MemberExpression(node) {
var prop = node.property; var prop = node.property;
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) { if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
// foo["bar"] => foo.bar // foo["bar"] => foo.bar
@@ -11,4 +11,4 @@ exports.MemberExpression = function (node) {
node.property = t.literal(prop.name); node.property = t.literal(prop.name);
node.computed = true; node.computed = true;
} }
}; }

View File

@@ -1,6 +1,6 @@
var t = require("../../../types"); import t from "../../../types";
exports.Property = function (node) { export function Property(node) {
var key = node.key; var key = node.key;
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) { if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
// "foo": "bar" -> foo: "bar" // "foo": "bar" -> foo: "bar"
@@ -10,4 +10,4 @@ exports.Property = function (node) {
// default: "bar" -> "default": "bar" // default: "bar" -> "default": "bar"
node.key = t.literal(key.name); node.key = t.literal(key.name);
} }
}; }

View File

@@ -1,11 +1,11 @@
var defineMap = require("../../helpers/define-map"); import * as defineMap from "../../helpers/define-map";
var t = require("../../../types"); import t from "../../../types";
exports.check = function (node) { export function check(node) {
return t.isProperty(node) && (node.kind === "get" || node.kind === "set"); return t.isProperty(node) && (node.kind === "get" || node.kind === "set");
}; }
exports.ObjectExpression = function (node) { export function ObjectExpression(node) {
var mutatorMap = {}; var mutatorMap = {};
var hasAny = false; var hasAny = false;
@@ -25,4 +25,4 @@ exports.ObjectExpression = function (node) {
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")), t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
[node, defineMap.build(mutatorMap)] [node, defineMap.build(mutatorMap)]
); );
}; }

View File

@@ -1,8 +1,8 @@
var t = require("../../../types"); import t from "../../../types";
exports.check = t.isArrowFunctionExpression; export var check = t.isArrowFunctionExpression;
exports.ArrowFunctionExpression = function (node) { export function ArrowFunctionExpression(node) {
t.ensureBlock(node); t.ensureBlock(node);
node._aliasFunction = "arrow"; node._aliasFunction = "arrow";
@@ -10,4 +10,4 @@ exports.ArrowFunctionExpression = function (node) {
node.type = "FunctionExpression"; node.type = "FunctionExpression";
return node; return node;
}; }

View File

@@ -1,4 +1,4 @@
var t = require("../../../types"); import t from "../../../types";
var visitor = { var visitor = {
enter(node, parent, scope, state) { enter(node, parent, scope, state) {
@@ -26,11 +26,9 @@ var visitor = {
} }
}; };
exports.optional = true; export var optional = true;
exports.Loop = export function BlockStatement(node, parent, scope, file) {
exports.Program =
exports.BlockStatement = function (node, parent, scope, file) {
var letRefs = node._letReferences; var letRefs = node._letReferences;
if (!letRefs) return; if (!letRefs) return;
@@ -40,4 +38,6 @@ exports.BlockStatement = function (node, parent, scope, file) {
}; };
scope.traverse(node, visitor, state); scope.traverse(node, visitor, state);
}; }
export { BlockStatement as Program, BlockStatement as Loop };

View File

@@ -1,15 +1,11 @@
var traverse = require("../../../traversal"); import traverse from "../../../traversal";
var object = require("../../../helpers/object"); import object from "../../../helpers/object";
var util = require("../../../util"); import * as util from "../../../util";
var t = require("../../../types"); import t from "../../../types";
var values = require("lodash/object/values"); import values from "lodash/object/values";
var extend = require("lodash/object/extend"); import extend from "lodash/object/extend";
exports.check = function (node) { function isLet(node, parent) {
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
};
var isLet = function (node, parent) {
if (!t.isVariableDeclaration(node)) return false; if (!t.isVariableDeclaration(node)) return false;
if (node._let) return true; if (node._let) return true;
if (node.kind !== "let") return false; if (node.kind !== "let") return false;
@@ -25,23 +21,27 @@ var isLet = function (node, parent) {
node._let = true; node._let = true;
node.kind = "var"; node.kind = "var";
return true; return true;
}; }
var isLetInitable = function (node, parent) { function isLetInitable(node, parent) {
return !t.isFor(parent) || !t.isFor(parent, { left: node }); return !t.isFor(parent) || !t.isFor(parent, { left: node });
}; }
var isVar = function (node, parent) { function isVar(node, parent) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent); return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
}; }
var standardizeLets = function (declars) { function standardizeLets(declars) {
for (var i = 0; i < declars.length; i++) { for (var i = 0; i < declars.length; i++) {
delete declars[i]._let; delete declars[i]._let;
} }
}; }
exports.VariableDeclaration = function (node, parent, scope, file) { export function check(node) {
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
}
export function VariableDeclaration(node, parent, scope, file) {
if (!isLet(node, parent)) return; if (!isLet(node, parent)) return;
if (isLetInitable(node) && file.transformers["es6.blockScopingTDZ"].canRun()) { if (isLetInitable(node) && file.transformers["es6.blockScopingTDZ"].canRun()) {
@@ -61,9 +61,9 @@ exports.VariableDeclaration = function (node, parent, scope, file) {
return nodes; return nodes;
} }
}; }
exports.Loop = function (node, parent, scope, file) { export function Loop(node, parent, scope, file) {
var init = node.left || node.init; var init = node.left || node.init;
if (isLet(init, node)) { if (isLet(init, node)) {
t.ensureBlock(node); t.ensureBlock(node);
@@ -71,15 +71,16 @@ exports.Loop = function (node, parent, scope, file) {
} }
var blockScoping = new BlockScoping(node, node.body, parent, scope, file); var blockScoping = new BlockScoping(node, node.body, parent, scope, file);
blockScoping.run(); blockScoping.run();
}; }
exports.Program = export function BlockStatement(block, parent, scope, file) {
exports.BlockStatement = function (block, parent, scope, file) {
if (!t.isLoop(parent)) { if (!t.isLoop(parent)) {
var blockScoping = new BlockScoping(false, block, parent, scope, file); var blockScoping = new BlockScoping(false, block, parent, scope, file);
blockScoping.run(); blockScoping.run();
} }
}; }
export { BlockStatement as Program };
function replace(node, parent, scope, remaps) { function replace(node, parent, scope, remaps) {
if (!t.isReferencedIdentifier(node, parent)) return; if (!t.isReferencedIdentifier(node, parent)) return;

View File

@@ -1,17 +1,17 @@
var ReplaceSupers = require("../../helpers/replace-supers"); import ReplaceSupers from "../../helpers/replace-supers";
var nameMethod = require("../../helpers/name-method"); import * as nameMethod from "../../helpers/name-method";
var defineMap = require("../../helpers/define-map"); import * as defineMap from "../../helpers/define-map";
var messages = require("../../../messages"); import * as messages from "../../../messages";
var util = require("../../../util"); import * as util from "../../../util";
var t = require("../../../types"); import t from "../../../types";
exports.check = t.isClass; export var check = t.isClass;
exports.ClassDeclaration = function (node, parent, scope, file) { export function ClassDeclaration(node, parent, scope, file) {
return new ClassTransformer(node, file, scope, true).run(); return new ClassTransformer(node, file, scope, true).run();
}; }
exports.ClassExpression = function (node, parent, scope, file) { export function ClassExpression(node, parent, scope, file) {
if (!node.id) { if (!node.id) {
if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) { if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) {
// var o = { foo: class {} }; // var o = { foo: class {} };
@@ -25,7 +25,7 @@ exports.ClassExpression = function (node, parent, scope, file) {
} }
return new ClassTransformer(node, file, scope, false).run(); return new ClassTransformer(node, file, scope, false).run();
}; }
class ClassTransformer { class ClassTransformer {

View File

@@ -1,9 +1,9 @@
var messages = require("../../../messages"); import * as messages from "../../../messages";
var t = require("../../../types"); import t from "../../../types";
exports.check = function (node) { export function check(node) {
return t.isVariableDeclaration(node, { kind: "const" }); return t.isVariableDeclaration(node, { kind: "const" });
}; }
var visitor = { var visitor = {
enter(node, parent, scope, state) { enter(node, parent, scope, state) {
@@ -36,13 +36,13 @@ var visitor = {
} }
}; };
exports.Scopable = function (node, parent, scope, file) { export function Scopable(node, parent, scope, file) {
scope.traverse(node, visitor, { scope.traverse(node, visitor, {
constants: scope.getAllBindingsOfKind("const"), constants: scope.getAllBindingsOfKind("const"),
file: file file: file
}); });
}; }
exports.VariableDeclaration = function (node) { export function VariableDeclaration(node) {
if (node.kind === "const") node.kind = "let"; if (node.kind === "const") node.kind = "let";
}; }

View File

@@ -1,10 +1,9 @@
var messages = require("../../../messages"); import * as messages from "../../../messages";
var t = require("../../../types"); import t from "../../../types";
exports.check = t.isPattern; export var check = t.isPattern;
exports.ForInStatement = export function ForOfStatement(node, parent, scope, file) {
exports.ForOfStatement = function (node, parent, scope, file) {
var left = node.left; var left = node.left;
if (t.isPattern(left)) { if (t.isPattern(left)) {
@@ -50,7 +49,9 @@ exports.ForOfStatement = function (node, parent, scope, file) {
var block = node.body; var block = node.body;
block.body = nodes.concat(block.body); block.body = nodes.concat(block.body);
}; }
export { ForOfStatement as ForInStatement };
exports.Function = function (node, parent, scope, file) { exports.Function = function (node, parent, scope, file) {
var nodes = []; var nodes = [];
@@ -83,7 +84,7 @@ exports.Function = function (node, parent, scope, file) {
block.body = nodes.concat(block.body); block.body = nodes.concat(block.body);
}; };
exports.CatchClause = function (node, parent, scope, file) { export function CatchClause(node, parent, scope, file) {
var pattern = node.param; var pattern = node.param;
if (!t.isPattern(pattern)) return; if (!t.isPattern(pattern)) return;
@@ -103,9 +104,9 @@ exports.CatchClause = function (node, parent, scope, file) {
node.body.body = nodes.concat(node.body.body); node.body.body = nodes.concat(node.body.body);
return node; return node;
}; }
exports.ExpressionStatement = function (node, parent, scope, file) { export function ExpressionStatement(node, parent, scope, file) {
var expr = node.expression; var expr = node.expression;
if (expr.type !== "AssignmentExpression") return; if (expr.type !== "AssignmentExpression") return;
if (!t.isPattern(expr.left)) return; if (!t.isPattern(expr.left)) return;
@@ -127,9 +128,9 @@ exports.ExpressionStatement = function (node, parent, scope, file) {
destructuring.init(expr.left, ref); destructuring.init(expr.left, ref);
return nodes; return nodes;
}; }
exports.AssignmentExpression = function (node, parent, scope, file) { export function AssignmentExpression(node, parent, scope, file) {
if (!t.isPattern(node.left)) return; if (!t.isPattern(node.left)) return;
var ref = scope.generateUidIdentifier("temp"); var ref = scope.generateUidIdentifier("temp");
@@ -152,18 +153,18 @@ exports.AssignmentExpression = function (node, parent, scope, file) {
nodes.push(ref); nodes.push(ref);
return t.toSequenceExpression(nodes, scope); return t.toSequenceExpression(nodes, scope);
}; }
var variableDeclarationHasPattern = function (node) { function variableDeclarationHasPattern(node) {
for (var i = 0; i < node.declarations.length; i++) { for (var i = 0; i < node.declarations.length; i++) {
if (t.isPattern(node.declarations[i].id)) { if (t.isPattern(node.declarations[i].id)) {
return true; return true;
} }
} }
return false; return false;
}; }
exports.VariableDeclaration = function (node, parent, scope, file) { export function VariableDeclaration(node, parent, scope, file) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return; if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
if (!variableDeclarationHasPattern(node)) return; if (!variableDeclarationHasPattern(node)) return;

View File

@@ -1,10 +1,10 @@
var messages = require("../../../messages"); import * as messages from "../../../messages";
var util = require("../../../util"); import * as util from "../../../util";
var t = require("../../../types"); import t from "../../../types";
exports.check = t.isForOfStatement; export var check = t.isForOfStatement;
exports.ForOfStatement = function (node, parent, scope, file) { export function ForOfStatement(node, parent, scope, file) {
var callback = spec; var callback = spec;
if (file.isLoose("es6.forOf")) callback = loose; if (file.isLoose("es6.forOf")) callback = loose;
@@ -32,8 +32,8 @@ exports.ForOfStatement = function (node, parent, scope, file) {
// todo: find out why this is necessary? #538 // todo: find out why this is necessary? #538
loop._scopeInfo = node._scopeInfo; loop._scopeInfo = node._scopeInfo;
return loop; return build.node;
}; }
var breakVisitor = { var breakVisitor = {
enter(node, parent, scope, state) { enter(node, parent, scope, state) {
@@ -113,6 +113,7 @@ var loose = function (node, parent, scope, file) {
return { return {
declar: declar, declar: declar,
node: loop,
loop: loop loop: loop
}; };
}; };
@@ -140,26 +141,33 @@ var spec = function (node, parent, scope, file) {
var iteratorKey = scope.generateUidIdentifier("iterator"); var iteratorKey = scope.generateUidIdentifier("iterator");
var loop = util.template("for-of", { var template = util.template("for-of", {
ITERATOR_KEY: iteratorKey, ITERATOR_HAD_ERROR_KEY: scope.generateUidIdentifier("didIteratorError"),
STEP_KEY: stepKey, ITERATOR_COMPLETION: scope.generateUidIdentifier("iteratorNormalCompletion"),
OBJECT: node.right ITERATOR_ERROR_KEY: scope.generateUidIdentifier("iteratorError"),
ITERATOR_KEY: iteratorKey,
STEP_KEY: stepKey,
OBJECT: node.right,
BODY: null
}); });
var loop = template[3].block.body[0];
// //
scope.traverse(node, breakVisitor, { scope.traverse(node, breakVisitor, {
iteratorKey: iteratorKey, iteratorKey: iteratorKey,
label: t.isLabeledStatement(parent) && parent.label.name,
wrapReturn: function (node) { wrapReturn: function (node) {
return t.ifStatement(t.memberExpression(iteratorKey, t.identifier("return")), node); return t.ifStatement(t.memberExpression(iteratorKey, t.identifier("return")), node);
}, }
label: t.isLabeledStatement(parent) && parent.label.name
}); });
// //
return { return {
declar: declar, declar: declar,
loop: loop loop: loop,
node: template
}; };
}; };

View File

@@ -1,8 +1,8 @@
var t = require("../../../types"); import t from "../../../types";
exports.check = require("../internal/modules").check; export { check } from "../internal/modules";
exports.ImportDeclaration = function (node, parent, scope, file) { export function ImportDeclaration(node, parent, scope, file) {
// flow type // flow type
if (node.isType) return; if (node.isType) return;
@@ -22,9 +22,9 @@ exports.ImportDeclaration = function (node, parent, scope, file) {
} }
return nodes; return nodes;
}; }
exports.ExportDeclaration = function (node, parent, scope, file) { export function ExportDeclaration(node, parent, scope, file) {
// flow type // flow type
if (t.isTypeAlias(node.declaration)) return; if (t.isTypeAlias(node.declaration)) return;
@@ -53,4 +53,4 @@ exports.ExportDeclaration = function (node, parent, scope, file) {
} }
return nodes; return nodes;
}; }

View File

@@ -1,11 +1,11 @@
var ReplaceSupers = require("../../helpers/replace-supers"); import ReplaceSupers from "../../helpers/replace-supers";
var t = require("../../../types"); import t from "../../../types";
exports.check = function (node) { export function check(node) {
return t.isIdentifier(node, { name: "super" }); return t.isIdentifier(node, { name: "super" });
}; }
exports.Property = function (node, parent, scope, file) { export function Property(node, parent, scope, file) {
if (!node.method) return; if (!node.method) return;
var value = node.value; var value = node.value;
@@ -29,4 +29,4 @@ exports.Property = function (node, parent, scope, file) {
]) ])
); );
} }
}; }

View File

@@ -1,9 +1,9 @@
var util = require("../../../util"); import * as util from "../../../util";
var t = require("../../../types"); import t from "../../../types";
exports.check = function (node) { export function check(node) {
return t.isFunction(node) && hasDefaults(node); return t.isFunction(node) && hasDefaults(node);
}; }
var hasDefaults = function (node) { var hasDefaults = function (node) {
for (var i = 0; i < node.params.length; i++) { for (var i = 0; i < node.params.length; i++) {

View File

@@ -1,7 +1,56 @@
var util = require("../../../util"); import isNumber from "lodash/lang/isNumber";
var t = require("../../../types"); import * as util from "../../../util";
import t from "../../../types";
exports.check = t.isRestElement; export var check = t.isRestElement;
var memberExpressionOptimisationVisitor = {
enter(node, parent, scope, state) {
// check if this scope has a local binding that will shadow the rest parameter
if (t.isScope(node, parent) && !scope.bindingIdentifierEquals(state.name, state.outerBinding)) {
return this.skip();
}
// skip over functions as whatever `arguments` we reference inside will refer
// to the wrong function
if (t.isFunctionDeclaration(node) || t.isFunctionExpression(node)) {
state.noOptimise = true;
scope.traverse(node, memberExpressionOptimisationVisitor, state);
state.noOptimise = false;
return this.skip();
}
// is this a referenced identifier and is it referencing the rest parameter?
if (!t.isReferencedIdentifier(node, parent, { name: state.name })) return;
if (!state.noOptimise && t.isMemberExpression(parent) && parent.computed) {
// if we know that this member expression is referencing a number then we can safely
// optimise it
var prop = parent.property;
if (isNumber(prop.value) || t.isUnaryExpression(prop) || t.isBinaryExpression(prop)) {
state.candidates.push(this);
state.canOptimise = true;
return;
}
}
state.canOptimise = false;
this.stop();
}
};
function optimizeMemberExpression(parent, offset) {
var newExpr;
var prop = parent.property;
if (t.isLiteral(prop)) {
prop.value += offset;
prop.raw = String(prop.value);
} else { // // UnaryExpression, BinaryExpression
newExpr = t.binaryExpression("+", prop, t.literal(offset));
parent.property = newExpr;
}
}
var hasRest = function (node) { var hasRest = function (node) {
return t.isRestElement(node.params[node.params.length - 1]); return t.isRestElement(node.params[node.params.length - 1]);
@@ -17,6 +66,41 @@ exports.Function = function (node, parent, scope) {
// otherwise `arguments` will be remapped in arrow functions // otherwise `arguments` will be remapped in arrow functions
argsId._ignoreAliasFunctions = true; argsId._ignoreAliasFunctions = true;
// support patterns
if (t.isPattern(rest)) {
var pattern = rest;
rest = scope.generateUidIdentifier("ref");
var declar = t.variableDeclaration("var", pattern.elements.map(function (elem, index) {
var accessExpr = t.memberExpression(rest, t.literal(index), true);
return t.variableDeclarator(elem, accessExpr);
}));
node.body.body.unshift(declar);
}
// check if rest is used in member expressions and optimise for those cases
var state = {
outerBinding: scope.getBindingIdentifier(rest.name),
canOptimise: false,
candidates: [],
method: node,
name: rest.name
};
scope.traverse(node, memberExpressionOptimisationVisitor, state);
// we only have shorthands and there's no other references
if (state.canOptimise) {
for (var i = 0; i < state.candidates.length; i++) {
var candidate = state.candidates[i];
candidate.node = argsId;
optimizeMemberExpression(candidate.parent, node.params.length);
}
return;
}
//
var start = t.literal(node.params.length); var start = t.literal(node.params.length);
var key = scope.generateUidIdentifier("key"); var key = scope.generateUidIdentifier("key");
var len = scope.generateUidIdentifier("len"); var len = scope.generateUidIdentifier("len");
@@ -42,22 +126,6 @@ exports.Function = function (node, parent, scope) {
); );
} }
// support patterns
if (t.isPattern(rest)) {
var pattern = rest;
rest = scope.generateUidIdentifier("ref");
// let the destructuring transformer handle this
var restDeclar = t.variableDeclaration("var", [
t.variableDeclarator(pattern, rest)
]);
// retain evaluation position
restDeclar._blockHoist = node.params.length + 1;
node.body.body.unshift(restDeclar);
}
scope.assignTypeGeneric(rest.name, "Array"); scope.assignTypeGeneric(rest.name, "Array");
var loop = util.template("rest", { var loop = util.template("rest", {

View File

@@ -1,48 +1,6 @@
var t = require("../../../types"); import t from "../../../types";
exports.check = function (node) { function loose(node, body, objId) {
return t.isProperty(node) && node.computed;
};
exports.ObjectExpression = function (node, parent, scope, file) {
var hasComputed = false;
for (var i = 0; i < node.properties.length; i++) {
hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" });
if (hasComputed) break;
}
if (!hasComputed) return;
var initProps = [];
var objId = scope.generateUidBasedOnNode(parent);
//
var body = [];
var container = t.functionExpression(null, [], t.blockStatement(body));
container._aliasFunction = true;
//
var callback = spec;
if (file.isLoose("es6.properties.computed")) callback = loose;
var result = callback(node, body, objId, initProps, file);
if (result) return result;
//
body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(objId, t.objectExpression(initProps))
]));
body.push(t.returnStatement(objId));
return t.callExpression(container, []);
};
var loose = function (node, body, objId) {
for (var i = 0; i < node.properties.length; i++) { for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i]; var prop = node.properties[i];
@@ -54,9 +12,9 @@ var loose = function (node, body, objId) {
) )
)); ));
} }
}; }
var spec = function (node, body, objId, initProps, file) { function spec(node, body, objId, initProps, file) {
var props = node.properties; var props = node.properties;
var prop, key; var prop, key;
@@ -124,4 +82,46 @@ var spec = function (node, body, objId, initProps, file) {
return first; return first;
} }
} }
}; }
export function check(node) {
return t.isProperty(node) && node.computed;
}
export function ObjectExpression(node, parent, scope, file) {
var hasComputed = false;
for (var i = 0; i < node.properties.length; i++) {
hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" });
if (hasComputed) break;
}
if (!hasComputed) return;
var initProps = [];
var objId = scope.generateUidBasedOnNode(parent);
//
var body = [];
var container = t.functionExpression(null, [], t.blockStatement(body));
container._aliasFunction = true;
//
var callback = spec;
if (file.isLoose("es6.properties.computed")) callback = loose;
var result = callback(node, body, objId, initProps, file);
if (result) return result;
//
body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(objId, t.objectExpression(initProps))
]));
body.push(t.returnStatement(objId));
return t.callExpression(container, []);
}

View File

@@ -1,11 +1,11 @@
var clone = require("lodash/lang/clone"); import clone from "lodash/lang/clone";
var t = require("../../../types"); import t from "../../../types";
exports.check = function (node) { export function check(node) {
return t.isProperty(node) && (node.method || node.shorthand); return t.isProperty(node) && (node.method || node.shorthand);
}; }
exports.Property = function (node) { export function Property(node) {
if (node.method) { if (node.method) {
node.method = false; node.method = false;
} }
@@ -14,4 +14,4 @@ exports.Property = function (node) {
node.shorthand = false; node.shorthand = false;
node.key = t.removeComments(clone(node.key)); node.key = t.removeComments(clone(node.key));
} }
}; }

View File

@@ -0,0 +1,14 @@
import * as regex from "../../helpers/regex";
import t from "../../../types";
export function check(node) {
return regex.is(node, "y");
}
export function Literal(node) {
if (!regex.is(node, "y")) return;
return t.newExpression(t.identifier("RegExp"), [
t.literal(node.regex.pattern),
t.literal(node.regex.flags)
]);
}

View File

@@ -0,0 +1,12 @@
import rewritePattern from "regexpu/rewrite-pattern";
import * as regex from "../../helpers/regex";
export function check(node) {
return regex.is(node, "u");
}
export function Literal(node) {
if (!regex.is(node, "u")) return;
regex.pullFlag(node, "y");
node.regex.pattern = rewritePattern(node.regex.pattern, node.regex.flags);
}

View File

@@ -1,22 +1,20 @@
var includes = require("lodash/collection/includes"); import includes from "lodash/collection/includes";
var t = require("../../../types"); import t from "../../../types";
exports.check = t.isSpreadElement; function getSpreadLiteral(spread, scope) {
var getSpreadLiteral = function (spread, scope) {
return scope.toArray(spread.argument, true); return scope.toArray(spread.argument, true);
}; }
var hasSpread = function (nodes) { function hasSpread(nodes) {
for (var i = 0; i < nodes.length; i++) { for (var i = 0; i < nodes.length; i++) {
if (t.isSpreadElement(nodes[i])) { if (t.isSpreadElement(nodes[i])) {
return true; return true;
} }
} }
return false; return false;
}; }
var build = function (props, scope) { function build(props, scope) {
var nodes = []; var nodes = [];
var _props = []; var _props = [];
@@ -40,9 +38,11 @@ var build = function (props, scope) {
push(); push();
return nodes; return nodes;
}; }
exports.ArrayExpression = function (node, parent, scope) { export var check = t.isSpreadElement;
export function ArrayExpression(node, parent, scope) {
var elements = node.elements; var elements = node.elements;
if (!hasSpread(elements)) return; if (!hasSpread(elements)) return;
@@ -55,9 +55,9 @@ exports.ArrayExpression = function (node, parent, scope) {
} }
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes); return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
}; }
exports.CallExpression = function (node, parent, scope) { export function CallExpression(node, parent, scope) {
var args = node.arguments; var args = node.arguments;
if (!hasSpread(args)) return; if (!hasSpread(args)) return;
@@ -95,9 +95,9 @@ exports.CallExpression = function (node, parent, scope) {
} }
node.arguments.unshift(contextLiteral); node.arguments.unshift(contextLiteral);
}; }
exports.NewExpression = function (node, parent, scope, file) { export function NewExpression(node, parent, scope, file) {
var args = node.arguments; var args = node.arguments;
if (!hasSpread(args)) return; if (!hasSpread(args)) return;
@@ -128,4 +128,4 @@ exports.NewExpression = function (node, parent, scope, file) {
} else { } else {
return t.callExpression(file.addHelper("apply-constructor"), [node.callee, args]); return t.callExpression(file.addHelper("apply-constructor"), [node.callee, args]);
} }
}; }

View File

@@ -1,9 +1,9 @@
var reduceRight = require("lodash/collection/reduceRight"); import reduceRight from "lodash/collection/reduceRight";
var messages = require("../../../messages"); import * as messages from "../../../messages";
var flatten = require("lodash/array/flatten"); import flatten from "lodash/array/flatten";
var util = require("../../../util"); import * as util from "../../../util";
var map = require("lodash/collection/map"); import map from "lodash/collection/map";
var t = require("../../../types"); import t from "../../../types";
exports.Function = function (node, parent, scope, file) { exports.Function = function (node, parent, scope, file) {
var tailCall = new TailCallTransformer(node, scope, file); var tailCall = new TailCallTransformer(node, scope, file);

View File

@@ -1,14 +1,14 @@
var t = require("../../../types"); import t from "../../../types";
var buildBinaryExpression = function (left, right) { var buildBinaryExpression = function (left, right) {
return t.binaryExpression("+", left, right); return t.binaryExpression("+", left, right);
}; };
exports.check = function (node) { export function check(node) {
return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node); return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node);
}; }
exports.TaggedTemplateExpression = function (node, parent, scope, file) { export function TaggedTemplateExpression(node, parent, scope, file) {
var args = []; var args = [];
var quasi = node.quasi; var quasi = node.quasi;
@@ -31,9 +31,9 @@ exports.TaggedTemplateExpression = function (node, parent, scope, file) {
args = args.concat(quasi.expressions); args = args.concat(quasi.expressions);
return t.callExpression(node.tag, args); return t.callExpression(node.tag, args);
}; }
exports.TemplateLiteral = function (node) { export function TemplateLiteral(node) {
var nodes = []; var nodes = [];
var i; var i;
@@ -61,4 +61,4 @@ exports.TemplateLiteral = function (node) {
} else { } else {
return nodes[0]; return nodes[0];
} }
}; }

View File

@@ -1,19 +0,0 @@
var rewritePattern = require("regexpu/rewrite-pattern");
var pull = require("lodash/array/pull");
var t = require("../../../types");
exports.check = function (node) {
return t.isLiteral(node) && node.regex && node.regex.flags.indexOf("u") >= 0;
};
exports.Literal = function (node) {
var regex = node.regex;
if (!regex) return;
var flags = regex.flags.split("");
if (regex.flags.indexOf("u") < 0) return;
pull(flags, "u");
regex.pattern = rewritePattern(regex.pattern, regex.flags);
regex.flags = flags.join("");
};

View File

@@ -1,9 +1,9 @@
// https://github.com/zenparsing/es-abstract-refs // https://github.com/zenparsing/es-abstract-refs
var util = require("../../../util"); import * as util from "../../../util";
var t = require("../../../types"); import t from "../../../types";
exports.experimental = true; export var experimental = true;
var container = function (parent, call, ret, file) { var container = function (parent, call, ret, file) {
if (t.isExpressionStatement(parent) && !file.isConsequenceExpressionStatement(parent)) { if (t.isExpressionStatement(parent) && !file.isConsequenceExpressionStatement(parent)) {
@@ -21,7 +21,7 @@ var container = function (parent, call, ret, file) {
} }
}; };
exports.AssignmentExpression = function (node, parent, scope, file) { export function AssignmentExpression(node, parent, scope, file) {
var left = node.left; var left = node.left;
if (!t.isVirtualPropertyExpression(left)) return; if (!t.isVirtualPropertyExpression(left)) return;
@@ -59,9 +59,9 @@ exports.AssignmentExpression = function (node, parent, scope, file) {
} }
return container(parent, call, value, file); return container(parent, call, value, file);
}; }
exports.UnaryExpression = function (node, parent, scope, file) { export function UnaryExpression(node, parent, scope, file) {
var arg = node.argument; var arg = node.argument;
if (!t.isVirtualPropertyExpression(arg)) return; if (!t.isVirtualPropertyExpression(arg)) return;
if (node.operator !== "delete") return; if (node.operator !== "delete") return;
@@ -72,9 +72,9 @@ exports.UnaryExpression = function (node, parent, scope, file) {
}); });
return container(parent, call, t.literal(true), file); return container(parent, call, t.literal(true), file);
}; }
exports.CallExpression = function (node, parent, scope) { export function CallExpression(node, parent, scope) {
var callee = node.callee; var callee = node.callee;
if (!t.isVirtualPropertyExpression(callee)) return; if (!t.isVirtualPropertyExpression(callee)) return;
@@ -95,17 +95,17 @@ exports.CallExpression = function (node, parent, scope) {
} else { } else {
return call; return call;
} }
}; }
exports.VirtualPropertyExpression = function (node) { export function VirtualPropertyExpression(node) {
return util.template("abstract-expression-get", { return util.template("abstract-expression-get", {
PROPERTY: node.property, PROPERTY: node.property,
OBJECT: node.object OBJECT: node.object
}); });
}; }
exports.PrivateDeclaration = function (node) { export function PrivateDeclaration(node) {
return t.variableDeclaration("const", node.declarations.map(function (id) { return t.variableDeclaration("const", node.declarations.map(function (id) {
return t.variableDeclarator(id, t.newExpression(t.identifier("WeakMap"), [])); return t.variableDeclarator(id, t.newExpression(t.identifier("WeakMap"), []));
})); }));
}; }

View File

@@ -1,17 +1,17 @@
var buildComprehension = require("../../helpers/build-comprehension"); import buildComprehension from "../../helpers/build-comprehension";
var traverse = require("../../../traversal"); import traverse from "../../../traversal";
var util = require("../../../util"); import * as util from "../../../util";
var t = require("../../../types"); import t from "../../../types";
exports.experimental = true; export var experimental = true;
exports.ComprehensionExpression = function (node, parent, scope, file) { export function ComprehensionExpression(node, parent, scope, file) {
var callback = array; var callback = array;
if (node.generator) callback = generator; if (node.generator) callback = generator;
return callback(node, parent, scope, file); return callback(node, parent, scope, file);
}; }
var generator = function (node) { function generator(node) {
var body = []; var body = [];
var container = t.functionExpression(null, [], t.blockStatement(body), true); var container = t.functionExpression(null, [], t.blockStatement(body), true);
container._aliasFunction = true; container._aliasFunction = true;
@@ -21,9 +21,9 @@ var generator = function (node) {
})); }));
return t.callExpression(container, []); return t.callExpression(container, []);
}; }
var array = function (node, parent, scope, file) { function array(node, parent, scope, file) {
var uid = scope.generateUidBasedOnNode(parent, file); var uid = scope.generateUidBasedOnNode(parent, file);
var container = util.template("array-comprehension-container", { var container = util.template("array-comprehension-container", {
@@ -50,4 +50,4 @@ var array = function (node, parent, scope, file) {
body.push(returnStatement); body.push(returnStatement);
return container; return container;
}; }

View File

@@ -1,9 +1,9 @@
// https://github.com/rwaldron/exponentiation-operator // https://github.com/rwaldron/exponentiation-operator
exports.experimental = true; import build from "../../helpers/build-binary-assignment-operator-transformer";
import t from "../../../types";
var build = require("../../helpers/build-binary-assignment-operator-transformer"); export var experimental = true;
var t = require("../../../types");
var MATH_POW = t.memberExpression(t.identifier("Math"), t.identifier("pow")); var MATH_POW = t.memberExpression(t.identifier("Math"), t.identifier("pow"));

View File

@@ -1,12 +1,12 @@
// https://github.com/sebmarkbage/ecmascript-rest-spread // https://github.com/sebmarkbage/ecmascript-rest-spread
var t = require("../../../types"); import t from "../../../types";
exports.experimental = true; export var experimental = true;
exports.manipulateOptions = function (opts) { export function manipulateOptions(opts) {
if (opts.whitelist.length) opts.whitelist.push("es6.destructuring"); if (opts.whitelist.length) opts.whitelist.push("es6.destructuring");
}; }
var hasSpread = function (node) { var hasSpread = function (node) {
for (var i = 0; i < node.properties.length; i++) { for (var i = 0; i < node.properties.length; i++) {
@@ -17,7 +17,7 @@ var hasSpread = function (node) {
return false; return false;
}; };
exports.ObjectExpression = function (node, parent, scope, file) { export function ObjectExpression(node, parent, scope, file) {
if (!hasSpread(node)) return; if (!hasSpread(node)) return;
var args = []; var args = [];
@@ -46,4 +46,4 @@ exports.ObjectExpression = function (node, parent, scope, file) {
} }
return t.callExpression(file.addHelper("extends"), args); return t.callExpression(file.addHelper("extends"), args);
}; }

View File

@@ -1,4 +1,4 @@
module.exports = { export default {
useStrict: require("./other/use-strict"), useStrict: require("./other/use-strict"),
"validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"), "validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"),
@@ -47,7 +47,8 @@ module.exports = {
"es6.forOf": require("./es6/for-of"), "es6.forOf": require("./es6/for-of"),
"es6.unicodeRegex": require("./es6/unicode-regex"), "es6.regex.sticky": require("./es6/regex.sticky"),
"es6.regex.unicode": require("./es6/regex.unicode"),
"es7.abstractReferences": require("./es7/abstract-references"), "es7.abstractReferences": require("./es7/abstract-references"),
"es6.constants": require("./es6/constants"), "es6.constants": require("./es6/constants"),

Some files were not shown because too many files have changed in this diff Show More