Compare commits
223 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4c6660d21 | ||
|
|
9676666e7c | ||
|
|
388133642d | ||
|
|
23b5eeb72f | ||
|
|
db36c3a7c2 | ||
|
|
e841b88cbc | ||
|
|
3d874f2479 | ||
|
|
228719102a | ||
|
|
c6ce1a248c | ||
|
|
ba9b85f64b | ||
|
|
56c868efee | ||
|
|
1f3c3832ba | ||
|
|
3b04a8c648 | ||
|
|
2270057b54 | ||
|
|
c3206aa9a4 | ||
|
|
1912d1b26a | ||
|
|
9208e7e594 | ||
|
|
ce332b3384 | ||
|
|
a567531f77 | ||
|
|
9cce72def0 | ||
|
|
2d8581c6dc | ||
|
|
14a000396a | ||
|
|
4c41f5a22f | ||
|
|
6be2a6e02a | ||
|
|
0a4fc16ca0 | ||
|
|
25d8377411 | ||
|
|
14267a788d | ||
|
|
ba5c5760b1 | ||
|
|
49904b3ab3 | ||
|
|
a212f035e4 | ||
|
|
ea471a6a17 | ||
|
|
f5bae0b696 | ||
|
|
9ec9e13aeb | ||
|
|
0b042b2681 | ||
|
|
83b4d12884 | ||
|
|
98d555498d | ||
|
|
fdc05cb977 | ||
|
|
928ebda5bc | ||
|
|
0a2003af66 | ||
|
|
02392635ef | ||
|
|
298cfac7f4 | ||
|
|
476b683f0f | ||
|
|
5c5b66df54 | ||
|
|
e7f6572a3b | ||
|
|
e9cfd2df3e | ||
|
|
a425136680 | ||
|
|
8d06a4301c | ||
|
|
1909a16dc7 | ||
|
|
3bfa1f610c | ||
|
|
4faf2b7730 | ||
|
|
4e5d6ee976 | ||
|
|
afb1ee79a1 | ||
|
|
efe3f30741 | ||
|
|
5ff0285ba7 | ||
|
|
d7bea2f325 | ||
|
|
32316ad942 | ||
|
|
7953eb560e | ||
|
|
faa10df84c | ||
|
|
ae344aa23e | ||
|
|
e0bfc72700 | ||
|
|
bf8f80faf7 | ||
|
|
77fa8bf01c | ||
|
|
34ca1ac04f | ||
|
|
85d33536e0 | ||
|
|
a4932e0e0f | ||
|
|
4ebd0a1e8a | ||
|
|
14e92e9e3f | ||
|
|
13687d98ed | ||
|
|
db93c52182 | ||
|
|
56a953df64 | ||
|
|
c38edbbb42 | ||
|
|
017bb6427a | ||
|
|
714ad40cb0 | ||
|
|
904a72fb3a | ||
|
|
146835e0f1 | ||
|
|
79ba97872c | ||
|
|
897566ccb3 | ||
|
|
4df1b6700b | ||
|
|
50f903caf7 | ||
|
|
7b8118d8bd | ||
|
|
0c1e1e757c | ||
|
|
62fa583fc1 | ||
|
|
8598000a69 | ||
|
|
edc8bee38e | ||
|
|
45b70d7fba | ||
|
|
49a53b26bb | ||
|
|
329b4e9d21 | ||
|
|
f1bca0013e | ||
|
|
87af83f1cb | ||
|
|
5156574bf2 | ||
|
|
ac098255be | ||
|
|
47b803ef24 | ||
|
|
7f61c8b65e | ||
|
|
4fa9aa63a3 | ||
|
|
d582c7c93a | ||
|
|
6266f5b924 | ||
|
|
c6920a0e60 | ||
|
|
825d84ba52 | ||
|
|
94a0eb5b06 | ||
|
|
b6d708caf2 | ||
|
|
0d542b61d3 | ||
|
|
5a842ab623 | ||
|
|
26d4b5f2cf | ||
|
|
ba0dfac53d | ||
|
|
8a4296a948 | ||
|
|
478f9e028f | ||
|
|
c4e56894d9 | ||
|
|
c6f13844ed | ||
|
|
5e81653680 | ||
|
|
8e2df3f1f9 | ||
|
|
a2cc384172 | ||
|
|
d37bf292a1 | ||
|
|
70eb641530 | ||
|
|
f845a9b2c4 | ||
|
|
ee5cb8d9ed | ||
|
|
9020a21ba2 | ||
|
|
fdda013d07 | ||
|
|
64477d934d | ||
|
|
45c507056a | ||
|
|
730b96c195 | ||
|
|
a185f91433 | ||
|
|
d053622802 | ||
|
|
74d6b61973 | ||
|
|
97784c8cca | ||
|
|
812d93553a | ||
|
|
d251b4cb56 | ||
|
|
caf38e1962 | ||
|
|
4ccbee4639 | ||
|
|
84196a3a07 | ||
|
|
29361c055a | ||
|
|
4277265591 | ||
|
|
812a2b315d | ||
|
|
0a1724fc3f | ||
|
|
bcc9e016b1 | ||
|
|
4ea0175ca7 | ||
|
|
799445c745 | ||
|
|
481ea12999 | ||
|
|
de6b608dda | ||
|
|
606f813822 | ||
|
|
e06c8cd106 | ||
|
|
9e3c67a8a2 | ||
|
|
91362f80b1 | ||
|
|
cde988f99f | ||
|
|
9ec0854659 | ||
|
|
bb17571e56 | ||
|
|
9161af58c0 | ||
|
|
e39f4e8025 | ||
|
|
f5e9909e71 | ||
|
|
46913fc55f | ||
|
|
d358a86e98 | ||
|
|
055545980c | ||
|
|
6fd7f9868e | ||
|
|
e8184a9bc5 | ||
|
|
f74de3ef55 | ||
|
|
9624f8287d | ||
|
|
e42d5a889e | ||
|
|
4c8e6481b6 | ||
|
|
0867df2691 | ||
|
|
b06f99ab30 | ||
|
|
9afa3f6b58 | ||
|
|
785cb4b72f | ||
|
|
dabe69856a | ||
|
|
24e70802b5 | ||
|
|
c1ba55a52d | ||
|
|
4c318166e1 | ||
|
|
c0af67eca1 | ||
|
|
eb14f1da00 | ||
|
|
3361b81658 | ||
|
|
a15f218e9b | ||
|
|
067cf43f52 | ||
|
|
689ce048e6 | ||
|
|
8a143bf957 | ||
|
|
9f7bcf585d | ||
|
|
f9efd8a272 | ||
|
|
8cd2326ff9 | ||
|
|
eb1ae70bfa | ||
|
|
24ef81908c | ||
|
|
b53b41cef3 | ||
|
|
ad245ed46a | ||
|
|
3f6199493e | ||
|
|
e06aac4783 | ||
|
|
6a5adfe338 | ||
|
|
07c7b5b419 | ||
|
|
7f985fe08a | ||
|
|
38f02a6429 | ||
|
|
f943bdcac0 | ||
|
|
8dc634edfc | ||
|
|
05b9cf17f0 | ||
|
|
69bbe89616 | ||
|
|
6b49958f7c | ||
|
|
e75ce94578 | ||
|
|
f666473724 | ||
|
|
ae817e3c9c | ||
|
|
2e9352de14 | ||
|
|
1e9e55ddef | ||
|
|
0799ed7116 | ||
|
|
5537250d4f | ||
|
|
7ada50937b | ||
|
|
f2ae88af93 | ||
|
|
726451f86f | ||
|
|
306cfc6328 | ||
|
|
a051a47048 | ||
|
|
5b2216b348 | ||
|
|
ad60d49611 | ||
|
|
a6d1a5a724 | ||
|
|
399d835285 | ||
|
|
b66367ddde | ||
|
|
37d29b7a6f | ||
|
|
1e708fb373 | ||
|
|
76ae1682a3 | ||
|
|
2ef0aa95c5 | ||
|
|
9cbb49c6b2 | ||
|
|
f04a734838 | ||
|
|
beb5ccab25 | ||
|
|
b8f8f24e82 | ||
|
|
c35a007401 | ||
|
|
e639c82f2f | ||
|
|
f365cc1248 | ||
|
|
2b75c67448 | ||
|
|
e5e9ae7e0f | ||
|
|
009422e997 | ||
|
|
386e221a0f | ||
|
|
58db94401e |
5
.6to5rc
Normal file
5
.6to5rc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"experimental": true,
|
||||
"playground": true,
|
||||
"loose": true
|
||||
}
|
||||
@@ -6,6 +6,6 @@ charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.js]
|
||||
[*.{js,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"esnext": true,
|
||||
"indent": 2,
|
||||
"freeze": true,
|
||||
"validthis": true,
|
||||
"camelcase": true,
|
||||
"unused": true,
|
||||
"eqnull": true,
|
||||
|
||||
@@ -3,6 +3,7 @@ language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
- "0.12"
|
||||
|
||||
branches:
|
||||
except:
|
||||
|
||||
81
CHANGELOG.md
81
CHANGELOG.md
@@ -11,6 +11,87 @@
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 3.6.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Multiline JSX string literals are now supported.
|
||||
* Fix scope tracking import specifiers incorrectly.
|
||||
* Fix templates incorrectly recursing into their replacements.
|
||||
* **Internal**
|
||||
* Type inferrence now extends to function return types.
|
||||
* Upgrade `acorn-6to5`.
|
||||
|
||||
## 3.6.0
|
||||
|
||||
* **New Feature**
|
||||
* Add playground class property initializers.
|
||||
* **Polish**
|
||||
* Completely reimplemented scope tracking, can now track types and optimise certain helpers based on it.
|
||||
* Extremely fast tail recursion optimisation implementation. Thanks [@RReverser](https://github.com/RReverser)!
|
||||
* **Internal**
|
||||
* `kexec` has been removed as an optional dependency and must be user installed.
|
||||
* Upgrade `regenerator-6to5`.
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Upgrade `core-js`.
|
||||
|
||||
## 3.5.3
|
||||
|
||||
* Enable `es6.tailCall` transformer with the first implementation that only works with self referencing calls until we can implement nested tail calls elegantly.
|
||||
|
||||
## 3.5.2
|
||||
|
||||
* Disable `es6.tailCall` temporairly after reports of it breaking.
|
||||
|
||||
## 3.5.1
|
||||
|
||||
* **Polish**
|
||||
* Allow tail calls to work across files without the runtime.
|
||||
* **Internal**
|
||||
* Upgrade `acorn-6to5`.
|
||||
|
||||
## 3.5.0
|
||||
|
||||
* **Bug Fix**
|
||||
* Destructuring patterns as the left operator in `ForInStatement`/`ForOfStatement`.
|
||||
* **Polish**
|
||||
* Make default parameter IIFE invocation smarter.
|
||||
* Make `__esModule` flag non-enumerable. Thanks [@daliwali](https://github.com/daliwali)!
|
||||
* **Internal**
|
||||
* More performance improvements.
|
||||
* Parsing is now ~30% faster thanks to [marijnh/acorn@7264bc0178e7e6af7cfe02e9e0c6b26ee0e6007f](https://github.com/marijnh/acorn/commit/7264bc0178e7e6af7cfe02e9e0c6b26ee0e6007f).
|
||||
* **New Feature**
|
||||
* Optional `es6.blockScopingTDZ` is now completely functional and handles all edgecases.
|
||||
* `super` in object literals.
|
||||
* Tail call optimisation. Thanks [@RReverser](https://github.com/RReverser)!
|
||||
|
||||
## 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**
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
# Contributing
|
||||
|
||||
Contributions are always welcome, no matter how large or small. Before contributing, please read the [code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
|
||||
Contributions are always welcome, no matter how large or small. Before
|
||||
contributing, please read the
|
||||
[code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
|
||||
|
||||
**NOTE:** Please do not send pull requests that fix linting issues. It's highly
|
||||
likely that they've already been fixed by the time it's submitted and it just
|
||||
pollutes the git tree.
|
||||
|
||||
## Developing
|
||||
|
||||
@@ -12,7 +18,8 @@ Contributions are always welcome, no matter how large or small. Before contribut
|
||||
* Link your forked clone (`npm link`)
|
||||
* Develop your changes ensuring you're fetching updates from upstream often
|
||||
* Ensure the test are passing (`make test`)
|
||||
* Create new pull request explaining your proposed change or reference an issue in your commit message
|
||||
* Create new pull request explaining your proposed change or reference an issue
|
||||
in your commit message
|
||||
|
||||
#### Code Standards
|
||||
|
||||
|
||||
15
Makefile
15
Makefile
@@ -5,10 +5,17 @@ UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
|
||||
JSHINT_CMD = node_modules/jshint/bin/jshint
|
||||
MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
JSCS_CMD = node_modules/jscs/bin/jscs
|
||||
6TO5_CMD = node_modules/6to5/bin/6to5
|
||||
|
||||
export NODE_ENV = test
|
||||
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime build-core watch-core
|
||||
|
||||
build-core:
|
||||
#node $(6TO5_CMD) src --out-dir lib
|
||||
|
||||
watch-core:
|
||||
#node $(6TO5_CMD) src --out-dir lib --watch
|
||||
|
||||
build:
|
||||
mkdir -p dist
|
||||
@@ -18,7 +25,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
|
||||
@@ -55,7 +62,7 @@ test-cov:
|
||||
export SIMPLE_6TO5_TESTS=1; \
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
|
||||
|
||||
test-travis: bootstrap
|
||||
test-travis: build-core bootstrap
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
|
||||
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi
|
||||
|
||||
@@ -92,7 +99,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; \
|
||||
|
||||
17
appveyor.yml
17
appveyor.yml
@@ -1,17 +0,0 @@
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.11"
|
||||
|
||||
install:
|
||||
- "npm install"
|
||||
- "cinst make"
|
||||
|
||||
test_script:
|
||||
- "node --version"
|
||||
- "npm --version"
|
||||
- "make test-spec"
|
||||
|
||||
build: "off"
|
||||
|
||||
version: "{build}"
|
||||
@@ -37,8 +37,13 @@ module.exports = function (commander, filenames, opts) {
|
||||
if (stat.isDirectory(filename)) {
|
||||
var dirname = filename;
|
||||
|
||||
_.each(util.readdirFilter(dirname), function (filename) {
|
||||
write(path.join(dirname, filename), filename);
|
||||
_.each(util.readdir(dirname), function (filename) {
|
||||
var src = path.join(dirname, filename);
|
||||
if (util.canCompile(filename)) {
|
||||
write(src, filename);
|
||||
} else {
|
||||
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
write(filename, filename);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -12,6 +12,10 @@ exports.readdirFilter = function (filename) {
|
||||
});
|
||||
};
|
||||
|
||||
exports.readdir = readdir;
|
||||
|
||||
exports.canCompile = util.canCompile;
|
||||
|
||||
exports.addSourceMappingUrl = function (code, loc) {
|
||||
return code + "\n//# sourceMappingURL=" + path.basename(loc);
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
@@ -1,14 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
require("./polyfill");
|
||||
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 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) {
|
||||
@@ -44,8 +44,10 @@ var mtime = function (filename) {
|
||||
var compile = function (filename) {
|
||||
var result;
|
||||
|
||||
var cacheKey = filename + ":" + JSON.stringify(transformOpts);
|
||||
|
||||
if (cache) {
|
||||
var cached = cache[filename];
|
||||
var cached = cache[cacheKey];
|
||||
if (cached && cached.mtime === mtime(filename)) {
|
||||
result = cached;
|
||||
}
|
||||
@@ -60,7 +62,7 @@ var compile = function (filename) {
|
||||
|
||||
if (cache) {
|
||||
result.mtime = mtime(filename);
|
||||
cache[filename] = result;
|
||||
cache[cacheKey] = result;
|
||||
}
|
||||
|
||||
maps[filename] = result.map;
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
var includes = require("lodash/collection/includes");
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, detected) {
|
||||
if (node.operator === "**=") {
|
||||
@@ -38,7 +38,7 @@ exports.Property = function (node, parent, detected) {
|
||||
};
|
||||
|
||||
exports.AssignmentPattern = function (node, parent, detected) {
|
||||
if (t.isFunction(parent) && _.contains(parent.params, node)) {
|
||||
if (t.isFunction(parent) && includes(parent.params, node)) {
|
||||
detected("es6.parameters.default");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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 includes = require("lodash/collection/includes");
|
||||
var isNumber = require("lodash/lang/isNumber");
|
||||
var util = require("../util");
|
||||
|
||||
function Buffer(position, format) {
|
||||
this.position = position;
|
||||
@@ -159,7 +159,7 @@ Buffer.prototype.isLast = function (cha, trimRight) {
|
||||
var last = buf[buf.length - 1];
|
||||
|
||||
if (Array.isArray(cha)) {
|
||||
return contains(cha, last);
|
||||
return includes(cha, last);
|
||||
} else {
|
||||
return cha === last;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ exports.IfStatement = function (node, print) {
|
||||
print.indentOnComments(node.consequent);
|
||||
|
||||
if (node.alternate) {
|
||||
if (this.isLast("}")) this.push(" ");
|
||||
if (this.isLast("}")) this.space();
|
||||
this.keyword("else");
|
||||
|
||||
if (this.format.format && !t.isBlockStatement(node.alternate)) {
|
||||
|
||||
@@ -12,12 +12,12 @@ 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 || {};
|
||||
@@ -25,6 +25,7 @@ function CodeGenerator(ast, opts, code) {
|
||||
this.comments = ast.comments || [];
|
||||
this.tokens = ast.tokens || [];
|
||||
this.format = CodeGenerator.normalizeOptions(code, opts);
|
||||
this.opts = opts;
|
||||
this.ast = ast;
|
||||
|
||||
this.whitespace = new Whitespace(this.tokens, this.comments);
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
48
lib/6to5/messages.js
Normal file
48
lib/6to5/messages.js
Normal file
@@ -0,0 +1,48 @@
|
||||
var util = require("util");
|
||||
|
||||
exports.messages = {
|
||||
tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence",
|
||||
JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.",
|
||||
classesIllegalBareSuper: "Illegal use of bare super",
|
||||
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
|
||||
classesIllegalConstructorKind: "Illegal kind for constructor method",
|
||||
scopeDuplicateDeclaration: "Duplicate declaration $1",
|
||||
undeclaredVariable: "Reference to undeclared variable $1",
|
||||
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
|
||||
settersInvalidParamLength: "Setters must have only one parameter",
|
||||
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
|
||||
expectedMemberExpressionOrIdentifier: "Expected type MemeberExpression or Identifier",
|
||||
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
|
||||
readOnly: "$1 is read-only",
|
||||
modulesIllegalExportName: "Illegal export $1",
|
||||
unknownForHead: "Unknown node type $1 in ForStatement"
|
||||
};
|
||||
|
||||
exports.get = function (key) {
|
||||
var msg = exports.messages[key];
|
||||
if (!msg) throw new ReferenceError("Unknown message `" + key + "`");
|
||||
|
||||
var args = [];
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args.push(arguments[i]);
|
||||
}
|
||||
args = exports.parseArgs(args);
|
||||
|
||||
return msg.replace(/\$(\d+)/g, function (str, i) {
|
||||
return args[--i];
|
||||
});
|
||||
};
|
||||
|
||||
exports.parseArgs = function (args) {
|
||||
return args.map(function (val) {
|
||||
if (val != null && val.inspect) {
|
||||
return val.inspect();
|
||||
} else {
|
||||
try {
|
||||
return JSON.stringify(val) || val + "";
|
||||
} catch (e) {
|
||||
return util.inspect(val);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,9 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("./types");
|
||||
var extend = require("lodash/object/extend");
|
||||
|
||||
require("./types/node");
|
||||
var t = require("./types");
|
||||
|
||||
// estraverse
|
||||
|
||||
|
||||
@@ -5,16 +5,17 @@ module.exports = File;
|
||||
var SHEBANG_REGEX = /^\#\!.*/;
|
||||
|
||||
var isFunction = require("lodash/lang/isFunction");
|
||||
var transform = require("./transformation");
|
||||
var generate = require("./generation");
|
||||
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 Scope = require("./traverse/scope");
|
||||
var util = require("./util");
|
||||
var includes = require("lodash/collection/includes");
|
||||
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");
|
||||
var t = require("../types");
|
||||
|
||||
function File(opts) {
|
||||
this.dynamicImportIds = {};
|
||||
@@ -40,6 +41,7 @@ File.helpers = [
|
||||
"tagged-template-literal-loose",
|
||||
"interop-require",
|
||||
"to-array",
|
||||
"to-consumable-array",
|
||||
"sliced-to-array",
|
||||
"object-without-properties",
|
||||
"has-own",
|
||||
@@ -53,7 +55,10 @@ File.helpers = [
|
||||
"get",
|
||||
"set",
|
||||
"class-call-check",
|
||||
"object-destructuring-empty"
|
||||
"object-destructuring-empty",
|
||||
"temporal-undefined",
|
||||
"temporal-assert-defined",
|
||||
"tail-call"
|
||||
];
|
||||
|
||||
File.validOptions = [
|
||||
@@ -119,7 +124,10 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
});
|
||||
|
||||
// normalize windows path separators to unix
|
||||
opts.filename = opts.filename.replace(/\\/g, "/");
|
||||
opts.filename = util.normalisePathSeparator(opts.filename);
|
||||
if (opts.sourceRoot) {
|
||||
opts.sourceRoot = util.normalisePathSeparator(opts.sourceRoot);
|
||||
}
|
||||
|
||||
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
|
||||
|
||||
@@ -128,7 +136,7 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
opts.optional = util.arrayify(opts.optional);
|
||||
opts.loose = util.arrayify(opts.loose);
|
||||
|
||||
if (contains(opts.loose, "all")) {
|
||||
if (includes(opts.loose, "all") || includes(opts.loose, true)) {
|
||||
opts.loose = Object.keys(transform.transformers);
|
||||
}
|
||||
|
||||
@@ -159,14 +167,29 @@ File.prototype.normalizeOptions = 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");
|
||||
}
|
||||
|
||||
var ensureEnabled = function (key) {
|
||||
var namespace = transform.transformerNamespaces[key];
|
||||
if (namespace === "es7") opts.experimental = true;
|
||||
if (namespace === "playground") opts.playground = true;
|
||||
};
|
||||
|
||||
each(opts.whitelist, ensureEnabled);
|
||||
each(opts.optional, ensureEnabled);
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
File.prototype.isLoose = function (key) {
|
||||
return contains(this.opts.loose, key);
|
||||
return includes(this.opts.loose, key);
|
||||
};
|
||||
|
||||
File.prototype.buildTransformers = function () {
|
||||
@@ -197,20 +220,10 @@ File.prototype.buildTransformers = function () {
|
||||
this.transformers = transformers;
|
||||
};
|
||||
|
||||
File.prototype.toArray = function (node, i) {
|
||||
if (t.isArrayExpression(node)) {
|
||||
return node;
|
||||
} else if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
return t.callExpression(t.memberExpression(this.addHelper("slice"), t.identifier("call")), [node]);
|
||||
} else {
|
||||
var declarationName = "to-array";
|
||||
var args = [node];
|
||||
if (i) {
|
||||
args.push(t.literal(i));
|
||||
declarationName = "sliced-to-array";
|
||||
}
|
||||
return t.callExpression(this.addHelper(declarationName), args);
|
||||
}
|
||||
File.prototype.debug = function (msg) {
|
||||
var parts = this.opts.filename;
|
||||
if (msg) parts += ": " + msg;
|
||||
util.debug(parts);
|
||||
};
|
||||
|
||||
File.prototype.getModuleFormatter = function (type) {
|
||||
@@ -265,7 +278,7 @@ File.prototype.addImport = function (source, name) {
|
||||
var id = this.dynamicImportIds[name];
|
||||
|
||||
if (!id) {
|
||||
id = this.dynamicImportIds[name] = this.generateUidIdentifier(name);
|
||||
id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(name);
|
||||
|
||||
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
|
||||
var declar = t.importDeclaration(specifiers, t.literal(source));
|
||||
@@ -283,8 +296,8 @@ File.prototype.isConsequenceExpressionStatement = function (node) {
|
||||
};
|
||||
|
||||
File.prototype.addHelper = function (name) {
|
||||
if (!contains(File.helpers, name)) {
|
||||
throw new ReferenceError("unknown declaration " + name);
|
||||
if (!includes(File.helpers, name)) {
|
||||
throw new ReferenceError("Unknown helper " + name);
|
||||
}
|
||||
|
||||
var program = this.ast.program;
|
||||
@@ -299,7 +312,7 @@ File.prototype.addHelper = function (name) {
|
||||
} else {
|
||||
var ref = util.template(name);
|
||||
ref._compact = true;
|
||||
var uid = this.generateUidIdentifier(name);
|
||||
var uid = this.scope.generateUidIdentifier(name);
|
||||
this.scope.push({
|
||||
key: name,
|
||||
id: uid,
|
||||
@@ -309,6 +322,10 @@ File.prototype.addHelper = function (name) {
|
||||
}
|
||||
};
|
||||
|
||||
File.prototype.logDeopt = function () {
|
||||
// todo, (node, msg)
|
||||
};
|
||||
|
||||
File.prototype.errorWithNode = function (node, msg, Error) {
|
||||
Error = Error || SyntaxError;
|
||||
|
||||
@@ -334,16 +351,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);
|
||||
@@ -356,42 +371,46 @@ File.prototype.transform = function (ast) {
|
||||
|
||||
this.checkNode(ast);
|
||||
|
||||
var astRun = function (key) {
|
||||
each(self.transformerStack, function (pass) {
|
||||
pass.astRun(key);
|
||||
});
|
||||
};
|
||||
|
||||
astRun("enter");
|
||||
this.call("pre");
|
||||
|
||||
each(this.transformerStack, function (pass) {
|
||||
pass.transform();
|
||||
});
|
||||
|
||||
astRun("exit");
|
||||
this.call("post");
|
||||
};
|
||||
|
||||
var checkTransformerVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
state.check(node, scope);
|
||||
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 self = this;
|
||||
var stack = this.transformerStack;
|
||||
scope = scope || this.scope;
|
||||
|
||||
var check = function (node, scope) {
|
||||
each(self.transformerStack, function (pass) {
|
||||
if (pass.shouldRun) return;
|
||||
pass.checkNode(node, scope);
|
||||
});
|
||||
};
|
||||
|
||||
check(node, scope);
|
||||
checkNode(stack, node, scope);
|
||||
|
||||
scope.traverse(node, checkTransformerVisitor, {
|
||||
check: check
|
||||
stack: stack
|
||||
});
|
||||
};
|
||||
|
||||
@@ -419,34 +438,8 @@ File.prototype.generate = function () {
|
||||
|
||||
if (opts.sourceMap === "inline") {
|
||||
result.code += "\n" + util.sourceMapToComment(result.map);
|
||||
result.map = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
File.prototype.generateUid = function (name, scope) {
|
||||
name = t.toIdentifier(name).replace(/^_+/, "");
|
||||
|
||||
scope = scope || this.scope;
|
||||
|
||||
var uid;
|
||||
var i = 0;
|
||||
do {
|
||||
uid = this._generateUid(name, i);
|
||||
i++;
|
||||
} 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.addDeclarationToFunctionScope("var", id);
|
||||
return id;
|
||||
};
|
||||
|
||||
File.prototype._generateUid = function (name, i) {
|
||||
var id = name;
|
||||
if (i > 1) id += i;
|
||||
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 = [];
|
||||
|
||||
284
lib/6to5/transformation/helpers/build-react-transformer.js
Normal file
284
lib/6to5/transformation/helpers/build-react-transformer.js
Normal file
@@ -0,0 +1,284 @@
|
||||
"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 messages = require("../../messages");
|
||||
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, messages.get("JSXNamespacedTags"));
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
if (t.isLiteral(value) && isString(value.value)) {
|
||||
value.value = value.value.replace(/\n\s+/g, " ");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
var cloneDeep = require("lodash/lang/cloneDeep");
|
||||
var traverse = require("../../traverse");
|
||||
var clone = require("lodash/lang/clone");
|
||||
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");
|
||||
|
||||
@@ -18,7 +18,7 @@ var getObjRef = function (node, nodes, file, scope) {
|
||||
} else if (t.isMemberExpression(node)) {
|
||||
ref = node.object;
|
||||
|
||||
if (t.isIdentifier(ref) && scope.hasReference(ref.name)) {
|
||||
if (t.isIdentifier(ref) && scope.hasGlobal(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
|
||||
|
||||
@@ -4,7 +4,7 @@ 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;
|
||||
|
||||
@@ -13,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.getBinding(state.id);
|
||||
var localDeclar = scope.getBindingIdentifier(state.id);
|
||||
if (localDeclar !== state.outerDeclar) return;
|
||||
|
||||
state.selfReference = true;
|
||||
context.stop();
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -31,20 +31,23 @@ exports.property = function (node, file, scope) {
|
||||
var state = {
|
||||
id: id,
|
||||
selfReference: false,
|
||||
outerDeclar: scope.getBinding(id),
|
||||
outerDeclar: scope.getBindingIdentifier(id),
|
||||
};
|
||||
|
||||
scope.traverse(node, visitor, state);
|
||||
|
||||
var method = node.value;
|
||||
|
||||
if (state.selfReference) {
|
||||
// todo: support generators
|
||||
node.value = util.template("property-method-assignment-wrapper", {
|
||||
FUNCTION: node.value,
|
||||
var templateName = "property-method-assignment-wrapper";
|
||||
if (method.generator) templateName += "-generator";
|
||||
node.value = util.template(templateName, {
|
||||
FUNCTION: method,
|
||||
FUNCTION_ID: key,
|
||||
FUNCTION_KEY: scope.generateUidIdentifier(id),
|
||||
WRAPPER_KEY: scope.generateUidIdentifier(id + "Wrapper")
|
||||
});
|
||||
} else {
|
||||
node.value.id = key;
|
||||
method.id = key;
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
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";
|
||||
|
||||
@@ -2,19 +2,24 @@
|
||||
|
||||
module.exports = ReplaceSupers;
|
||||
|
||||
var t = require("../../types");
|
||||
var messages = require("../../messages");
|
||||
var t = require("../../types");
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} opts
|
||||
* @param {Boolean} [inClass]
|
||||
*/
|
||||
|
||||
function ReplaceSupers(opts) {
|
||||
this.topLevelThisReference = null;
|
||||
function ReplaceSupers(opts, inClass) {
|
||||
this.topLevelThisReference = opts.topLevelThisReference;
|
||||
this.methodNode = opts.methodNode;
|
||||
this.className = opts.className;
|
||||
this.superName = opts.superName;
|
||||
this.isStatic = opts.isStatic;
|
||||
this.hasSuper = false;
|
||||
this.inClass = inClass;
|
||||
this.isLoose = opts.isLoose;
|
||||
this.scope = opts.scope;
|
||||
this.file = opts.file;
|
||||
@@ -28,16 +33,23 @@ function ReplaceSupers(opts) {
|
||||
* _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this)
|
||||
*
|
||||
* @param {Node} property
|
||||
* @param {boolean} isStatic
|
||||
* @param {boolean} isComputed
|
||||
* @param {Node} value
|
||||
* @param {Boolean} isComputed
|
||||
* @param {Node} thisExpression
|
||||
*
|
||||
* @returns {Node}
|
||||
*/
|
||||
ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic, isComputed, thisExpression) {
|
||||
|
||||
ReplaceSupers.prototype.setSuperProperty = function (property, value, isComputed, thisExpression) {
|
||||
return t.callExpression(
|
||||
this.file.addHelper("set"),
|
||||
[
|
||||
isStatic ? this.superName : t.memberExpression(this.superName, t.identifier("prototype")),
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[
|
||||
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
|
||||
]
|
||||
),
|
||||
isComputed ? property : t.literal(property.name),
|
||||
value,
|
||||
thisExpression
|
||||
@@ -53,17 +65,22 @@ ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic,
|
||||
* _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
|
||||
*
|
||||
* @param {Node} property
|
||||
* @param {boolean} isStatic
|
||||
* @param {boolean} isComputed
|
||||
* @param {Boolean} isComputed
|
||||
* @param {Node} thisExpression
|
||||
*
|
||||
* @returns {Node}
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.getSuperProperty = function (property, isStatic, isComputed, thisExpression) {
|
||||
ReplaceSupers.prototype.getSuperProperty = function (property, isComputed, thisExpression) {
|
||||
return t.callExpression(
|
||||
this.file.addHelper("get"),
|
||||
[
|
||||
isStatic ? this.superName : t.memberExpression(this.superName, t.identifier("prototype")),
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[
|
||||
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
|
||||
]
|
||||
),
|
||||
isComputed ? property : t.literal(property.name),
|
||||
thisExpression
|
||||
]
|
||||
@@ -79,19 +96,19 @@ ReplaceSupers.prototype.replace = function () {
|
||||
};
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
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 context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
|
||||
// break on object methods
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
var getThisReference = topLevel ?
|
||||
@@ -126,7 +143,7 @@ ReplaceSupers.prototype.getThisReference = function () {
|
||||
if (this.topLevelThisReference) {
|
||||
return this.topLevelThisReference;
|
||||
} else {
|
||||
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
|
||||
var ref = this.topLevelThisReference = this.scope.generateUidIdentifier("this");
|
||||
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
|
||||
]));
|
||||
@@ -143,7 +160,8 @@ ReplaceSupers.prototype.getThisReference = function () {
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
ReplaceSupers.prototype.getLooseSuperProperty = function (methodNode, id, parent) {
|
||||
ReplaceSupers.prototype.getLooseSuperProperty = function (id, parent) {
|
||||
var methodNode = this.methodNode;
|
||||
var methodName = methodNode.key;
|
||||
var superName = this.superName || t.identifier("Function");
|
||||
|
||||
@@ -185,13 +203,15 @@ ReplaceSupers.prototype.getLooseSuperProperty = function (methodNode, id, parent
|
||||
|
||||
ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return this.getLooseSuperProperty(this.methodNode, node, parent);
|
||||
this.hasSuper = true;
|
||||
return this.getLooseSuperProperty(node, parent);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
this.hasSuper = true;
|
||||
t.appendToMemberExpression(callee, t.identifier("call"));
|
||||
node.arguments.unshift(getThisReference());
|
||||
}
|
||||
@@ -212,13 +232,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, messages.get("classesIllegalBareSuper"));
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -227,38 +247,32 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
|
||||
// bare `super` call is illegal inside non-constructors
|
||||
// - https://esdiscuss.org/topic/super-call-in-methods
|
||||
// - https://twitter.com/wycats/status/544553184396836864
|
||||
if (methodNode.key.name !== "constructor") {
|
||||
if (methodNode.key.name !== "constructor" || !this.inClass) {
|
||||
var methodName = methodNode.key.name || "METHOD_NAME";
|
||||
throw this.file.errorWithNode(node, "Direct super call is illegal in non-constructor, use super." + methodName + "() instead");
|
||||
throw this.file.errorWithNode(node, messages.get("classesIllegalSuperCall", methodName));
|
||||
}
|
||||
} 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);
|
||||
this.hasSuper = true;
|
||||
return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference());
|
||||
}
|
||||
|
||||
if (!property) return;
|
||||
|
||||
this.hasSuper = true;
|
||||
|
||||
thisReference = getThisReference();
|
||||
var superProperty = this.getSuperProperty(property, methodNode.static, computed, thisReference);
|
||||
var superProperty = this.getSuperProperty(property, computed, thisReference);
|
||||
if (args) {
|
||||
if (args.length === 1 && t.isSpreadElement(args[0])) {
|
||||
// super(...arguments);
|
||||
@@ -276,3 +290,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.normalizeAst(ast);
|
||||
ast = normalizeAst(ast);
|
||||
|
||||
var file = new File(opts);
|
||||
file.addCode(code);
|
||||
@@ -56,8 +56,9 @@ transform._ensureTransformerNames = function (type, rawKeys) {
|
||||
return keys;
|
||||
};
|
||||
|
||||
transform.transformers = object();
|
||||
transform.namespaces = object();
|
||||
transform.transformerNamespaces = object();
|
||||
transform.transformers = object();
|
||||
transform.namespaces = object();
|
||||
|
||||
transform.deprecatedTransformerMap = require("./transformers/deprecated");
|
||||
transform.moduleFormatters = require("./modules");
|
||||
@@ -66,8 +67,10 @@ var rawTransformers = require("./transformers");
|
||||
|
||||
each(rawTransformers, function (transformer, key) {
|
||||
var namespace = key.split(".")[0];
|
||||
|
||||
transform.namespaces[namespace] = transform.namespaces[namespace] || [];
|
||||
transform.namespaces[namespace].push(key);
|
||||
transform.transformerNamespaces[key] = namespace;
|
||||
|
||||
transform.transformers[key] = new Transformer(key, transformer);
|
||||
});
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
|
||||
module.exports = DefaultFormatter;
|
||||
|
||||
var messages = require("../../messages");
|
||||
var extend = require("lodash/object/extend");
|
||||
var object = require("../../helpers/object");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var extend = require("lodash/object/extend");
|
||||
|
||||
function DefaultFormatter(file) {
|
||||
this.file = file;
|
||||
this.ids = object();
|
||||
this.scope = file.scope;
|
||||
this.file = file;
|
||||
this.ids = object();
|
||||
|
||||
this.hasNonDefaultExports = false;
|
||||
|
||||
@@ -27,7 +29,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) {
|
||||
@@ -38,7 +40,7 @@ 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;
|
||||
@@ -63,7 +65,7 @@ DefaultFormatter.prototype.getLocalExports = function () {
|
||||
};
|
||||
|
||||
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.getBindingIdentifiers(node));
|
||||
@@ -77,9 +79,9 @@ DefaultFormatter.prototype.getLocalImports = function () {
|
||||
};
|
||||
|
||||
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));
|
||||
@@ -107,7 +109,7 @@ var remapVisitor = {
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(node) && formatter.isLocalReference(node.left, scope)) {
|
||||
context.skip();
|
||||
this.skip();
|
||||
return formatter.remapExportAssignment(node);
|
||||
}
|
||||
}
|
||||
@@ -124,13 +126,6 @@ DefaultFormatter.prototype.isLocalReference = function (node) {
|
||||
return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.checkLocalReference = function (node) {
|
||||
var file = this.file;
|
||||
if (this.isLocalReference(node)) {
|
||||
throw file.errorWithNode(node, "Illegal assignment of module import");
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
||||
return t.assignmentExpression(
|
||||
"=",
|
||||
@@ -146,7 +141,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.getBinding(name);
|
||||
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getModuleName = function () {
|
||||
@@ -213,14 +208,11 @@ 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");
|
||||
throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name));
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
var inherits = false;
|
||||
if (node.specifiers.length === 1) inherits = node;
|
||||
|
||||
if (node.source) {
|
||||
var ref = this.getExternalReference(node, nodes);
|
||||
|
||||
@@ -228,7 +220,7 @@ DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
// export * from "foo";
|
||||
nodes.push(this.buildExportsWildcard(ref, node));
|
||||
} else {
|
||||
if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
|
||||
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 {
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ var DefaultFormatter = require("./_default");
|
||||
var CommonFormatter = require("./common");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var includes = require("lodash/collection/includes");
|
||||
var values = require("lodash/object/values");
|
||||
|
||||
function AMDFormatter() {
|
||||
@@ -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
|
||||
|
||||
@@ -71,7 +70,7 @@ AMDFormatter.prototype.getModuleName = function () {
|
||||
};
|
||||
|
||||
AMDFormatter.prototype._getExternalReference = function (node) {
|
||||
return this.file.generateUidIdentifier(node.source.value);
|
||||
return this.scope.generateUidIdentifier(node.source.value);
|
||||
};
|
||||
|
||||
AMDFormatter.prototype.importDeclaration = function (node) {
|
||||
@@ -82,12 +81,12 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
var key = t.getSpecifierName(specifier);
|
||||
var ref = this.getExternalReference(node);
|
||||
|
||||
if (contains(this.file.dynamicImported, node)) {
|
||||
if (includes(this.file.dynamicImported, node)) {
|
||||
// Prevent unnecessary renaming of dynamic imports.
|
||||
this.ids[node.source.value] = ref;
|
||||
} else if (t.isImportBatchSpecifier(specifier)) {
|
||||
// import * as bar from "foo";
|
||||
} else if (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);
|
||||
@@ -3,7 +3,7 @@
|
||||
module.exports = CommonJSFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var includes = require("lodash/collection/includes");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
@@ -14,8 +14,13 @@ function CommonJSFormatter() {
|
||||
util.inherits(CommonJSFormatter, DefaultFormatter);
|
||||
|
||||
CommonJSFormatter.prototype.init = function () {
|
||||
if (this.hasNonDefaultExports) {
|
||||
this.file.ast.program.body.push(util.template("exports-module-declaration", true));
|
||||
var file = this.file;
|
||||
var scope = file.scope;
|
||||
|
||||
scope.rename("module");
|
||||
|
||||
if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
|
||||
file.ast.program.body.push(util.template("exports-module-declaration", true));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,20 +31,24 @@ 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 (!includes(this.file.dynamicImported, node)) {
|
||||
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";
|
||||
@@ -84,7 +93,7 @@ CommonJSFormatter.prototype._getExternalReference = function (node, nodes) {
|
||||
var call = t.callExpression(t.identifier("require"), [node.source]);
|
||||
|
||||
if (this.localImportOccurences[source] > 1) {
|
||||
var uid = this.file.generateUidIdentifier(source);
|
||||
var uid = this.scope.generateUidIdentifier(source);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(uid, call)
|
||||
]));
|
||||
|
||||
@@ -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")
|
||||
};
|
||||
|
||||
@@ -12,8 +12,9 @@ var each = require("lodash/collection/each");
|
||||
var map = require("lodash/collection/map");
|
||||
|
||||
function SystemFormatter(file) {
|
||||
this.exportIdentifier = file.generateUidIdentifier("export");
|
||||
this.noInteropRequire = true;
|
||||
this.exportIdentifier = file.scope.generateUidIdentifier("export");
|
||||
this.noInteropRequireExport = true;
|
||||
this.noInteropRequireImport = true;
|
||||
|
||||
DefaultFormatter.apply(this, arguments);
|
||||
}
|
||||
@@ -28,7 +29,7 @@ SystemFormatter.prototype._addImportSource = function (node, exportNode) {
|
||||
};
|
||||
|
||||
SystemFormatter.prototype.buildExportsWildcard = function (objectIdentifier, node) {
|
||||
var leftIdentifier = this.file.generateUidIdentifier("key");
|
||||
var leftIdentifier = this.scope.generateUidIdentifier("key");
|
||||
var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true);
|
||||
|
||||
var left = t.variableDeclaration("var", [
|
||||
@@ -68,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) {
|
||||
@@ -81,7 +82,7 @@ var runnerSettersVisitor = {
|
||||
state.nodes.push(node);
|
||||
}
|
||||
|
||||
context.remove();
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -103,10 +104,10 @@ SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators
|
||||
};
|
||||
|
||||
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)) {
|
||||
@@ -148,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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
3
lib/6to5/transformation/templates/.6to5rc
Normal file
3
lib/6to5/transformation/templates/.6to5rc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"blacklist": ["useStrict"]
|
||||
}
|
||||
1
lib/6to5/transformation/templates/corejs-is-iterator.js
Normal file
1
lib/6to5/transformation/templates/corejs-is-iterator.js
Normal file
@@ -0,0 +1 @@
|
||||
CORE_ID.$for.isIterable(VALUE);
|
||||
@@ -1 +1 @@
|
||||
var VARIABLE_NAME = ARGUMENTS[ARGUMENT_KEY] === undefined ? DEFAULT_VALUE : ARGUMENTS[ARGUMENT_KEY];
|
||||
let VARIABLE_NAME = ARGUMENTS[ARGUMENT_KEY] === undefined ? DEFAULT_VALUE : ARGUMENTS[ARGUMENT_KEY];
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
(function (obj, defaults) {
|
||||
for (var key in defaults) {
|
||||
if (obj[key] === undefined) {
|
||||
obj[key] = defaults[key];
|
||||
var keys = Object.getOwnPropertyNames(defaults);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var value = Object.getOwnPropertyDescriptor(defaults, key);
|
||||
if (value && value.configurable && obj[key] === undefined) {
|
||||
Object.defineProperty(obj, key, value);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
exports.__esModule = true;
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
(function (FUNCTION_KEY) {
|
||||
var WRAPPER_KEY = function* FUNCTION_ID() {
|
||||
return yield* FUNCTION_KEY.apply(this, arguments);
|
||||
};
|
||||
|
||||
WRAPPER_KEY.toString = function () {
|
||||
return FUNCTION_KEY.toString();
|
||||
};
|
||||
|
||||
return WRAPPER_KEY;
|
||||
})(FUNCTION)
|
||||
@@ -4,21 +4,16 @@
|
||||
if (desc === undefined) {
|
||||
var parent = Object.getPrototypeOf(object);
|
||||
|
||||
if (parent === null) {
|
||||
return;
|
||||
} else {
|
||||
if (parent !== null) {
|
||||
return set(parent, property, value, receiver);
|
||||
}
|
||||
} else if ("value" in desc && desc.writable) {
|
||||
desc.value = value;
|
||||
return;
|
||||
return desc.value = value;
|
||||
} else {
|
||||
var setter = desc.set;
|
||||
|
||||
if (setter === undefined) {
|
||||
return;
|
||||
if (setter !== undefined) {
|
||||
return setter.call(receiver, value);
|
||||
}
|
||||
|
||||
return setter.call(receiver, value);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
(function (arr, i) {
|
||||
if (Array.isArray(arr)) {
|
||||
return arr;
|
||||
} else {
|
||||
} else if (Symbol.iterator in Object(arr)) {
|
||||
var _arr = [];
|
||||
for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
|
||||
_arr.push(_step.value);
|
||||
if (i && _arr.length === i) break;
|
||||
}
|
||||
return _arr;
|
||||
} else {
|
||||
throw new TypeError("Invalid attempt to destructure non-iterable instance");
|
||||
}
|
||||
});
|
||||
|
||||
3
lib/6to5/transformation/templates/tail-call-body.js
Normal file
3
lib/6to5/transformation/templates/tail-call-body.js
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
FUNCTION_ID:while (true) BLOCK
|
||||
}
|
||||
23
lib/6to5/transformation/templates/tail-call.js
Normal file
23
lib/6to5/transformation/templates/tail-call.js
Normal file
@@ -0,0 +1,23 @@
|
||||
(function () {
|
||||
function Tail(func, args, context) {
|
||||
this.func = func;
|
||||
this.args = args;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
Tail.prototype._isTailDescriptor = true;
|
||||
|
||||
var isRunning = false;
|
||||
|
||||
return function (func, args, context) {
|
||||
var result = new Tail(func, args, context);
|
||||
if (!isRunning) {
|
||||
isRunning = true;
|
||||
do {
|
||||
result = result.func.apply(result.context, result.args);
|
||||
} while (result instanceof Tail || (result && result._isTailDescriptor));
|
||||
isRunning = false;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})()
|
||||
@@ -0,0 +1,6 @@
|
||||
(function (val, name, undef) {
|
||||
if (val === undef) {
|
||||
throw new ReferenceError(name + " is not defined - temporal dead zone");
|
||||
}
|
||||
return true;
|
||||
})
|
||||
1
lib/6to5/transformation/templates/temporal-undefined.js
Normal file
1
lib/6to5/transformation/templates/temporal-undefined.js
Normal file
@@ -0,0 +1 @@
|
||||
({})
|
||||
8
lib/6to5/transformation/templates/to-consumable-array.js
Normal file
8
lib/6to5/transformation/templates/to-consumable-array.js
Normal file
@@ -0,0 +1,8 @@
|
||||
(function (arr) {
|
||||
if (Array.isArray(arr)) {
|
||||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
|
||||
return arr2;
|
||||
} else {
|
||||
return Array.from(arr);
|
||||
}
|
||||
});
|
||||
@@ -1,7 +1,6 @@
|
||||
module.exports = TransformerPass;
|
||||
|
||||
var util = require("../util");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var includes = require("lodash/collection/includes");
|
||||
|
||||
/**
|
||||
* This class is responsible for traversing over the provided `File`s
|
||||
@@ -15,17 +14,6 @@ function TransformerPass(file, transformer) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
TransformerPass.prototype.astRun = function (key) {
|
||||
if (!this.shouldRun) return;
|
||||
|
||||
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;
|
||||
|
||||
@@ -37,14 +25,14 @@ TransformerPass.prototype.canRun = function () {
|
||||
|
||||
// blacklist
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && contains(blacklist, key)) return false;
|
||||
if (blacklist.length && includes(blacklist, key)) return false;
|
||||
|
||||
// whitelist
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist.length && !contains(whitelist, key)) return false;
|
||||
if (whitelist.length) return includes(whitelist, key);
|
||||
|
||||
// optional
|
||||
if (transformer.optional && !contains(opts.optional, key)) return false;
|
||||
if (transformer.optional && !includes(opts.optional, key)) return false;
|
||||
|
||||
// experimental
|
||||
if (transformer.experimental && !opts.experimental) return false;
|
||||
@@ -64,31 +52,12 @@ TransformerPass.prototype.checkNode = function (node) {
|
||||
}
|
||||
};
|
||||
|
||||
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.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 };
|
||||
file.scope.traverse(file.ast, transformVisitor, 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,13 +16,23 @@ var each = require("lodash/collection/each");
|
||||
*/
|
||||
|
||||
function Transformer(key, transformer, opts) {
|
||||
this.manipulateOptions = transformer.manipulateOptions;
|
||||
this.check = transformer.check;
|
||||
transformer = clone(transformer);
|
||||
|
||||
this.experimental = !!transformer.experimental;
|
||||
this.playground = !!transformer.playground;
|
||||
this.secondPass = !!transformer.secondPass;
|
||||
this.optional = !!transformer.optional;
|
||||
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 || {};
|
||||
|
||||
@@ -34,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"
|
||||
}
|
||||
|
||||
@@ -3,31 +3,27 @@
|
||||
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.getBinding(node.name) !== declared) return;
|
||||
if (scope.getBindingIdentifier(node.name) !== declared) return;
|
||||
|
||||
var declaredLoc = declared.loc;
|
||||
var referenceLoc = node.loc;
|
||||
var assert = t.callExpression(
|
||||
state.file.addHelper("temporal-assert-defined"),
|
||||
[node, t.literal(node.name), state.file.addHelper("temporal-undefined")]
|
||||
);
|
||||
|
||||
if (!declaredLoc || !referenceLoc) return;
|
||||
this.skip();
|
||||
|
||||
// does this reference appear on a line before the declaration?
|
||||
var before = referenceLoc.start.line < declaredLoc.start.line;
|
||||
|
||||
if (referenceLoc.start.line === declaredLoc.start.line) {
|
||||
// this reference appears on the same line
|
||||
// check it appears before the declaration
|
||||
before = referenceLoc.start.col < declaredLoc.start.col;
|
||||
}
|
||||
|
||||
if (before) {
|
||||
throw state.file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
|
||||
if (t.isAssignmentExpression(parent) || t.isUpdateExpression(parent)) {
|
||||
if (parent._ignoreBlockScopingTDZ) return;
|
||||
this.parentPath.replaceNode(t.sequenceExpression([assert, parent]));
|
||||
} else {
|
||||
return t.logicalExpression("&&", assert, node);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -36,7 +32,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;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traverse");
|
||||
var traverse = require("../../../traversal");
|
||||
var object = require("../../../helpers/object");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
@@ -17,7 +17,7 @@ var isLet = function (node, parent) {
|
||||
if (node.kind !== "let") return false;
|
||||
|
||||
// https://github.com/6to5/6to5/issues/255
|
||||
if (!t.isFor(parent) || t.isFor(parent) && parent.left !== node) {
|
||||
if (isLetInitable(node, parent)) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var declar = node.declarations[i];
|
||||
declar.init = declar.init || t.identifier("undefined");
|
||||
@@ -29,6 +29,10 @@ var isLet = function (node, parent) {
|
||||
return true;
|
||||
};
|
||||
|
||||
var isLetInitable = function (node, parent) {
|
||||
return !t.isFor(parent) || t.isFor(parent) && parent.left !== node;
|
||||
};
|
||||
|
||||
var isVar = function (node, parent) {
|
||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
|
||||
};
|
||||
@@ -39,11 +43,29 @@ var standardizeLets = function (declars) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent) {
|
||||
isLet(node, parent);
|
||||
exports.VariableDeclaration = function (node, parent, scope, file) {
|
||||
if (!isLet(node, parent)) return;
|
||||
|
||||
if (isLetInitable(node) && file.transformers["es6.blockScopingTDZ"].canRun()) {
|
||||
var nodes = [node];
|
||||
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var decl = node.declarations[i];
|
||||
if (decl.init) {
|
||||
var assign = t.assignmentExpression("=", decl.id, decl.init);
|
||||
assign._ignoreBlockScopingTDZ = true;
|
||||
nodes.push(t.expressionStatement(assign));
|
||||
}
|
||||
decl.init = file.addHelper("temporal-undefined");
|
||||
}
|
||||
|
||||
node._blockHoist = 2;
|
||||
|
||||
return nodes;
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
@@ -54,7 +76,7 @@ exports.Loop = function (node, parent, scope, context, file) {
|
||||
};
|
||||
|
||||
exports.Program =
|
||||
exports.BlockStatement = function (block, parent, scope, context, file) {
|
||||
exports.BlockStatement = function (block, parent, scope, file) {
|
||||
if (!t.isLoop(parent)) {
|
||||
var blockScoping = new BlockScoping(false, block, parent, scope, file);
|
||||
blockScoping.run();
|
||||
@@ -108,19 +130,19 @@ BlockScoping.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 ownBinding = scope.getBinding(node.name);
|
||||
var ownBinding = scope.getBindingIdentifier(node.name);
|
||||
if (ownBinding === remap.binding) {
|
||||
node.name = remap.uid;
|
||||
} else {
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +151,7 @@ var replaceVisitor = {
|
||||
};
|
||||
|
||||
function traverseReplace(node, parent, scope, remaps) {
|
||||
replace(node, parent, scope, null, remaps);
|
||||
replace(node, parent, scope, remaps);
|
||||
scope.traverse(node, replaceVisitor, remaps);
|
||||
}
|
||||
|
||||
@@ -153,7 +175,7 @@ BlockScoping.prototype.remap = function () {
|
||||
// this is the defining identifier of a declaration
|
||||
var ref = letRefs[key];
|
||||
|
||||
if (scope.parentHasReference(key)) {
|
||||
if (scope.parentHasBinding(key) || scope.hasGlobal(key)) {
|
||||
var uid = scope.generateUidIdentifier(ref.name).name;
|
||||
ref.name = uid;
|
||||
|
||||
@@ -225,7 +247,7 @@ BlockScoping.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;
|
||||
|
||||
@@ -241,10 +263,10 @@ var letReferenceFunctionVisitor = {
|
||||
};
|
||||
|
||||
var letReferenceBlockVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isFunction(node)) {
|
||||
scope.traverse(node, letReferenceFunctionVisitor, state);
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -310,7 +332,7 @@ 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)) {
|
||||
@@ -320,7 +342,7 @@ var loopVisitor = {
|
||||
}
|
||||
|
||||
if (t.isFunction(node) || t.isLoop(node)) {
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
var loopText = loopNodeTo(node);
|
||||
@@ -362,7 +384,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);
|
||||
}
|
||||
@@ -395,7 +417,7 @@ BlockScoping.prototype.checkLoop = function () {
|
||||
};
|
||||
|
||||
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));
|
||||
@@ -407,7 +429,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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,16 +3,17 @@
|
||||
var ReplaceSupers = require("../../helpers/replace-supers");
|
||||
var nameMethod = require("../../helpers/name-method");
|
||||
var defineMap = require("../../helpers/define-map");
|
||||
var messages = require("../../../messages");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isClass;
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, scope, context, file) {
|
||||
return new Class(node, file, scope, true).run();
|
||||
exports.ClassDeclaration = function (node, parent, scope, file) {
|
||||
return new ClassTransformer(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 {} };
|
||||
@@ -25,7 +26,7 @@ exports.ClassExpression = function (node, parent, scope, context, file) {
|
||||
}
|
||||
}
|
||||
|
||||
return new Class(node, file, scope, false).run();
|
||||
return new ClassTransformer(node, file, scope, false).run();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -34,10 +35,10 @@ exports.ClassExpression = function (node, parent, scope, context, file) {
|
||||
* @param {Node} node
|
||||
* @param {File} file
|
||||
* @param {Scope} scope
|
||||
* @param {Boolean} closure
|
||||
* @param {Boolean} isStatement
|
||||
*/
|
||||
|
||||
function Class(node, file, scope, isStatement) {
|
||||
function ClassTransformer(node, file, scope, isStatement) {
|
||||
this.isStatement = isStatement;
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
@@ -61,7 +62,7 @@ function Class(node, file, scope, isStatement) {
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
Class.prototype.run = function () {
|
||||
ClassTransformer.prototype.run = function () {
|
||||
var superName = this.superName;
|
||||
var className = this.className;
|
||||
var file = this.file;
|
||||
@@ -98,8 +99,7 @@ Class.prototype.run = function () {
|
||||
closureArgs.push(superName);
|
||||
|
||||
if (!t.isIdentifier(superName)) {
|
||||
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
superName = superRef;
|
||||
superName = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
}
|
||||
|
||||
closureParams.push(superName);
|
||||
@@ -138,7 +138,7 @@ Class.prototype.run = function () {
|
||||
* Description
|
||||
*/
|
||||
|
||||
Class.prototype.buildBody = function () {
|
||||
ClassTransformer.prototype.buildBody = function () {
|
||||
var constructor = this.constructor;
|
||||
var className = this.className;
|
||||
var superName = this.superName;
|
||||
@@ -152,10 +152,11 @@ Class.prototype.buildBody = function () {
|
||||
methodNode: node,
|
||||
className: this.className,
|
||||
superName: this.superName,
|
||||
isStatic: node.static,
|
||||
isLoose: this.isLoose,
|
||||
scope: this.scope,
|
||||
file: this.file
|
||||
});
|
||||
}, true);
|
||||
replaceSupers.replace();
|
||||
|
||||
if (node.key.name === "constructor") {
|
||||
@@ -166,6 +167,8 @@ Class.prototype.buildBody = function () {
|
||||
} else if (t.isPrivateDeclaration(node)) {
|
||||
this.closure = true;
|
||||
body.unshift(node);
|
||||
} else if (t.isClassProperty(node)) {
|
||||
this.pushProperty(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,12 +206,12 @@ Class.prototype.buildBody = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Push a method to it's respective mutatorMap.
|
||||
* Push a method to its respective mutatorMap.
|
||||
*
|
||||
* @param {Node} node MethodDefinition
|
||||
*/
|
||||
|
||||
Class.prototype.pushMethod = function (node) {
|
||||
ClassTransformer.prototype.pushMethod = function (node) {
|
||||
var methodName = node.key;
|
||||
|
||||
var kind = node.kind;
|
||||
@@ -244,15 +247,39 @@ Class.prototype.pushMethod = function (node) {
|
||||
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Node} node
|
||||
*/
|
||||
|
||||
ClassTransformer.prototype.pushProperty = function (node) {
|
||||
if (!node.value) return;
|
||||
|
||||
var key;
|
||||
|
||||
if (node.static) {
|
||||
key = t.memberExpression(this.className, node.key);
|
||||
this.body.push(
|
||||
t.expressionStatement(t.assignmentExpression("=", key, node.value))
|
||||
);
|
||||
} else {
|
||||
key = t.memberExpression(t.thisExpression(), node.key);
|
||||
this.constructor.body.body.unshift(
|
||||
t.expressionStatement(t.assignmentExpression("=", key, node.value))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace the constructor body of our class.
|
||||
*
|
||||
* @param {Node} method MethodDefinition
|
||||
*/
|
||||
|
||||
Class.prototype.pushConstructor = function (method) {
|
||||
ClassTransformer.prototype.pushConstructor = function (method) {
|
||||
if (method.kind) {
|
||||
throw this.file.errorWithNode(method, "illegal kind for constructor method");
|
||||
throw this.file.errorWithNode(method, messages.get("classesIllegalConstructorKind"));
|
||||
}
|
||||
|
||||
var construct = this.constructor;
|
||||
|
||||
@@ -1,43 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../../types");
|
||||
var messages = require("../../../messages");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isVariableDeclaration(node, { kind: "const" });
|
||||
};
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
|
||||
if (t.isMemberExpression(node.left || node.argument)) return;
|
||||
|
||||
var ids = t.getBindingIdentifiers(node);
|
||||
|
||||
for (var key in ids) {
|
||||
var id = ids[key];
|
||||
for (var name in ids) {
|
||||
var id = ids[name];
|
||||
|
||||
var constant = state.constants[key];
|
||||
var constant = state.constants[name];
|
||||
|
||||
// no constant exists
|
||||
if (!constant) continue;
|
||||
|
||||
var constantIdentifier = constant.identifier;
|
||||
|
||||
// check if the assignment id matches the constant declaration id
|
||||
// if it does then it was the id used to initially declare the
|
||||
// constant so we can just ignore it
|
||||
if (id === constant) continue;
|
||||
if (id === constantIdentifier) continue;
|
||||
|
||||
var localBinding = scope.getBinding(key);
|
||||
if (localBinding !== constant) continue;
|
||||
// check if there's been a local binding that shadows this constant
|
||||
if (!scope.bindingIdentifierEquals(name, constantIdentifier)) continue;
|
||||
|
||||
throw state.file.errorWithNode(id, key + " is read-only");
|
||||
throw state.file.errorWithNode(id, messages.get("readOnly", name));
|
||||
}
|
||||
} else if (t.isScope(node)) {
|
||||
context.skip();
|
||||
} else if (t.isScope(node, parent)) {
|
||||
this.skip();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.Scope = function (node, parent, scope, context, file) {
|
||||
exports.Scopable = function (node, parent, scope, file) {
|
||||
scope.traverse(node, visitor, {
|
||||
constants: scope.getAllDeclarationsOfKind("const"),
|
||||
constants: scope.getAllBindingsOfKind("const"),
|
||||
file: file
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../../types");
|
||||
var messages = require("../../../messages");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isPattern;
|
||||
|
||||
function Destructuring(opts) {
|
||||
function DestructuringTransformer(opts) {
|
||||
this.blockHoist = opts.blockHoist;
|
||||
this.operator = opts.operator;
|
||||
this.nodes = opts.nodes;
|
||||
@@ -13,7 +14,7 @@ function Destructuring(opts) {
|
||||
this.kind = opts.kind;
|
||||
}
|
||||
|
||||
Destructuring.prototype.buildVariableAssignment = function (id, init) {
|
||||
DestructuringTransformer.prototype.buildVariableAssignment = function (id, init) {
|
||||
var op = this.operator;
|
||||
if (t.isMemberExpression(id)) op = "=";
|
||||
|
||||
@@ -32,7 +33,7 @@ Destructuring.prototype.buildVariableAssignment = function (id, init) {
|
||||
return node;
|
||||
};
|
||||
|
||||
Destructuring.prototype.buildVariableDeclaration = function (id, init) {
|
||||
DestructuringTransformer.prototype.buildVariableDeclaration = function (id, init) {
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
@@ -40,7 +41,7 @@ Destructuring.prototype.buildVariableDeclaration = function (id, init) {
|
||||
return declar;
|
||||
};
|
||||
|
||||
Destructuring.prototype.push = function (elem, parentId) {
|
||||
DestructuringTransformer.prototype.push = function (elem, parentId) {
|
||||
if (t.isObjectPattern(elem)) {
|
||||
this.pushObjectPattern(elem, parentId);
|
||||
} else if (t.isArrayPattern(elem)) {
|
||||
@@ -52,7 +53,7 @@ Destructuring.prototype.push = function (elem, parentId) {
|
||||
}
|
||||
};
|
||||
|
||||
Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
|
||||
DestructuringTransformer.prototype.pushAssignmentPattern = function (pattern, parentId) {
|
||||
var tempParentId = this.scope.generateUidBasedOnNode(parentId);
|
||||
|
||||
var declar = t.variableDeclaration("var", [
|
||||
@@ -71,7 +72,7 @@ Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
|
||||
));
|
||||
};
|
||||
|
||||
Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
|
||||
DestructuringTransformer.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++) {
|
||||
@@ -92,7 +93,7 @@ Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i)
|
||||
this.nodes.push(this.buildVariableAssignment(prop.argument, value));
|
||||
};
|
||||
|
||||
Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
|
||||
DestructuringTransformer.prototype.pushObjectProperty = function (prop, parentId) {
|
||||
if (t.isLiteral(prop.key)) prop.computed = true;
|
||||
|
||||
var pattern2 = prop.value;
|
||||
@@ -105,13 +106,19 @@ Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
|
||||
}
|
||||
};
|
||||
|
||||
Destructuring.prototype.pushObjectPattern = function (pattern, parentId) {
|
||||
DestructuringTransformer.prototype.pushObjectPattern = function (pattern, parentId) {
|
||||
if (!pattern.properties.length) {
|
||||
this.nodes.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("object-destructuring-empty"), [parentId])
|
||||
));
|
||||
}
|
||||
|
||||
if (pattern.properties.length > 1 && t.isMemberExpression(parentId)) {
|
||||
var temp = this.scope.generateUidBasedOnNode(parentId, this.file);
|
||||
this.nodes.push(this.buildVariableDeclaration(temp, parentId));
|
||||
parentId = temp;
|
||||
}
|
||||
|
||||
for (var i = 0; i < pattern.properties.length; i++) {
|
||||
var prop = pattern.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
@@ -131,18 +138,20 @@ var hasRest = function (pattern) {
|
||||
return false;
|
||||
};
|
||||
|
||||
Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
|
||||
DestructuringTransformer.prototype.pushArrayPattern = function (pattern, parentId) {
|
||||
if (!pattern.elements) return;
|
||||
|
||||
// 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 toArray = this.scope.toArray(parentId, count);
|
||||
|
||||
var _parentId = this.scope.generateUidBasedOnNode(parentId, this.file);
|
||||
var _parentId = this.scope.generateUidBasedOnNode(parentId);
|
||||
this.nodes.push(this.buildVariableDeclaration(_parentId, toArray));
|
||||
parentId = _parentId;
|
||||
|
||||
this.scope.assignTypeGeneric(parentId.name, "Array");
|
||||
|
||||
for (var i = 0; i < pattern.elements.length; i++) {
|
||||
var elem = pattern.elements[i];
|
||||
|
||||
@@ -152,7 +161,7 @@ Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
|
||||
var newPatternId;
|
||||
|
||||
if (t.isRestElement(elem)) {
|
||||
newPatternId = this.file.toArray(parentId);
|
||||
newPatternId = this.scope.toArray(parentId);
|
||||
|
||||
if (i > 0) {
|
||||
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
|
||||
@@ -167,7 +176,7 @@ Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
|
||||
}
|
||||
};
|
||||
|
||||
Destructuring.prototype.init = function (pattern, parentId) {
|
||||
DestructuringTransformer.prototype.init = function (pattern, parentId) {
|
||||
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
var key = this.scope.generateUidBasedOnNode(parentId);
|
||||
this.nodes.push(this.buildVariableDeclaration(key, parentId));
|
||||
@@ -178,22 +187,41 @@ Destructuring.prototype.init = function (pattern, parentId) {
|
||||
};
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
var declar = node.left;
|
||||
if (!t.isVariableDeclaration(declar)) return;
|
||||
exports.ForOfStatement = function (node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
|
||||
var pattern = declar.declarations[0].id;
|
||||
if (t.isPattern(left)) {
|
||||
// for ({ length: k } in { abc: 3 });
|
||||
|
||||
var temp = scope.generateUidIdentifier("ref");
|
||||
|
||||
node.left = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp)
|
||||
]);
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
node.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(left, temp)
|
||||
]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!t.isVariableDeclaration(left)) return;
|
||||
|
||||
var pattern = left.declarations[0].id;
|
||||
if (!t.isPattern(pattern)) return;
|
||||
|
||||
var key = scope.generateUidIdentifier("ref");
|
||||
node.left = t.variableDeclaration(declar.kind, [
|
||||
node.left = t.variableDeclaration(left.kind, [
|
||||
t.variableDeclarator(key, null)
|
||||
]);
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var destructuring = new Destructuring({
|
||||
kind: declar.kind,
|
||||
var destructuring = new DestructuringTransformer({
|
||||
kind: left.kind,
|
||||
file: file,
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
@@ -207,18 +235,18 @@ 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;
|
||||
var hasDestructuringTransformer = false;
|
||||
|
||||
node.params = node.params.map(function (pattern, i) {
|
||||
if (!t.isPattern(pattern)) return pattern;
|
||||
|
||||
hasDestructuring = true;
|
||||
hasDestructuringTransformer = true;
|
||||
var parentId = scope.generateUidIdentifier("ref");
|
||||
|
||||
var destructuring = new Destructuring({
|
||||
var destructuring = new DestructuringTransformer({
|
||||
blockHoist: node.params.length - i,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
@@ -230,7 +258,7 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
return parentId;
|
||||
});
|
||||
|
||||
if (!hasDestructuring) return;
|
||||
if (!hasDestructuringTransformer) return;
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
@@ -238,7 +266,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;
|
||||
|
||||
@@ -247,8 +275,8 @@ exports.CatchClause = function (node, parent, scope, context, file) {
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var destructuring = new Destructuring({
|
||||
kind: "var",
|
||||
var destructuring = new DestructuringTransformer({
|
||||
kind: "let",
|
||||
file: file,
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
@@ -256,9 +284,11 @@ exports.CatchClause = function (node, parent, scope, context, file) {
|
||||
destructuring.init(pattern, ref);
|
||||
|
||||
node.body.body = nodes.concat(node.body.body);
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
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;
|
||||
@@ -271,7 +301,7 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
t.variableDeclarator(ref, expr.right)
|
||||
]));
|
||||
|
||||
var destructuring = new Destructuring({
|
||||
var destructuring = new DestructuringTransformer({
|
||||
operator: expr.operator,
|
||||
file: file,
|
||||
scope: scope,
|
||||
@@ -282,7 +312,7 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
|
||||
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");
|
||||
@@ -294,7 +324,7 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
|
||||
var nodes = [];
|
||||
nodes.push(t.assignmentExpression("=", ref, node.right));
|
||||
|
||||
var destructuring = new Destructuring({
|
||||
var destructuring = new DestructuringTransformer({
|
||||
operator: node.operator,
|
||||
file: file,
|
||||
scope: scope,
|
||||
@@ -316,7 +346,7 @@ var variableDeclarationhasPattern = function (node) {
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, scope, context, file) {
|
||||
exports.VariableDeclaration = function (node, parent, scope, file) {
|
||||
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
|
||||
if (!variableDeclarationhasPattern(node)) return;
|
||||
|
||||
@@ -329,7 +359,7 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
|
||||
var destructuring = new Destructuring({
|
||||
var destructuring = new DestructuringTransformer({
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
kind: node.kind,
|
||||
@@ -360,7 +390,7 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
|
||||
declar = declar || t.variableDeclaration(node.kind, []);
|
||||
|
||||
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
|
||||
throw file.errorWithNode(node, "Cannot use this node within the current parent");
|
||||
throw file.errorWithNode(node, messages.get("invalidParentForThisNode"));
|
||||
}
|
||||
|
||||
declar.declarations = declar.declarations.concat(node.declarations);
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
var messages = require("../../../messages");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isForOfStatement;
|
||||
|
||||
exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
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;
|
||||
@@ -17,7 +18,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
// inherit comments from the original loop
|
||||
t.inheritsComments(loop, node);
|
||||
|
||||
// ensure that it's a block so we can take all it's statemetns
|
||||
// ensure that it's a block so we can take all its statements
|
||||
t.ensureBlock(node);
|
||||
|
||||
// add the value declaration to the new loop body
|
||||
@@ -28,13 +29,15 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
// push the rest of the original loop body onto our new body
|
||||
block.body = block.body.concat(node.body.body);
|
||||
|
||||
t.inherits(loop, node);
|
||||
|
||||
// todo: find out why this is necessary? #538
|
||||
loop._scopeInfo = node._scopeInfo;
|
||||
|
||||
return loop;
|
||||
};
|
||||
|
||||
var loose = function (node, parent, scope, context, file) {
|
||||
var loose = function (node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
var declar, id;
|
||||
|
||||
@@ -48,7 +51,7 @@ var loose = function (node, parent, scope, context, file) {
|
||||
t.variableDeclarator(left.declarations[0].id, id)
|
||||
]);
|
||||
} else {
|
||||
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
|
||||
throw file.errorWithNode(left, messages.get("unknownForHead", left.type));
|
||||
}
|
||||
|
||||
var loop = util.template("for-of-loose", {
|
||||
@@ -71,7 +74,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;
|
||||
|
||||
@@ -87,7 +90,7 @@ var spec = function (node, parent, scope, context, file) {
|
||||
t.variableDeclarator(left.declarations[0].id, stepValue)
|
||||
]);
|
||||
} else {
|
||||
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
|
||||
throw file.errorWithNode(left, messages.get("unknownForHead", left.type));
|
||||
}
|
||||
|
||||
var loop = util.template("for-of", {
|
||||
|
||||
@@ -4,7 +4,7 @@ var t = require("../../../types");
|
||||
|
||||
exports.check = require("../internal/modules").check;
|
||||
|
||||
exports.ImportDeclaration = function (node, parent, scope, context, file) {
|
||||
exports.ImportDeclaration = function (node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
|
||||
if (node.specifiers.length) {
|
||||
@@ -23,7 +23,7 @@ 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;
|
||||
|
||||
|
||||
34
lib/6to5/transformation/transformers/es6/object-super.js
Normal file
34
lib/6to5/transformation/transformers/es6/object-super.js
Normal file
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
|
||||
var ReplaceSupers = require("../../helpers/replace-supers");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isIdentifier(node, { name: "super" });
|
||||
};
|
||||
|
||||
exports.Property = function (node, parent, scope, file) {
|
||||
if (!node.method) return;
|
||||
|
||||
var value = node.value;
|
||||
var thisExpr = scope.generateUidIdentifier("this");
|
||||
|
||||
var replaceSupers = new ReplaceSupers({
|
||||
topLevelThisReference: thisExpr,
|
||||
methodNode: node,
|
||||
className: thisExpr,
|
||||
isStatic: true,
|
||||
scope: scope,
|
||||
file: file
|
||||
});
|
||||
|
||||
replaceSupers.replace();
|
||||
|
||||
if (replaceSupers.hasSuper) {
|
||||
value.body.body.unshift(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(thisExpr, t.thisExpression())
|
||||
])
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -9,21 +9,23 @@ exports.check = function (node) {
|
||||
|
||||
var hasDefaults = function (node) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
if (t.isAssignmentPattern(node.params[i])) return true;
|
||||
if (!t.isIdentifier(node.params[i])) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var iifeVisitor = {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (t.isReferencedIdentifier(node, parent) && state.scope.hasOwnReference(node.name)) {
|
||||
state.iife = true;
|
||||
context.stop();
|
||||
}
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
if (!state.scope.hasOwnBinding(node.name)) return;
|
||||
if (state.scope.bindingIdentifierEquals(node.name, node)) return;
|
||||
|
||||
state.iife = true;
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope) {
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
if (!hasDefaults(node)) return;
|
||||
|
||||
t.ensureBlock(node);
|
||||
@@ -37,35 +39,53 @@ exports.Function = function (node, parent, scope) {
|
||||
|
||||
var state = { iife: false, scope: scope };
|
||||
|
||||
var pushDefNode = function (left, right, i) {
|
||||
var defNode = util.template("default-parameter", {
|
||||
VARIABLE_NAME: left,
|
||||
DEFAULT_VALUE: right,
|
||||
ARGUMENT_KEY: t.literal(i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true);
|
||||
file.checkNode(defNode);
|
||||
defNode._blockHoist = node.params.length - i;
|
||||
body.push(defNode);
|
||||
};
|
||||
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
var param = node.params[i];
|
||||
|
||||
if (!t.isAssignmentPattern(param)) {
|
||||
lastNonDefaultParam = +i + 1;
|
||||
if (!t.isRestElement(param)) {
|
||||
lastNonDefaultParam = i + 1;
|
||||
}
|
||||
|
||||
if (!t.isIdentifier(param)) {
|
||||
scope.traverse(param, iifeVisitor, state);
|
||||
}
|
||||
|
||||
if (file.transformers["es6.blockScopingTDZ"].canRun()) {
|
||||
pushDefNode(param, t.identifier("undefined"), i);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
var left = param.left;
|
||||
var right = param.right;
|
||||
|
||||
node.params[i] = scope.generateUidIdentifier("x");
|
||||
var placeholder = scope.generateUidIdentifier("x");
|
||||
placeholder._isDefaultPlaceholder = true;
|
||||
node.params[i] = placeholder;
|
||||
|
||||
if (!state.iife) {
|
||||
if (t.isIdentifier(right) && scope.hasOwnReference(right.name)) {
|
||||
if (t.isIdentifier(right) && scope.hasOwnBinding(right.name)) {
|
||||
state.iife = true;
|
||||
} else {
|
||||
scope.traverse(right, iifeVisitor, state);
|
||||
}
|
||||
}
|
||||
|
||||
var defNode = util.template("default-parameter", {
|
||||
VARIABLE_NAME: left,
|
||||
DEFAULT_VALUE: right,
|
||||
ARGUMENT_KEY: t.literal(+i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true);
|
||||
defNode._blockHoist = node.params.length - i;
|
||||
body.push(defNode);
|
||||
pushDefNode(left, right, i);
|
||||
}
|
||||
|
||||
// we need to cut off all trailing default parameters
|
||||
|
||||
@@ -60,6 +60,8 @@ exports.Function = function (node, parent, scope) {
|
||||
node.body.body.unshift(restDeclar);
|
||||
}
|
||||
|
||||
scope.assignTypeGeneric(rest.name, "Array");
|
||||
|
||||
var loop = util.template("rest", {
|
||||
ARGUMENTS: argsId,
|
||||
ARRAY_KEY: arrKey,
|
||||
|
||||
@@ -6,7 +6,7 @@ exports.check = function (node) {
|
||||
return t.isProperty(node) && node.computed;
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
exports.ObjectExpression = function (node, parent, scope, file) {
|
||||
var hasComputed = false;
|
||||
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
|
||||
@@ -8,7 +8,7 @@ exports.check = function (node) {
|
||||
return t.isProperty(node) && (node.method || node.shorthand);
|
||||
};
|
||||
|
||||
exports.Property = function (node, parent, scope, context, file) {
|
||||
exports.Property = function (node, parent, scope, file) {
|
||||
if (node.method) {
|
||||
node.method = false;
|
||||
nameMethod.property(node, file, scope);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
var contains = require("lodash/collection/contains");
|
||||
var includes = require("lodash/collection/includes");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isSpreadElement;
|
||||
|
||||
var getSpreadLiteral = function (spread, file) {
|
||||
return file.toArray(spread.argument);
|
||||
var getSpreadLiteral = function (spread, scope) {
|
||||
return scope.toArray(spread.argument, true);
|
||||
};
|
||||
|
||||
var hasSpread = function (nodes) {
|
||||
@@ -18,7 +18,7 @@ var hasSpread = function (nodes) {
|
||||
return false;
|
||||
};
|
||||
|
||||
var build = function (props, file) {
|
||||
var build = function (props, scope) {
|
||||
var nodes = [];
|
||||
|
||||
var _props = [];
|
||||
@@ -33,7 +33,7 @@ var build = function (props, file) {
|
||||
var prop = props[i];
|
||||
if (t.isSpreadElement(prop)) {
|
||||
push();
|
||||
nodes.push(getSpreadLiteral(prop, file));
|
||||
nodes.push(getSpreadLiteral(prop, scope));
|
||||
} else {
|
||||
_props.push(prop);
|
||||
}
|
||||
@@ -44,11 +44,11 @@ var build = function (props, file) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.ArrayExpression = function (node, parent, scope, context, file) {
|
||||
exports.ArrayExpression = function (node, parent, scope) {
|
||||
var elements = node.elements;
|
||||
if (!hasSpread(elements)) return;
|
||||
|
||||
var nodes = build(elements, file);
|
||||
var nodes = build(elements, scope);
|
||||
var first = nodes.shift();
|
||||
|
||||
if (!t.isArrayExpression(first)) {
|
||||
@@ -59,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) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
@@ -71,10 +71,10 @@ exports.CallExpression = function (node, parent, scope, context, file) {
|
||||
if (args.length === 1 && args[0].argument.name === "arguments") {
|
||||
nodes = [args[0].argument];
|
||||
} else {
|
||||
nodes = build(args, file);
|
||||
nodes = build(args, scope);
|
||||
}
|
||||
var first = nodes.shift();
|
||||
|
||||
var first = nodes.shift();
|
||||
if (nodes.length) {
|
||||
node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
|
||||
} else {
|
||||
@@ -99,13 +99,13 @@ 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;
|
||||
|
||||
var nativeType = t.isIdentifier(node.callee) && contains(t.NATIVE_TYPE_NAMES, node.callee.name);
|
||||
var nativeType = t.isIdentifier(node.callee) && includes(t.NATIVE_TYPE_NAMES, node.callee.name);
|
||||
|
||||
var nodes = build(args, file);
|
||||
var nodes = build(args, scope);
|
||||
|
||||
if (nativeType) {
|
||||
nodes.unshift(t.arrayExpression([t.literal(null)]));
|
||||
|
||||
359
lib/6to5/transformation/transformers/es6/tail-call.js
Normal file
359
lib/6to5/transformation/transformers/es6/tail-call.js
Normal file
@@ -0,0 +1,359 @@
|
||||
"use strict";
|
||||
|
||||
var reduceRight = require("lodash/collection/reduceRight");
|
||||
var messages = require("../../../messages");
|
||||
var flatten = require("lodash/array/flatten");
|
||||
var util = require("../../../util");
|
||||
var map = require("lodash/collection/map");
|
||||
var t = require("../../../types");
|
||||
|
||||
function returnBlock(expr) {
|
||||
return t.blockStatement([t.returnStatement(expr)]);
|
||||
}
|
||||
|
||||
function TailCallTransformer(node, scope, file) {
|
||||
this.hasTailRecursion = false;
|
||||
this.needsArguments = false;
|
||||
this.setsArguments = false;
|
||||
this.needsThis = false;
|
||||
this.ownerId = node.id;
|
||||
this.vars = [];
|
||||
|
||||
this.scope = scope;
|
||||
this.file = file;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
TailCallTransformer.prototype.getArgumentsId = function () {
|
||||
return this.argumentsId = this.argumentsId || this.scope.generateUidIdentifier("arguments");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getThisId = function () {
|
||||
return this.thisId = this.thisId || this.scope.generateUidIdentifier("this");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getLeftId = function () {
|
||||
return this.leftId = this.leftId || this.scope.generateUidIdentifier("left");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getFunctionId = function () {
|
||||
return this.functionId = this.functionId || this.scope.generateUidIdentifier("function");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getParams = function () {
|
||||
var params = this.params;
|
||||
|
||||
if (!params) {
|
||||
params = this.node.params;
|
||||
this.paramDecls = [];
|
||||
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var param = params[i];
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
this.paramDecls.push(t.variableDeclarator(
|
||||
param,
|
||||
params[i] = this.scope.generateUidIdentifier("x")
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.params = params;
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.hasDeopt = function () {
|
||||
// check if the ownerId has been reassigned, if it has then it's not safe to
|
||||
// perform optimisations
|
||||
var ownerIdInfo = this.scope.getBindingInfo(this.ownerId.name);
|
||||
return ownerIdInfo && ownerIdInfo.reassigned;
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.run = function () {
|
||||
var scope = this.scope;
|
||||
var node = this.node;
|
||||
|
||||
// only tail recursion can be optimized as for now, so we can skip anonymous
|
||||
// functions entirely
|
||||
var ownerId = this.ownerId;
|
||||
if (!ownerId) return;
|
||||
|
||||
// traverse the function and look for tail recursion
|
||||
scope.traverse(node, firstPass, this);
|
||||
|
||||
if (!this.hasTailRecursion) return;
|
||||
|
||||
if (this.hasDeopt()) {
|
||||
this.file.logDeopt(node, messages.get("tailCallReassignmentDeopt"));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
scope.traverse(node, secondPass, this);
|
||||
|
||||
if (!this.needsThis || !this.needsArguments) {
|
||||
scope.traverse(node, thirdPass, this);
|
||||
}
|
||||
|
||||
var body = t.ensureBlock(node).body;
|
||||
|
||||
if (this.vars.length > 0) {
|
||||
var declarations = flatten(map(this.vars, function (decl) {
|
||||
return decl.declarations;
|
||||
}, this));
|
||||
var statement = reduceRight(declarations, function (expr, decl) {
|
||||
return t.assignmentExpression("=", decl.id, expr);
|
||||
}, t.identifier("undefined"));
|
||||
body.unshift(t.expressionStatement(statement));
|
||||
}
|
||||
|
||||
var paramDecls = this.paramDecls;
|
||||
if (paramDecls.length > 0) {
|
||||
body.unshift(t.variableDeclaration("var", paramDecls));
|
||||
}
|
||||
|
||||
node.body = util.template("tail-call-body", {
|
||||
THIS_ID: this.thisId,
|
||||
ARGUMENTS_ID: this.argumentsId,
|
||||
FUNCTION_ID: this.getFunctionId(),
|
||||
BLOCK: node.body
|
||||
});
|
||||
|
||||
var topVars = [];
|
||||
|
||||
if (this.needsThis) {
|
||||
topVars.push(t.variableDeclarator(this.getThisId(), t.thisExpression()));
|
||||
}
|
||||
|
||||
if (this.needsArguments || this.setsArguments) {
|
||||
var decl = t.variableDeclarator(this.getArgumentsId());
|
||||
if (this.needsArguments) {
|
||||
decl.init = t.identifier("arguments");
|
||||
}
|
||||
topVars.push(decl);
|
||||
}
|
||||
|
||||
var leftId = this.leftId;
|
||||
if (leftId) {
|
||||
topVars.push(t.variableDeclarator(leftId));
|
||||
}
|
||||
|
||||
if (topVars.length > 0) {
|
||||
node.body.body.unshift(t.variableDeclaration("var", topVars));
|
||||
}
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransform = function (node) {
|
||||
if (!node) return;
|
||||
|
||||
var handler = this["subTransform" + node.type];
|
||||
if (handler) return handler.call(this, node);
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformConditionalExpression = function (node) {
|
||||
var callConsequent = this.subTransform(node.consequent);
|
||||
var callAlternate = this.subTransform(node.alternate);
|
||||
if (!callConsequent && !callAlternate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if ternary operator had tail recursion in value, convert to optimized if-statement
|
||||
node.type = "IfStatement";
|
||||
node.consequent = callConsequent ? t.toBlock(callConsequent) : returnBlock(node.consequent);
|
||||
|
||||
if (callAlternate) {
|
||||
node.alternate = t.isIfStatement(callAlternate) ? callAlternate : t.toBlock(callAlternate);
|
||||
} else {
|
||||
node.alternate = returnBlock(node.alternate);
|
||||
}
|
||||
|
||||
return [node];
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformLogicalExpression = function (node) {
|
||||
// only call in right-value of can be optimized
|
||||
var callRight = this.subTransform(node.right);
|
||||
if (!callRight) return;
|
||||
|
||||
// cache left value as it might have side-effects
|
||||
var leftId = this.getLeftId();
|
||||
var testExpr = t.assignmentExpression(
|
||||
"=",
|
||||
leftId,
|
||||
node.left
|
||||
);
|
||||
|
||||
if (node.operator === "&&") {
|
||||
testExpr = t.unaryExpression("!", testExpr);
|
||||
}
|
||||
|
||||
return [t.ifStatement(testExpr, returnBlock(leftId))].concat(callRight);
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformSequenceExpression = function (node) {
|
||||
var seq = node.expressions;
|
||||
|
||||
// only last element can be optimized
|
||||
var lastCall = this.subTransform(seq[seq.length - 1]);
|
||||
if (!lastCall) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove converted expression from sequence
|
||||
// and convert to regular expression if needed
|
||||
if (--seq.length === 1) {
|
||||
node = seq[0];
|
||||
}
|
||||
|
||||
return [t.expressionStatement(node)].concat(lastCall);
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformCallExpression = function (node) {
|
||||
var callee = node.callee, thisBinding, args;
|
||||
|
||||
if (t.isMemberExpression(callee, { computed: false }) && t.isIdentifier(callee.property)) {
|
||||
switch (callee.property.name) {
|
||||
case "call":
|
||||
args = t.arrayExpression(node.arguments.slice(1));
|
||||
break;
|
||||
|
||||
case "apply":
|
||||
args = node.arguments[1] || t.identifier("undefined");
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
thisBinding = node.arguments[0];
|
||||
callee = callee.object;
|
||||
}
|
||||
|
||||
// only tail recursion can be optimized as for now
|
||||
if (!t.isIdentifier(callee) || !this.scope.bindingIdentifierEquals(callee.name, this.ownerId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hasTailRecursion = true;
|
||||
|
||||
if (this.hasDeopt()) return;
|
||||
|
||||
var body = [];
|
||||
|
||||
if (!t.isThisExpression(thisBinding)) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
this.getThisId(),
|
||||
thisBinding || t.identifier("undefined")
|
||||
)));
|
||||
}
|
||||
|
||||
if (!args) {
|
||||
args = t.arrayExpression(node.arguments);
|
||||
}
|
||||
|
||||
var argumentsId = this.getArgumentsId();
|
||||
var params = this.getParams();
|
||||
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
argumentsId,
|
||||
args
|
||||
)));
|
||||
|
||||
var i, param;
|
||||
|
||||
if (t.isArrayExpression(args)) {
|
||||
var elems = args.elements;
|
||||
for (i = 0; i < elems.length && i < params.length; i++) {
|
||||
param = params[i];
|
||||
var elem = elems[i] || (elems[i] = t.identifier("undefined"));
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
elems[i] = t.assignmentExpression("=", param, elem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.setsArguments = true;
|
||||
for (i = 0; i < params.length; i++) {
|
||||
param = params[i];
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
param,
|
||||
t.memberExpression(argumentsId, t.literal(i), true)
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.push(t.continueStatement(this.getFunctionId()));
|
||||
|
||||
return body;
|
||||
};
|
||||
|
||||
// looks for and replaces tail recursion calls
|
||||
var firstPass = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isReturnStatement(node)) {
|
||||
this.skip();
|
||||
return state.subTransform(node.argument);
|
||||
} else if (t.isTryStatement(parent)) {
|
||||
if (node === parent.block) {
|
||||
this.skip();
|
||||
} else if (parent.finalizer && node !== parent.finalizer) {
|
||||
this.skip();
|
||||
}
|
||||
} else if (t.isFunction(node)) {
|
||||
this.skip();
|
||||
} else if (t.isVariableDeclaration(node)) {
|
||||
this.skip();
|
||||
state.vars.push(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// hoists up function declarations, replaces `this` and `arguments` and marks
|
||||
// them as needed
|
||||
var secondPass = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isThisExpression(node)) {
|
||||
state.needsThis = true;
|
||||
return state.getThisId();
|
||||
} else if (t.isReferencedIdentifier(node, parent, { name: "arguments" })) {
|
||||
state.needsArguments = true;
|
||||
return state.getArgumentsId();
|
||||
} else if (t.isFunction(node)) {
|
||||
this.skip();
|
||||
if (t.isFunctionDeclaration(node)) {
|
||||
node = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(node.id, t.toExpression(node))
|
||||
]);
|
||||
node._blockHoist = 2;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// optimizes recursion by removing `this` and `arguments` if they aren't used
|
||||
var thirdPass = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (!t.isExpressionStatement(node)) return;
|
||||
|
||||
var expr = node.expression;
|
||||
if (!t.isAssignmentExpression(expr)) return;
|
||||
|
||||
if (!state.needsThis && expr.left === state.getThisId()) {
|
||||
this.remove();
|
||||
} else if (!state.needsArguments && expr.left === state.getArgumentsId() && t.isArrayExpression(expr.right)) {
|
||||
return map(expr.right.elements, function (elem) {
|
||||
return t.expressionStatement(elem);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
var tailCall = new TailCallTransformer(node, scope, file);
|
||||
tailCall.run();
|
||||
};
|
||||
@@ -10,7 +10,7 @@ exports.check = function (node) {
|
||||
return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node);
|
||||
};
|
||||
|
||||
exports.TaggedTemplateExpression = function (node, parent, scope, context, file) {
|
||||
exports.TaggedTemplateExpression = function (node, parent, scope, file) {
|
||||
var args = [];
|
||||
var quasi = node.quasi;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -19,7 +19,7 @@ var hasSpread = function (node) {
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (node, parent, scope, context, file) {
|
||||
exports.ObjectExpression = function (node, parent, scope, file) {
|
||||
if (!hasSpread(node)) return;
|
||||
|
||||
var args = [];
|
||||
|
||||
@@ -11,6 +11,7 @@ module.exports = {
|
||||
"playground.memoizationOperator": require("./playground/memoization-operator"),
|
||||
"playground.objectGetterMemoization": require("./playground/object-getter-memoization"),
|
||||
|
||||
reactCompat: require("./other/react-compat"),
|
||||
react: require("./other/react"),
|
||||
|
||||
_modules: require("./internal/modules"),
|
||||
@@ -27,9 +28,9 @@ module.exports = {
|
||||
asyncToGenerator: require("./other/async-to-generator"),
|
||||
bluebirdCoroutines: require("./other/bluebird-coroutines"),
|
||||
|
||||
"es6.objectSuper": require("./es6/object-super"),
|
||||
"es7.objectRestSpread": require("./es7/object-rest-spread"),
|
||||
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
|
||||
"es6.spread": require("./es6/spread"),
|
||||
"es6.templateLiterals": require("./es6/template-literals"),
|
||||
|
||||
"es5.properties.mutators": require("./es5/properties.mutators"),
|
||||
@@ -45,6 +46,18 @@ module.exports = {
|
||||
|
||||
"es6.constants": require("./es6/constants"),
|
||||
|
||||
// needs to be before `es6.parameters.default` as default parameters will destroy the rest param
|
||||
"es6.parameters.rest": require("./es6/parameters.rest"),
|
||||
|
||||
// needs to be after `es6.parameters.rest` as we use `toArray` and avoid turning an already known array into one
|
||||
"es6.spread": require("./es6/spread"),
|
||||
|
||||
// needs to be before `es6.blockScoping` as default parameters have a TDZ
|
||||
"es6.parameters.default": require("./es6/parameters.default"),
|
||||
|
||||
// needs to be before `es6.blockScoping` as let variables may be produced
|
||||
"es6.destructuring": require("./es6/destructuring"),
|
||||
|
||||
// needs to be before `_aliasFunction` due to block scopes sometimes being wrapped in a
|
||||
// closure
|
||||
"es6.blockScoping": require("./es6/block-scoping"),
|
||||
@@ -52,10 +65,9 @@ module.exports = {
|
||||
// needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks
|
||||
"es6.blockScopingTDZ": require("./es6/block-scoping-tdz"),
|
||||
|
||||
"es6.parameters.default": require("./es6/parameters.default"),
|
||||
"es6.parameters.rest": require("./es6/parameters.rest"),
|
||||
|
||||
"es6.destructuring": require("./es6/destructuring"),
|
||||
// needs to be after `es6.parameters.*` and `es6.blockScoping` due to needing pure
|
||||
// identifiers in parameters and variable declarators
|
||||
"es6.tailCall": require("./es6/tail-call"),
|
||||
|
||||
regenerator: require("./other/regenerator"),
|
||||
|
||||
@@ -79,11 +91,13 @@ 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")
|
||||
"minification.renameLocalVariables": require("./minification/rename-local-variables"),
|
||||
|
||||
_cleanUp: require("./internal/cleanup")
|
||||
};
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
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;
|
||||
|
||||
@@ -25,11 +25,11 @@ 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;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ var functionVisitor = {
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
scope.traverse(node, functionChildrenVisitor, state);
|
||||
|
||||
return context.skip();
|
||||
return this.skip();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
5
lib/6to5/transformation/transformers/internal/cleanup.js
Normal file
5
lib/6to5/transformation/transformers/internal/cleanup.js
Normal file
@@ -0,0 +1,5 @@
|
||||
exports.SequenceExpression = function (node) {
|
||||
if (node.expressions.length === 1) {
|
||||
return node.expressions[0];
|
||||
}
|
||||
};
|
||||
@@ -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,7 +8,7 @@
|
||||
|
||||
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);
|
||||
|
||||
@@ -2,8 +2,9 @@ var t = require("../../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context) {
|
||||
// remove consequenceless expressions such as local variables and literals
|
||||
exports.ExpressionStatement = function (node) {
|
||||
// remove consequence-less expressions such as local variables and literals
|
||||
// note: will remove directives
|
||||
//
|
||||
// var foo = true; foo; -> var foo = true;
|
||||
// "foo"; ->
|
||||
@@ -11,12 +12,12 @@ exports.ExpressionStatement = function (node, parent, scope, context) {
|
||||
|
||||
var expr = node.expression;
|
||||
if (t.isLiteral(expr) || (t.isIdentifier(node) && t.hasBinding(node.name))) {
|
||||
context.remove();
|
||||
this.remove();
|
||||
}
|
||||
};
|
||||
|
||||
exports.IfStatement = {
|
||||
exit: function (node, parent, scope, context) {
|
||||
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
|
||||
@@ -25,7 +26,7 @@ exports.IfStatement = {
|
||||
var alternate = node.alternate;
|
||||
var test = node.test;
|
||||
|
||||
// we can check if a test will be truthy 100% and if so we can inline
|
||||
// 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; }
|
||||
@@ -33,11 +34,11 @@ exports.IfStatement = {
|
||||
//
|
||||
|
||||
if (t.isLiteral(test) && test.value) {
|
||||
return alternate;
|
||||
return consequent;
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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; } ->
|
||||
@@ -47,7 +48,7 @@ exports.IfStatement = {
|
||||
if (alternate) {
|
||||
return alternate;
|
||||
} else {
|
||||
return context.remove();
|
||||
return this.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,15 +61,13 @@ exports.IfStatement = {
|
||||
alternate = node.alternate = null;
|
||||
}
|
||||
|
||||
// turn alternate blocks into a consequent and flip the test if the
|
||||
// consequent block is empty
|
||||
// if the consequent block is empty turn alternate blocks into a consequent
|
||||
// and flip the test
|
||||
//
|
||||
// if (foo) {} else { bar; }
|
||||
// if (!foo) { bar; }
|
||||
// if (foo) {} else { bar; } -> if (!foo) { bar; }
|
||||
//
|
||||
|
||||
if (t.blockStatement(consequent) && !consequent.body.length &&
|
||||
t.isBlockStatement(alternate) && alternate.body.length) {
|
||||
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);
|
||||
|
||||
@@ -6,8 +6,12 @@ var isConsole = t.buildMatchMemberExpression("console", true);
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.CallExpression = function (node, parent, scope, context) {
|
||||
exports.CallExpression = function (node, parent) {
|
||||
if (isConsole(node.callee)) {
|
||||
context.remove();
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
this.parentPath.remove();
|
||||
} else {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@ var t = require("../../../types");
|
||||
|
||||
exports.optional = true;
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, context) {
|
||||
exports.ExpressionStatement = function (node) {
|
||||
if (t.isIdentifier(node.expression, { name: "debugger" })) {
|
||||
context.remove();
|
||||
this.remove();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
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
|
||||
exports.Scopable = function () {
|
||||
//for (var name in scope.bindings) {
|
||||
// scope.rename(name, scope.generateUidIdentifier("a").name);
|
||||
//}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
297
lib/6to5/transformation/transformers/other/react.js
vendored
297
lib/6to5/transformation/transformers/other/react.js
vendored
@@ -1,291 +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 isString = require("lodash/lang/isString");
|
||||
var esutils = require("esutils");
|
||||
var react = require("../../helpers/react");
|
||||
var t = require("../../../types");
|
||||
|
||||
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, 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);
|
||||
}
|
||||
|
||||
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, context, 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);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -7,10 +7,9 @@ exports.check = function (node) {
|
||||
return t.isFunction(node) && (node.async || node.generator);
|
||||
};
|
||||
|
||||
exports.ast = {
|
||||
before: function (ast, file) {
|
||||
regenerator.transform(ast, {
|
||||
includeRuntime: file.opts.includeRegenerator && "if used"
|
||||
});
|
||||
exports.Program = {
|
||||
enter: function (ast) {
|
||||
regenerator.transform(ast);
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ var util = require("../../../util");
|
||||
var core = require("core-js/library");
|
||||
var t = require("../../../types");
|
||||
var has = require("lodash/object/has");
|
||||
var contains = require("lodash/collection/contains");
|
||||
var includes = require("lodash/collection/includes");
|
||||
|
||||
var coreHas = function (node) {
|
||||
return node.name !== "_" && has(core, node.name);
|
||||
@@ -20,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)) {
|
||||
@@ -30,30 +30,44 @@ 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.getBindingIdentifier(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.getBinding(node.name)) {
|
||||
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && includes(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBindingIdentifier(node.name)) {
|
||||
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
|
||||
return t.memberExpression(file.get("coreIdentifier"), node);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
|
||||
|
||||
if (node.arguments.length) return;
|
||||
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (!callee.computed) return;
|
||||
if (node.arguments.length) return false;
|
||||
|
||||
if (!t.isMemberExpression(callee)) return false;
|
||||
if (!callee.computed) return false;
|
||||
|
||||
prop = callee.property;
|
||||
if (!t.isIdentifier(prop.object, { name: "Symbol" })) return;
|
||||
if (!t.isIdentifier(prop.property, { name: "iterator" })) return;
|
||||
if (!t.isIdentifier(prop.object, { name: "Symbol" })) return false;
|
||||
if (!t.isIdentifier(prop.property, { name: "iterator" })) return false;
|
||||
|
||||
return util.template("corejs-iterator", {
|
||||
CORE_ID: file.get("coreIdentifier"),
|
||||
VALUE: callee.object
|
||||
});
|
||||
} else if (t.isBinaryExpression(node)) {
|
||||
// Symbol.iterator in arr -> core.$for.isIterable(arr)
|
||||
|
||||
if (node.operator !== "in") return;
|
||||
|
||||
var left = node.left;
|
||||
if (!t.isMemberExpression(left)) return;
|
||||
if (!t.isIdentifier(left.object, { name: "Symbol" })) return;
|
||||
if (!t.isIdentifier(left.property, { name: "iterator" })) return;
|
||||
|
||||
return util.template("corejs-is-iterator", {
|
||||
CORE_ID: file.get("coreIdentifier"),
|
||||
VALUE: node.right
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -64,28 +78,26 @@ exports.manipulateOptions = function (opts) {
|
||||
if (opts.whitelist.length) opts.whitelist.push("es6.modules");
|
||||
};
|
||||
|
||||
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) {
|
||||
file.scope.traverse(ast, astVisitor, file);
|
||||
}
|
||||
exports.post = function (file) {
|
||||
file.scope.traverse(file.ast, astVisitor, file);
|
||||
};
|
||||
|
||||
exports.Identifier = function (node, parent, scope, context, file) {
|
||||
if (node.name === "regeneratorRuntime" && t.isReferenced(node, parent)) {
|
||||
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 (t.isReferencedIdentifier(node, parent, { name: "regeneratorRuntime" })) {
|
||||
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 () {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
|
||||
var t = require("../../../types");
|
||||
var messages = require("../../../messages");
|
||||
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.playground = true;
|
||||
|
||||
@@ -11,7 +12,7 @@ build(exports, {
|
||||
if (is) {
|
||||
var left = node.left;
|
||||
if (!t.isMemberExpression(left) && !t.isIdentifier(left)) {
|
||||
throw file.errorWithNode(left, "Expected type MemeberExpression or Identifier");
|
||||
throw file.errorWithNode(left, messages.get("expectedMemberExpressionOrIdentifier"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ exports.BindMemberExpression = function (node, parent, scope) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.BindFunctionExpression = function (node, parent, scope, context, file) {
|
||||
exports.BindFunctionExpression = function (node, parent, scope) {
|
||||
var buildCall = function (args) {
|
||||
var param = scope.generateUidIdentifier("val");
|
||||
return t.functionExpression(null, [param], t.blockStatement([
|
||||
@@ -34,7 +34,7 @@ exports.BindFunctionExpression = function (node, parent, scope, context, file) {
|
||||
]));
|
||||
};
|
||||
|
||||
var temp = scope.generateTemp(file, "args");
|
||||
var temp = scope.generateTemp("args");
|
||||
|
||||
return t.sequenceExpression([
|
||||
t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user