Compare commits
130 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f6199493e | ||
|
|
e06aac4783 | ||
|
|
6a5adfe338 | ||
|
|
07c7b5b419 | ||
|
|
7f985fe08a | ||
|
|
38f02a6429 | ||
|
|
f943bdcac0 | ||
|
|
8dc634edfc | ||
|
|
05b9cf17f0 | ||
|
|
69bbe89616 | ||
|
|
6b49958f7c | ||
|
|
e75ce94578 | ||
|
|
f666473724 | ||
|
|
ae817e3c9c | ||
|
|
2e9352de14 | ||
|
|
1e9e55ddef | ||
|
|
0799ed7116 | ||
|
|
5537250d4f | ||
|
|
7ada50937b | ||
|
|
f2ae88af93 | ||
|
|
726451f86f | ||
|
|
306cfc6328 | ||
|
|
a051a47048 | ||
|
|
ad60d49611 | ||
|
|
a6d1a5a724 | ||
|
|
399d835285 | ||
|
|
b66367ddde | ||
|
|
37d29b7a6f | ||
|
|
1e708fb373 | ||
|
|
76ae1682a3 | ||
|
|
2ef0aa95c5 | ||
|
|
9cbb49c6b2 | ||
|
|
f04a734838 | ||
|
|
beb5ccab25 | ||
|
|
b8f8f24e82 | ||
|
|
c35a007401 | ||
|
|
e639c82f2f | ||
|
|
f365cc1248 | ||
|
|
2b75c67448 | ||
|
|
e5e9ae7e0f | ||
|
|
009422e997 | ||
|
|
386e221a0f | ||
|
|
58db94401e | ||
|
|
f9be9bab89 | ||
|
|
dc7e963c9f | ||
|
|
a786f39b1b | ||
|
|
95cf793df4 | ||
|
|
ea2ad96089 | ||
|
|
4b2cf2e2c5 | ||
|
|
23b8c72e9a | ||
|
|
80876a2c0a | ||
|
|
c923010292 | ||
|
|
c84af909f7 | ||
|
|
d6b39bc89b | ||
|
|
39fe737cb6 | ||
|
|
37ef976515 | ||
|
|
fa5a3022d4 | ||
|
|
58bed088f5 | ||
|
|
4f023e83f8 | ||
|
|
7d950cd60a | ||
|
|
ffc9244f88 | ||
|
|
6ede3986c7 | ||
|
|
5a81d22167 | ||
|
|
2bf2e26a64 | ||
|
|
ee466e90ca | ||
|
|
911e3939b9 | ||
|
|
ca6f8e9a96 | ||
|
|
55f2cffc22 | ||
|
|
ca482b79ad | ||
|
|
b1f0ecf244 | ||
|
|
36fa174901 | ||
|
|
e8dc4628ae | ||
|
|
7a0dbb0203 | ||
|
|
8d81a382f7 | ||
|
|
86fbba08d8 | ||
|
|
23c6e7e168 | ||
|
|
c35f041091 | ||
|
|
618c6a8e67 | ||
|
|
23429f7b7f | ||
|
|
d6052b483a | ||
|
|
3b3255a964 | ||
|
|
49847e70af | ||
|
|
c228d76e44 | ||
|
|
2562b0c201 | ||
|
|
6da6bc3eb8 | ||
|
|
bbcfc3c9f2 | ||
|
|
12b1de7c9d | ||
|
|
721636f475 | ||
|
|
4c94941ceb | ||
|
|
f06535e915 | ||
|
|
389914c427 | ||
|
|
c7f5715d8e | ||
|
|
29f866525e | ||
|
|
de61455a55 | ||
|
|
fd579a8772 | ||
|
|
8e708906a8 | ||
|
|
b7680059c8 | ||
|
|
239369314c | ||
|
|
f2d1fc47d1 | ||
|
|
aab35736c5 | ||
|
|
a9405e5e80 | ||
|
|
9880990fa7 | ||
|
|
6674611b26 | ||
|
|
e92ec6aba7 | ||
|
|
1801b725bd | ||
|
|
72de8f5c9b | ||
|
|
895d965568 | ||
|
|
3a11c7d46b | ||
|
|
92d9b3ff5f | ||
|
|
630f1717f0 | ||
|
|
e6e93840a6 | ||
|
|
b2ad79cf88 | ||
|
|
706797eb47 | ||
|
|
4163d1372a | ||
|
|
4413da8d6e | ||
|
|
8e23d623c8 | ||
|
|
e712c5225b | ||
|
|
8bdb723004 | ||
|
|
9f912f548e | ||
|
|
41d721e372 | ||
|
|
df6ffe025c | ||
|
|
28b6b4af44 | ||
|
|
9e80071caa | ||
|
|
0da4303358 | ||
|
|
83e225f30a | ||
|
|
420505ca40 | ||
|
|
f9a26fd903 | ||
|
|
ca0539190e | ||
|
|
2e3226b520 | ||
|
|
7959852eeb |
6
.jscsrc
6
.jscsrc
@@ -14,7 +14,6 @@
|
||||
},
|
||||
"disallowSpacesInsideArrayBrackets": true,
|
||||
"disallowSpacesInsideParentheses": true,
|
||||
"disallowQuotedKeysInObjects": true,
|
||||
"disallowSpaceAfterObjectKeys": true,
|
||||
"disallowSpaceAfterPrefixUnaryOperators": true,
|
||||
"disallowSpaceBeforePostfixUnaryOperators": true,
|
||||
@@ -33,10 +32,8 @@
|
||||
"requireCommaBeforeLineBreak": true,
|
||||
"requireSpaceBeforeBinaryOperators": true,
|
||||
"requireSpaceAfterBinaryOperators": true,
|
||||
"requireCamelCaseOrUpperCaseIdentifiers": true,
|
||||
"requireLineFeedAtFileEnd": true,
|
||||
"requireCapitalizedConstructors": true,
|
||||
"requireDotNotation": true,
|
||||
"requireSpacesInForStatement": true,
|
||||
"requireCurlyBraces": [
|
||||
"do"
|
||||
@@ -52,7 +49,8 @@
|
||||
"return",
|
||||
"try",
|
||||
"catch",
|
||||
"typeof"
|
||||
"typeof",
|
||||
"function"
|
||||
],
|
||||
"validateLineBreaks": "LF",
|
||||
"validateQuoteMarks": "\"",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"esnext": true,
|
||||
"indent": 2,
|
||||
"freeze": true,
|
||||
"validthis": true,
|
||||
"camelcase": true,
|
||||
"unused": true,
|
||||
"eqnull": true,
|
||||
|
||||
82
CHANGELOG.md
82
CHANGELOG.md
@@ -11,10 +11,82 @@
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 3.3.3
|
||||
## 3.4.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix conflicting `--module-ids` shorthand arg in `$ 6to5`.
|
||||
* Add require hook options to cache key.
|
||||
* Fix strict module formatter.
|
||||
|
||||
## 3.4.0
|
||||
|
||||
* **New Feature**
|
||||
* Add `commonStandard` module formatter.
|
||||
* **Bug Fix**
|
||||
* Fix conflicting `--module-ids` shorthand arg in `$ 6to5`.
|
||||
* **Internal**
|
||||
* Lots of internal refactoring with scope tracking and traversal.
|
||||
* **Polish**
|
||||
* Don't return `map` in the API result if `sourceMap` was set to `"inline"`.
|
||||
|
||||
## 3.3.12
|
||||
|
||||
* **Bug Fix**
|
||||
* Don't override `MemberExpression`s with `core-js` in `selfContained` if a local binding exists.
|
||||
|
||||
## 3.3.11
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix the require cache.
|
||||
|
||||
## 3.3.10
|
||||
|
||||
* **Internal**
|
||||
* Restructure transformers so they're only ran if the AST contains nodes that they need to worry about. Improves transpilation speed significantly.
|
||||
* **Bug Fix**
|
||||
* Fix source maps not tracking end of node locations.
|
||||
* **Spec Compliancy**
|
||||
* Use static super references as the home object is actually done at definition time.
|
||||
* **Polish**
|
||||
* Force the `es6.destructuring` transformer to be whitelisted when the `es7.objectSpread` transformer is.
|
||||
* Join sibling string literals when creating JSX.
|
||||
|
||||
## 3.3.9
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix super inside of functions.
|
||||
* Fix super constructor inheritance.
|
||||
|
||||
## 3.3.7
|
||||
|
||||
* **Bug Fix**
|
||||
* Add `--use-strict` to valid node flags in `6to5-node`.
|
||||
* Fix booleans not being properly stripped from the arguments in `6to5-node`.
|
||||
* Force `.js` extension when writing files to directories with `6to5`.
|
||||
|
||||
## 3.3.5
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix block scoping inside of while loops.
|
||||
* Make module name regex more conservative. Thanks [@johlrich](https://github.com/johlrich)!
|
||||
* Fix block scoping of constants.
|
||||
* Fix istanbul interop.
|
||||
* Make JSX transforming more inline with the official transformer with spaces after non-empty last lines.
|
||||
* **Polish**
|
||||
* Make it illegal to export a property called `__esModule`.
|
||||
|
||||
## 3.3.4
|
||||
|
||||
* **Polish**
|
||||
* Add istanbul `require` interop.
|
||||
* **Bug Fix**
|
||||
* Fix incorrect source map column tracking in specific scenarios.
|
||||
|
||||
## 3.3.3
|
||||
|
||||
* **Polish**
|
||||
* Remap top level `this` to `undefined` instead of throwing an error.
|
||||
* **Bug Fix**
|
||||
* Run `selfContained` transformer over the regenerator runtime when building `6to5-runtime`.
|
||||
* Fix `t.isReferenced` not properly allowing `value` nodes.
|
||||
|
||||
@@ -325,8 +397,8 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
* **Polish**
|
||||
* Rest parameters now allocate the array before populating.
|
||||
* **Internal**
|
||||
* `for...in` loops have been changed to optimised `for` loops - better performance and no enumeration of protoype keys.
|
||||
* Parts of the code generator have now been optimised thanks to [gaearon](https://github.com/gaearon).
|
||||
* `for...in` loops have been changed to optimized `for` loops - better performance and no enumeration of protoype keys.
|
||||
* Parts of the code generator have now been optimized thanks to [gaearon](https://github.com/gaearon).
|
||||
|
||||
## 2.12.3
|
||||
|
||||
@@ -349,7 +421,7 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
* **Bug Fix**
|
||||
* Support non-string JSX literals.
|
||||
* **New Feature**
|
||||
* Loose mode for some transformers that enables non-spec behaviour.
|
||||
* Loose mode for some transformers that enables non-spec behavior.
|
||||
* **Internal**
|
||||
* Uglify `--mangle sort` has been added to the build script, cutting minified scripts in half.
|
||||
|
||||
@@ -787,7 +859,7 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 1.13.2
|
||||
|
||||
* Optimise `Array.from` usage by adding a helper method.
|
||||
* Optimize `Array.from` usage by adding a helper method.
|
||||
* Upgrade `acorn-6to5`.
|
||||
|
||||
## 1.13.1
|
||||
|
||||
4
Makefile
4
Makefile
@@ -18,7 +18,7 @@ build:
|
||||
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
|
||||
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
|
||||
|
||||
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
|
||||
node $(BROWSERIFY_CMD) lib/6to5/api/browser.js -s to5 >dist/6to5.js
|
||||
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
|
||||
|
||||
node bin/6to5-runtime >dist/runtime.js
|
||||
@@ -92,7 +92,7 @@ publish:
|
||||
make publish-core
|
||||
make publish-runtime
|
||||
|
||||
rm -rf templates.json browser.js browser-polyfill.js
|
||||
rm -rf templates.json browser.js browser-polyfill.js runtime.js
|
||||
|
||||
publish-runtime:
|
||||
cd packages; \
|
||||
|
||||
2
NOTES.md
2
NOTES.md
@@ -1,3 +1,3 @@
|
||||
# Notes
|
||||
|
||||
* Wildcard exports/imports wont normalise if `export default` is a non-object. See [#224](https://github.com/6to5/6to5/issues/224).
|
||||
* Wildcard exports/imports wont normalize if `export default` is a non-object. See [#224](https://github.com/6to5/6to5/issues/224).
|
||||
|
||||
7
bin/6to5-minify
Executable file
7
bin/6to5-minify
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var opts = require("./6to5").opts;
|
||||
opts.optional = (opts.optional || []).concat("minification");
|
||||
opts.format = {
|
||||
compact: true
|
||||
};
|
||||
@@ -5,7 +5,7 @@
|
||||
* when found, before invoking the "real" _6to5-node(1) executable.
|
||||
*/
|
||||
|
||||
var args = ["--harmony", __dirname + "/_6to5-node"];
|
||||
var args = [__dirname + "/_6to5-node"];
|
||||
|
||||
process.argv.slice(2).forEach(function(arg){
|
||||
var flag = arg.split("=")[0];
|
||||
@@ -35,6 +35,7 @@ process.argv.slice(2).forEach(function(arg){
|
||||
case "--prof":
|
||||
case "--throw-deprecation":
|
||||
case "--trace-deprecation":
|
||||
case "--use-strict":
|
||||
args.unshift(arg);
|
||||
break;
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ module.exports = function (commander, filenames, opts) {
|
||||
}
|
||||
|
||||
var write = function (src, relative) {
|
||||
// remove extension and then append back on .js
|
||||
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
|
||||
|
||||
var dest = path.join(commander.outDir, relative);
|
||||
|
||||
var data = util.compile(src, { sourceMapName: dest });
|
||||
|
||||
@@ -23,7 +23,7 @@ commander.option("-L, --loose [list]", "List of transformers to enable loose mod
|
||||
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
|
||||
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
|
||||
commander.option("-c, --remove-comments", "Remove comments from the compiled code", false);
|
||||
commander.option("-m, --module-ids", "Insert module id in modules", false);
|
||||
commander.option("-M, --module-ids", "Insert module id in modules", false);
|
||||
commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code");
|
||||
commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false);
|
||||
|
||||
@@ -114,12 +114,17 @@ exports.opts = {
|
||||
loose: commander.loose
|
||||
};
|
||||
|
||||
var fn;
|
||||
setTimeout(function () {
|
||||
// this is just a hack to give `6to5-minify` and other files including this
|
||||
// time to modify `exports.opts`
|
||||
|
||||
if (commander.outDir) {
|
||||
fn = require("./dir");
|
||||
} else {
|
||||
fn = require("./file");
|
||||
}
|
||||
var fn;
|
||||
|
||||
fn(commander, filenames, exports.opts);
|
||||
if (commander.outDir) {
|
||||
fn = require("./dir");
|
||||
} else {
|
||||
fn = require("./file");
|
||||
}
|
||||
|
||||
fn(commander, filenames, exports.opts);
|
||||
}, 0);
|
||||
|
||||
@@ -2,7 +2,7 @@ var readdir = require("fs-readdir-recursive");
|
||||
var index = require("./index");
|
||||
var util = require("../../lib/6to5/util");
|
||||
var path = require("path");
|
||||
var to5 = require("../../lib/6to5");
|
||||
var to5 = require("../../lib/6to5/api/node");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ var commander = require("commander");
|
||||
var Module = require("module");
|
||||
var path = require("path");
|
||||
var repl = require("repl");
|
||||
var to5 = require("../lib/6to5");
|
||||
var to5 = require("../lib/6to5/api/node");
|
||||
var util = require("../lib/6to5/util");
|
||||
var vm = require("vm");
|
||||
var _ = require("lodash");
|
||||
@@ -72,7 +72,8 @@ if (program.eval || program.print) {
|
||||
}
|
||||
|
||||
if (arg[0] === "-") {
|
||||
if (program[arg.slice(2)]) {
|
||||
var parsedArg = program[arg.slice(2)];
|
||||
if (parsedArg && parsedArg !== true) {
|
||||
ignoreNext = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var transform = module.exports = require("./transformation");
|
||||
var transform = module.exports = require("../transformation");
|
||||
|
||||
transform.version = require("../../package").version;
|
||||
transform.version = require("../../../package").version;
|
||||
|
||||
transform.transform = transform;
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
var transform = require("./transformation");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var isFunction = require("lodash/lang/isFunction");
|
||||
var transform = require("../transformation");
|
||||
var util = require("../util");
|
||||
var fs = require("fs");
|
||||
|
||||
exports.version = require("../../package").version;
|
||||
exports.version = require("../../../package").version;
|
||||
|
||||
exports.runtime = require("./build-runtime");
|
||||
exports.runtime = require("../build-runtime");
|
||||
|
||||
exports.types = require("./types");
|
||||
exports.types = require("../types");
|
||||
|
||||
exports.register = function (opts) {
|
||||
var register = require("./register");
|
||||
var register = require("./register/node");
|
||||
if (opts != null) register(opts);
|
||||
return register;
|
||||
};
|
||||
|
||||
exports.polyfill = function () {
|
||||
require("./polyfill");
|
||||
require("../polyfill");
|
||||
};
|
||||
|
||||
exports.canCompile = util.canCompile;
|
||||
@@ -4,4 +4,4 @@
|
||||
|
||||
module.exports = function () {};
|
||||
|
||||
require("./polyfill");
|
||||
require("../../polyfill");
|
||||
@@ -12,14 +12,6 @@ exports.save = function () {
|
||||
};
|
||||
|
||||
exports.load = function () {
|
||||
if (!fs.existsSync(FILENAME)) return;
|
||||
|
||||
try {
|
||||
data = JSON.parse(fs.readFileSync(FILENAME));
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
process.on("exit", exports.save);
|
||||
|
||||
var sigint = function () {
|
||||
@@ -29,6 +21,14 @@ exports.load = function () {
|
||||
};
|
||||
|
||||
process.on("SIGINT", sigint);
|
||||
|
||||
if (!fs.existsSync(FILENAME)) return;
|
||||
|
||||
try {
|
||||
data = JSON.parse(fs.readFileSync(FILENAME));
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
exports.get = function () {
|
||||
152
lib/6to5/api/register/node.js
Normal file
152
lib/6to5/api/register/node.js
Normal file
@@ -0,0 +1,152 @@
|
||||
"use strict";
|
||||
|
||||
require("../../polyfill");
|
||||
|
||||
var sourceMapSupport = require("source-map-support");
|
||||
var registerCache = require("./cache");
|
||||
var extend = require("lodash/object/extend");
|
||||
var each = require("lodash/collection/each");
|
||||
var util = require("../../util");
|
||||
var to5 = require("../node");
|
||||
var fs = require("fs");
|
||||
|
||||
sourceMapSupport.install({
|
||||
retrieveSourceMap: function (source) {
|
||||
var map = maps && maps[source];
|
||||
if (map) {
|
||||
return {
|
||||
url: null,
|
||||
map: map
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
registerCache.load();
|
||||
var cache = registerCache.get();
|
||||
|
||||
//
|
||||
|
||||
var transformOpts = {};
|
||||
var ignoreRegex = /node_modules/;
|
||||
var onlyRegex;
|
||||
var exts = {};
|
||||
var maps = {};
|
||||
|
||||
var mtime = function (filename) {
|
||||
return +fs.statSync(filename).mtime;
|
||||
};
|
||||
|
||||
var compile = function (filename) {
|
||||
var result;
|
||||
|
||||
var cacheKey = filename + ":" + JSON.stringify(transformOpts);
|
||||
|
||||
if (cache) {
|
||||
var cached = cache[cacheKey];
|
||||
if (cached && cached.mtime === mtime(filename)) {
|
||||
result = cached;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = to5.transformFileSync(filename, extend({
|
||||
sourceMap: true,
|
||||
ast: false
|
||||
}, transformOpts));
|
||||
}
|
||||
|
||||
if (cache) {
|
||||
result.mtime = mtime(filename);
|
||||
cache[cacheKey] = result;
|
||||
}
|
||||
|
||||
maps[filename] = result.map;
|
||||
|
||||
return result.code;
|
||||
};
|
||||
|
||||
var shouldIgnore = function (filename) {
|
||||
return (ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename));
|
||||
};
|
||||
|
||||
var istanbulMonkey = {};
|
||||
|
||||
if (process.env.running_under_istanbul) { // jshint ignore:line
|
||||
// we need to monkey patch fs.readFileSync so we can hook into
|
||||
// what istanbul gets, it's extremely dirty but it's the only way
|
||||
var _readFileSync = fs.readFileSync;
|
||||
|
||||
fs.readFileSync = function (filename) {
|
||||
if (istanbulMonkey[filename]) {
|
||||
delete istanbulMonkey[filename];
|
||||
var code = compile(filename);
|
||||
istanbulMonkey[filename] = true;
|
||||
return code;
|
||||
} else {
|
||||
return _readFileSync.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var istanbulLoader = function (m, filename, old) {
|
||||
istanbulMonkey[filename] = true;
|
||||
old(m, filename);
|
||||
};
|
||||
|
||||
var normalLoader = function (m, filename) {
|
||||
m._compile(compile(filename), filename);
|
||||
};
|
||||
|
||||
var registerExtension = function (ext) {
|
||||
var old = require.extensions[ext];
|
||||
|
||||
var loader = normalLoader;
|
||||
if (process.env.running_under_istanbul) loader = istanbulLoader; // jshint ignore:line
|
||||
|
||||
require.extensions[ext] = function (m, filename) {
|
||||
if (shouldIgnore(filename)) {
|
||||
old(m, filename);
|
||||
} else {
|
||||
loader(m, filename, old);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var hookExtensions = function (_exts) {
|
||||
each(exts, function (old, ext) {
|
||||
require.extensions[ext] = old;
|
||||
});
|
||||
|
||||
exts = {};
|
||||
|
||||
each(_exts, function (ext) {
|
||||
exts[ext] = require.extensions[ext];
|
||||
registerExtension(ext);
|
||||
});
|
||||
};
|
||||
|
||||
hookExtensions(util.canCompile.EXTENSIONS);
|
||||
|
||||
module.exports = function (opts) {
|
||||
// normalize options
|
||||
opts = opts || {};
|
||||
|
||||
if (opts.only != null) onlyRegex = util.regexify(opts.only);
|
||||
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
|
||||
|
||||
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
|
||||
|
||||
if (opts.cache === false) cache = null;
|
||||
|
||||
delete opts.extensions;
|
||||
delete opts.ignore;
|
||||
delete opts.cache;
|
||||
delete opts.only;
|
||||
|
||||
extend(transformOpts, opts);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
var File = require("./file");
|
||||
var File = require("./transformation/file");
|
||||
var util = require("./util");
|
||||
var each = require("lodash/collection/each");
|
||||
var t = require("./types");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module.exports = detect;
|
||||
|
||||
var SYNTAX_KEYS = require("./syntax-keys");
|
||||
var traverse = require("../traverse");
|
||||
var traverse = require("../traversal");
|
||||
var visitors = traverse.explode(require("./visitors"));
|
||||
|
||||
function detect(ast) {
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
module.exports = Buffer;
|
||||
|
||||
var util = require("../util");
|
||||
var isNumber = require("lodash/lang/isNumber");
|
||||
var isBoolean = require("lodash/lang/isBoolean");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var isNumber = require("lodash/lang/isNumber");
|
||||
var util = require("../util");
|
||||
|
||||
function Buffer(position, format) {
|
||||
this.position = position;
|
||||
@@ -19,7 +19,7 @@ Buffer.prototype.get = function () {
|
||||
};
|
||||
|
||||
Buffer.prototype.getIndent = function () {
|
||||
if (this.format.compact) {
|
||||
if (this.format.compact || this.format.concise) {
|
||||
return "";
|
||||
} else {
|
||||
return util.repeat(this._indent, this.format.indent.style);
|
||||
@@ -53,10 +53,12 @@ Buffer.prototype.rightBrace = function () {
|
||||
|
||||
Buffer.prototype.keyword = function (name) {
|
||||
this.push(name);
|
||||
this.push(" ");
|
||||
this.space();
|
||||
};
|
||||
|
||||
Buffer.prototype.space = function () {
|
||||
if (this.format.compact) return;
|
||||
|
||||
if (this.buf && !this.isLast([" ", "\n"])) {
|
||||
this.push(" ");
|
||||
}
|
||||
@@ -70,7 +72,7 @@ Buffer.prototype.removeLast = function (cha) {
|
||||
};
|
||||
|
||||
Buffer.prototype.newline = function (i, removeLast) {
|
||||
if (this.format.compact) {
|
||||
if (this.format.compact || this.format.concise) {
|
||||
this.space();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ exports.UnaryExpression = function (node, print) {
|
||||
}
|
||||
|
||||
this.push(node.operator);
|
||||
if (hasSpace) this.space();
|
||||
if (hasSpace) this.push(" ");
|
||||
print(node.argument);
|
||||
};
|
||||
|
||||
@@ -33,9 +33,13 @@ exports.UpdateExpression = function (node, print) {
|
||||
|
||||
exports.ConditionalExpression = function (node, print) {
|
||||
print(node.test);
|
||||
this.push(" ? ");
|
||||
this.space();
|
||||
this.push("?");
|
||||
this.space();
|
||||
print(node.consequent);
|
||||
this.push(" : ");
|
||||
this.space();
|
||||
this.push(":");
|
||||
this.space();
|
||||
print(node.alternate);
|
||||
};
|
||||
|
||||
@@ -44,13 +48,13 @@ exports.NewExpression = function (node, print) {
|
||||
print(node.callee);
|
||||
if (node.arguments.length || this.format.parentheses) {
|
||||
this.push("(");
|
||||
print.join(node.arguments, { separator: ", " });
|
||||
print.list(node.arguments);
|
||||
this.push(")");
|
||||
}
|
||||
};
|
||||
|
||||
exports.SequenceExpression = function (node, print) {
|
||||
print.join(node.expressions, { separator: ", " });
|
||||
print.list(node.expressions);
|
||||
};
|
||||
|
||||
exports.ThisExpression = function () {
|
||||
@@ -72,9 +76,7 @@ exports.CallExpression = function (node, print) {
|
||||
separator += " ";
|
||||
}
|
||||
|
||||
print.join(node.arguments, {
|
||||
separator: separator
|
||||
});
|
||||
print.list(node.arguments, { separator: separator });
|
||||
|
||||
if (node._prettyCall) {
|
||||
this.newline();
|
||||
@@ -115,10 +117,11 @@ exports.BinaryExpression =
|
||||
exports.LogicalExpression =
|
||||
exports.AssignmentPattern =
|
||||
exports.AssignmentExpression = function (node, print) {
|
||||
// todo: add cases where the spaces can be dropped when in compact mode
|
||||
print(node.left);
|
||||
this.space();
|
||||
this.push(" ");
|
||||
this.push(node.operator);
|
||||
this.space();
|
||||
this.push(" ");
|
||||
print(node.right);
|
||||
};
|
||||
|
||||
|
||||
@@ -75,6 +75,4 @@ exports.JSXClosingElement = function (node, print) {
|
||||
this.push(">");
|
||||
};
|
||||
|
||||
exports.JSXEmptyExpression = function () {
|
||||
|
||||
};
|
||||
exports.JSXEmptyExpression = function () {};
|
||||
|
||||
@@ -4,11 +4,7 @@ var t = require("../../types");
|
||||
|
||||
exports._params = function (node, print) {
|
||||
this.push("(");
|
||||
|
||||
print.join(node.params, {
|
||||
separator: ", "
|
||||
});
|
||||
|
||||
print.list(node.params);
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
@@ -45,11 +41,14 @@ exports.FunctionExpression = function (node, print) {
|
||||
if (node.async) this.push("async ");
|
||||
this.push("function");
|
||||
if (node.generator) this.push("*");
|
||||
this.push(" ");
|
||||
|
||||
if (node.id) {
|
||||
this.space();
|
||||
this.push(" ");
|
||||
print(node.id);
|
||||
} else {
|
||||
this.space();
|
||||
}
|
||||
|
||||
this._params(node, print);
|
||||
this.space();
|
||||
print(node.body);
|
||||
|
||||
@@ -23,6 +23,11 @@ exports.IfStatement = function (node, print) {
|
||||
if (node.alternate) {
|
||||
if (this.isLast("}")) this.push(" ");
|
||||
this.keyword("else");
|
||||
|
||||
if (this.format.format && !t.isBlockStatement(node.alternate)) {
|
||||
this.push(" ");
|
||||
}
|
||||
|
||||
print.indentOnComments(node.alternate);
|
||||
}
|
||||
};
|
||||
@@ -190,7 +195,7 @@ exports.VariableDeclaration = function (node, print, parent) {
|
||||
sep += " ";
|
||||
}
|
||||
|
||||
print.join(node.declarations, { separator: sep });
|
||||
print.list(node.declarations, { separator: sep });
|
||||
|
||||
if (!t.isFor(parent)) {
|
||||
this.semicolon();
|
||||
|
||||
@@ -27,7 +27,7 @@ exports.ObjectPattern = function (node, print) {
|
||||
this.push("{");
|
||||
this.space();
|
||||
|
||||
print.join(props, { separator: ", ", indent: true });
|
||||
print.list(props, { indent: true });
|
||||
|
||||
this.space();
|
||||
this.push("}");
|
||||
@@ -49,7 +49,8 @@ exports.Property = function (node, print) {
|
||||
if (node.shorthand) return;
|
||||
}
|
||||
|
||||
this.push(": ");
|
||||
this.push(":");
|
||||
this.space();
|
||||
print(node.value);
|
||||
}
|
||||
};
|
||||
@@ -71,7 +72,7 @@ exports.ArrayPattern = function (node, print) {
|
||||
// both (all) of the holes.
|
||||
self.push(",");
|
||||
} else {
|
||||
if (i > 0) self.push(" ");
|
||||
if (i > 0 && !self.format.compact) self.push(" ");
|
||||
print(elem);
|
||||
if (i < len - 1) self.push(",");
|
||||
}
|
||||
@@ -93,8 +94,10 @@ exports.Literal = function (node) {
|
||||
});
|
||||
|
||||
this.push(val);
|
||||
} else if (type === "boolean" || type === "number") {
|
||||
this.push(JSON.stringify(val));
|
||||
} else if (type === "number") {
|
||||
this.push(val + "");
|
||||
} else if (type === "boolean") {
|
||||
this.push(val ? "true" : "false");
|
||||
} else if (node.regex) {
|
||||
this.push("/" + node.regex.pattern + "/" + node.regex.flags);
|
||||
} else if (val === null) {
|
||||
|
||||
@@ -12,19 +12,20 @@ var Whitespace = require("./whitespace");
|
||||
var SourceMap = require("./source-map");
|
||||
var Position = require("./position");
|
||||
var Buffer = require("./buffer");
|
||||
var extend = require("lodash/object/extend");
|
||||
var merge = require("lodash/object/merge");
|
||||
var each = require("lodash/collection/each");
|
||||
var util = require("../util");
|
||||
var n = require("./node");
|
||||
var t = require("../types");
|
||||
var each = require("lodash/collection/each");
|
||||
var extend = require("lodash/object/extend");
|
||||
var merge = require("lodash/object/merge");
|
||||
|
||||
function CodeGenerator(ast, opts, code) {
|
||||
opts = opts || {};
|
||||
|
||||
this.comments = ast.comments || [];
|
||||
this.tokens = ast.tokens || [];
|
||||
this.format = CodeGenerator.normaliseOptions(code, opts);
|
||||
this.format = CodeGenerator.normalizeOptions(code, opts);
|
||||
this.opts = opts;
|
||||
this.ast = ast;
|
||||
|
||||
this.whitespace = new Whitespace(this.tokens, this.comments);
|
||||
@@ -39,7 +40,7 @@ each(Buffer.prototype, function (fn, key) {
|
||||
};
|
||||
});
|
||||
|
||||
CodeGenerator.normaliseOptions = function (code, opts) {
|
||||
CodeGenerator.normalizeOptions = function (code, opts) {
|
||||
var style = " ";
|
||||
if (code) {
|
||||
var indent = detectIndent(code).indent;
|
||||
@@ -50,6 +51,7 @@ CodeGenerator.normaliseOptions = function (code, opts) {
|
||||
parentheses: true,
|
||||
comments: opts.comments == null || opts.comments,
|
||||
compact: false,
|
||||
concise: false,
|
||||
indent: {
|
||||
adjustMultilineComment: true,
|
||||
style: style,
|
||||
@@ -111,6 +113,16 @@ CodeGenerator.prototype.buildPrint = function (parent) {
|
||||
return self.printJoin(print, nodes, opts);
|
||||
};
|
||||
|
||||
print.list = function (items, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
var sep = opts.separator || ", ";
|
||||
if (self.format.compact) sep = ",";
|
||||
opts.separator = sep;
|
||||
|
||||
print.join(items, opts);
|
||||
};
|
||||
|
||||
print.block = function (node) {
|
||||
return self.printBlock(print, node);
|
||||
};
|
||||
@@ -129,9 +141,9 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
node._compact = true;
|
||||
}
|
||||
|
||||
var oldCompact = this.format.compact;
|
||||
var oldConcise = this.format.concise;
|
||||
if (node._compact) {
|
||||
this.format.compact = true;
|
||||
this.format.concise = true;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
@@ -199,7 +211,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
throw new ReferenceError("unknown node of type " + JSON.stringify(node.type) + " with constructor " + JSON.stringify(node && node.constructor.name));
|
||||
}
|
||||
|
||||
this.format.compact = oldCompact;
|
||||
this.format.concise = oldConcise;
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printJoin = function (print, nodes, opts) {
|
||||
|
||||
@@ -48,8 +48,6 @@ SourceMap.prototype.mark = function (node, type) {
|
||||
|
||||
var original = loc[type];
|
||||
|
||||
if (generated.line === original.line && generated.column === original.column) return; // nothing to map
|
||||
|
||||
map.addMapping({
|
||||
source: this.opts.sourceFileName,
|
||||
generated: generated,
|
||||
|
||||
9
lib/6to5/helpers/normalize-ast.js
Normal file
9
lib/6to5/helpers/normalize-ast.js
Normal file
@@ -0,0 +1,9 @@
|
||||
var t = require("../types");
|
||||
|
||||
module.exports = function (ast, comments, tokens) {
|
||||
if (ast && ast.type === "Program") {
|
||||
return t.file(ast, comments || [], tokens || []);
|
||||
} else {
|
||||
throw new Error("Not a valid ast?");
|
||||
}
|
||||
};
|
||||
49
lib/6to5/helpers/parse.js
Normal file
49
lib/6to5/helpers/parse.js
Normal file
@@ -0,0 +1,49 @@
|
||||
var normalizeAst = require("./normalize-ast");
|
||||
var estraverse = require("estraverse");
|
||||
var codeFrame = require("./code-frame");
|
||||
var acorn = require("acorn-6to5");
|
||||
|
||||
module.exports = function (opts, code, callback) {
|
||||
try {
|
||||
var comments = [];
|
||||
var tokens = [];
|
||||
|
||||
var ast = acorn.parse(code, {
|
||||
allowImportExportEverywhere: opts.allowImportExportEverywhere,
|
||||
allowReturnOutsideFunction: !opts._anal,
|
||||
ecmaVersion: opts.experimental ? 7 : 6,
|
||||
playground: opts.playground,
|
||||
strictMode: opts.strictMode,
|
||||
onComment: comments,
|
||||
locations: true,
|
||||
onToken: tokens,
|
||||
ranges: true
|
||||
});
|
||||
|
||||
estraverse.attachComments(ast, comments, tokens);
|
||||
|
||||
ast = normalizeAst(ast, comments, tokens);
|
||||
|
||||
if (callback) {
|
||||
return callback(ast);
|
||||
} else {
|
||||
return ast;
|
||||
}
|
||||
} catch (err) {
|
||||
if (!err._6to5) {
|
||||
err._6to5 = true;
|
||||
var message = opts.filename + ": " + err.message;
|
||||
|
||||
var loc = err.loc;
|
||||
if (loc) {
|
||||
var frame = codeFrame(code, loc.line, loc.column + 1);
|
||||
message += frame;
|
||||
}
|
||||
|
||||
if (err.stack) err.stack = err.stack.replace(err.message, message);
|
||||
err.message = message;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("./types");
|
||||
var extend = require("lodash/object/extend");
|
||||
var t = require("./types");
|
||||
|
||||
require("./types/node");
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
require("./polyfill");
|
||||
|
||||
var sourceMapSupport = require("source-map-support");
|
||||
var registerCache = require("./register-cache");
|
||||
var util = require("./util");
|
||||
var to5 = require("./index");
|
||||
var fs = require("fs");
|
||||
var extend = require("lodash/object/extend");
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
sourceMapSupport.install({
|
||||
retrieveSourceMap: function (source) {
|
||||
var map = maps && maps[source];
|
||||
if (map) {
|
||||
return {
|
||||
url: null,
|
||||
map: map
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
registerCache.load();
|
||||
var cache = registerCache.get();
|
||||
|
||||
//
|
||||
|
||||
var transformOpts = {};
|
||||
var ignoreRegex = /node_modules/;
|
||||
var onlyRegex;
|
||||
var whitelist = [];
|
||||
var exts = {};
|
||||
var maps = {};
|
||||
var old = require.extensions[".js"];
|
||||
|
||||
var mtime = function (filename) {
|
||||
return +fs.statSync(filename).mtime;
|
||||
};
|
||||
|
||||
var loader = function (m, filename) {
|
||||
if ((ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename))) {
|
||||
return old.apply(this, arguments);
|
||||
}
|
||||
|
||||
var result;
|
||||
|
||||
if (cache) {
|
||||
var cached = cache[filename];
|
||||
if (cached && cached.mtime === mtime(filename)) {
|
||||
result = cached;
|
||||
}
|
||||
}
|
||||
|
||||
result = result || to5.transformFileSync(filename, extend({
|
||||
whitelist: whitelist,
|
||||
sourceMap: true,
|
||||
ast: false
|
||||
}, transformOpts));
|
||||
|
||||
if (cache) {
|
||||
result.mtime = mtime(filename);
|
||||
cache[filename] = result;
|
||||
}
|
||||
|
||||
maps[filename] = result.map;
|
||||
|
||||
m._compile(result.code, filename);
|
||||
};
|
||||
|
||||
var hookExtensions = function (_exts) {
|
||||
each(exts, function (old, ext) {
|
||||
require.extensions[ext] = old;
|
||||
});
|
||||
|
||||
exts = {};
|
||||
|
||||
each(_exts, function (ext) {
|
||||
exts[ext] = require.extensions[ext];
|
||||
require.extensions[ext] = loader;
|
||||
});
|
||||
};
|
||||
|
||||
hookExtensions(util.canCompile.EXTENSIONS);
|
||||
|
||||
module.exports = function (opts) {
|
||||
// normalise options
|
||||
opts = opts || {};
|
||||
|
||||
if (opts.only != null) onlyRegex = util.regexify(opts.only);
|
||||
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
|
||||
|
||||
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
|
||||
|
||||
if (opts.cache === false) cache = null;
|
||||
|
||||
delete opts.extensions;
|
||||
delete opts.ignore;
|
||||
delete opts.cache;
|
||||
delete opts.only;
|
||||
|
||||
extend(transformOpts, opts);
|
||||
};
|
||||
@@ -4,16 +4,18 @@ module.exports = File;
|
||||
|
||||
var SHEBANG_REGEX = /^\#\!.*/;
|
||||
|
||||
var transform = require("./transformation");
|
||||
var generate = require("./generation");
|
||||
var clone = require("./helpers/clone");
|
||||
var Scope = require("./traverse/scope");
|
||||
var util = require("./util");
|
||||
var t = require("./types");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var each = require("lodash/collection/each");
|
||||
var defaults = require("lodash/object/defaults");
|
||||
var isFunction = require("lodash/lang/isFunction");
|
||||
var transform = require("./index");
|
||||
var generate = require("../generation");
|
||||
var defaults = require("lodash/object/defaults");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var clone = require("../helpers/clone");
|
||||
var parse = require("../helpers/parse");
|
||||
var Scope = require("../traversal/scope");
|
||||
var util = require("../util");
|
||||
var path = require("path");
|
||||
var each = require("lodash/collection/each");
|
||||
var t = require("../types");
|
||||
|
||||
function File(opts) {
|
||||
this.dynamicImportIds = {};
|
||||
@@ -24,7 +26,7 @@ function File(opts) {
|
||||
this.data = {};
|
||||
|
||||
this.lastStatements = [];
|
||||
this.opts = this.normaliseOptions(opts);
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.ast = {};
|
||||
|
||||
this.buildTransformers();
|
||||
@@ -50,7 +52,9 @@ File.helpers = [
|
||||
"typeof",
|
||||
"extends",
|
||||
"get",
|
||||
"set"
|
||||
"set",
|
||||
"class-call-check",
|
||||
"object-destructuring-empty"
|
||||
];
|
||||
|
||||
File.validOptions = [
|
||||
@@ -85,7 +89,7 @@ File.validOptions = [
|
||||
"accept"
|
||||
];
|
||||
|
||||
File.prototype.normaliseOptions = function (opts) {
|
||||
File.prototype.normalizeOptions = function (opts) {
|
||||
opts = clone(opts);
|
||||
|
||||
for (var key in opts) {
|
||||
@@ -115,9 +119,11 @@ File.prototype.normaliseOptions = function (opts) {
|
||||
ast: true
|
||||
});
|
||||
|
||||
// normalise windows path separators to unix
|
||||
// normalize windows path separators to unix
|
||||
opts.filename = opts.filename.replace(/\\/g, "/");
|
||||
|
||||
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);
|
||||
@@ -154,8 +160,14 @@ File.prototype.normaliseOptions = function (opts) {
|
||||
|
||||
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);
|
||||
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` - backwards compatibility will be removed in v4.0.0");
|
||||
}
|
||||
|
||||
return opts;
|
||||
};
|
||||
@@ -177,6 +189,7 @@ File.prototype.buildTransformers = function () {
|
||||
|
||||
if (pass.canRun(file)) {
|
||||
stack.push(pass);
|
||||
|
||||
if (transformer.secondPass) {
|
||||
secondaryStack.push(pass);
|
||||
}
|
||||
@@ -191,6 +204,12 @@ File.prototype.buildTransformers = function () {
|
||||
this.transformers = transformers;
|
||||
};
|
||||
|
||||
File.prototype.debug = function (msg) {
|
||||
var parts = this.opts.filename;
|
||||
if (msg) parts += ": " + msg;
|
||||
util.debug(parts);
|
||||
};
|
||||
|
||||
File.prototype.toArray = function (node, i) {
|
||||
if (t.isArrayExpression(node)) {
|
||||
return node;
|
||||
@@ -328,16 +347,14 @@ File.prototype.parse = function (code) {
|
||||
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
|
||||
//opts.strictMode = this.transformers.useStrict.canRun();
|
||||
|
||||
return util.parse(opts, code, function (tree) {
|
||||
return parse(opts, code, function (tree) {
|
||||
self.transform(tree);
|
||||
return self.generate();
|
||||
});
|
||||
};
|
||||
|
||||
File.prototype.transform = function (ast) {
|
||||
var self = this;
|
||||
|
||||
util.debug(this.opts.filename);
|
||||
this.debug();
|
||||
|
||||
this.ast = ast;
|
||||
this.lastStatements = t.getLastStatements(ast.program);
|
||||
@@ -348,19 +365,49 @@ File.prototype.transform = function (ast) {
|
||||
modFormatter.init();
|
||||
}
|
||||
|
||||
var astRun = function (key) {
|
||||
each(self.transformerStack, function (pass) {
|
||||
pass.astRun(key);
|
||||
});
|
||||
};
|
||||
this.checkNode(ast);
|
||||
|
||||
astRun("enter");
|
||||
this.call("pre");
|
||||
|
||||
each(this.transformerStack, function (pass) {
|
||||
pass.transform();
|
||||
});
|
||||
|
||||
astRun("exit");
|
||||
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 = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
checkNode(state.stack, node, scope);
|
||||
}
|
||||
};
|
||||
|
||||
var checkNode = function (stack, node, scope) {
|
||||
each(stack, function (pass) {
|
||||
if (pass.shouldRun) return;
|
||||
pass.checkNode(node, scope);
|
||||
});
|
||||
};
|
||||
|
||||
File.prototype.checkNode = function (node, scope) {
|
||||
var stack = this.transformerStack;
|
||||
scope = scope || this.scope;
|
||||
|
||||
checkNode(stack, node, scope);
|
||||
|
||||
scope.traverse(node, checkTransformerVisitor, {
|
||||
stack: stack
|
||||
});
|
||||
};
|
||||
|
||||
File.prototype.generate = function () {
|
||||
@@ -387,6 +434,7 @@ File.prototype.generate = function () {
|
||||
|
||||
if (opts.sourceMap === "inline") {
|
||||
result.code += "\n" + util.sourceMapToComment(result.map);
|
||||
result.map = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -402,14 +450,14 @@ File.prototype.generateUid = function (name, scope) {
|
||||
do {
|
||||
uid = this._generateUid(name, i);
|
||||
i++;
|
||||
} while (scope.has(uid));
|
||||
} while (scope.hasReference(uid));
|
||||
return uid;
|
||||
};
|
||||
|
||||
File.prototype.generateUidIdentifier = function (name, scope) {
|
||||
scope = scope || this.scope;
|
||||
var id = t.identifier(this.generateUid(name, scope));
|
||||
scope.add(id);
|
||||
scope.addDeclarationToFunctionScope("var", id);
|
||||
return id;
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ module.exports = function (exports, opts) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (file.isConsequenceExpressionStatement(node)) return;
|
||||
|
||||
@@ -29,7 +29,7 @@ module.exports = function (exports, opts) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
if (!isAssignment(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
@@ -8,7 +8,7 @@ module.exports = function (exports, opts) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (file.isConsequenceExpressionStatement(node)) return;
|
||||
|
||||
@@ -27,7 +27,7 @@ module.exports = function (exports, opts) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
if (!opts.is(node, file)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
278
lib/6to5/transformation/helpers/build-react-transformer.js
Normal file
278
lib/6to5/transformation/helpers/build-react-transformer.js
Normal file
@@ -0,0 +1,278 @@
|
||||
"use strict";
|
||||
|
||||
// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser)
|
||||
// https://github.com/RReverser/jsx-transpiler
|
||||
|
||||
// jsx
|
||||
|
||||
var isString = require("lodash/lang/isString");
|
||||
var esutils = require("esutils");
|
||||
var react = require("./react");
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (exports, opts) {
|
||||
exports.check = function (node) {
|
||||
if (t.isJSX(node)) return true;
|
||||
if (react.isCreateClass(node)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.JSXIdentifier = function (node, parent) {
|
||||
if (node.name === "this" && t.isReferenced(node, parent)) {
|
||||
return t.thisExpression();
|
||||
} else if (esutils.keyword.isIdentifierName(node.name)) {
|
||||
node.type = "Identifier";
|
||||
} else {
|
||||
return t.literal(node.name);
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXNamespacedName = function (node, parent, scope, file) {
|
||||
throw file.errorWithNode(node, "Namespace tags are not supported. ReactJSX is not XML.");
|
||||
};
|
||||
|
||||
exports.JSXMemberExpression = {
|
||||
exit: function (node) {
|
||||
node.computed = t.isLiteral(node.property);
|
||||
node.type = "MemberExpression";
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXExpressionContainer = function (node) {
|
||||
return node.expression;
|
||||
};
|
||||
|
||||
exports.JSXAttribute = {
|
||||
exit: function (node) {
|
||||
var value = node.value || t.literal(true);
|
||||
return t.inherits(t.property("init", node.name, value), node);
|
||||
}
|
||||
};
|
||||
exports.JSXOpeningElement = {
|
||||
exit: function (node, parent, scope, file) {
|
||||
var tagExpr = node.name;
|
||||
var args = [];
|
||||
|
||||
var tagName;
|
||||
if (t.isIdentifier(tagExpr)) {
|
||||
tagName = tagExpr.name;
|
||||
} else if (t.isLiteral(tagExpr)) {
|
||||
tagName = tagExpr.value;
|
||||
}
|
||||
|
||||
var state = {
|
||||
tagExpr: tagExpr,
|
||||
tagName: tagName,
|
||||
args: args
|
||||
};
|
||||
|
||||
if (opts.pre) {
|
||||
opts.pre(state);
|
||||
}
|
||||
|
||||
var attribs = node.attributes;
|
||||
if (attribs.length) {
|
||||
attribs = buildJSXOpeningElementAttributes(attribs, file);
|
||||
} else {
|
||||
attribs = t.literal(null);
|
||||
}
|
||||
|
||||
args.push(attribs);
|
||||
|
||||
if (opts.post) {
|
||||
opts.post(state);
|
||||
}
|
||||
|
||||
return state.call || t.callExpression(state.callee, args);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The logic for this is quite terse. It's because we need to
|
||||
* support spread elements. We loop over all attributes,
|
||||
* breaking on spreads, we then push a new object containg
|
||||
* all prior attributes to an array for later processing.
|
||||
*/
|
||||
|
||||
var buildJSXOpeningElementAttributes = function (attribs, file) {
|
||||
var _props = [];
|
||||
var objs = [];
|
||||
|
||||
var pushProps = function () {
|
||||
if (!_props.length) return;
|
||||
|
||||
objs.push(t.objectExpression(_props));
|
||||
_props = [];
|
||||
};
|
||||
|
||||
while (attribs.length) {
|
||||
var prop = attribs.shift();
|
||||
if (t.isJSXSpreadAttribute(prop)) {
|
||||
pushProps();
|
||||
objs.push(prop.argument);
|
||||
} else {
|
||||
_props.push(prop);
|
||||
}
|
||||
}
|
||||
|
||||
pushProps();
|
||||
|
||||
if (objs.length === 1) {
|
||||
// only one object
|
||||
attribs = objs[0];
|
||||
} else {
|
||||
// looks like we have multiple objects
|
||||
if (!t.isObjectExpression(objs[0])) {
|
||||
objs.unshift(t.objectExpression([]));
|
||||
}
|
||||
|
||||
// spread it
|
||||
attribs = t.callExpression(
|
||||
file.addHelper("extends"),
|
||||
objs
|
||||
);
|
||||
}
|
||||
|
||||
return attribs;
|
||||
};
|
||||
|
||||
exports.JSXElement = {
|
||||
exit: function (node) {
|
||||
var callExpr = node.openingElement;
|
||||
|
||||
for (var i = 0; i < node.children.length; i++) {
|
||||
var child = node.children[i];
|
||||
|
||||
if (t.isLiteral(child) && typeof child.value === "string") {
|
||||
cleanJSXElementLiteralChild(child, callExpr.arguments);
|
||||
continue;
|
||||
} else if (t.isJSXEmptyExpression(child)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
callExpr.arguments.push(child);
|
||||
}
|
||||
|
||||
callExpr.arguments = flatten(callExpr.arguments);
|
||||
|
||||
if (callExpr.arguments.length >= 3) {
|
||||
callExpr._prettyCall = true;
|
||||
}
|
||||
|
||||
return t.inherits(callExpr, node);
|
||||
}
|
||||
};
|
||||
|
||||
var isStringLiteral = function (node) {
|
||||
return t.isLiteral(node) && isString(node.value);
|
||||
};
|
||||
|
||||
var flatten = function (args) {
|
||||
var flattened = [];
|
||||
var last;
|
||||
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
var arg = args[i];
|
||||
if (isStringLiteral(arg) && isStringLiteral(last)) {
|
||||
last.value += arg.value;
|
||||
} else {
|
||||
last = arg;
|
||||
flattened.push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
return flattened;
|
||||
};
|
||||
|
||||
var cleanJSXElementLiteralChild = function (child, args) {
|
||||
var lines = child.value.split(/\r\n|\n|\r/);
|
||||
|
||||
var lastNonEmptyLine = 0;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
if (lines[i].match(/[^ \t]/)) {
|
||||
lastNonEmptyLine = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
|
||||
var isFirstLine = i === 0;
|
||||
var isLastLine = i === lines.length - 1;
|
||||
var isLastNonEmptyLine = i === lastNonEmptyLine;
|
||||
|
||||
// replace rendered whitespace tabs with spaces
|
||||
var trimmedLine = line.replace(/\t/g, " ");
|
||||
|
||||
// trim whitespace touching a newline
|
||||
if (!isFirstLine) {
|
||||
trimmedLine = trimmedLine.replace(/^[ ]+/, "");
|
||||
}
|
||||
|
||||
// trim whitespace touching an endline
|
||||
if (!isLastLine) {
|
||||
trimmedLine = trimmedLine.replace(/[ ]+$/, "");
|
||||
}
|
||||
|
||||
if (trimmedLine) {
|
||||
if (!isLastNonEmptyLine) {
|
||||
trimmedLine += " ";
|
||||
}
|
||||
|
||||
args.push(t.literal(trimmedLine));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// display names
|
||||
|
||||
var addDisplayName = function (id, call) {
|
||||
var props = call.arguments[0].properties;
|
||||
var safe = true;
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var prop = props[i];
|
||||
if (t.isIdentifier(prop.key, { name: "displayName" })) {
|
||||
safe = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (safe) {
|
||||
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
|
||||
}
|
||||
};
|
||||
|
||||
exports.ExportDeclaration = function (node, parent, scope, file) {
|
||||
if (node.default && react.isCreateClass(node.declaration)) {
|
||||
addDisplayName(file.opts.basename, node.declaration);
|
||||
}
|
||||
};
|
||||
|
||||
exports.AssignmentExpression =
|
||||
exports.Property =
|
||||
exports.VariableDeclarator = function (node) {
|
||||
var left, right;
|
||||
|
||||
if (t.isAssignmentExpression(node)) {
|
||||
left = node.left;
|
||||
right = node.right;
|
||||
} else if (t.isProperty(node)) {
|
||||
left = node.key;
|
||||
right = node.value;
|
||||
} else if (t.isVariableDeclarator(node)) {
|
||||
left = node.id;
|
||||
right = node.init;
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(left)) {
|
||||
left = left.property;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(left) && react.isCreateClass(right)) {
|
||||
addDisplayName(left.name, right);
|
||||
}
|
||||
};
|
||||
};
|
||||
73
lib/6to5/transformation/helpers/define-map.js
Normal file
73
lib/6to5/transformation/helpers/define-map.js
Normal file
@@ -0,0 +1,73 @@
|
||||
var cloneDeep = require("lodash/lang/cloneDeep");
|
||||
var traverse = require("../../traversal");
|
||||
var clone = require("lodash/lang/clone");
|
||||
var each = require("lodash/collection/each");
|
||||
var has = require("lodash/object/has");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.push = function (mutatorMap, key, kind, computed, value) {
|
||||
var alias;
|
||||
|
||||
if (t.isIdentifier(key)) {
|
||||
alias = key.name;
|
||||
if (computed) alias = "computed:" + alias;
|
||||
} else if (t.isLiteral(key)) {
|
||||
alias = String(key.value);
|
||||
} else {
|
||||
alias = JSON.stringify(traverse.removeProperties(cloneDeep(key)));
|
||||
}
|
||||
|
||||
var map;
|
||||
if (has(mutatorMap, alias)) {
|
||||
map = mutatorMap[alias];
|
||||
} else {
|
||||
map = {};
|
||||
}
|
||||
mutatorMap[alias] = map;
|
||||
|
||||
map._key = key;
|
||||
if (computed) {
|
||||
map._computed = true;
|
||||
}
|
||||
|
||||
map[kind] = value;
|
||||
};
|
||||
|
||||
exports.build = function (mutatorMap) {
|
||||
var objExpr = t.objectExpression([]);
|
||||
|
||||
each(mutatorMap, function (map) {
|
||||
var mapNode = t.objectExpression([]);
|
||||
|
||||
var propNode = t.property("init", map._key, mapNode, map._computed);
|
||||
|
||||
if (!map.get && !map.set) {
|
||||
map.writable = t.literal(true);
|
||||
}
|
||||
|
||||
if (map.enumerable === false) {
|
||||
delete map.enumerable;
|
||||
} else {
|
||||
map.enumerable = t.literal(true);
|
||||
}
|
||||
|
||||
map.configurable = t.literal(true);
|
||||
|
||||
each(map, function (node, key) {
|
||||
if (key[0] === "_") return;
|
||||
|
||||
node = clone(node);
|
||||
var inheritNode = node;
|
||||
if (t.isMethodDefinition(node)) node = node.value;
|
||||
|
||||
var prop = t.property("init", t.identifier(key), node);
|
||||
t.inheritsComments(prop, inheritNode);
|
||||
t.removeComments(inheritNode);
|
||||
mapNode.properties.push(prop);
|
||||
});
|
||||
|
||||
objExpr.properties.push(propNode);
|
||||
});
|
||||
|
||||
return objExpr;
|
||||
};
|
||||
@@ -5,7 +5,7 @@ var t = require("../../types");
|
||||
var getObjRef = function (node, nodes, file, scope) {
|
||||
var ref;
|
||||
if (t.isIdentifier(node)) {
|
||||
if (scope.has(node.name, true)) {
|
||||
if (scope.hasBinding(node.name)) {
|
||||
// this variable is declared in scope so we can be 100% sure
|
||||
// that evaluating it multiple times wont trigger a getter
|
||||
// or something else
|
||||
@@ -18,7 +18,7 @@ var getObjRef = function (node, nodes, file, scope) {
|
||||
} else if (t.isMemberExpression(node)) {
|
||||
ref = node.object;
|
||||
|
||||
if (t.isIdentifier(ref) && scope.has(ref.name)) {
|
||||
if (t.isIdentifier(ref) && scope.hasReference(ref.name)) {
|
||||
// the object reference that we need to save is locally declared
|
||||
// so as per the previous comment we can be 100% sure evaluating
|
||||
// it multiple times will be safe
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
// check if this node is an identifier that matches the same as our function id
|
||||
if (!t.isIdentifier(node, { name: state.id })) return;
|
||||
|
||||
@@ -14,11 +13,11 @@ var visitor = {
|
||||
|
||||
// check that we don't have a local variable declared as that removes the need
|
||||
// for the wrapper
|
||||
var localDeclar = scope.get(state.id, true);
|
||||
var localDeclar = scope.getBinding(state.id);
|
||||
if (localDeclar !== state.outerDeclar) return;
|
||||
|
||||
state.selfReference = true;
|
||||
context.stop();
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,10 +31,10 @@ exports.property = function (node, file, scope) {
|
||||
var state = {
|
||||
id: id,
|
||||
selfReference: false,
|
||||
outerDeclar: scope.get(id, true),
|
||||
outerDeclar: scope.getBinding(id),
|
||||
};
|
||||
|
||||
traverse(node, visitor, scope, state);
|
||||
scope.traverse(node, visitor, state);
|
||||
|
||||
if (state.selfReference) {
|
||||
// todo: support generators
|
||||
|
||||
4
lib/6to5/transformation/helpers/react.js
vendored
4
lib/6to5/transformation/helpers/react.js
vendored
@@ -20,3 +20,7 @@ exports.isCreateClass = function (node) {
|
||||
};
|
||||
|
||||
exports.isReactComponent = t.buildMatchMemberExpression("React.Component");
|
||||
|
||||
exports.isCompatTag = function (tagName) {
|
||||
return tagName && /^[a-z]|\-/.test(tagName);
|
||||
};
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
var t = require("../../types");
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context) {
|
||||
if (t.isFunction(node)) context.skip();
|
||||
enter: function (node) {
|
||||
if (t.isFunction(node)) this.skip();
|
||||
|
||||
if (t.isAwaitExpression(node)) {
|
||||
node.type = "YieldExpression";
|
||||
@@ -23,7 +22,7 @@ module.exports = function (node, callId, scope) {
|
||||
node.async = false;
|
||||
node.generator = true;
|
||||
|
||||
traverse(node, visitor, scope);
|
||||
scope.traverse(node, visitor);
|
||||
|
||||
var call = t.callExpression(callId, [node]);
|
||||
var id = node.id;
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
module.exports = ReplaceSupers;
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
var t = require("../../types");
|
||||
|
||||
/**
|
||||
* Description
|
||||
@@ -65,7 +64,7 @@ ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic,
|
||||
* @returns {Node}
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed, thisExpression) {
|
||||
ReplaceSupers.prototype.getSuperProperty = function (property, isStatic, isComputed, thisExpression) {
|
||||
return t.callExpression(
|
||||
this.file.addHelper("get"),
|
||||
[
|
||||
@@ -81,6 +80,70 @@ ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.replace = function () {
|
||||
this.traverseLevel(this.methodNode.value, true);
|
||||
};
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
var topLevel = state.topLevel;
|
||||
var self = state.self;
|
||||
|
||||
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
|
||||
// we need to call traverseLevel again so we're context aware
|
||||
self.traverseLevel(node, false);
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
|
||||
// break on object methods
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
var getThisReference = topLevel ?
|
||||
// top level so `this` is the instance
|
||||
t.thisExpression :
|
||||
// not in the top level so we need to create a reference
|
||||
self.getThisReference.bind(self);
|
||||
|
||||
var callback = self.specHandle;
|
||||
if (self.isLoose) callback = self.looseHandle;
|
||||
return callback.call(self, getThisReference, node, parent);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @param {Boolean} topLevel
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
|
||||
var state = { self: this, topLevel: topLevel };
|
||||
this.scope.traverse(node, visitor, state);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.getThisReference = function () {
|
||||
if (this.topLevelThisReference) {
|
||||
return this.topLevelThisReference;
|
||||
} else {
|
||||
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
|
||||
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
|
||||
]));
|
||||
return ref;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
@@ -90,7 +153,7 @@ ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.looseSuperProperty = function (methodNode, id, parent) {
|
||||
ReplaceSupers.prototype.getLooseSuperProperty = function (methodNode, id, parent) {
|
||||
var methodName = methodNode.key;
|
||||
var superName = this.superName || t.identifier("Function");
|
||||
|
||||
@@ -122,70 +185,6 @@ ReplaceSupers.prototype.looseSuperProperty = function (methodNode, id, parent) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.replace = function () {
|
||||
this.traverseLevel(this.methodNode.value, true);
|
||||
};
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
var topLevel = state.topLevel;
|
||||
var self = state.self;
|
||||
|
||||
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
|
||||
// we need to call traverseLevel again so we're context aware
|
||||
self.traverseLevel(node, false);
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
|
||||
// break on object methods
|
||||
return context.skip();
|
||||
}
|
||||
|
||||
var getThisReference = topLevel ?
|
||||
// top level so `this` is the instance
|
||||
t.thisExpression :
|
||||
// not in the top level so we need to create a reference
|
||||
self.getThisReference;
|
||||
|
||||
var callback = self.specHandle;
|
||||
if (self.isLoose) callback = self.looseHandle;
|
||||
return callback.call(self, getThisReference, node, parent);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @param {Boolean} topLevel
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
|
||||
var state = { self: this, topLevel: topLevel };
|
||||
traverse(node, visitor, this.scope, state);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.getThisReference = function () {
|
||||
if (this.topLevelThisReference) {
|
||||
return this.topLevelThisReference;
|
||||
} else {
|
||||
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
|
||||
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
|
||||
]));
|
||||
return ref;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
@@ -196,7 +195,7 @@ ReplaceSupers.prototype.getThisReference = function () {
|
||||
|
||||
ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return this.looseSuperProperty(this.methodNode, node, parent);
|
||||
return this.getLooseSuperProperty(this.methodNode, node, parent);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
@@ -223,13 +222,13 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
|
||||
var args;
|
||||
var thisReference;
|
||||
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
|
||||
throw this.file.errorWithNode(node, "illegal use of bare super");
|
||||
}
|
||||
} else if (t.isCallExpression(node)) {
|
||||
if (isIllegalBareSuper(node, parent)) {
|
||||
throw this.file.errorWithNode(node, "Illegal use of bare super");
|
||||
}
|
||||
|
||||
if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (t.isIdentifier(callee, { name: "super" })) {
|
||||
if (isSuper(callee, node)) {
|
||||
// super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
|
||||
property = methodNode.key;
|
||||
computed = methodNode.computed;
|
||||
@@ -242,34 +241,25 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
|
||||
var methodName = methodNode.key.name || "METHOD_NAME";
|
||||
throw this.file.errorWithNode(node, "Direct super call is illegal in non-constructor, use super." + methodName + "() instead");
|
||||
}
|
||||
} else {
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
} 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)) {
|
||||
if (!t.isIdentifier(node.object, { name: "super" })) return;
|
||||
|
||||
} 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)) {
|
||||
if (!t.isIdentifier(node.left.object, { name: "super" })) return;
|
||||
if (methodNode.kind !== "set") return;
|
||||
|
||||
thisReference = getThisReference();
|
||||
} else if (t.isAssignmentExpression(node) && isSuper(node.left.object, node.left) && methodNode.kind === "set") {
|
||||
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
|
||||
return this.setSuperProperty(node.left.property, node.right, methodNode.static, node.left.computed, thisReference);
|
||||
return this.setSuperProperty(node.left.property, node.right, methodNode.static, node.left.computed, getThisReference());
|
||||
}
|
||||
|
||||
if (!property) return;
|
||||
|
||||
thisReference = getThisReference();
|
||||
var superProperty = this.superProperty(property, methodNode.static, computed, thisReference);
|
||||
var superProperty = this.getSuperProperty(property, methodNode.static, computed, thisReference);
|
||||
if (args) {
|
||||
if (args.length === 1 && t.isSpreadElement(args[0])) {
|
||||
// super(...arguments);
|
||||
@@ -287,3 +277,14 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
|
||||
return superProperty;
|
||||
}
|
||||
};
|
||||
|
||||
var isIllegalBareSuper = function (node, parent) {
|
||||
if (!isSuper(node, parent)) return false;
|
||||
if (t.isMemberExpression(parent, { computed: false })) return false;
|
||||
if (t.isCallExpression(parent, { callee: node })) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
var isSuper = function (node, parent) {
|
||||
return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent);
|
||||
};
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
module.exports = transform;
|
||||
|
||||
var Transformer = require("./transformer");
|
||||
var object = require("../helpers/object");
|
||||
var File = require("../file");
|
||||
var util = require("../util");
|
||||
var each = require("lodash/collection/each");
|
||||
var normalizeAst = require("../helpers/normalize-ast");
|
||||
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);
|
||||
@@ -14,7 +14,7 @@ function transform(code, opts) {
|
||||
}
|
||||
|
||||
transform.fromAst = function (ast, code, opts) {
|
||||
ast = util.normaliseAst(ast);
|
||||
ast = normalizeAst(ast);
|
||||
|
||||
var file = new File(opts);
|
||||
file.addCode(code);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
module.exports = DefaultFormatter;
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var object = require("../../helpers/object");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
@@ -28,7 +27,7 @@ function DefaultFormatter(file) {
|
||||
}
|
||||
|
||||
DefaultFormatter.prototype.doDefaultExportInterop = function (node) {
|
||||
return node.default && !this.noInteropRequire && !this.hasNonDefaultExports;
|
||||
return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.bumpImportOccurences = function (node) {
|
||||
@@ -39,13 +38,13 @@ DefaultFormatter.prototype.bumpImportOccurences = function (node) {
|
||||
};
|
||||
|
||||
var exportsVisitor = {
|
||||
enter: function (node, parent, scope, context, formatter) {
|
||||
enter: function (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.getDeclarations(declar));
|
||||
extend(formatter.localExports, t.getBindingIdentifiers(declar));
|
||||
}
|
||||
|
||||
if (!node.default) {
|
||||
@@ -60,27 +59,27 @@ var exportsVisitor = {
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getLocalExports = function () {
|
||||
traverse(this.file.ast, exportsVisitor, this.file.scope, this);
|
||||
this.file.scope.traverse(this.file.ast, exportsVisitor, this);
|
||||
};
|
||||
|
||||
var importsVisitor = {
|
||||
enter: function (node, parent, scope, context, formatter) {
|
||||
enter: function (node, parent, scope, formatter) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
formatter.hasLocalImports = true;
|
||||
extend(formatter.localImports, t.getDeclarations(node));
|
||||
extend(formatter.localImports, t.getBindingIdentifiers(node));
|
||||
formatter.bumpImportOccurences(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getLocalImports = function () {
|
||||
traverse(this.file.ast, importsVisitor, this.file.scope, this);
|
||||
this.file.scope.traverse(this.file.ast, importsVisitor, this);
|
||||
};
|
||||
|
||||
var remapVisitor = {
|
||||
enter: function (node, parent, scope, context, formatter) {
|
||||
enter: function (node, parent, scope, formatter) {
|
||||
if (t.isUpdateExpression(node) && formatter.isLocalReference(node.argument, scope)) {
|
||||
context.skip();
|
||||
this.skip();
|
||||
|
||||
// expand to long file assignment expression
|
||||
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
|
||||
@@ -108,7 +107,7 @@ var remapVisitor = {
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(node) && formatter.isLocalReference(node.left, scope)) {
|
||||
context.skip();
|
||||
this.skip();
|
||||
return formatter.remapExportAssignment(node);
|
||||
}
|
||||
}
|
||||
@@ -116,7 +115,7 @@ var remapVisitor = {
|
||||
|
||||
DefaultFormatter.prototype.remapAssignments = function () {
|
||||
if (this.hasLocalImports) {
|
||||
traverse(this.file.ast, remapVisitor, this.file.scope, this);
|
||||
this.file.scope.traverse(this.file.ast, remapVisitor, this);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -147,7 +146,7 @@ DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
||||
DefaultFormatter.prototype.isLocalReference = function (node, scope) {
|
||||
var localExports = this.localExports;
|
||||
var name = node.name;
|
||||
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.get(name, true);
|
||||
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBinding(name);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getModuleName = function () {
|
||||
@@ -171,12 +170,12 @@ DefaultFormatter.prototype.getModuleName = function () {
|
||||
|
||||
if (!opts.keepModuleIdExtensions) {
|
||||
// remove extension
|
||||
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
|
||||
filenameRelative = filenameRelative.replace(/\.(\w*?)$/, "");
|
||||
}
|
||||
|
||||
moduleName += filenameRelative;
|
||||
|
||||
// normalise path separators
|
||||
// normalize path separators
|
||||
moduleName = moduleName.replace(/\\/g, "/");
|
||||
|
||||
return moduleName;
|
||||
@@ -212,6 +211,12 @@ DefaultFormatter.prototype.getExternalReference = function (node, nodes) {
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.checkExportIdentifier = function (node) {
|
||||
if (t.isIdentifier(node, { name: "__esModule" })) {
|
||||
throw this.file.errorWithNode(node, "Illegal export __esModule - this is used internally for CommonJS interop");
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
var inherits = false;
|
||||
if (node.specifiers.length === 1) inherits = node;
|
||||
@@ -223,8 +228,8 @@ DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
// export * from "foo";
|
||||
nodes.push(this.buildExportsWildcard(ref, node));
|
||||
} else {
|
||||
if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
|
||||
// importing a default so we need to normalise it
|
||||
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));
|
||||
@@ -251,6 +256,7 @@ DefaultFormatter.prototype.buildExportsWildcard = function (objectIdentifier) {
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.buildExportsAssignment = function (id, init) {
|
||||
this.checkExportIdentifier(id);
|
||||
return util.template("exports-assign", {
|
||||
VALUE: init,
|
||||
KEY: id
|
||||
|
||||
@@ -4,7 +4,7 @@ var util = require("../../util");
|
||||
|
||||
module.exports = function (Parent) {
|
||||
var Constructor = function () {
|
||||
this.noInteropRequire = true;
|
||||
this.noInteropRequireExport = true;
|
||||
Parent.apply(this, arguments);
|
||||
};
|
||||
|
||||
|
||||
@@ -29,9 +29,8 @@ AMDFormatter.prototype.buildDependencyLiterals = function () {
|
||||
* Wrap the entire body in a `define` wrapper.
|
||||
*/
|
||||
|
||||
AMDFormatter.prototype.transform = function (ast) {
|
||||
var program = ast.program;
|
||||
var body = program.body;
|
||||
AMDFormatter.prototype.transform = function (program) {
|
||||
var body = program.body;
|
||||
|
||||
// build an array of module names
|
||||
|
||||
@@ -87,7 +86,7 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
this.ids[node.source.value] = ref;
|
||||
} else if (t.isImportBatchSpecifier(specifier)) {
|
||||
// import * as bar from "foo";
|
||||
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
|
||||
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) {
|
||||
// import foo from "foo";
|
||||
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
|
||||
} else {
|
||||
|
||||
13
lib/6to5/transformation/modules/common-standard.js
Normal file
13
lib/6to5/transformation/modules/common-standard.js
Normal file
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = CommonStandardFormatter;
|
||||
|
||||
var CommonStrictFormatter = require("./common-strict");
|
||||
var util = require("../../util");
|
||||
|
||||
function CommonStandardFormatter() {
|
||||
this.noInteropRequireImport = true;
|
||||
CommonStrictFormatter.apply(this, arguments);
|
||||
}
|
||||
|
||||
util.inherits(CommonStandardFormatter, CommonStrictFormatter);
|
||||
@@ -14,7 +14,7 @@ function CommonJSFormatter() {
|
||||
util.inherits(CommonJSFormatter, DefaultFormatter);
|
||||
|
||||
CommonJSFormatter.prototype.init = function () {
|
||||
if (this.hasNonDefaultExports) {
|
||||
if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
|
||||
this.file.ast.program.body.push(util.template("exports-module-declaration", true));
|
||||
}
|
||||
};
|
||||
@@ -27,19 +27,23 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
|
||||
// import foo from "foo";
|
||||
if (t.isSpecifierDefault(specifier)) {
|
||||
if (!contains(this.file.dynamicImported, node)) {
|
||||
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
|
||||
if (this.noInteropRequireImport) {
|
||||
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) {
|
||||
ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]);
|
||||
}
|
||||
|
||||
// import * as bar from "foo";
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
variableName,
|
||||
t.callExpression(this.file.addHelper("interop-require-wildcard"), [
|
||||
ref
|
||||
])
|
||||
)
|
||||
t.variableDeclarator(variableName, ref)
|
||||
]));
|
||||
} else {
|
||||
// import { foo } from "foo";
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
module.exports = {
|
||||
commonStrict: require("./common-strict"),
|
||||
amdStrict: require("./amd-strict"),
|
||||
umdStrict: require("./umd-strict"),
|
||||
common: require("./common"),
|
||||
system: require("./system"),
|
||||
ignore: require("./ignore"),
|
||||
amd: require("./amd"),
|
||||
umd: require("./umd")
|
||||
commonStandard: require("./common-standard"),
|
||||
commonStrict: require("./common-strict"),
|
||||
amdStrict: require("./amd-strict"),
|
||||
umdStrict: require("./umd-strict"),
|
||||
common: require("./common"),
|
||||
system: require("./system"),
|
||||
ignore: require("./ignore"),
|
||||
amd: require("./amd"),
|
||||
umd: require("./umd")
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ module.exports = SystemFormatter;
|
||||
var DefaultFormatter = require("./_default");
|
||||
var AMDFormatter = require("./amd");
|
||||
var useStrict = require("../helpers/use-strict");
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var last = require("lodash/array/last");
|
||||
@@ -14,7 +13,8 @@ var map = require("lodash/collection/map");
|
||||
|
||||
function SystemFormatter(file) {
|
||||
this.exportIdentifier = file.generateUidIdentifier("export");
|
||||
this.noInteropRequire = true;
|
||||
this.noInteropRequireExport = true;
|
||||
this.noInteropRequireImport = true;
|
||||
|
||||
DefaultFormatter.apply(this, arguments);
|
||||
}
|
||||
@@ -69,7 +69,7 @@ SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
};
|
||||
|
||||
var runnerSettersVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (node._importSource === state.source) {
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
each(node.declarations, function (declar) {
|
||||
@@ -82,7 +82,7 @@ var runnerSettersVisitor = {
|
||||
state.nodes.push(node);
|
||||
}
|
||||
|
||||
context.remove();
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -97,17 +97,17 @@ SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators
|
||||
hoistDeclarators: hoistDeclarators
|
||||
};
|
||||
|
||||
traverse(block, runnerSettersVisitor, scope, state);
|
||||
scope.traverse(block, runnerSettersVisitor, state);
|
||||
|
||||
return t.functionExpression(null, [uid], t.blockStatement(state.nodes));
|
||||
}));
|
||||
};
|
||||
|
||||
var hoistVariablesVisitor = {
|
||||
enter: function (node, parent, scope, context, hoistDeclarators) {
|
||||
enter: function (node, parent, scope, hoistDeclarators) {
|
||||
if (t.isFunction(node)) {
|
||||
// nothing inside is accessible
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
@@ -149,19 +149,17 @@ var hoistVariablesVisitor = {
|
||||
};
|
||||
|
||||
var hoistFunctionsVisitor = {
|
||||
enter: function (node, parent, scope, context, handlerBody) {
|
||||
if (t.isFunction(node)) context.skip();
|
||||
enter: function (node, parent, scope, handlerBody) {
|
||||
if (t.isFunction(node)) this.skip();
|
||||
|
||||
if (t.isFunctionDeclaration(node) || node._blockHoist) {
|
||||
handlerBody.push(node);
|
||||
context.remove();
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SystemFormatter.prototype.transform = function (ast) {
|
||||
var program = ast.program;
|
||||
|
||||
SystemFormatter.prototype.transform = function (program) {
|
||||
var hoistDeclarators = [];
|
||||
var moduleName = this.getModuleName();
|
||||
var moduleNameLiteral = t.literal(moduleName);
|
||||
@@ -182,7 +180,7 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
var returnStatement = handlerBody.pop();
|
||||
|
||||
// hoist up all variable declarations
|
||||
traverse(block, hoistVariablesVisitor, this.file.scope, hoistDeclarators);
|
||||
this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators);
|
||||
|
||||
if (hoistDeclarators.length) {
|
||||
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators);
|
||||
@@ -191,7 +189,7 @@ SystemFormatter.prototype.transform = function (ast) {
|
||||
}
|
||||
|
||||
// hoist up function declarations for circular references
|
||||
traverse(block, hoistFunctionsVisitor, this.file.scope, handlerBody);
|
||||
this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody);
|
||||
|
||||
handlerBody.push(returnStatement);
|
||||
|
||||
|
||||
@@ -13,9 +13,8 @@ function UMDFormatter() {
|
||||
|
||||
util.inherits(UMDFormatter, AMDFormatter);
|
||||
|
||||
UMDFormatter.prototype.transform = function (ast) {
|
||||
var program = ast.program;
|
||||
var body = program.body;
|
||||
UMDFormatter.prototype.transform = function (program) {
|
||||
var body = program.body;
|
||||
|
||||
// build an array of module names
|
||||
|
||||
|
||||
5
lib/6to5/transformation/templates/class-call-check.js
Normal file
5
lib/6to5/transformation/templates/class-call-check.js
Normal file
@@ -0,0 +1,5 @@
|
||||
(function (instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
});
|
||||
@@ -1,3 +1,3 @@
|
||||
if (Object.getPrototypeOf(CLASS_NAME) !== null) {
|
||||
Object.getPrototypeOf(CLASS_NAME).apply(this, arguments);
|
||||
if (SUPER_NAME != null) {
|
||||
SUPER_NAME.apply(this, arguments);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
(function (obj) {
|
||||
if (obj == null) throw new TypeError("Cannot destructure undefined");
|
||||
});
|
||||
@@ -1,7 +1,5 @@
|
||||
module.exports = TransformerPass;
|
||||
|
||||
var traverse = require("../traverse");
|
||||
var util = require("../util");
|
||||
var contains = require("lodash/collection/contains");
|
||||
|
||||
/**
|
||||
@@ -11,64 +9,55 @@ var contains = require("lodash/collection/contains");
|
||||
|
||||
function TransformerPass(file, transformer) {
|
||||
this.transformer = transformer;
|
||||
this.shouldRun = !transformer.check;
|
||||
this.handlers = transformer.handlers;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
TransformerPass.prototype.astRun = function (key) {
|
||||
var handlers = this.handlers;
|
||||
var file = this.file;
|
||||
|
||||
if (handlers.ast && handlers.ast[key]) {
|
||||
handlers.ast[key](file.ast, file);
|
||||
}
|
||||
};
|
||||
|
||||
TransformerPass.prototype.canRun = function () {
|
||||
var transformer = this.transformer;
|
||||
|
||||
var opts = this.file.opts;
|
||||
var key = transformer.key;
|
||||
|
||||
// internal
|
||||
if (key[0] === "_") return true;
|
||||
|
||||
// blacklist
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && contains(blacklist, key)) return false;
|
||||
|
||||
// whitelist
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist.length && !contains(whitelist, key)) return false;
|
||||
|
||||
// optional
|
||||
if (transformer.optional && !contains(opts.optional, key)) return false;
|
||||
|
||||
// experimental
|
||||
if (transformer.experimental && !opts.experimental) return false;
|
||||
|
||||
// playground
|
||||
if (transformer.playground && !opts.playground) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
var transformVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
var fns = state.handlers[node.type];
|
||||
if (!fns) return;
|
||||
return fns.enter(node, parent, scope, context, state.file, state.pass);
|
||||
},
|
||||
|
||||
exit: function (node, parent, scope, context, state) {
|
||||
var fns = state.handlers[node.type];
|
||||
if (!fns) return;
|
||||
return fns.exit(node, parent, scope, context, state.file, state.pass);
|
||||
TransformerPass.prototype.checkNode = function (node) {
|
||||
var check = this.transformer.check;
|
||||
if (check) {
|
||||
return this.shouldRun = check(node);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
TransformerPass.prototype.transform = function () {
|
||||
if (!this.shouldRun) return;
|
||||
|
||||
var file = this.file;
|
||||
|
||||
util.debug(file.opts.filename + ": Running transformer " + this.transformer.key);
|
||||
file.debug("Running transformer " + this.transformer.key);
|
||||
|
||||
this.astRun("before");
|
||||
|
||||
var state = { file: file, handlers: this.handlers, pass: this };
|
||||
traverse(file.ast, transformVisitor, file.scope, state);
|
||||
|
||||
this.astRun("after");
|
||||
file.scope.traverse(file.ast, this.handlers, file);
|
||||
};
|
||||
|
||||
@@ -4,8 +4,9 @@ module.exports = Transformer;
|
||||
|
||||
var TransformerPass = require("./transformer-pass");
|
||||
var isFunction = require("lodash/lang/isFunction");
|
||||
var traverse = require("../traverse");
|
||||
var traverse = require("../traversal");
|
||||
var isObject = require("lodash/lang/isObject");
|
||||
var clone = require("../helpers/clone");
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
/**
|
||||
@@ -15,17 +16,30 @@ var each = require("lodash/collection/each");
|
||||
*/
|
||||
|
||||
function Transformer(key, transformer, opts) {
|
||||
this.manipulateOptions = transformer.manipulateOptions;
|
||||
this.experimental = !!transformer.experimental;
|
||||
this.playground = !!transformer.playground;
|
||||
this.secondPass = !!transformer.secondPass;
|
||||
this.optional = !!transformer.optional;
|
||||
this.handlers = this.normalise(transformer);
|
||||
this.opts = opts || {};
|
||||
this.key = key;
|
||||
transformer = clone(transformer);
|
||||
|
||||
var take = function (key) {
|
||||
var val = transformer[key];
|
||||
delete transformer[key];
|
||||
return val;
|
||||
};
|
||||
|
||||
this.manipulateOptions = take("manipulateOptions");
|
||||
this.check = take("check");
|
||||
this.post = take("post");
|
||||
this.pre = take("pre");
|
||||
|
||||
this.experimental = !!take("experimental");
|
||||
this.playground = !!take("playground");
|
||||
this.secondPass = !!take("secondPass");
|
||||
this.optional = !!take("optional");
|
||||
|
||||
this.handlers = this.normalize(transformer);
|
||||
this.opts = opts || {};
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
Transformer.prototype.normalise = function (transformer) {
|
||||
Transformer.prototype.normalize = function (transformer) {
|
||||
var self = this;
|
||||
|
||||
if (isFunction(transformer)) {
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
"generatorComprehension": "es7.comprehensions",
|
||||
"arrowFunctions": "es6.arrowFunctions",
|
||||
"classes": "es6.classes",
|
||||
"objectSpread": "es7.objectSpread",
|
||||
"objectSpread": "es7.objectRestSpread",
|
||||
"es7.objectSpread": "es7.objectRestSpread",
|
||||
"exponentiationOperator": "es7.exponentiationOperator",
|
||||
"spread": "es6.spread",
|
||||
"templateLiterals": "es6.templateLiterals",
|
||||
@@ -33,6 +34,8 @@
|
||||
"coreAliasing": "selfContained",
|
||||
"undefinedToVoid": "spec.undefinedToVoid",
|
||||
"undeclaredVariableCheck": "validation.undeclaredVariableCheck",
|
||||
"specPropertyLiterals": "minification.propertyLiterals",
|
||||
"specMemberExpressionLiterals": "minification.memberExpressionLiterals"
|
||||
"specPropertyLiterals": "es3.propertyLiterals",
|
||||
"specMemberExpressionLiterals": "es3.memberExpressionLiterals",
|
||||
"minification.propertyLiterals": "es3.propertyLiterals",
|
||||
"minification.memberExpressionLiterals": "es3.memberExpressionLiterals"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
var defineMap = require("../../helpers/define-map");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isProperty(node) && (node.kind === "get" || node.kind === "set");
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node) {
|
||||
var mutatorMap = {};
|
||||
@@ -10,7 +14,7 @@ exports.ObjectExpression = function (node) {
|
||||
node.properties = node.properties.filter(function (prop) {
|
||||
if (prop.kind === "get" || prop.kind === "set") {
|
||||
hasAny = true;
|
||||
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.computed, prop.value);
|
||||
defineMap.push(mutatorMap, prop.key, prop.kind, prop.computed, prop.value);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -21,6 +25,6 @@ exports.ObjectExpression = function (node) {
|
||||
|
||||
return t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
|
||||
[node, util.buildDefineProperties(mutatorMap)]
|
||||
[node, defineMap.build(mutatorMap)]
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isArrowFunctionExpression;
|
||||
|
||||
exports.ArrowFunctionExpression = function (node) {
|
||||
t.ensureBlock(node);
|
||||
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var t = require("../../../types");
|
||||
var t = require("../../../types");
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
var declared = state.letRefs[node.name];
|
||||
if (!declared) return;
|
||||
|
||||
// declared node is different in this scope
|
||||
if (scope.get(node.name, true) !== declared) return;
|
||||
if (scope.getBinding(node.name) !== declared) return;
|
||||
|
||||
var declaredLoc = declared.loc;
|
||||
var referenceLoc = node.loc;
|
||||
@@ -37,7 +36,7 @@ exports.optional = true;
|
||||
|
||||
exports.Loop =
|
||||
exports.Program =
|
||||
exports.BlockStatement = function (node, parent, scope, context, file) {
|
||||
exports.BlockStatement = function (node, parent, scope, file) {
|
||||
var letRefs = node._letReferences;
|
||||
if (!letRefs) return;
|
||||
|
||||
@@ -46,5 +45,5 @@ exports.BlockStatement = function (node, parent, scope, context, file) {
|
||||
file: file
|
||||
};
|
||||
|
||||
traverse(node, visitor, scope, state);
|
||||
scope.traverse(node, visitor, state);
|
||||
};
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var traverse = require("../../../traversal");
|
||||
var object = require("../../../helpers/object");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
var values = require("lodash/object/values");
|
||||
var extend = require("lodash/object/extend");
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
|
||||
};
|
||||
|
||||
var isLet = function (node, parent) {
|
||||
if (!t.isVariableDeclaration(node)) return false;
|
||||
if (node._let) return true;
|
||||
@@ -29,7 +33,7 @@ var isVar = function (node, parent) {
|
||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
|
||||
};
|
||||
|
||||
var standardiseLets = function (declars) {
|
||||
var standardizeLets = function (declars) {
|
||||
for (var i = 0; i < declars.length; i++) {
|
||||
delete declars[i]._let;
|
||||
}
|
||||
@@ -39,21 +43,21 @@ exports.VariableDeclaration = function (node, parent) {
|
||||
isLet(node, parent);
|
||||
};
|
||||
|
||||
exports.Loop = function (node, parent, scope, context, file) {
|
||||
exports.Loop = function (node, parent, scope, file) {
|
||||
var init = node.left || node.init;
|
||||
if (isLet(init, node)) {
|
||||
t.ensureBlock(node);
|
||||
node.body._letDeclarators = [init];
|
||||
}
|
||||
var letScoping = new LetScoping(node, node.body, parent, scope, file);
|
||||
letScoping.run();
|
||||
var blockScoping = new BlockScoping(node, node.body, parent, scope, file);
|
||||
blockScoping.run();
|
||||
};
|
||||
|
||||
exports.Program =
|
||||
exports.BlockStatement = function (block, parent, scope, context, file) {
|
||||
exports.BlockStatement = function (block, parent, scope, file) {
|
||||
if (!t.isLoop(parent)) {
|
||||
var letScoping = new LetScoping(false, block, parent, scope, file);
|
||||
letScoping.run();
|
||||
var blockScoping = new BlockScoping(false, block, parent, scope, file);
|
||||
blockScoping.run();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -67,7 +71,7 @@ exports.BlockStatement = function (block, parent, scope, context, file) {
|
||||
* @param {File} file
|
||||
*/
|
||||
|
||||
function LetScoping(loopParent, block, parent, scope, file) {
|
||||
function BlockScoping(loopParent, block, parent, scope, file) {
|
||||
this.loopParent = loopParent;
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
@@ -84,7 +88,7 @@ function LetScoping(loopParent, block, parent, scope, file) {
|
||||
* Start the ball rolling.
|
||||
*/
|
||||
|
||||
LetScoping.prototype.run = function () {
|
||||
BlockScoping.prototype.run = function () {
|
||||
var block = this.block;
|
||||
if (block._letDone) return;
|
||||
block._letDone = true;
|
||||
@@ -104,19 +108,19 @@ LetScoping.prototype.run = function () {
|
||||
}
|
||||
};
|
||||
|
||||
function replace(node, parent, scope, context, remaps) {
|
||||
function replace(node, parent, scope, remaps) {
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
var remap = remaps[node.name];
|
||||
if (!remap) return;
|
||||
|
||||
var own = scope.get(node.name, true);
|
||||
if (own === remap.node) {
|
||||
var ownBinding = scope.getBinding(node.name);
|
||||
if (ownBinding === remap.binding) {
|
||||
node.name = remap.uid;
|
||||
} else {
|
||||
// scope already has it's own declaration that doesn't
|
||||
// scope already has it's own binding that doesn't
|
||||
// match the one we have a stored replacement for
|
||||
if (context) context.skip();
|
||||
if (this) this.skip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,15 +129,15 @@ var replaceVisitor = {
|
||||
};
|
||||
|
||||
function traverseReplace(node, parent, scope, remaps) {
|
||||
replace(node, parent, scope, null, remaps);
|
||||
traverse(node, replaceVisitor, scope, remaps);
|
||||
replace(node, parent, scope, remaps);
|
||||
scope.traverse(node, replaceVisitor, remaps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
LetScoping.prototype.remap = function () {
|
||||
BlockScoping.prototype.remap = function () {
|
||||
var hasRemaps = false;
|
||||
var letRefs = this.letReferences;
|
||||
var scope = this.scope;
|
||||
@@ -149,13 +153,13 @@ LetScoping.prototype.remap = function () {
|
||||
// this is the defining identifier of a declaration
|
||||
var ref = letRefs[key];
|
||||
|
||||
if (scope.parentHas(key)) {
|
||||
if (scope.parentHasReference(key)) {
|
||||
var uid = scope.generateUidIdentifier(ref.name).name;
|
||||
ref.name = uid;
|
||||
|
||||
hasRemaps = true;
|
||||
remaps[key] = remaps[uid] = {
|
||||
node: ref,
|
||||
binding: ref,
|
||||
uid: uid
|
||||
};
|
||||
}
|
||||
@@ -172,14 +176,14 @@ LetScoping.prototype.remap = function () {
|
||||
traverseReplace(loopParent.update, loopParent, scope, remaps);
|
||||
}
|
||||
|
||||
traverse(this.block, replaceVisitor, scope, remaps);
|
||||
scope.traverse(this.block, replaceVisitor, remaps);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
LetScoping.prototype.needsClosure = function () {
|
||||
BlockScoping.prototype.needsClosure = function () {
|
||||
var block = this.block;
|
||||
|
||||
// if we're inside of a for loop then we search to see if there are any
|
||||
@@ -221,13 +225,13 @@ LetScoping.prototype.needsClosure = function () {
|
||||
};
|
||||
|
||||
var letReferenceFunctionVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
// not a direct reference
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
if (scope.hasOwn(node.name, true)) return;
|
||||
if (scope.hasOwnBinding(node.name)) return;
|
||||
|
||||
// not a part of our scope
|
||||
if (!state.letReferences[node.name]) return;
|
||||
@@ -237,10 +241,10 @@ var letReferenceFunctionVisitor = {
|
||||
};
|
||||
|
||||
var letReferenceBlockVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isFunction(node)) {
|
||||
traverse(node, letReferenceFunctionVisitor, scope, state);
|
||||
return context.skip();
|
||||
scope.traverse(node, letReferenceFunctionVisitor, state);
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -249,7 +253,7 @@ var letReferenceBlockVisitor = {
|
||||
* Description
|
||||
*/
|
||||
|
||||
LetScoping.prototype.getLetReferences = function () {
|
||||
BlockScoping.prototype.getLetReferences = function () {
|
||||
var block = this.block;
|
||||
|
||||
var declarators = block._letDeclarators || [];
|
||||
@@ -258,7 +262,7 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
//
|
||||
for (var i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
extend(this.outsideLetReferences, t.getDeclarations(declar));
|
||||
extend(this.outsideLetReferences, t.getBindingIdentifiers(declar));
|
||||
}
|
||||
|
||||
//
|
||||
@@ -274,7 +278,7 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
//
|
||||
for (i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
var keys = t.getDeclarations(declar);
|
||||
var keys = t.getBindingIdentifiers(declar);
|
||||
extend(this.letReferences, keys);
|
||||
this.hasLetReferences = true;
|
||||
}
|
||||
@@ -283,7 +287,7 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
if (!this.hasLetReferences) return;
|
||||
|
||||
// set let references to plain var references
|
||||
standardiseLets(declarators);
|
||||
standardizeLets(declarators);
|
||||
|
||||
var state = {
|
||||
letReferences: this.letReferences,
|
||||
@@ -292,7 +296,7 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
|
||||
// traverse through this block, stopping on functions and checking if they
|
||||
// contain any local let references
|
||||
traverse(this.block, letReferenceBlockVisitor, this.scope, state);
|
||||
this.scope.traverse(this.block, letReferenceBlockVisitor, state);
|
||||
|
||||
return state.closurify;
|
||||
};
|
||||
@@ -306,17 +310,17 @@ var loopNodeTo = function (node) {
|
||||
};
|
||||
|
||||
var loopVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
var replace;
|
||||
|
||||
if (t.isLoop(node)) {
|
||||
state.ignoreLabeless = true;
|
||||
traverse(node, loopVisitor, scope, state);
|
||||
scope.traverse(node, loopVisitor, state);
|
||||
state.ignoreLabeless = false;
|
||||
}
|
||||
|
||||
if (t.isFunction(node) || t.isLoop(node)) {
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
var loopText = loopNodeTo(node);
|
||||
@@ -358,7 +362,7 @@ var loopVisitor = {
|
||||
};
|
||||
|
||||
var loopLabelVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isLabeledStatement(node)) {
|
||||
state.innerLabels.push(node.label.name);
|
||||
}
|
||||
@@ -374,7 +378,7 @@ var loopLabelVisitor = {
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
LetScoping.prototype.checkLoop = function () {
|
||||
BlockScoping.prototype.checkLoop = function () {
|
||||
var state = {
|
||||
hasBreakContinue: false,
|
||||
ignoreLabeless: false,
|
||||
@@ -384,14 +388,14 @@ LetScoping.prototype.checkLoop = function () {
|
||||
map: {}
|
||||
};
|
||||
|
||||
traverse(this.block, loopLabelVisitor, this.scope, state);
|
||||
traverse(this.block, loopVisitor, this.scope, state);
|
||||
this.scope.traverse(this.block, loopLabelVisitor, state);
|
||||
this.scope.traverse(this.block, loopVisitor, state);
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
var hoistVarDeclarationsVisitor = {
|
||||
enter: function (node, parent, scope, context, self) {
|
||||
enter: function (node, parent, scope, self) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init, node)) {
|
||||
node.init = t.sequenceExpression(self.pushDeclar(node.init));
|
||||
@@ -403,7 +407,7 @@ var hoistVarDeclarationsVisitor = {
|
||||
} else if (isVar(node, parent)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -413,7 +417,7 @@ var hoistVarDeclarationsVisitor = {
|
||||
* once we wrap everything in a closure.
|
||||
*/
|
||||
|
||||
LetScoping.prototype.hoistVarDeclarations = function () {
|
||||
BlockScoping.prototype.hoistVarDeclarations = function () {
|
||||
traverse(this.block, hoistVarDeclarationsVisitor, this.scope, this);
|
||||
};
|
||||
|
||||
@@ -425,7 +429,7 @@ LetScoping.prototype.hoistVarDeclarations = function () {
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
LetScoping.prototype.pushDeclar = function (node) {
|
||||
BlockScoping.prototype.pushDeclar = function (node) {
|
||||
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
|
||||
return t.variableDeclarator(declar.id);
|
||||
})));
|
||||
@@ -450,7 +454,7 @@ LetScoping.prototype.pushDeclar = function (node) {
|
||||
* @param {Node} call CallExpression
|
||||
*/
|
||||
|
||||
LetScoping.prototype.build = function (ret, call) {
|
||||
BlockScoping.prototype.build = function (ret, call) {
|
||||
var has = this.has;
|
||||
if (has.hasReturn || has.hasBreakContinue) {
|
||||
this.buildHas(ret, call);
|
||||
@@ -466,7 +470,7 @@ LetScoping.prototype.build = function (ret, call) {
|
||||
* @param {Node} call CallExpression
|
||||
*/
|
||||
|
||||
LetScoping.prototype.buildHas = function (ret, call) {
|
||||
BlockScoping.prototype.buildHas = function (ret, call) {
|
||||
var body = this.body;
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
|
||||
var ReplaceSupers = require("../../helpers/replace-supers");
|
||||
var nameMethod = require("../../helpers/name-method");
|
||||
var defineMap = require("../../helpers/define-map");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, scope, context, file) {
|
||||
exports.check = t.isClass;
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, scope, file) {
|
||||
return new Class(node, file, scope, true).run();
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, scope, context, file) {
|
||||
exports.ClassExpression = function (node, parent, scope, file) {
|
||||
if (!node.id) {
|
||||
if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) {
|
||||
// var o = { foo: class {} };
|
||||
@@ -47,7 +50,8 @@ function Class(node, file, scope, isStatement) {
|
||||
this.staticMutatorMap = {};
|
||||
this.hasConstructor = false;
|
||||
this.className = node.id || scope.generateUidIdentifier("class");
|
||||
this.superName = node.superClass;
|
||||
this.superName = node.superClass || t.identifier("Function");
|
||||
this.hasSuper = !!node.superClass;
|
||||
this.isLoose = file.isLoose("es6.classes");
|
||||
}
|
||||
|
||||
@@ -66,12 +70,19 @@ Class.prototype.run = function () {
|
||||
|
||||
var body = this.body = [];
|
||||
|
||||
var constructorBody = t.blockStatement([
|
||||
t.expressionStatement(t.callExpression(file.addHelper("class-call-check"), [
|
||||
t.thisExpression(),
|
||||
className
|
||||
]))
|
||||
]);
|
||||
var constructor;
|
||||
|
||||
if (this.node.id) {
|
||||
constructor = t.functionDeclaration(className, [], t.blockStatement([]));
|
||||
constructor = t.functionDeclaration(className, [], constructorBody);
|
||||
body.push(constructor);
|
||||
} else {
|
||||
constructor = t.functionExpression(null, [], t.blockStatement([]));
|
||||
constructor = t.functionExpression(null, [], constructorBody);
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(className, constructor)
|
||||
]));
|
||||
@@ -83,7 +94,7 @@ Class.prototype.run = function () {
|
||||
|
||||
//
|
||||
|
||||
if (superName) {
|
||||
if (this.hasSuper) {
|
||||
closureArgs.push(superName);
|
||||
|
||||
if (!t.isIdentifier(superName)) {
|
||||
@@ -159,11 +170,10 @@ Class.prototype.buildBody = function () {
|
||||
}
|
||||
|
||||
// we have no constructor, we have a super, and the super doesn't appear to be falsy
|
||||
if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) {
|
||||
var defaultConstructorTemplate = "class-super-constructor-call";
|
||||
if (this.isLoose) defaultConstructorTemplate += "-loose";
|
||||
|
||||
constructor.body.body.push(util.template(defaultConstructorTemplate, {
|
||||
if (!this.hasConstructor && this.hasSuper && !t.isFalsyExpression(superName)) {
|
||||
var helperName = "class-super-constructor-call";
|
||||
if (this.isLoose) helperName += "-loose";
|
||||
constructor.body.body.push(util.template(helperName, {
|
||||
CLASS_NAME: className,
|
||||
SUPER_NAME: this.superName
|
||||
}, true));
|
||||
@@ -173,11 +183,11 @@ Class.prototype.buildBody = function () {
|
||||
var staticProps;
|
||||
|
||||
if (this.hasInstanceMutators) {
|
||||
instanceProps = util.buildDefineProperties(this.instanceMutatorMap);
|
||||
instanceProps = defineMap.build(this.instanceMutatorMap);
|
||||
}
|
||||
|
||||
if (this.hasStaticMutators) {
|
||||
staticProps = util.buildDefineProperties(this.staticMutatorMap);
|
||||
staticProps = defineMap.build(this.staticMutatorMap);
|
||||
}
|
||||
|
||||
if (instanceProps || staticProps) {
|
||||
@@ -230,8 +240,8 @@ Class.prototype.pushMethod = function (node) {
|
||||
this.hasInstanceMutators = true;
|
||||
}
|
||||
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
|
||||
util.pushMutatorMap(mutatorMap, methodName, "enumerable", node.computed, false);
|
||||
defineMap.push(mutatorMap, methodName, kind, node.computed, node);
|
||||
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -255,5 +265,5 @@ Class.prototype.pushConstructor = function (method) {
|
||||
|
||||
construct._ignoreUserWhitespace = true;
|
||||
construct.params = fn.params;
|
||||
construct.body = fn.body;
|
||||
construct.body.body = construct.body.body.concat(fn.body.body);
|
||||
};
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var t = require("../../../types");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isVariableDeclaration(node, { kind: "const" });
|
||||
};
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isDeclaration(node) || t.isAssignmentExpression(node)) {
|
||||
var ids = t.getDeclarations(node);
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
|
||||
var ids = t.getBindingIdentifiers(node);
|
||||
|
||||
for (var key in ids) {
|
||||
var id = ids[key];
|
||||
@@ -21,16 +24,19 @@ var visitor = {
|
||||
// constant so we can just ignore it
|
||||
if (id === constant) continue;
|
||||
|
||||
// check if there's been a local binding that shadows this constant
|
||||
if (!scope.bindingEquals(key, constant)) continue;
|
||||
|
||||
throw state.file.errorWithNode(id, key + " is read-only");
|
||||
}
|
||||
} else if (t.isScope(node)) {
|
||||
context.skip();
|
||||
this.skip();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.Scope = function (node, parent, scope, context, file) {
|
||||
traverse(node, visitor, scope, {
|
||||
exports.Scope = function (node, parent, scope, file) {
|
||||
scope.traverse(node, visitor, {
|
||||
constants: scope.getAllDeclarationsOfKind("const"),
|
||||
file: file
|
||||
});
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
// TODO: Clean up
|
||||
|
||||
var t = require("../../../types");
|
||||
|
||||
var buildVariableAssign = function (opts, id, init) {
|
||||
var op = opts.operator;
|
||||
exports.check = t.isPattern;
|
||||
|
||||
function Destructuring(opts) {
|
||||
this.blockHoist = opts.blockHoist;
|
||||
this.operator = opts.operator;
|
||||
this.nodes = opts.nodes;
|
||||
this.scope = opts.scope;
|
||||
this.file = opts.file;
|
||||
this.kind = opts.kind;
|
||||
}
|
||||
|
||||
Destructuring.prototype.buildVariableAssignment = function (id, init) {
|
||||
var op = this.operator;
|
||||
if (t.isMemberExpression(id)) op = "=";
|
||||
|
||||
var node;
|
||||
@@ -13,47 +22,46 @@ var buildVariableAssign = function (opts, id, init) {
|
||||
if (op) {
|
||||
node = t.expressionStatement(t.assignmentExpression(op, id, init));
|
||||
} else {
|
||||
node = t.variableDeclaration(opts.kind, [
|
||||
node = t.variableDeclaration(this.kind, [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
}
|
||||
|
||||
node._blockHoist = opts.blockHoist;
|
||||
node._blockHoist = this.blockHoist;
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
var buildVariableDeclar = function (opts, id, init) {
|
||||
Destructuring.prototype.buildVariableDeclaration = function (id, init) {
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
declar._blockHoist = opts.blockHoist;
|
||||
declar._blockHoist = this.blockHoist;
|
||||
return declar;
|
||||
};
|
||||
|
||||
var push = function (opts, nodes, elem, parentId) {
|
||||
Destructuring.prototype.push = function (elem, parentId) {
|
||||
if (t.isObjectPattern(elem)) {
|
||||
pushObjectPattern(opts, nodes, elem, parentId);
|
||||
this.pushObjectPattern(elem, parentId);
|
||||
} else if (t.isArrayPattern(elem)) {
|
||||
pushArrayPattern(opts, nodes, elem, parentId);
|
||||
this.pushArrayPattern(elem, parentId);
|
||||
} else if (t.isAssignmentPattern(elem)) {
|
||||
pushAssignmentPattern(opts, nodes, elem, parentId);
|
||||
this.pushAssignmentPattern(elem, parentId);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(opts, elem, parentId));
|
||||
this.nodes.push(this.buildVariableAssignment(elem, parentId));
|
||||
}
|
||||
};
|
||||
|
||||
var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
|
||||
var tempParentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
|
||||
Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
|
||||
var tempParentId = this.scope.generateUidBasedOnNode(parentId);
|
||||
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(tempParentId, parentId)
|
||||
]);
|
||||
declar._blockHoist = opts.blockHoist;
|
||||
nodes.push(declar);
|
||||
declar._blockHoist = this.blockHoist;
|
||||
this.nodes.push(declar);
|
||||
|
||||
nodes.push(buildVariableAssign(
|
||||
opts,
|
||||
this.nodes.push(this.buildVariableAssignment(
|
||||
pattern.left,
|
||||
t.conditionalExpression(
|
||||
t.binaryExpression("===", tempParentId, t.identifier("undefined")),
|
||||
@@ -63,72 +71,88 @@ var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
|
||||
));
|
||||
};
|
||||
|
||||
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
|
||||
Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
|
||||
// get all the keys that appear in this object before the current spread
|
||||
var keys = [];
|
||||
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
|
||||
var prop2 = pattern.properties[i2];
|
||||
|
||||
if (i2 >= i) break;
|
||||
if (t.isSpreadProperty(prop2)) continue;
|
||||
|
||||
var key = prop2.key;
|
||||
if (t.isIdentifier(key)) {
|
||||
key = t.literal(prop2.key.name);
|
||||
}
|
||||
keys.push(key);
|
||||
}
|
||||
keys = t.arrayExpression(keys);
|
||||
|
||||
var value = t.callExpression(this.file.addHelper("object-without-properties"), [parentId, keys]);
|
||||
this.nodes.push(this.buildVariableAssignment(prop.argument, value));
|
||||
};
|
||||
|
||||
Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
|
||||
if (t.isLiteral(prop.key)) prop.computed = true;
|
||||
|
||||
var pattern2 = prop.value;
|
||||
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
|
||||
|
||||
if (t.isPattern(pattern2)) {
|
||||
this.push(pattern2, patternId2);
|
||||
} else {
|
||||
this.nodes.push(this.buildVariableAssignment(pattern2, patternId2));
|
||||
}
|
||||
};
|
||||
|
||||
Destructuring.prototype.pushObjectPattern = function (pattern, parentId) {
|
||||
if (!pattern.properties.length) {
|
||||
this.nodes.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("object-destructuring-empty"), [parentId])
|
||||
));
|
||||
}
|
||||
|
||||
for (var i = 0; i < pattern.properties.length; i++) {
|
||||
var prop = pattern.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
// get all the keys that appear in this object before the current spread
|
||||
var keys = [];
|
||||
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
|
||||
var prop2 = pattern.properties[i2];
|
||||
|
||||
if (i2 >= i) break;
|
||||
if (t.isSpreadProperty(prop2)) continue;
|
||||
|
||||
var key = prop2.key;
|
||||
if (t.isIdentifier(key)) {
|
||||
key = t.literal(prop2.key.name);
|
||||
}
|
||||
keys.push(key);
|
||||
}
|
||||
keys = t.arrayExpression(keys);
|
||||
|
||||
var value = t.callExpression(opts.file.addHelper("object-without-properties"), [parentId, keys]);
|
||||
nodes.push(buildVariableAssign(opts, prop.argument, value));
|
||||
this.pushObjectSpread(pattern, parentId, prop, i);
|
||||
} else {
|
||||
if (t.isLiteral(prop.key)) prop.computed = true;
|
||||
|
||||
var pattern2 = prop.value;
|
||||
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
|
||||
|
||||
if (t.isPattern(pattern2)) {
|
||||
push(opts, nodes, pattern2, patternId2);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(opts, pattern2, patternId2));
|
||||
}
|
||||
this.pushObjectProperty(prop, parentId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
if (!pattern.elements) return;
|
||||
|
||||
var i;
|
||||
|
||||
var hasRest = false;
|
||||
for (i = 0; i < pattern.elements.length; i++) {
|
||||
var hasRest = function (pattern) {
|
||||
for (var i = 0; i < pattern.elements.length; i++) {
|
||||
if (t.isRestElement(pattern.elements[i])) {
|
||||
hasRest = true;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var toArray = opts.file.toArray(parentId, !hasRest && pattern.elements.length);
|
||||
Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
|
||||
if (!pattern.elements) return;
|
||||
|
||||
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
|
||||
nodes.push(buildVariableDeclar(opts, _parentId, toArray));
|
||||
// if we have a rest then we need all the elements
|
||||
var count = !hasRest(pattern) && pattern.elements.length;
|
||||
|
||||
var toArray = this.file.toArray(parentId, count);
|
||||
|
||||
var _parentId = this.scope.generateUidBasedOnNode(parentId, this.file);
|
||||
this.nodes.push(this.buildVariableDeclaration(_parentId, toArray));
|
||||
parentId = _parentId;
|
||||
|
||||
for (i = 0; i < pattern.elements.length; i++) {
|
||||
for (var i = 0; i < pattern.elements.length; i++) {
|
||||
var elem = pattern.elements[i];
|
||||
if (!elem) continue;
|
||||
|
||||
i = +i;
|
||||
// hole
|
||||
if (!elem) continue;
|
||||
|
||||
var newPatternId;
|
||||
|
||||
if (t.isRestElement(elem)) {
|
||||
newPatternId = opts.file.toArray(parentId);
|
||||
newPatternId = this.file.toArray(parentId);
|
||||
|
||||
if (i > 0) {
|
||||
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
|
||||
@@ -139,27 +163,22 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
newPatternId = t.memberExpression(parentId, t.literal(i), true);
|
||||
}
|
||||
|
||||
push(opts, nodes, elem, newPatternId);
|
||||
this.push(elem, newPatternId);
|
||||
}
|
||||
};
|
||||
|
||||
var pushPattern = function (opts) {
|
||||
var nodes = opts.nodes;
|
||||
var pattern = opts.pattern;
|
||||
var parentId = opts.id;
|
||||
var scope = opts.scope;
|
||||
|
||||
Destructuring.prototype.init = function (pattern, parentId) {
|
||||
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
var key = scope.generateUidBasedOnNode(parentId);
|
||||
nodes.push(buildVariableDeclar(opts, key, parentId));
|
||||
var key = this.scope.generateUidBasedOnNode(parentId);
|
||||
this.nodes.push(this.buildVariableDeclaration(key, parentId));
|
||||
parentId = key;
|
||||
}
|
||||
|
||||
push(opts, nodes, pattern, parentId);
|
||||
this.push(pattern, parentId);
|
||||
};
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
exports.ForOfStatement = function (node, parent, scope, file) {
|
||||
var declar = node.left;
|
||||
if (!t.isVariableDeclaration(declar)) return;
|
||||
|
||||
@@ -173,11 +192,14 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
|
||||
var nodes = [];
|
||||
|
||||
push({
|
||||
var destructuring = new Destructuring({
|
||||
kind: declar.kind,
|
||||
file: file,
|
||||
scope: scope
|
||||
}, nodes, pattern, key);
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
|
||||
destructuring.init(pattern, key);
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
@@ -185,7 +207,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuring = false;
|
||||
@@ -196,15 +218,14 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
hasDestructuring = true;
|
||||
var parentId = scope.generateUidIdentifier("ref");
|
||||
|
||||
pushPattern({
|
||||
var destructuring = new Destructuring({
|
||||
blockHoist: node.params.length - i,
|
||||
pattern: pattern,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
file: file,
|
||||
kind: "var",
|
||||
id: parentId
|
||||
});
|
||||
destructuring.init(pattern, parentId);
|
||||
|
||||
return parentId;
|
||||
});
|
||||
@@ -217,7 +238,7 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.CatchClause = function (node, parent, scope, context, file) {
|
||||
exports.CatchClause = function (node, parent, scope, file) {
|
||||
var pattern = node.param;
|
||||
if (!t.isPattern(pattern)) return;
|
||||
|
||||
@@ -226,16 +247,18 @@ exports.CatchClause = function (node, parent, scope, context, file) {
|
||||
|
||||
var nodes = [];
|
||||
|
||||
push({
|
||||
var destructuring = new Destructuring({
|
||||
kind: "var",
|
||||
file: file,
|
||||
scope: scope
|
||||
}, nodes, pattern, ref);
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
destructuring.init(pattern, ref);
|
||||
|
||||
node.body.body = nodes.concat(node.body.body);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
if (!t.isPattern(expr.left)) return;
|
||||
@@ -248,16 +271,18 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
t.variableDeclarator(ref, expr.right)
|
||||
]));
|
||||
|
||||
push({
|
||||
var destructuring = new Destructuring({
|
||||
operator: expr.operator,
|
||||
file: file,
|
||||
scope: scope
|
||||
}, nodes, expr.left, ref);
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
destructuring.init(expr.left, ref);
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
if (!t.isPattern(node.left)) return;
|
||||
|
||||
var ref = scope.generateUidIdentifier("temp");
|
||||
@@ -269,50 +294,50 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
var nodes = [];
|
||||
nodes.push(t.assignmentExpression("=", ref, node.right));
|
||||
|
||||
push({
|
||||
var destructuring = new Destructuring({
|
||||
operator: node.operator,
|
||||
file: file,
|
||||
scope: scope
|
||||
}, nodes, node.left, ref);
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
destructuring.init(node.left, ref);
|
||||
|
||||
nodes.push(ref);
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, scope, context, file) {
|
||||
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
|
||||
|
||||
var nodes = [];
|
||||
var i;
|
||||
var declar;
|
||||
|
||||
var hasPattern = false;
|
||||
for (i = 0; i < node.declarations.length; i++) {
|
||||
declar = node.declarations[i];
|
||||
if (t.isPattern(declar.id)) {
|
||||
hasPattern = true;
|
||||
break;
|
||||
var variableDeclarationhasPattern = function (node) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
if (t.isPattern(node.declarations[i].id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!hasPattern) return;
|
||||
return false;
|
||||
};
|
||||
|
||||
for (i = 0; i < node.declarations.length; i++) {
|
||||
exports.VariableDeclaration = function (node, parent, scope, file) {
|
||||
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
|
||||
if (!variableDeclarationhasPattern(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
var declar;
|
||||
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
declar = node.declarations[i];
|
||||
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
var opts = {
|
||||
pattern: pattern,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
kind: node.kind,
|
||||
file: file,
|
||||
id: patternId,
|
||||
};
|
||||
|
||||
var destructuring = new Destructuring({
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
kind: node.kind,
|
||||
file: file
|
||||
});
|
||||
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
pushPattern(opts);
|
||||
destructuring.init(pattern, patternId);
|
||||
|
||||
if (+i !== node.declarations.length - 1) {
|
||||
// we aren't the last declarator so let's just make the
|
||||
@@ -320,11 +345,14 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
|
||||
t.inherits(nodes[nodes.length - 1], declar);
|
||||
}
|
||||
} else {
|
||||
nodes.push(t.inherits(buildVariableAssign(opts, declar.id, declar.init), declar));
|
||||
nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar));
|
||||
}
|
||||
}
|
||||
|
||||
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
|
||||
// https://github.com/6to5/6to5/issues/113
|
||||
// for (let [x] = [0]; false;) {}
|
||||
|
||||
declar = null;
|
||||
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
exports.check = t.isForOfStatement;
|
||||
|
||||
exports.ForOfStatement = function (node, parent, scope, file) {
|
||||
var callback = spec;
|
||||
if (file.isLoose("es6.forOf")) callback = loose;
|
||||
|
||||
var build = callback(node, parent, scope, context, file);
|
||||
var build = callback(node, parent, scope, file);
|
||||
var declar = build.declar;
|
||||
var loop = build.loop;
|
||||
var block = loop.body;
|
||||
@@ -32,7 +34,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
return loop;
|
||||
};
|
||||
|
||||
var loose = function (node, parent, scope, context, file) {
|
||||
var loose = function (node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
var declar, id;
|
||||
|
||||
@@ -69,7 +71,7 @@ var loose = function (node, parent, scope, context, file) {
|
||||
};
|
||||
};
|
||||
|
||||
var spec = function (node, parent, scope, context, file) {
|
||||
var spec = function (node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
var declar;
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.ImportDeclaration = function (node, parent, scope, context, file) {
|
||||
exports.check = require("../internal/modules").check;
|
||||
|
||||
exports.ImportDeclaration = function (node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
|
||||
if (node.specifiers.length) {
|
||||
@@ -21,12 +23,12 @@ exports.ImportDeclaration = function (node, parent, scope, context, file) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.ExportDeclaration = function (node, parent, scope, context, file) {
|
||||
exports.ExportDeclaration = function (node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
var i;
|
||||
|
||||
if (node.declaration) {
|
||||
// make sure variable exports have an initialiser
|
||||
// make sure variable exports have an initializer
|
||||
// this is done here to avoid duplicating it in the module formatters
|
||||
if (t.isVariableDeclaration(node.declaration)) {
|
||||
var declar = node.declaration.declarations[0];
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isFunction(node) && hasDefaults(node);
|
||||
};
|
||||
|
||||
var hasDefaults = function (node) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
@@ -12,10 +15,10 @@ var hasDefaults = function (node) {
|
||||
};
|
||||
|
||||
var iifeVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isReferencedIdentifier(node, parent) && state.scope.hasOwn(node.name)) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isReferencedIdentifier(node, parent) && state.scope.hasOwnReference(node.name)) {
|
||||
state.iife = true;
|
||||
context.stop();
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -48,10 +51,10 @@ exports.Function = function (node, parent, scope) {
|
||||
node.params[i] = scope.generateUidIdentifier("x");
|
||||
|
||||
if (!state.iife) {
|
||||
if (t.isIdentifier(right) && scope.hasOwn(right.name)) {
|
||||
if (t.isIdentifier(right) && scope.hasOwnReference(right.name)) {
|
||||
state.iife = true;
|
||||
} else {
|
||||
traverse(right, iifeVisitor, scope, state);
|
||||
scope.traverse(right, iifeVisitor, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isRestElement;
|
||||
|
||||
var hasRest = function (node) {
|
||||
return t.isRestElement(node.params[node.params.length - 1]);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
exports.check = function (node) {
|
||||
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++) {
|
||||
@@ -58,7 +62,7 @@ var spec = function (node, body, objId, initProps, file) {
|
||||
var props = node.properties;
|
||||
var prop, key;
|
||||
|
||||
// normalise key
|
||||
// normalize key
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
|
||||
@@ -4,7 +4,11 @@ var nameMethod = require("../../helpers/name-method");
|
||||
var t = require("../../../types");
|
||||
var clone = require("lodash/lang/clone");
|
||||
|
||||
exports.Property = function (node, parent, scope, context, file) {
|
||||
exports.check = function (node) {
|
||||
return t.isProperty(node) && (node.method || node.shorthand);
|
||||
};
|
||||
|
||||
exports.Property = function (node, parent, scope, file) {
|
||||
if (node.method) {
|
||||
node.method = false;
|
||||
nameMethod.property(node, file, scope);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../../types");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isSpreadElement;
|
||||
|
||||
var getSpreadLiteral = function (spread, file) {
|
||||
return file.toArray(spread.argument);
|
||||
@@ -42,7 +44,7 @@ var build = function (props, file) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.ArrayExpression = function (node, parent, scope, context, file) {
|
||||
exports.ArrayExpression = function (node, parent, scope, file) {
|
||||
var elements = node.elements;
|
||||
if (!hasSpread(elements)) return;
|
||||
|
||||
@@ -57,7 +59,7 @@ exports.ArrayExpression = function (node, parent, scope, context, file) {
|
||||
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node, parent, scope, context, file) {
|
||||
exports.CallExpression = function (node, parent, scope, file) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
@@ -97,7 +99,7 @@ exports.CallExpression = function (node, parent, scope, context, file) {
|
||||
node.arguments.unshift(contextLiteral);
|
||||
};
|
||||
|
||||
exports.NewExpression = function (node, parent, scope, context, file) {
|
||||
exports.NewExpression = function (node, parent, scope, file) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
|
||||
@@ -6,7 +6,11 @@ var buildBinaryExpression = function (left, right) {
|
||||
return t.binaryExpression("+", left, right);
|
||||
};
|
||||
|
||||
exports.TaggedTemplateExpression = function (node, parent, scope, context, file) {
|
||||
exports.check = function (node) {
|
||||
return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node);
|
||||
};
|
||||
|
||||
exports.TaggedTemplateExpression = function (node, parent, scope, file) {
|
||||
var args = [];
|
||||
var quasi = node.quasi;
|
||||
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
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;
|
||||
|
||||
@@ -23,7 +23,7 @@ var container = function (parent, call, ret, file) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
if (!t.isVirtualPropertyExpression(left)) return;
|
||||
|
||||
@@ -63,7 +63,7 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
return container(parent, call, value, file);
|
||||
};
|
||||
|
||||
exports.UnaryExpression = function (node, parent, scope, context, file) {
|
||||
exports.UnaryExpression = function (node, parent, scope, file) {
|
||||
var arg = node.argument;
|
||||
if (!t.isVirtualPropertyExpression(arg)) return;
|
||||
if (node.operator !== "delete") return;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
var buildComprehension = require("../../helpers/build-comprehension");
|
||||
var traverse = require("../../../traverse");
|
||||
var traverse = require("../../../traversal");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.experimental = true;
|
||||
|
||||
exports.ComprehensionExpression = function (node, parent, scope, context, file) {
|
||||
exports.ComprehensionExpression = function (node, parent, scope, file) {
|
||||
var callback = array;
|
||||
if (node.generator) callback = generator;
|
||||
return callback(node, parent, scope, file);
|
||||
|
||||
@@ -6,18 +6,21 @@ var t = require("../../../types");
|
||||
|
||||
exports.experimental = true;
|
||||
|
||||
exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
var hasSpread = false;
|
||||
var i;
|
||||
var prop;
|
||||
for (i = 0; i < node.properties.length; i++) {
|
||||
prop = node.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
hasSpread = true;
|
||||
break;
|
||||
exports.manipulateOptions = function (opts) {
|
||||
if (opts.whitelist.length) opts.whitelist.push("es6.destructuring");
|
||||
};
|
||||
|
||||
var hasSpread = function (node) {
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
if (t.isSpreadProperty(node.properties[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!hasSpread) return;
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent, scope, file) {
|
||||
if (!hasSpread(node)) return;
|
||||
|
||||
var args = [];
|
||||
var props = [];
|
||||
@@ -28,8 +31,8 @@ exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
props = [];
|
||||
};
|
||||
|
||||
for (i = 0; i < node.properties.length; i++) {
|
||||
prop = node.properties[i];
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
var prop = node.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
push();
|
||||
args.push(prop.argument);
|
||||
@@ -11,8 +11,8 @@ module.exports = {
|
||||
"playground.memoizationOperator": require("./playground/memoization-operator"),
|
||||
"playground.objectGetterMemoization": require("./playground/object-getter-memoization"),
|
||||
|
||||
reactCompat: require("./other/react-compat"),
|
||||
react: require("./other/react"),
|
||||
"optimisation.react": require("./optimisation/react"),
|
||||
|
||||
_modules: require("./internal/modules"),
|
||||
|
||||
@@ -28,7 +28,7 @@ module.exports = {
|
||||
asyncToGenerator: require("./other/async-to-generator"),
|
||||
bluebirdCoroutines: require("./other/bluebird-coroutines"),
|
||||
|
||||
"es7.objectSpread": require("./es7/object-spread"),
|
||||
"es7.objectRestSpread": require("./es7/object-rest-spread"),
|
||||
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
|
||||
"es6.spread": require("./es6/spread"),
|
||||
"es6.templateLiterals": require("./es6/template-literals"),
|
||||
@@ -80,6 +80,11 @@ module.exports = {
|
||||
"spec.typeofSymbol": require("./spec/typeof-symbol"),
|
||||
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
|
||||
|
||||
"minification.propertyLiterals": require("./minification/property-literals"),
|
||||
"minification.memberExpressionLiterals": require("./minification/member-expression-literals")
|
||||
"es3.propertyLiterals": require("./es3/property-literals"),
|
||||
"es3.memberExpressionLiterals": require("./es3/member-expression-literals"),
|
||||
|
||||
"minification.removeDebugger": require("./minification/remove-debugger"),
|
||||
"minification.removeConsoleCalls": require("./minification/remove-console-calls"),
|
||||
"minification.deadCodeElimination": require("./minification/dead-code-elimination"),
|
||||
"minification.renameLocalVariables": require("./minification/rename-local-variables")
|
||||
};
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var t = require("../../../types");
|
||||
var t = require("../../../types");
|
||||
|
||||
var functionChildrenVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return context.skip();
|
||||
if (node._ignoreAliasFunctions) return this.skip();
|
||||
|
||||
var getId;
|
||||
|
||||
@@ -26,20 +25,20 @@ var functionChildrenVisitor = {
|
||||
};
|
||||
|
||||
var functionVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, functionChildrenVisitor, scope, state);
|
||||
scope.traverse(node, functionChildrenVisitor, state);
|
||||
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,7 +57,7 @@ var go = function (getBody, node, scope) {
|
||||
|
||||
// traverse the function and find all alias functions so we can alias
|
||||
// `arguments` and `this` if necessary
|
||||
traverse(node, functionVisitor, scope, state);
|
||||
scope.traverse(node, functionVisitor, state);
|
||||
|
||||
var body;
|
||||
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
var useStrict = require("../../helpers/use-strict");
|
||||
|
||||
exports.ast = {
|
||||
exit: function (ast, file) {
|
||||
if (!file.transformers["es6.modules"].canRun()) return;
|
||||
exports.post = function (file) {
|
||||
if (!file.transformers["es6.modules"].canRun()) return;
|
||||
|
||||
useStrict.wrap(ast.program, function () {
|
||||
ast.program.body = file.dynamicImports.concat(ast.program.body);
|
||||
});
|
||||
var program = file.ast.program;
|
||||
|
||||
if (file.moduleFormatter.transform) {
|
||||
file.moduleFormatter.transform(ast);
|
||||
}
|
||||
useStrict.wrap(program, function () {
|
||||
program.body = file.dynamicImports.concat(program.body);
|
||||
});
|
||||
|
||||
if (file.moduleFormatter.transform) {
|
||||
file.moduleFormatter.transform(program);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,13 +8,17 @@
|
||||
|
||||
var t = require("../../../types");
|
||||
|
||||
var resolveModuleSource = function (node, parent, scope, context, file) {
|
||||
var resolveModuleSource = function (node, parent, scope, file) {
|
||||
var resolveModuleSource = file.opts.resolveModuleSource;
|
||||
if (node.source && resolveModuleSource) {
|
||||
node.source.value = resolveModuleSource(node.source.value);
|
||||
}
|
||||
};
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isImportDeclaration(node) || t.isExportDeclaration(node);
|
||||
};
|
||||
|
||||
exports.ImportDeclaration = resolveModuleSource;
|
||||
|
||||
exports.ExportDeclaration = function (node, parent, scope) {
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.ExpressionStatement = function (node) {
|
||||
// remove consequenceless expressions such as local variables and literals
|
||||
//
|
||||
// var foo = true; foo; -> var foo = true;
|
||||
// "foo"; ->
|
||||
//
|
||||
|
||||
var expr = node.expression;
|
||||
if (t.isLiteral(expr) || (t.isIdentifier(node) && t.hasBinding(node.name))) {
|
||||
this.remove();
|
||||
}
|
||||
};
|
||||
|
||||
exports.IfStatement = {
|
||||
exit: function (node) {
|
||||
// todo: in scenarios where we can just return the consequent or
|
||||
// alternate we should drop the block statement if it contains no
|
||||
// block scoped variables
|
||||
|
||||
var consequent = node.consequent;
|
||||
var alternate = node.alternate;
|
||||
var test = node.test;
|
||||
|
||||
// we can check if a test will be truthy 100% and if so then we can inline
|
||||
// the consequent and completely ignore the alternate
|
||||
//
|
||||
// if (true) { foo; } -> { foo; }
|
||||
// if ("foo") { foo; } -> { foo; }
|
||||
//
|
||||
|
||||
if (t.isLiteral(test) && test.value) {
|
||||
return alternate;
|
||||
}
|
||||
|
||||
// we can check if a test will be falsy 100% and if so we can inline the
|
||||
// alternate if there is one and completely remove the consequent
|
||||
//
|
||||
// if ("") { bar; } else { foo; } -> { foo; }
|
||||
// if ("") { bar; } ->
|
||||
//
|
||||
|
||||
if (t.isFalsyExpression(test)) {
|
||||
if (alternate) {
|
||||
return alternate;
|
||||
} else {
|
||||
return this.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// remove alternate blocks that are empty
|
||||
//
|
||||
// if (foo) { foo; } else {} -> if (foo) { foo; }
|
||||
//
|
||||
|
||||
if (t.isBlockStatement(alternate) && !alternate.body.length) {
|
||||
alternate = node.alternate = null;
|
||||
}
|
||||
|
||||
// if the consequent block is empty turn alternate blocks into a consequent
|
||||
// and flip the test
|
||||
//
|
||||
// if (foo) {} else { bar; } -> if (!foo) { bar; }
|
||||
//
|
||||
|
||||
if (t.blockStatement(consequent) && !consequent.body.length &&
|
||||
t.isBlockStatement(alternate) && alternate.body.length) {
|
||||
node.consequent = node.alternate;
|
||||
node.alternate = null;
|
||||
node.test = t.unaryExpression("!", test, true);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../../types");
|
||||
|
||||
var isConsole = t.buildMatchMemberExpression("console", true);
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.CallExpression = function (node) {
|
||||
if (isConsole(node.callee)) {
|
||||
this.remove();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.ExpressionStatement = function (node) {
|
||||
if (t.isIdentifier(node.expression, { name: "debugger" })) {
|
||||
this.remove();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
//var t = require("../../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.Scope = function () {
|
||||
// todo: get all binding identifiers, generate compact names
|
||||
// that wont collide and then call the remap identifier helper
|
||||
|
||||
// this transformer **has** to be ran last as it will absolutley
|
||||
// destroy the scope tree
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
module.exports = BaseOptimiser;
|
||||
|
||||
var object = require("../../../../helpers/object");
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Node} node
|
||||
*/
|
||||
|
||||
function BaseOptimiser(node) {
|
||||
this.methods = object();
|
||||
this.types = object();
|
||||
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
BaseOptimiser.prototype.run = function () {
|
||||
this.getMethods();
|
||||
this.getTypes();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an `ObjectExpression` `node` that contains `propTypes`.
|
||||
*
|
||||
* Search it and match it against the types that we can optimise
|
||||
* and register it for consumption later.
|
||||
*
|
||||
* @param {Node} node
|
||||
*/
|
||||
|
||||
BaseOptimiser.prototype.addPropTypes = function (node) {
|
||||
var props = node.properties;
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
this.addPropType(props[i]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a `Property` node as a prop type.
|
||||
*
|
||||
* We'll try and resolve it to a known type if we can and normalise
|
||||
* it for consumption later.
|
||||
*
|
||||
* @param {Node} prop
|
||||
*/
|
||||
|
||||
BaseOptimiser.prototype.addPropType = function () {
|
||||
|
||||
};
|
||||
@@ -1,51 +0,0 @@
|
||||
module.exports = CreateClassOptimiser;
|
||||
|
||||
var BaseOptimiser = require("./base");
|
||||
var util = require("../../../../util");
|
||||
var t = require("../../../../types");
|
||||
|
||||
function CreateClassOptimiser() {
|
||||
BaseOptimiser.apply(this, arguments);
|
||||
}
|
||||
|
||||
util.inherits(CreateClassOptimiser, BaseOptimiser);
|
||||
|
||||
/**
|
||||
* Get all function expressions.
|
||||
*/
|
||||
|
||||
CreateClassOptimiser.prototype.getMethods = function () {
|
||||
var props = this.node.properties;
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var prop = props[i];
|
||||
|
||||
// irrelevant
|
||||
if (!t.isFunctionExpression(prop.value)) continue;
|
||||
|
||||
// deopt
|
||||
if (prop.computed) continue;
|
||||
|
||||
this.methods[prop.key.name] = prop;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find a `propTypes` property.
|
||||
*/
|
||||
|
||||
CreateClassOptimiser.prototype.getTypes = function () {
|
||||
var props = this.node.properties;
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var prop = props[i];
|
||||
var key = t.toComputedKey(prop, prop.key);
|
||||
|
||||
if (t.isLiteral(key, { value: "propTypes" }) && t.isObjectExpression(prop.value)) {
|
||||
this.addPropTypes(prop.value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// not found
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
var CreateClassOptimiser = require("./create-class");
|
||||
var NativeClassOptimiser = require("./native-class");
|
||||
var react = require("../../../helpers/react");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.CallExpression = function (node) {
|
||||
if (react.isCreateClass(node)) {
|
||||
new CreateClassOptimiser(node.arguments[0]).run();
|
||||
}
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node) {
|
||||
if (react.isReactComponent(node.superClass)) {
|
||||
new NativeClassOptimiser(node).run();
|
||||
}
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
module.exports = NativeClassOptimiser;
|
||||
|
||||
var BaseOptimiser = require("./base");
|
||||
var util = require("../../../../util");
|
||||
var t = require("../../../../types");
|
||||
|
||||
function NativeClassOptimiser() {
|
||||
BaseOptimiser.apply(this, arguments);
|
||||
}
|
||||
|
||||
util.inherits(NativeClassOptimiser, BaseOptimiser);
|
||||
|
||||
/**
|
||||
* Get all instance methods.
|
||||
*/
|
||||
|
||||
NativeClassOptimiser.prototype.getMethods = function () {
|
||||
var body = this.node.body;
|
||||
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
var node = body[i];
|
||||
|
||||
// PrivateDeclaration etc
|
||||
if (!t.isMethodDefinition(node)) continue;
|
||||
|
||||
// deopt
|
||||
if (node.computed) continue;
|
||||
|
||||
// irrelevant
|
||||
if (node.static) continue;
|
||||
|
||||
this.methods[node.key.name] = node;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
NativeClassOptimiser.prototype.getTypes = function () {
|
||||
|
||||
};
|
||||
@@ -7,7 +7,7 @@ exports.optional = true;
|
||||
|
||||
exports.manipulateOptions = bluebirdCoroutines.manipulateOptions;
|
||||
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"), scope);
|
||||
|
||||
@@ -10,7 +10,7 @@ exports.manipulateOptions = function (opts) {
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.Function = function (node, parent, scope, context, file) {
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return remapAsyncToGenerator(
|
||||
|
||||
29
lib/6to5/transformation/transformers/other/react-compat.js
vendored
Normal file
29
lib/6to5/transformation/transformers/other/react-compat.js
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
"use strict";
|
||||
|
||||
var react = require("../../helpers/react");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.manipulateOptions = function (opts) {
|
||||
opts.blacklist.push("react");
|
||||
};
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
require("../../helpers/build-react-transformer")(exports, {
|
||||
pre: function (state) {
|
||||
state.callee = state.tagExpr;
|
||||
},
|
||||
|
||||
post: function (state) {
|
||||
if (react.isCompatTag(state.tagName)) {
|
||||
state.call = t.callExpression(
|
||||
t.memberExpression(
|
||||
t.memberExpression(t.identifier("React"), t.identifier("DOM")),
|
||||
state.tagExpr,
|
||||
t.isLiteral(state.tagExpr)
|
||||
),
|
||||
state.args
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
249
lib/6to5/transformation/transformers/other/react.js
vendored
249
lib/6to5/transformation/transformers/other/react.js
vendored
@@ -1,243 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser)
|
||||
// https://github.com/RReverser/jsx-transpiler
|
||||
var react = require("../../helpers/react");
|
||||
var t = require("../../../types");
|
||||
|
||||
// jsx
|
||||
|
||||
var esutils = require("esutils");
|
||||
var react = require("../../helpers/react");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.JSXIdentifier = function (node, parent) {
|
||||
if (node.name === "this" && t.isReferenced(node, parent)) {
|
||||
return t.thisExpression();
|
||||
} else if (esutils.keyword.isIdentifierName(node.name)) {
|
||||
node.type = "Identifier";
|
||||
} else {
|
||||
return t.literal(node.name);
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXNamespacedName = function (node, parent, scope, context, file) {
|
||||
throw file.errorWithNode(node, "Namespace tags are not supported. ReactJSX is not XML.");
|
||||
};
|
||||
|
||||
exports.JSXMemberExpression = {
|
||||
exit: function (node) {
|
||||
node.computed = t.isLiteral(node.property);
|
||||
node.type = "MemberExpression";
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXExpressionContainer = function (node) {
|
||||
return node.expression;
|
||||
};
|
||||
|
||||
exports.JSXAttribute = {
|
||||
exit: function (node) {
|
||||
var value = node.value || t.literal(true);
|
||||
return t.inherits(t.property("init", node.name, value), node);
|
||||
}
|
||||
};
|
||||
|
||||
var isCompatTag = function (tagName) {
|
||||
return /^[a-z]|\-/.test(tagName);
|
||||
};
|
||||
|
||||
exports.JSXOpeningElement = {
|
||||
exit: function (node, parent, scope, context, file) {
|
||||
var reactCompat = file.opts.reactCompat;
|
||||
var tagExpr = node.name;
|
||||
var args = [];
|
||||
|
||||
var tagName;
|
||||
if (t.isIdentifier(tagExpr)) {
|
||||
tagName = tagExpr.name;
|
||||
} else if (t.isLiteral(tagExpr)) {
|
||||
tagName = tagExpr.value;
|
||||
}
|
||||
|
||||
if (!reactCompat) {
|
||||
if (tagName && isCompatTag(tagName)) {
|
||||
args.push(t.literal(tagName));
|
||||
} else {
|
||||
args.push(tagExpr);
|
||||
}
|
||||
}
|
||||
|
||||
var attribs = node.attributes;
|
||||
if (attribs.length) {
|
||||
attribs = buildJSXOpeningElementAttributes(attribs, file);
|
||||
require("../../helpers/build-react-transformer")(exports, {
|
||||
pre: function (state) {
|
||||
var tagName = state.tagName;
|
||||
var args = state.args;
|
||||
if (react.isCompatTag(tagName)) {
|
||||
args.push(t.literal(tagName));
|
||||
} else {
|
||||
attribs = t.literal(null);
|
||||
args.push(state.tagExpr);
|
||||
}
|
||||
},
|
||||
|
||||
args.push(attribs);
|
||||
|
||||
if (reactCompat) {
|
||||
if (tagName && isCompatTag(tagName)) {
|
||||
return t.callExpression(
|
||||
t.memberExpression(
|
||||
t.memberExpression(t.identifier("React"), t.identifier("DOM")),
|
||||
tagExpr,
|
||||
t.isLiteral(tagExpr)
|
||||
),
|
||||
args
|
||||
);
|
||||
}
|
||||
} else {
|
||||
tagExpr = t.memberExpression(t.identifier("React"), t.identifier("createElement"));
|
||||
}
|
||||
|
||||
return t.callExpression(tagExpr, args);
|
||||
post: function (state) {
|
||||
state.callee = t.memberExpression(t.identifier("React"), t.identifier("createElement"));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The logic for this is quite terse. It's because we need to
|
||||
* support spread elements. We loop over all attributes,
|
||||
* breaking on spreads, we then push a new object containg
|
||||
* all prior attributes to an array for later processing.
|
||||
*/
|
||||
|
||||
var buildJSXOpeningElementAttributes = function (attribs, file) {
|
||||
var _props = [];
|
||||
var objs = [];
|
||||
|
||||
var pushProps = function () {
|
||||
if (!_props.length) return;
|
||||
|
||||
objs.push(t.objectExpression(_props));
|
||||
_props = [];
|
||||
};
|
||||
|
||||
while (attribs.length) {
|
||||
var prop = attribs.shift();
|
||||
if (t.isJSXSpreadAttribute(prop)) {
|
||||
pushProps();
|
||||
objs.push(prop.argument);
|
||||
} else {
|
||||
_props.push(prop);
|
||||
}
|
||||
}
|
||||
|
||||
pushProps();
|
||||
|
||||
if (objs.length === 1) {
|
||||
// only one object
|
||||
attribs = objs[0];
|
||||
} else {
|
||||
// looks like we have multiple objects
|
||||
if (!t.isObjectExpression(objs[0])) {
|
||||
objs.unshift(t.objectExpression([]));
|
||||
}
|
||||
|
||||
// spread it
|
||||
attribs = t.callExpression(
|
||||
file.addHelper("extends"),
|
||||
objs
|
||||
);
|
||||
}
|
||||
|
||||
return attribs;
|
||||
};
|
||||
|
||||
exports.JSXElement = {
|
||||
exit: function (node) {
|
||||
var callExpr = node.openingElement;
|
||||
|
||||
for (var i = 0; i < node.children.length; i++) {
|
||||
var child = node.children[i];
|
||||
|
||||
if (t.isLiteral(child) && typeof child.value === "string") {
|
||||
cleanJSXElementLiteralChild(child, callExpr.arguments);
|
||||
continue;
|
||||
} else if (t.isJSXEmptyExpression(child)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
callExpr.arguments.push(child);
|
||||
}
|
||||
|
||||
if (callExpr.arguments.length >= 3) {
|
||||
callExpr._prettyCall = true;
|
||||
}
|
||||
|
||||
return t.inherits(callExpr, node);
|
||||
}
|
||||
};
|
||||
|
||||
var cleanJSXElementLiteralChild = function (child, args) {
|
||||
var lines = child.value.split(/\r\n|\n|\r/);
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
|
||||
var isFirstLine = i === 0;
|
||||
var isLastLine = i === lines.length - 1;
|
||||
|
||||
// replace rendered whitespace tabs with spaces
|
||||
var trimmedLine = line.replace(/\t/g, " ");
|
||||
|
||||
// trim whitespace touching a newline
|
||||
if (!isFirstLine) {
|
||||
trimmedLine = trimmedLine.replace(/^[ ]+/, "");
|
||||
}
|
||||
|
||||
// trim whitespace touching an endline
|
||||
if (!isLastLine) {
|
||||
trimmedLine = trimmedLine.replace(/[ ]+$/, "");
|
||||
}
|
||||
|
||||
if (trimmedLine) {
|
||||
args.push(t.literal(trimmedLine));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// display names
|
||||
|
||||
var addDisplayName = function (id, call) {
|
||||
if (!react.isCreateClass(call)) return;
|
||||
|
||||
var props = call.arguments[0].properties;
|
||||
var safe = true;
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var prop = props[i];
|
||||
if (t.isIdentifier(prop.key, { name: "displayName" })) {
|
||||
safe = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (safe) {
|
||||
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
|
||||
}
|
||||
};
|
||||
|
||||
exports.AssignmentExpression =
|
||||
exports.Property =
|
||||
exports.VariableDeclarator = function (node) {
|
||||
var left, right;
|
||||
|
||||
if (t.isAssignmentExpression(node)) {
|
||||
left = node.left;
|
||||
right = node.right;
|
||||
} else if (t.isProperty(node)) {
|
||||
left = node.key;
|
||||
right = node.value;
|
||||
} else if (t.isVariableDeclarator(node)) {
|
||||
left = node.id;
|
||||
right = node.init;
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(left)) {
|
||||
left = left.property;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(left)) {
|
||||
addDisplayName(left.name, right);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
var regenerator = require("regenerator-6to5");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.ast = {
|
||||
before: function (ast, file) {
|
||||
regenerator.transform(ast, {
|
||||
includeRuntime: file.opts.includeRegenerator && "if used"
|
||||
});
|
||||
exports.check = function (node) {
|
||||
return t.isFunction(node) && (node.async || node.generator);
|
||||
};
|
||||
|
||||
exports.Program = {
|
||||
enter: function (ast) {
|
||||
regenerator.transform(ast);
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var util = require("../../../util");
|
||||
var core = require("core-js/library");
|
||||
var t = require("../../../types");
|
||||
@@ -21,7 +20,7 @@ var ALIASABLE_CONSTRUCTORS = [
|
||||
];
|
||||
|
||||
var astVisitor = {
|
||||
enter: function (node, parent, scope, context, file) {
|
||||
enter: function (node, parent, scope, file) {
|
||||
var prop;
|
||||
|
||||
if (t.isMemberExpression(node) && t.isReferenced(node, parent)) {
|
||||
@@ -31,11 +30,11 @@ var astVisitor = {
|
||||
|
||||
if (!t.isReferenced(obj, node)) return;
|
||||
|
||||
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name)) {
|
||||
context.skip();
|
||||
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name) && !scope.getBinding(obj.name)) {
|
||||
this.skip();
|
||||
return t.prependToMemberExpression(node, file.get("coreIdentifier"));
|
||||
}
|
||||
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && contains(ALIASABLE_CONSTRUCTORS, node.name) && !scope.get(node.name, true)) {
|
||||
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && contains(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBinding(node.name)) {
|
||||
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
|
||||
return t.memberExpression(file.get("coreIdentifier"), node);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
@@ -61,27 +60,29 @@ var astVisitor = {
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.ast = {
|
||||
enter: function (ast, file) {
|
||||
file.setDynamic("runtimeIdentifier", function () {
|
||||
return file.addImport("6to5-runtime/helpers", "to5Helpers");
|
||||
});
|
||||
|
||||
file.setDynamic("coreIdentifier", function () {
|
||||
return file.addImport("6to5-runtime/core-js", "core");
|
||||
});
|
||||
|
||||
file.setDynamic("regeneratorIdentifier", function () {
|
||||
return file.addImport("6to5-runtime/regenerator", "regeneratorRuntime");
|
||||
});
|
||||
},
|
||||
|
||||
after: function (ast, file) {
|
||||
traverse(ast, astVisitor, null, file);
|
||||
}
|
||||
exports.manipulateOptions = function (opts) {
|
||||
if (opts.whitelist.length) opts.whitelist.push("es6.modules");
|
||||
};
|
||||
|
||||
exports.Identifier = function (node, parent, scope, context, file) {
|
||||
exports.post = function (file) {
|
||||
file.scope.traverse(file.ast, astVisitor, file);
|
||||
};
|
||||
|
||||
exports.pre = function (file) {
|
||||
file.setDynamic("runtimeIdentifier", function () {
|
||||
return file.addImport("6to5-runtime/helpers", "to5Helpers");
|
||||
});
|
||||
|
||||
file.setDynamic("coreIdentifier", function () {
|
||||
return file.addImport("6to5-runtime/core-js", "core");
|
||||
});
|
||||
|
||||
file.setDynamic("regeneratorIdentifier", function () {
|
||||
return file.addImport("6to5-runtime/regenerator", "regeneratorRuntime");
|
||||
});
|
||||
};
|
||||
|
||||
exports.Identifier = function (node, parent, scope, file) {
|
||||
if (node.name === "regeneratorRuntime" && t.isReferenced(node, parent)) {
|
||||
return file.get("regeneratorIdentifier");
|
||||
}
|
||||
|
||||
@@ -3,17 +3,16 @@
|
||||
var useStrict = require("../../helpers/use-strict");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.ast = {
|
||||
exit: function (ast) {
|
||||
if (!useStrict.has(ast.program)) {
|
||||
ast.program.body.unshift(t.expressionStatement(t.literal("use strict")));
|
||||
}
|
||||
exports.post = function (file) {
|
||||
var program = file.ast.program;
|
||||
if (!useStrict.has(program)) {
|
||||
program.body.unshift(t.expressionStatement(t.literal("use strict")));
|
||||
}
|
||||
};
|
||||
|
||||
exports.FunctionDeclaration =
|
||||
exports.FunctionExpression = function (node, parent, scope, context) {
|
||||
context.skip();
|
||||
exports.FunctionExpression = function () {
|
||||
this.skip();
|
||||
};
|
||||
|
||||
exports.ThisExpression = function () {
|
||||
|
||||
@@ -26,7 +26,7 @@ exports.BindMemberExpression = function (node, parent, scope) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.BindFunctionExpression = function (node, parent, scope, context, file) {
|
||||
exports.BindFunctionExpression = function (node, parent, scope, file) {
|
||||
var buildCall = function (args) {
|
||||
var param = scope.generateUidIdentifier("val");
|
||||
return t.functionExpression(null, [param], t.blockStatement([
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var t = require("../../../types");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.playground = true;
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isFunction(node)) return;
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isFunction(node)) return this.skip();
|
||||
|
||||
if (t.isReturnStatement(node) && node.argument) {
|
||||
node.argument = t.memberExpression(t.callExpression(state.file.addHelper("define-property"), [
|
||||
@@ -20,7 +19,7 @@ var visitor = {
|
||||
};
|
||||
|
||||
exports.Property =
|
||||
exports.MethodDefinition = function (node, parent, scope, context, file) {
|
||||
exports.MethodDefinition = function (node, parent, scope, file) {
|
||||
if (node.kind !== "memo") return;
|
||||
node.kind = "get";
|
||||
|
||||
@@ -38,5 +37,7 @@ exports.MethodDefinition = function (node, parent, scope, context, file) {
|
||||
file: file
|
||||
};
|
||||
|
||||
traverse(value, visitor, scope, state);
|
||||
scope.traverse(value, visitor, state);
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ var buildDefaultsCallExpression = function (expr, ref, file) {
|
||||
exports.optional = true;
|
||||
exports.secondPass = true;
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
if (!isProtoAssignmentExpression(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
@@ -33,7 +33,7 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
return t.toSequenceExpression(nodes);
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
var expr = node.expression;
|
||||
if (!t.isAssignmentExpression(expr, { operator: "=" })) return;
|
||||
|
||||
@@ -42,7 +42,7 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
exports.ObjectExpression = function (node, parent, scope, file) {
|
||||
var proto;
|
||||
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
|
||||
@@ -4,8 +4,8 @@ var t = require("../../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.UnaryExpression = function (node, parent, scope, context, file) {
|
||||
context.skip();
|
||||
exports.UnaryExpression = function (node, parent, scope, file) {
|
||||
this.skip();
|
||||
|
||||
if (node.operator === "typeof") {
|
||||
var call = t.callExpression(file.addHelper("typeof"), [node.argument]);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
exports.ForOfStatement = function (node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
if (t.isVariableDeclaration(left)) {
|
||||
var declar = left.declarations[0];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user