Compare commits
371 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4942ba6dd7 | ||
|
|
b63bd8cba0 | ||
|
|
cd1eb11171 | ||
|
|
6e1c12fd78 | ||
|
|
a4ea71b85d | ||
|
|
1df69bdbeb | ||
|
|
84c2766756 | ||
|
|
1f000ac83d | ||
|
|
322aa246b8 | ||
|
|
601bbb86cd | ||
|
|
5c39685650 | ||
|
|
e6ac5eccd0 | ||
|
|
c4c9f7984f | ||
|
|
8d472a14be | ||
|
|
4fd007948c | ||
|
|
f4e516e8ce | ||
|
|
7fcd8ea642 | ||
|
|
add0a7d5fe | ||
|
|
e9445c9277 | ||
|
|
df66fa0a7f | ||
|
|
0a85211e8e | ||
|
|
ac8fc24fdb | ||
|
|
71c4a29a78 | ||
|
|
08dde22939 | ||
|
|
d3ea0fe84f | ||
|
|
22851cd1ac | ||
|
|
987dc0692f | ||
|
|
560d60e3e7 | ||
|
|
e96d02c972 | ||
|
|
13a2d469a3 | ||
|
|
0b232ed228 | ||
|
|
9053e0dedf | ||
|
|
873e820210 | ||
|
|
27bb08eadf | ||
|
|
bea903c69f | ||
|
|
198a9c6ead | ||
|
|
9c92679053 | ||
|
|
87d2bdadeb | ||
|
|
fa71f2a7f9 | ||
|
|
66e7134335 | ||
|
|
99a1cf08f9 | ||
|
|
5de9c22452 | ||
|
|
694a8dc456 | ||
|
|
2df1ca3971 | ||
|
|
6c7cdc9b7c | ||
|
|
52b1d055ac | ||
|
|
2a316bf362 | ||
|
|
26ce0b8c8b | ||
|
|
275c4cc34e | ||
|
|
bc914e6f23 | ||
|
|
4ea425ac7b | ||
|
|
bd255257f1 | ||
|
|
41f072d112 | ||
|
|
2a4c8e8423 | ||
|
|
122705bdaf | ||
|
|
f84e0ba640 | ||
|
|
64216ec384 | ||
|
|
a948928973 | ||
|
|
5ab891b39d | ||
|
|
2a742b5fac | ||
|
|
cd6b678b51 | ||
|
|
c290a008b2 | ||
|
|
e8f0c8e8a4 | ||
|
|
22eb8edf41 | ||
|
|
a3eb8900a9 | ||
|
|
bf74f5a634 | ||
|
|
98e9a45f63 | ||
|
|
1d91a758b4 | ||
|
|
b94b4b335b | ||
|
|
104b1f4c9b | ||
|
|
00c95f6a94 | ||
|
|
f14dc60934 | ||
|
|
2fc8010034 | ||
|
|
882ed48438 | ||
|
|
49578fe223 | ||
|
|
01bdb7efdc | ||
|
|
fc7fc384c9 | ||
|
|
bd78e3ed4d | ||
|
|
1f990f4030 | ||
|
|
d8e4a4a776 | ||
|
|
473b6d6a91 | ||
|
|
3d975da530 | ||
|
|
1a4110e0a1 | ||
|
|
a03d491ac6 | ||
|
|
e01e010577 | ||
|
|
132ac00ec7 | ||
|
|
1673f78ab5 | ||
|
|
76b8a06e90 | ||
|
|
711f84c826 | ||
|
|
4b4ff007e9 | ||
|
|
e31e68cae3 | ||
|
|
778b4e3a27 | ||
|
|
6011db7ae1 | ||
|
|
363b1631f5 | ||
|
|
01286ebd5b | ||
|
|
fe918a3535 | ||
|
|
2fb6c7820c | ||
|
|
e7cbbefc11 | ||
|
|
f4fdc3adc6 | ||
|
|
2cd49b08ec | ||
|
|
1b16ff3a0b | ||
|
|
b7c298a0ee | ||
|
|
5da4397392 | ||
|
|
ea5954121e | ||
|
|
37b2e747d5 | ||
|
|
3dd6eb1202 | ||
|
|
319ed09407 | ||
|
|
77f9596682 | ||
|
|
00cb90541a | ||
|
|
d26f441a5c | ||
|
|
11fc7cd0ce | ||
|
|
c38428c536 | ||
|
|
bf40849e35 | ||
|
|
194fb77b9c | ||
|
|
ceb8e812b6 | ||
|
|
3a261a5e05 | ||
|
|
4c1ad04b2c | ||
|
|
0d9e6aca67 | ||
|
|
aac6303696 | ||
|
|
833a4900da | ||
|
|
525169460a | ||
|
|
13785bddb0 | ||
|
|
84332da399 | ||
|
|
aae7d8190b | ||
|
|
03dcc335d8 | ||
|
|
9ca05b1971 | ||
|
|
2a27b7c16c | ||
|
|
c92fd6f0bb | ||
|
|
2267344471 | ||
|
|
593e4ca670 | ||
|
|
e563783a1e | ||
|
|
615425c808 | ||
|
|
55e2010311 | ||
|
|
74f40c2824 | ||
|
|
c26ce1c114 | ||
|
|
2537768772 | ||
|
|
8af05634fa | ||
|
|
74614e712e | ||
|
|
ad923cf8fa | ||
|
|
c7d69b2f92 | ||
|
|
2a0b63f3bb | ||
|
|
01934b6960 | ||
|
|
8ffd2e843f | ||
|
|
6d68b3da4d | ||
|
|
79b4207b44 | ||
|
|
30a90d2554 | ||
|
|
bac8758369 | ||
|
|
d00faf4a72 | ||
|
|
b986a4e482 | ||
|
|
f11f364d2c | ||
|
|
c4a0f62eef | ||
|
|
072fff0f4c | ||
|
|
59b81b389a | ||
|
|
4a439857d2 | ||
|
|
187f7ba01e | ||
|
|
e6da342e8b | ||
|
|
1c22c608a9 | ||
|
|
8e96130bc0 | ||
|
|
0f47814b41 | ||
|
|
b32d56a168 | ||
|
|
5f26a0c5cc | ||
|
|
2245bbc6c4 | ||
|
|
b8d61f1528 | ||
|
|
e97e916b5c | ||
|
|
b688154aee | ||
|
|
ccb56fe33f | ||
|
|
5e67dfbd9e | ||
|
|
6f6d9bd5a8 | ||
|
|
61b9c28ce6 | ||
|
|
d11d0d3216 | ||
|
|
bd876f7a4d | ||
|
|
f9f48620de | ||
|
|
ce9a82c194 | ||
|
|
24f6dfa8e2 | ||
|
|
f592f95a68 | ||
|
|
2e0cd0f349 | ||
|
|
e17d5bdb13 | ||
|
|
c1c22ed5f7 | ||
|
|
bf07f54e57 | ||
|
|
eef0344cb2 | ||
|
|
88a85c0ca8 | ||
|
|
302e6f4caa | ||
|
|
36c16a0227 | ||
|
|
0ee4a15d01 | ||
|
|
fbdaedc4f8 | ||
|
|
75c8d73d35 | ||
|
|
21599d3a9a | ||
|
|
9fbbabc7e4 | ||
|
|
8c1fe49b2e | ||
|
|
763b4caf32 | ||
|
|
c0248cf04c | ||
|
|
a7a6ee80f2 | ||
|
|
aa298b1e0a | ||
|
|
9c0a8e22d2 | ||
|
|
7c1a924ef6 | ||
|
|
1d975a2635 | ||
|
|
67cfdbd447 | ||
|
|
ab02231d39 | ||
|
|
40a2d14c7c | ||
|
|
573283f260 | ||
|
|
0497860462 | ||
|
|
a173775fec | ||
|
|
c5214ffe70 | ||
|
|
3d62af004d | ||
|
|
d7af8c6261 | ||
|
|
680c6b166a | ||
|
|
5bad458b09 | ||
|
|
055f894a88 | ||
|
|
da8edecc09 | ||
|
|
cd6dea6480 | ||
|
|
69d7ac0e0c | ||
|
|
dae46bfbfa | ||
|
|
b5b175c45a | ||
|
|
569c681c4f | ||
|
|
ed1e4a7820 | ||
|
|
b55f941dae | ||
|
|
a0219ef278 | ||
|
|
b9266b0c4c | ||
|
|
a1239e5f5a | ||
|
|
2f279de7d1 | ||
|
|
c70b3586fb | ||
|
|
3928384c27 | ||
|
|
e469f7f589 | ||
|
|
988ab0e823 | ||
|
|
e708394408 | ||
|
|
7c3ab8bc3c | ||
|
|
2b11a45117 | ||
|
|
d5666912d4 | ||
|
|
2eab56c38b | ||
|
|
888ab5473a | ||
|
|
5fe1c07d9a | ||
|
|
758a873894 | ||
|
|
e91926d094 | ||
|
|
5085b96753 | ||
|
|
66f67b92ce | ||
|
|
3c9fa13a1f | ||
|
|
5f21fc2f17 | ||
|
|
4bd4e4cdbe | ||
|
|
3c7b2d7872 | ||
|
|
5db757354a | ||
|
|
063b379d4f | ||
|
|
af42fe3d30 | ||
|
|
3c808fcef2 | ||
|
|
a29505f75d | ||
|
|
05942d17bf | ||
|
|
be0d4b344b | ||
|
|
f1a2401681 | ||
|
|
2d61672cdb | ||
|
|
1b00ba21a1 | ||
|
|
f8ea386f3c | ||
|
|
2527fffbad | ||
|
|
86498ad990 | ||
|
|
27c8804214 | ||
|
|
2b6f0ee780 | ||
|
|
c7c9660c79 | ||
|
|
ff025e63ec | ||
|
|
9fb6681ad3 | ||
|
|
301887f88d | ||
|
|
b519bb6a68 | ||
|
|
b6e366ad94 | ||
|
|
ba2204156c | ||
|
|
2545292bce | ||
|
|
c763cf364c | ||
|
|
1db7247d9a | ||
|
|
1a1e6bc3ba | ||
|
|
d184bc93b9 | ||
|
|
e12cca974a | ||
|
|
b17bc95b4f | ||
|
|
a71f260377 | ||
|
|
8cbc1f7f06 | ||
|
|
34335018e9 | ||
|
|
136bddab33 | ||
|
|
b2951c5462 | ||
|
|
07de6f5f4a | ||
|
|
99ea00ca18 | ||
|
|
ab5c6a38eb | ||
|
|
52cee84625 | ||
|
|
20dc8b05c9 | ||
|
|
ba5992621d | ||
|
|
cdae98f653 | ||
|
|
81434bb557 | ||
|
|
3af0fc6fb7 | ||
|
|
3f60062ab6 | ||
|
|
76499bb26e | ||
|
|
44f2f701e1 | ||
|
|
032bc0af5e | ||
|
|
0e822a7e54 | ||
|
|
51e521f0e0 | ||
|
|
e5ce69d6af | ||
|
|
e3b8fa93e2 | ||
|
|
f4ce3a23ad | ||
|
|
39f4696ac7 | ||
|
|
4a9918ec6b | ||
|
|
c87e14f6a9 | ||
|
|
680771c81b | ||
|
|
cad3f63723 | ||
|
|
eceda64528 | ||
|
|
b8ec87e058 | ||
|
|
04bd023787 | ||
|
|
f1759dc419 | ||
|
|
2985f1b40b | ||
|
|
14d1b6701e | ||
|
|
eb3cc9ff07 | ||
|
|
b97a2bd61d | ||
|
|
49e7e3b998 | ||
|
|
11ac6ff084 | ||
|
|
54e7e495ac | ||
|
|
fafdb1a18a | ||
|
|
b599e2c794 | ||
|
|
7f57d3d6a2 | ||
|
|
a2b0ee6809 | ||
|
|
83e8c4bddd | ||
|
|
57aca3c77f | ||
|
|
f80527832c | ||
|
|
2ecceaac45 | ||
|
|
32f8f9e663 | ||
|
|
3447204d97 | ||
|
|
c500532469 | ||
|
|
3396cc84f1 | ||
|
|
1de4893a69 | ||
|
|
abba930f36 | ||
|
|
c84097cf57 | ||
|
|
790b81938c | ||
|
|
187bbca731 | ||
|
|
4ccc12b04d | ||
|
|
9a5f97d85b | ||
|
|
4ed77e136b | ||
|
|
0339d21c33 | ||
|
|
4502aee988 | ||
|
|
55150853b4 | ||
|
|
b9da4f988c | ||
|
|
bf0ca10253 | ||
|
|
fcc4734a1f | ||
|
|
d1c5c773fa | ||
|
|
01ce38c5ac | ||
|
|
cc6d440f0e | ||
|
|
2b21f4b571 | ||
|
|
24d9833170 | ||
|
|
20f21987de | ||
|
|
fad0be8a45 | ||
|
|
02c42b94f5 | ||
|
|
4808689795 | ||
|
|
6231dceb1c | ||
|
|
1753afa782 | ||
|
|
4097da09bd | ||
|
|
c7965df42d | ||
|
|
1027f8a5a4 | ||
|
|
cbd6be30bf | ||
|
|
7e299470fd | ||
|
|
c794c2aede | ||
|
|
1a58087460 | ||
|
|
44f6fc67f8 | ||
|
|
e4a3d222d6 | ||
|
|
5a96c2e015 | ||
|
|
43390c0d1f | ||
|
|
d166656149 | ||
|
|
acc4d289e4 | ||
|
|
717e6df407 | ||
|
|
286404c6f2 | ||
|
|
f191fd7883 | ||
|
|
74f36cfaa0 | ||
|
|
71aed8b269 | ||
|
|
9e6b0b45b3 | ||
|
|
7bbb3725d4 | ||
|
|
1210c92405 | ||
|
|
714ca9fbc8 | ||
|
|
60713f0e5f | ||
|
|
f1f5f8bb27 | ||
|
|
a69f095720 | ||
|
|
d50d4972a7 | ||
|
|
bd91bbee71 |
@@ -1,3 +0,0 @@
|
||||
java_script:
|
||||
enabled: true
|
||||
config_file: .jshintrc
|
||||
248
CHANGELOG.md
248
CHANGELOG.md
@@ -1,142 +1,330 @@
|
||||
# 1.12.26
|
||||
# Changelog
|
||||
|
||||
Gaps between patch versions are faulty/broken releases.
|
||||
|
||||
## 2.0.2
|
||||
|
||||
* Inherit comments in `for-of` transformer.
|
||||
* Remove `interopRequire` from `system` module formatter.
|
||||
|
||||
## 2.0.1
|
||||
|
||||
* Remap `UpdateExpression` module export binding.
|
||||
* Fix automatic closure on `PrivateDeclaration` in classes.
|
||||
|
||||
## 2.0.0
|
||||
|
||||
* Make string literal generation only escapes unicode that it has to.
|
||||
* Internal code generation format options have been exposed.
|
||||
* Change playground method binding operator from `:` to `#` removing ambiguous syntax with terns.
|
||||
* Fix rest parameters in async and generator functions.
|
||||
* Export/import declarations replace by the modules transformer now inherit comments.
|
||||
* Added playground flag to `6to5-node`.
|
||||
* `6to5-node` now behaves the same as `node`.
|
||||
* `6to5-node` now uses `kexec` to become the forked process to correctly propagate signals on unix.
|
||||
* Constants are now block scoped.
|
||||
* Exposed ast transformer.
|
||||
* Merged `commonInterop` and `common` module formatters.
|
||||
* Fix generator comprehensions not inheriting `arguments`, `this` etc.
|
||||
* Object and class mutator shorthand are now enumerable.
|
||||
* Remove regenerator `Generator has already finished` error which isn't spec-compliant.
|
||||
* Expose internal `spec` transformers that nicen up code output.
|
||||
* Add export variable declaration default initializers.
|
||||
* Propagate export declaration reassignments.
|
||||
* Add initializer default to block scoped variable declarations within a loop.
|
||||
* Flow type support.
|
||||
* Make async/await contextual keywords.
|
||||
* Allow `yield`ing of non-objects.
|
||||
* Class declarations now lack an IIFE.
|
||||
* Support falsy and `null` super classes.
|
||||
* Add support for experimental abstract references `private` declarations.
|
||||
* Leave out IIFE for class declarations.
|
||||
* Switched to [core-js](https://github.com/zloirock/core-js) from [es6-symbol](https://github.com/medikoo/es6-symbol) and [es6-shim](https://github.com/paulmillr/es6-shim/) for built-in polyfill.
|
||||
* `amd` and `umd` module formatters now behave the same as `common` with `interopRequire`.
|
||||
* Micro-optimizations to boost performance by 200%.
|
||||
* Rename module formatter methods `import` to `importDeclaration` and `export` to `exportDeclaration`.
|
||||
* Support multiple declarators in export variable declarations.
|
||||
* Freeze tagged template literal object.
|
||||
* Remove inlined `regenerator` fork.
|
||||
* Remove `ParenthesizedExpression`.
|
||||
* Rename `object-spread` helper to `object-without-properties`.
|
||||
* Rename `class-props` helper to `prototype-properties`.
|
||||
* Rename `extends` helper to `inherits`.
|
||||
* Completely rewritten `system` module formatter.
|
||||
|
||||
## 1.15.0
|
||||
|
||||
* Don't alias `GeneratorFunction` and check the name which causes minifiers to remove the name and throw an error later on when we check if it's set.
|
||||
|
||||
## 1.14.18
|
||||
|
||||
* Fix files only containg comments not being output.
|
||||
* Fix duplicate comments on property key shorthands.
|
||||
|
||||
## 1.14.17
|
||||
|
||||
* Add default initializer to let variables within loop bodies.
|
||||
* Fix excessive `break` replacement inside of switches in let scoping.
|
||||
|
||||
## 1.14.16
|
||||
|
||||
* Add object getter memos and this shorthand to playground.
|
||||
* Fix while loops in let scoping.
|
||||
* Upgrade `acorn-6to5`.
|
||||
|
||||
## 1.14.14
|
||||
|
||||
* Fix template literals escaping.
|
||||
|
||||
## 1.14.13
|
||||
|
||||
* Fix let scoping of `while` loops.
|
||||
* Make class methods enumerable.
|
||||
|
||||
## 1.14.12
|
||||
|
||||
* Fix duplicate dynamic expressions in call spread.
|
||||
|
||||
## 1.14.10
|
||||
|
||||
* Fix let scoping unneccesary override.
|
||||
|
||||
## 1.14.6
|
||||
|
||||
* Avoid ensuring a block on non-array node replacements.
|
||||
|
||||
## 1.14.5
|
||||
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Fix JSON recursion error for unknown code generator node types.
|
||||
* Ensure that a statement is a block on block/statement types when replacing them with multiple nodes.
|
||||
|
||||
## 1.14.4
|
||||
|
||||
* Merge pretzel maps and method binding.
|
||||
|
||||
## 1.14.3
|
||||
|
||||
* Add playground pretzel maps.
|
||||
|
||||
## 1.14.2
|
||||
|
||||
* Fix `commonInterop` default export handling.
|
||||
* Fix keyworded property key identifiers being turned into computed property key literals.
|
||||
|
||||
## 1.14.1
|
||||
|
||||
* Inherit comments from `ClassDeclaration`.
|
||||
|
||||
## 1.14.0
|
||||
|
||||
* Add [playground](https://6to5.github.io/playground.html).
|
||||
|
||||
## 1.13.13
|
||||
|
||||
* Fix `--debug` in `bin/6to5-node`. Thanks [@timoxley](https://github.com/timoxley).
|
||||
|
||||
## 1.13.12
|
||||
|
||||
* Ignore `XJSEmptyExpression`s in `react` transformer output.
|
||||
|
||||
## 1.13.11
|
||||
|
||||
* Fix `util.regexify` on falsy values.
|
||||
* Fix `_aliasFunction` with rest parameters.
|
||||
* Export as `module.exports` instead of `exports.default` if there are no other `ExportDeclaration`s in `commonInterop` module formatter.
|
||||
* Add `system` module formatter. Thanks [@douglasduteil](https://github.com/douglasduteil).
|
||||
|
||||
## 1.13.10
|
||||
|
||||
* Add support for `AssignmentExpression` destructuring outside of `ExpressionStatement`.
|
||||
|
||||
## 1.13.9
|
||||
|
||||
* Fix `VirtualPropertyExpression` visitor keys.
|
||||
|
||||
## 1.13.8
|
||||
|
||||
* Only use a single reference in abstract references.
|
||||
|
||||
## 1.13.7
|
||||
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Add experimental exponentiation operator support.
|
||||
|
||||
## 1.13.6
|
||||
|
||||
* Fix experimental object spread/rest helper.
|
||||
|
||||
## 1.13.5
|
||||
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Add experimental support for object spread/rest.
|
||||
* Change `arguments` to array to an additional helper method.
|
||||
|
||||
## 1.13.4
|
||||
|
||||
* Fix single spread element returning itself.
|
||||
|
||||
## 1.13.3
|
||||
|
||||
* Upgrade `acorn-6to5`.
|
||||
* Add experimental support for abstract references.
|
||||
|
||||
## 1.13.2
|
||||
|
||||
* Optimise `Array.from` usage by adding a helper method.
|
||||
* Upgrade `acorn-6to5`.
|
||||
|
||||
## 1.13.1
|
||||
|
||||
* Fix constructor spread optimisation. Thanks [@zloirock](https://github.com/zloirock).
|
||||
|
||||
## 1.13.0
|
||||
|
||||
* Put experimental ES7 features behind a flag `--experimental` and `experimental` option.
|
||||
* Constructor spread performance increase. Thanks [@RReverser](https://github.com/RReverser).
|
||||
* Use `self` instead of `window` in the optional 6to5 runtime. Thanks [@RReverser](https://github.com/RReverser).
|
||||
|
||||
## 1.12.26
|
||||
|
||||
* Support computed property destructuring.
|
||||
|
||||
# 1.12.25
|
||||
## 1.12.25
|
||||
|
||||
* Update `acorn-6to5`, `ast-types`, `es6-shim`, `chokidar`, `estraverse` and `private`.
|
||||
|
||||
# 1.12.24
|
||||
## 1.12.24
|
||||
|
||||
* Collect references that haven't been declared in scope.
|
||||
|
||||
# 1.12.23
|
||||
## 1.12.23
|
||||
|
||||
* Fix generator function export hoisting.
|
||||
|
||||
# 1.12.22
|
||||
## 1.12.22
|
||||
|
||||
* Update `fs-readdir-recursive` and `chokidar`.
|
||||
* Support array destructuring on iterables.
|
||||
* Make amd module id optional. Thanks [@webpro](https://github.com/webpro).
|
||||
|
||||
# 1.12.21
|
||||
## 1.12.21
|
||||
|
||||
* Fix unneccesary let scoping replacement.
|
||||
* Add `commonInterop` module formatter. Thanks [@Naddiseo](https://github.com/Naddiseo).
|
||||
* Fix `return` outside of function body bug. Thanks [@brentburg](https://github.com/brentburg).
|
||||
* Add more flexible option types.
|
||||
|
||||
# 1.12.20
|
||||
## 1.12.20
|
||||
|
||||
* Append `sourceMappingURL` when using `bin/6to5` and output sourcemaps.
|
||||
|
||||
# 1.12.19
|
||||
## 1.12.19
|
||||
|
||||
* Add `comments` option and `--remove-comments` flag. Thanks [@webpro](htps://github.com/webpro).
|
||||
* Embed `regenerator`.
|
||||
|
||||
# 1.12.18
|
||||
## 1.12.18
|
||||
|
||||
* Use `global` reference instead of `window`.
|
||||
|
||||
# 1.12.17
|
||||
## 1.12.17
|
||||
|
||||
* Add `moduleName`, `sourceRoot` and `filenameRelative` options. Thanks [@darvelo](https://github.com/darvelo).
|
||||
* Traversal optimisations.
|
||||
|
||||
# 1.12.16
|
||||
## 1.12.16
|
||||
|
||||
* Fix comments not being retained from `MethodDefinition` in classes.
|
||||
* Add temporal dead zone in default parameters.
|
||||
|
||||
# 1.12.15
|
||||
## 1.12.15
|
||||
|
||||
* Update `acorn-6to5`.
|
||||
|
||||
# 1.12.14
|
||||
## 1.12.14
|
||||
|
||||
* Fix duplicate let scoping in functions.
|
||||
* Make JSX whitespace more React-compliant.
|
||||
* Add `_memberExpressionKeywords` transformer that turns keyword identifiers to computed literals.
|
||||
* Upgrade `regenerator-6to5`.
|
||||
|
||||
# 1.12.13
|
||||
## 1.12.13
|
||||
|
||||
* Support duplicate constants within different block scopes.
|
||||
* Fix for-head duplication testing and replacement.
|
||||
* Support `raw` property on tagged template literals.
|
||||
|
||||
# 1.12.12
|
||||
## 1.12.12
|
||||
|
||||
* Make scope tracker more reliable to handle all edgecases.
|
||||
|
||||
# 1.12.11
|
||||
## 1.12.11
|
||||
|
||||
* Block scope classes.
|
||||
* Fix generation of integer `Literal`s in `MemberExpression`.
|
||||
|
||||
# 1.12.10
|
||||
## 1.12.10
|
||||
|
||||
* Fix let scoping var hoisting.
|
||||
|
||||
# 1.12.9
|
||||
## 1.12.9
|
||||
|
||||
* Escape unicode characters when generating string `Literal`s.
|
||||
* Fix semicolons being output for statements in `ExportDeclaration`.
|
||||
* Fix `WithStatement` missing parenthesis.
|
||||
|
||||
# 1.12.8
|
||||
## 1.12.8
|
||||
|
||||
* Temporarily forbid `AssignmentExpression` destructuring outside of `ExpressionStatement`.
|
||||
|
||||
# 1.12.7
|
||||
## 1.12.7
|
||||
|
||||
* Update to latest `acorn-6to5`.
|
||||
|
||||
# 1.12.6
|
||||
## 1.12.6
|
||||
|
||||
* Update to latest `acorn-6to5`.
|
||||
|
||||
# 1.12.5
|
||||
## 1.12.5
|
||||
|
||||
* Fix excessive whitespace trimming resulting in innaccurate sourcemap line.
|
||||
|
||||
# 1.12.4
|
||||
## 1.12.4
|
||||
|
||||
* Add `doc` folder for documentation.
|
||||
|
||||
# 1.12.3
|
||||
## 1.12.3
|
||||
|
||||
* Support generator comprehensions.
|
||||
* Use `Array.from` instead of `Array.prototype.slice` in spread transformer.
|
||||
* Support spread in `NewExpression`s.
|
||||
|
||||
# 1.12.2
|
||||
## 1.12.2
|
||||
|
||||
* Upgrade `matcha` to `0.6.0` and `browserify` to `6.3.2`.
|
||||
* Add own `trimRight` helper instead of relying on the string instance method.
|
||||
* Support JSX spreads that aren't the first.
|
||||
|
||||
# 1.12.1
|
||||
## 1.12.1
|
||||
|
||||
* Fix `this` and `arguments` mapping in the `_aliasFunctions` transformer.
|
||||
|
||||
# 1.12.0
|
||||
## 1.12.0
|
||||
|
||||
* Combine `jsx` and `react` transformers to `react`.
|
||||
* Update `react` syntax output to React v0.12.
|
||||
|
||||
# 1.11.15
|
||||
## 1.11.15
|
||||
|
||||
* Fix JSX literal whitespace generation.
|
||||
|
||||
# 1.11.14
|
||||
## 1.11.14
|
||||
|
||||
* Avoid using a switch for let-scoping continue and break statements and use an if statement instead.
|
||||
* Remove excess whitespace and newlines from JSX literals.
|
||||
|
||||
# 1.11.13
|
||||
## 1.11.13
|
||||
|
||||
* Update regenerator-6to5
|
||||
* Add support for most escodegen formatting options
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
* CamelCase all class names
|
||||
* camelBack all variable names
|
||||
* **Spacing**
|
||||
* 80 character line max
|
||||
* Spaces after all keywords
|
||||
* Spaces before all left curly braces
|
||||
* **Comments**
|
||||
|
||||
2
Makefile
2
Makefile
@@ -16,7 +16,7 @@ bench:
|
||||
node node_modules/matcha/bin/_matcha
|
||||
|
||||
lint:
|
||||
$(JSHINT_CMD) lib bin benchmark/index.js
|
||||
$(JSHINT_CMD) --reporter node_modules/jshint-stylish/stylish.js lib bin benchmark/index.js
|
||||
|
||||
test-clean:
|
||||
rm -rf test/tmp
|
||||
|
||||
15
README.md
15
README.md
@@ -3,8 +3,12 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://gratipay.com/sebmck">
|
||||
<img alt="Gratipay" src="https://img.shields.io/gratipay/sebmck.svg?style=flat">
|
||||
</a>
|
||||
|
||||
<a href="https://travis-ci.org/6to5/6to5">
|
||||
<img alt="Travis Status" src="http://img.shields.io/travis/6to5/6to5.svg?branch=master&style=flat&label=travis">
|
||||
<img alt="Travis Status" src="http://img.shields.io/travis/6to5/6to5/master.svg?style=flat&label=travis">
|
||||
</a>
|
||||
|
||||
<a href="https://ci.appveyor.com/project/sebmck/6to5">
|
||||
@@ -24,6 +28,11 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
**6to5** turns ES6+ code into vanilla ES5, so you can use next generation features **today.**
|
||||
<p align="center">
|
||||
<strong>6to5</strong> turns ES6+ code into vanilla ES5, so you can use next generation features <strong>today.</strong>
|
||||
</p>
|
||||
|
||||
For more information view the [documentation](https://6to5.github.io).
|
||||
<p align="center">
|
||||
For more information view the <a href="https://6to5.github.io">documentation</a>. For
|
||||
support visit the <a href="https://gitter.im/6to5/6to5">gitter room</a>.
|
||||
</p>
|
||||
|
||||
@@ -2,9 +2,9 @@ Error.stackTraceLimit = Infinity;
|
||||
|
||||
var jsTrans = require("jstransform");
|
||||
var traceur = require("traceur");
|
||||
var es6tr = require("es6-transpiler");
|
||||
//var es6tr = require("es6-transpiler");
|
||||
var es6now = require("es6now");
|
||||
var esnext = require("esnext");
|
||||
//var esnext = require("esnext");
|
||||
var to5 = require("../lib/6to5");
|
||||
|
||||
//var uglify = require("uglify-js");
|
||||
@@ -56,12 +56,12 @@ var compilers = {
|
||||
}
|
||||
},
|
||||
|
||||
esnext: {
|
||||
/*esnext: {
|
||||
runtime: readResolve("esnext/node_modules/regenerator/runtime.js") || readResolve("regenerator/runtime.js"),
|
||||
compile: function (code) {
|
||||
return esnext.compile(code).code;
|
||||
}
|
||||
},
|
||||
},*/
|
||||
|
||||
es6now: {
|
||||
runtime: readResolve("es6now/runtime/ES6.js"),
|
||||
@@ -70,13 +70,13 @@ var compilers = {
|
||||
}
|
||||
},
|
||||
|
||||
"es6-transpiler": {
|
||||
/*"es6-transpiler": {
|
||||
compile: function (code) {
|
||||
var result = es6tr.run({ src: code });
|
||||
if (result.errors.length) throw new Error(result.join("; "));
|
||||
return result.src;
|
||||
}
|
||||
},
|
||||
},*/
|
||||
|
||||
jstransform: {
|
||||
compile: function (code) {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
* when found, before invoking the "real" _6to5-node(1) executable.
|
||||
*/
|
||||
|
||||
var spawn = require("child_process").spawn;
|
||||
var args = ["--harmony", __dirname + "/_6to5-node"];
|
||||
|
||||
process.argv.slice(2).forEach(function(arg){
|
||||
@@ -14,18 +13,19 @@ process.argv.slice(2).forEach(function(arg){
|
||||
switch (flag) {
|
||||
case "-d":
|
||||
args.unshift("--debug");
|
||||
args.push("--no-timeouts");
|
||||
break;
|
||||
|
||||
case "debug":
|
||||
case "--debug":
|
||||
case "--debug-brk":
|
||||
args.unshift(arg);
|
||||
args.push("--no-timeouts");
|
||||
break;
|
||||
|
||||
case "-gc":
|
||||
case "--expose-gc":
|
||||
args.unshift("--expose-gc");
|
||||
break;
|
||||
|
||||
case "--gc-global":
|
||||
case "--harmony":
|
||||
case "--harmony-proxies":
|
||||
@@ -37,20 +37,32 @@ process.argv.slice(2).forEach(function(arg){
|
||||
case "--trace-deprecation":
|
||||
args.unshift(arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (0 == arg.indexOf("--trace")) args.unshift(arg);
|
||||
else args.push(arg);
|
||||
if (arg.indexOf("--trace") === 0) {
|
||||
args.unshift(arg);
|
||||
} else {
|
||||
args.push(arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
var proc = spawn(process.argv[0], args, { stdio: "inherit" });
|
||||
proc.on("exit", function (code, signal) {
|
||||
process.on("exit", function (){
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal);
|
||||
} else {
|
||||
process.exit(code);
|
||||
}
|
||||
try {
|
||||
var kexec = require("kexec");
|
||||
kexec(process.argv[0], args);
|
||||
} catch (err) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
|
||||
var child_process = require("child_process");
|
||||
var proc = child_process.spawn(process.argv[0], args, { stdio: "inherit" });
|
||||
proc.on("exit", function (code, signal) {
|
||||
process.on("exit", function () {
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal);
|
||||
} else {
|
||||
process.exit(code);
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -113,16 +113,14 @@ module.exports = function (commander, filenames) {
|
||||
walk();
|
||||
|
||||
if (commander.watch) {
|
||||
var watcher = chokidar.watch(filenames, {
|
||||
chokidar.watch(filenames, {
|
||||
persistent: true,
|
||||
ignoreInitial: true
|
||||
});
|
||||
|
||||
_.each(["add", "change", "unlink"], function (type) {
|
||||
watcher.on(type, function (filename) {
|
||||
}).on("all", function (type, filename) {
|
||||
if (type === "add" || type === "change" || type === "unlink" ) {
|
||||
console.log(type, filename);
|
||||
walk();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -11,6 +11,8 @@ commander.option("-s, --source-maps", "Save source map alongside the compiled co
|
||||
commander.option("-f, --filename [filename]", "Filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]", "stdin");
|
||||
commander.option("-w, --watch", "Recompile files on changes");
|
||||
commander.option("-r, --runtime", "Replace 6to5 declarations with references to a runtime");
|
||||
commander.option("-e, --experimental", "Enable experimental support for proposed ES7 features");
|
||||
commander.option("-p, --playground", "Enable playground support");
|
||||
|
||||
commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common");
|
||||
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
|
||||
@@ -87,11 +89,13 @@ if (errors.length) {
|
||||
|
||||
exports.opts = {
|
||||
sourceMapName: commander.outFile,
|
||||
amdModuleIds: commander.amdModuleIds,
|
||||
experimental: commander.experimental,
|
||||
playground: commander.playground,
|
||||
blacklist: commander.blacklist,
|
||||
whitelist: commander.whitelist,
|
||||
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
|
||||
comments: !commander.removeComments,
|
||||
amdModuleIds: commander.amdModuleIds,
|
||||
runtime: commander.runtime,
|
||||
modules: commander.modules
|
||||
};
|
||||
|
||||
@@ -1,41 +1,49 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var commander = require("commander");
|
||||
var path = require("path");
|
||||
var repl = require("repl");
|
||||
var to5 = require("../lib/6to5");
|
||||
var util = require("../lib/6to5/util");
|
||||
var vm = require("vm");
|
||||
var _ = require("lodash");
|
||||
var roadrunner = require("roadrunner");
|
||||
var commander = require("commander");
|
||||
var Module = require("module");
|
||||
var path = require("path");
|
||||
var repl = require("repl");
|
||||
var to5 = require("../lib/6to5");
|
||||
var util = require("../lib/6to5/util");
|
||||
var vm = require("vm");
|
||||
var _ = require("lodash");
|
||||
|
||||
commander.option("-e, --eval [script]", "evaluate script");
|
||||
commander.option("-p, --print", "evaluate script and print result");
|
||||
commander.option("-i, --ignore [regex]", "ignore all files that match this regex when using the require hook");
|
||||
commander.option("-x, --extensions [extensions]", "list of extensions to hook into [.es6,.js]", util.list);
|
||||
commander.option("-e, --eval [script]", "Evaluate script");
|
||||
commander.option("-p, --print", "Evaluate script and print result");
|
||||
commander.option("-i, --ignore [regex]", "Ignore all files that match this regex when using the require hook");
|
||||
commander.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js]");
|
||||
commander.option("-r, --experimental", "Enable experimental support for proposed ES7 features");
|
||||
commander.option("-g, --playground", "Enable playground support");
|
||||
commander.option("-c, --cache", "Cache compiled files and require paths");
|
||||
|
||||
var pkg = require("../package.json");
|
||||
commander.version(pkg.version);
|
||||
commander.usage("[options] [ -e script | script.js ] [arguments]");
|
||||
commander.parse(process.argv);
|
||||
|
||||
if (commander.cache) roadrunner.load();
|
||||
|
||||
//
|
||||
|
||||
var registerOpts = {};
|
||||
|
||||
if (commander.ignore) {
|
||||
registerOpts.ignoreRegex = new RegExp(commander.ignore);
|
||||
}
|
||||
|
||||
if (commander.extensions && commander.extensions.length) {
|
||||
registerOpts.extensions = commander.extensions;
|
||||
}
|
||||
|
||||
to5.register(registerOpts);
|
||||
to5.register({
|
||||
experimental: commander.experimental,
|
||||
extensions: commander.extensions,
|
||||
playground: commander.playground,
|
||||
ignore: commander.ignore,
|
||||
cache: commander.cache && roadrunner.get("6to5")
|
||||
});
|
||||
|
||||
//
|
||||
|
||||
var _eval = function (code, filename) {
|
||||
code = to5.transform(code, { filename: filename, blacklist: ["useStrict"] }).code;
|
||||
code = to5.transform(code, {
|
||||
filename: filename,
|
||||
blacklist: ["useStrict"],
|
||||
experimental: commander.experimental,
|
||||
playground: commander.playground
|
||||
}).code;
|
||||
return vm.runInThisContext(code, filename);
|
||||
};
|
||||
|
||||
@@ -43,21 +51,34 @@ if (commander.eval) {
|
||||
var result = _eval(commander.eval, "eval");
|
||||
if (commander.print) console.log(result);
|
||||
} else {
|
||||
var filenames = commander.args;
|
||||
if (commander.args.length) {
|
||||
// slice all arguments up to the first filename since they're 6to5 args that we handle
|
||||
var args = process.argv.slice(2);
|
||||
|
||||
if (filenames.length) {
|
||||
_.each(filenames, function (filename) {
|
||||
if (!util.isAbsolute(filename)) {
|
||||
filename = path.join(process.cwd(), filename);
|
||||
var i = 0;
|
||||
_.each(args, function (arg, i2) {
|
||||
if (arg[0] !== "-") {
|
||||
i = i2;
|
||||
return false;
|
||||
}
|
||||
|
||||
require(require.resolve(filename));
|
||||
});
|
||||
args = args.slice(i);
|
||||
|
||||
// make the filename absolute
|
||||
var filename = args[0]
|
||||
if (!util.isAbsolute(filename)) args[0] = path.join(process.cwd(), filename);
|
||||
|
||||
// add back on node and concat the sliced args
|
||||
process.argv = ["node"].concat(args);
|
||||
|
||||
Module.runMain();
|
||||
} else {
|
||||
replStart();
|
||||
}
|
||||
}
|
||||
|
||||
if (commander.cache) roadrunner.save();
|
||||
|
||||
function replStart() {
|
||||
repl.start({
|
||||
prompt: "> ",
|
||||
|
||||
@@ -30,7 +30,9 @@ test.test();
|
||||
You can build a browser version of the compiler by running the following in the
|
||||
6to5 directory:
|
||||
|
||||
$ make build
|
||||
```sh
|
||||
$ make build
|
||||
```
|
||||
|
||||
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
|
||||
|
||||
@@ -38,7 +40,9 @@ This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
|
||||
|
||||
To test 6to5 in your browser run:
|
||||
|
||||
$ make test-browser
|
||||
```sh
|
||||
$ make test-browser
|
||||
```
|
||||
|
||||
And open `test/browser.html` in your browser if it doesn't open automatically.
|
||||
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
# Caveats
|
||||
|
||||
## Async/Generators
|
||||
In order for certain features to work they require certain polyfills. You can
|
||||
satisfy **all** 6to5 feature requirements by using the included
|
||||
[polyfill](polyfill.md).
|
||||
|
||||
The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js)
|
||||
and an [ES6 polyfill](polyfill.md) are required in order for generators to work.
|
||||
You may alternatively selectively include what you need:
|
||||
|
||||
## Classes
|
||||
| Feature | Requirements |
|
||||
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| Abstract References | [experimental](experimental.md), `Symbol` |
|
||||
| Array destructuring | `Array.isArray`, `Array.from` |
|
||||
| Async functions, Generators | [experimental](experimental.md), [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) |
|
||||
| Comprehensions | [experimental](experimental.md), `Array.isArray`, `Array.from` |
|
||||
| For Of | `Symbol`, `prototype[Symbol.iterator]` |
|
||||
| Object spread/rest | [experimental](experimental.md), `Object.assign` |
|
||||
| Spread | `Array.isArray`, `Array.from` |
|
||||
|
||||
Built-in classes such as `Date`, `Array` and `DOM` cannot be subclassed due to
|
||||
limitations in ES5 implementations.
|
||||
## ES5
|
||||
|
||||
Since 6to5 assumes that your code will be ran in an ES5 environment it uses ES5
|
||||
functions. So if you're using an environment that has limited or no support for
|
||||
ES5 such as lower versions of IE then using the
|
||||
[es5-shim](https://github.com/es-shims/es5-shim) along with the
|
||||
[6to5 polyfill](polyfill.md) will add support for these methods.
|
||||
|
||||
## Internet Explorer
|
||||
|
||||
### Classes (9 and below)
|
||||
|
||||
If you're inheriting from a class then static properties are inherited from it
|
||||
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
|
||||
@@ -31,13 +49,11 @@ class Bar extends Foo {
|
||||
}
|
||||
```
|
||||
|
||||
## For-of
|
||||
## Getters/setters (8 and below)
|
||||
|
||||
A polyfill is required for for-of functionality that implements `Symbol` and
|
||||
adds `prototype[Symbol.iterator]` behaviour to built-ins. Using the polyfills
|
||||
specified in [polyfill](polyfill.md) suffices.
|
||||
In IE8 `Object.defineProperty` can only be used on DOM objects. This is
|
||||
unfortunate as it's required to set getters and setters. Due to this if
|
||||
you plan on supporting IE8 or below then the user of getters and setters
|
||||
isn't recommended.
|
||||
|
||||
### Array destructuring / Spread
|
||||
|
||||
An [ES6 polyfill](polyfill.md) is required for spread and array destructuring.
|
||||
More specifically a polyfill for `Array.from`.
|
||||
Reference: [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Internet_Explorer_8_specific_notes).
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Differences
|
||||
|
||||
## Philosophy
|
||||
There are three main points that separate 6to5 from all other transpilers.
|
||||
|
||||
### Readable code
|
||||
|
||||
The fundamental concept behind 6to5 is that the generated code must be close as
|
||||
possible to the original, retaining all the same formatting and readability.
|
||||
@@ -17,7 +19,7 @@ var seattlers = [for (c of customers) if (c.city == "Seattle") { name: c.name, a
|
||||
is generated to the following with 6to5:
|
||||
|
||||
```javascript
|
||||
var seattlers = customers.filter(function (c) {
|
||||
var seattlers = Array.from(customers).filter(function (c) {
|
||||
return c.city == "Seattle";
|
||||
}).map(function (c) {
|
||||
return {
|
||||
@@ -51,8 +53,27 @@ As you can tell, it's not very pretty, unreadable even. Instead of mapping
|
||||
directly to a runtime, like other transpilers, 6to5 maps directly to the
|
||||
equivalent ES5.
|
||||
|
||||
I'm not saying 6to5 is for everyone or even suited for everything. Traceur is
|
||||
better suited if you'd like a full ES6 environment with polyfills and all.
|
||||
Sometimes there are little inline functions that 6to5 needs. These are
|
||||
placed at the top of your file much like coffee-script does. If these
|
||||
are bother you then you can use the [optional runtime](optional-runtime.md).
|
||||
We promise that these inline functions will never be significant and will
|
||||
always be used as little as possible.
|
||||
|
||||
### Static analysis
|
||||
|
||||
6to5 uses a lot of static analysis to simplify code as much as possible.
|
||||
Not many other transpilers do this, and those that do don't do it nearly
|
||||
as much as 6to5. This process is pretty intensive but it leads to higher
|
||||
quality code.
|
||||
|
||||
### Spec compliancy
|
||||
|
||||
6to5 prides itself on
|
||||
[spec compliancy](https://kangax.github.io/compat-table/es6/). We have
|
||||
excellent support for edgecases, something that many other transpilers
|
||||
suffer from, including Traceur. When you use 6to5 you can be confident
|
||||
that when you turn it off and use your code in a full ES6 environment
|
||||
**it'll just work**.
|
||||
|
||||
## Comparison to other transpilers
|
||||
|
||||
@@ -62,42 +83,45 @@ better suited if you'd like a full ES6 environment with polyfills and all.
|
||||
| ---------------------------- | ---- | ------- | -------------- | ------ | ------ | ----------- |
|
||||
| Source maps | ✓ | ✓ | ✓ | ✓ | | ✓ |
|
||||
| No compiler global pollution | ✓ | | ✓ | ✓ | | ✓ |
|
||||
| No runtime | ✓ | | ✓ | | | ✓ |
|
||||
| Browser support | ✓ | ✓ | | ✓ | | |
|
||||
| Optional runtime | ✓ | | ✓ | | | ✓ |
|
||||
| Browser compiler | ✓ | ✓ | | ✓ | | |
|
||||
|
||||
### Language Support
|
||||
|
||||
| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform |
|
||||
| ---------------------------- | ----- | ------- | -------------- | ------ | ------ | ----------- |
|
||||
| Array comprehension | ✓ | ✓ | ✓ | | | |
|
||||
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Async functions | ✓ | ✓ | | ✓ | | |
|
||||
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Constants | ✓ | ✓ | ✓ | | | |
|
||||
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Generators | ✓ | ✓ | | ✓ | | |
|
||||
| Generator comprehension | ✓ | ✓ | | | | |
|
||||
| Let scoping | ✓ | ✓ | ✓ | | | |
|
||||
| Modules | ✓ | ✓ | | | ✓ | |
|
||||
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Unicode regex | ✓ | ✓ | ✓ | | | |
|
||||
|
||||
|
||||
|
||||
|
||||
| | 6to5 | Traceur | es6-transpiler | esnext | es6now | jstransform |
|
||||
| ---------------------------- | ---- | ------- | -------------- | ------ | ------ | ----------- |
|
||||
| Abstract references | ✓ | | | | | |
|
||||
| Array comprehension | ✓ | ✓ | ✓ | | | |
|
||||
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Async functions | ✓ | ✓ | | ✓ | | |
|
||||
| Async generator functions | ✓ | ✓ | | | | |
|
||||
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Constants | ✓ | ✓ | ✓ | | | |
|
||||
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Exponentiation operator | ✓ | ✓ | | | | |
|
||||
| Flow types | ✓ | | | | | ✓ |
|
||||
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Generators | ✓ | ✓ | | ✓ | | |
|
||||
| Generator comprehension | ✓ | ✓ | | | | |
|
||||
| JSX | ✓ | | | | | |
|
||||
| Let scoping | ✓ | ✓ | ✓ | | | |
|
||||
| Modules | ✓ | ✓ | | | ✓ | |
|
||||
| Object rest/spread | ✓ | | | | | ✓ |
|
||||
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| React | ✓ | | | | | |
|
||||
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
|
||||
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
|
||||
| Unicode regex | ✓ | ✓ | ✓ | | | |
|
||||
|
||||
### [Traceur](https://github.com/google/traceur-compiler)
|
||||
|
||||
Traceur requires quite a bulky runtime (~75KB) and produces quite verbose code.
|
||||
While this can be trimmed down by selectively building the runtime, it's an
|
||||
unneccesary step when a runtime can be eliminated entirely.
|
||||
unnecessary step when a large runtime can be eliminated entirely.
|
||||
|
||||
### [es6now](https://github.com/zenparsing/es6now)
|
||||
|
||||
|
||||
8
doc/experimental.md
Normal file
8
doc/experimental.md
Normal file
@@ -0,0 +1,8 @@
|
||||
## Experimental
|
||||
|
||||
6to5 also has experimental support for ES7 proposals. You can enable this with
|
||||
the `experimental: true` option when using the [Node API](#node) or
|
||||
`--experimental` when using the [CLI](#cli).
|
||||
|
||||
**WARNING:** These proposals are subject to change so use with
|
||||
**extreme caution**.
|
||||
@@ -1,6 +1,14 @@
|
||||
# Features
|
||||
|
||||
## Array comprehension
|
||||
## Abstract references ([experimental](experimental.md)) ([spec](https://github.com/zenparsing/es-abstract-refs))
|
||||
|
||||
```javascript
|
||||
foo::bar;
|
||||
foo::bar = baz;
|
||||
delete foo::bar;
|
||||
```
|
||||
|
||||
## Array comprehensions ([experimental](experimental.md))
|
||||
|
||||
```javascript
|
||||
var results = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }]
|
||||
@@ -31,7 +39,7 @@ var bob = {
|
||||
};
|
||||
```
|
||||
|
||||
## Async functions
|
||||
## Async functions ([experimental](experimental.md)) ([spec](https://github.com/lukehoban/ecmascript-asyncawait))
|
||||
|
||||
```javascript
|
||||
async function chainAnimationsAsync(elem, animations) {
|
||||
@@ -41,6 +49,12 @@ async function chainAnimationsAsync(elem, animations) {
|
||||
}
|
||||
```
|
||||
|
||||
## Async generator functions ([experimental](experimental.md)) ([spec](https://github.com/jhusain/asyncgenerator))
|
||||
|
||||
```javascript
|
||||
|
||||
```
|
||||
|
||||
## Classes
|
||||
|
||||
```javascript
|
||||
@@ -122,6 +136,15 @@ var [a] = [];
|
||||
a === undefined;
|
||||
```
|
||||
|
||||
## Exponentiation operator ([experimental](experimental.md)) ([spec](https://github.com/rwaldron/exponentiation-operator))
|
||||
|
||||
```javascript
|
||||
var a = 2;
|
||||
a **= 2;
|
||||
|
||||
var squared = 2 ** 2;
|
||||
```
|
||||
|
||||
## For-of
|
||||
|
||||
```javascript
|
||||
@@ -150,7 +173,7 @@ for (var n of fibonacci()) {
|
||||
}
|
||||
```
|
||||
|
||||
## Generator comprehension
|
||||
## Generator comprehensions ([experimental](experimental.md))
|
||||
|
||||
```javascript
|
||||
var nums = [1, 2, 3, 4, 5, 6];
|
||||
@@ -191,6 +214,13 @@ export default test;
|
||||
0o767 === 503; // true
|
||||
```
|
||||
|
||||
## Object spread/rest ([experimental](experimental.md)) ([spec](https://github.com/sebmarkbage/ecmascript-rest-spread))
|
||||
|
||||
```javascript
|
||||
var n = { x, y, ...z };
|
||||
var { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
|
||||
```
|
||||
|
||||
## Property method assignment
|
||||
|
||||
```javascript
|
||||
@@ -244,7 +274,6 @@ var x = 5;
|
||||
var y = 10;
|
||||
console.log(`${x} + ${y} = ${x + y}`); // "5 + 10 = 15"
|
||||
```
|
||||
|
||||
## Unicode regex
|
||||
|
||||
```javascript
|
||||
|
||||
20
doc/index.md
20
doc/index.md
@@ -3,7 +3,7 @@
|
||||
- **Readable** - formatting is retained if possible so your generated code is as similar as possible.
|
||||
- **Extensible** - with a large range of [plugins](plugins.md) and **browser support**.
|
||||
- **Lossless** - **source map support** so you can debug your compiled code with ease.
|
||||
- **Compact** - maps directly to the equivalent ES5 with **no runtime**[\*](caveats.md#generators).
|
||||
- **Compact** - maps directly to the equivalent ES5 with **no runtime**[\*](caveats.md).
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -19,32 +19,40 @@ how you want to use it.
|
||||
6to5 will simply compile your ES6+ script to ES5 if you pass it as an argument
|
||||
to the command-line tool `6to5`:
|
||||
|
||||
$ 6to5 script.js
|
||||
```sh
|
||||
$ 6to5 script.js
|
||||
```
|
||||
|
||||
If you have a file written using ES6+ and you just want to run it, `6to5-node`
|
||||
has you covered:
|
||||
|
||||
$ 6to5-node script.js
|
||||
```sh
|
||||
$ 6to5-node script.js
|
||||
```
|
||||
|
||||
And it doesn't end here! To see all the ways you can use 6to5, check out the
|
||||
[Usage](http://6to5.github.io/usage.html) page.
|
||||
|
||||
## [Features](features.md)
|
||||
|
||||
- [Array comprehension](features.md#array-comprehension)
|
||||
- [Async functions](features.md#async-functions)
|
||||
- [Abstract references](features.md#abstract-references) ([experimental](experimental.md))
|
||||
- [Array comprehension](features.md#array-comprehension) ([experimental](experimental.md))
|
||||
- [Async functions](features.md#async-functions) ([experimental](experimental.md))
|
||||
- [Async generator functions](features.md#async-generator-functions) ([experimental](experimental.md))
|
||||
- [Arrow functions](features.md#arrow-functions)
|
||||
- [Classes](features.md#classes)
|
||||
- [Computed property names](features.md#computed-property-names)
|
||||
- [Constants](features.md#constants)
|
||||
- [Default parameters](features.md#default-parameters)
|
||||
- [Destructuring](features.md#destructuring)
|
||||
- [Exponentiation operator](features.md#exponentiation-operator) ([experimental](experimental.md))
|
||||
- [For-of](features.md#for-of)
|
||||
- [Generators](features.md#generators)
|
||||
- [Generator comprehension](features.md#generator-comprehension)
|
||||
- [Generator comprehension](features.md#generator-comprehension) ([experimental](experimental.md))
|
||||
- [Let scoping](features.md#let-scoping)
|
||||
- [Modules](features.md#modules)
|
||||
- [Numeric literals](features.md#numeric-literals)
|
||||
- [Object Rest/Spread](features.md#object-rest-spread) ([experimental](experimental.md))
|
||||
- [Property method assignment](features.md#property-method-assignment)
|
||||
- [Property name shorthand](features.md#property-name-shorthand)
|
||||
- [React/JSX](react.md)
|
||||
|
||||
124
doc/modules.md
124
doc/modules.md
@@ -4,7 +4,9 @@
|
||||
|
||||
### CLI
|
||||
|
||||
$ 6to5 --modules common script.js
|
||||
```sh
|
||||
$ 6to5 --modules common script.js
|
||||
```
|
||||
|
||||
### Node
|
||||
|
||||
@@ -15,11 +17,26 @@ to5.transform('import "foo";', { modules: "common" });
|
||||
|
||||
## Formats
|
||||
|
||||
### Common (Default)
|
||||
* [AMD](#amd)
|
||||
* [Common (Default)](#common-default)
|
||||
* [Ignore](#ignore)
|
||||
* [System](#system)
|
||||
* [UMD](#umd)
|
||||
|
||||
### Common
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules common
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
export default test;
|
||||
|
||||
export {test};
|
||||
export var test = 5;
|
||||
|
||||
import "foo";
|
||||
|
||||
import foo from "foo";
|
||||
@@ -27,32 +44,38 @@ import * as foo from "foo";
|
||||
|
||||
import {bar} from "foo";
|
||||
import {foo as bar} from "foo";
|
||||
|
||||
export {test};
|
||||
export var test = 5;
|
||||
|
||||
export default test;
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
"use strict";
|
||||
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
exports = module.exports = test;
|
||||
|
||||
exports.test = test;
|
||||
var test = exports.test = 5;
|
||||
|
||||
require("foo");
|
||||
|
||||
var foo = require("foo").default;
|
||||
var foo = _interopRequire(require("foo"));
|
||||
|
||||
var foo = require("foo");
|
||||
|
||||
var bar = require("foo").bar;
|
||||
var bar = require("foo").foo;
|
||||
|
||||
exports.test = test;
|
||||
var test = 5; exports.test = test;
|
||||
|
||||
exports.default = test;
|
||||
```
|
||||
|
||||
### AMD
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules amd
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
@@ -67,9 +90,14 @@ export function bar() {
|
||||
|
||||
```javascript
|
||||
define(["exports", "foo"], function (exports, _foo) {
|
||||
exports.bar = bar;
|
||||
"use strict";
|
||||
|
||||
var foo = _foo.default;
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
exports.bar = bar;
|
||||
var foo = _interopRequire(_foo);
|
||||
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
@@ -85,6 +113,10 @@ define("filename", ["exports", "foo"], function (exports, _foo) {})
|
||||
|
||||
### UMD
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules umd
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
@@ -104,10 +136,15 @@ export function bar() {
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(exports, require("foo"));
|
||||
}
|
||||
})(function (exports) {
|
||||
exports.bar = bar;
|
||||
})(function (exports, _foo) {
|
||||
"use strict";
|
||||
|
||||
var foo = _foo.default;
|
||||
var _interopRequire = function (obj) {
|
||||
return obj && (obj["default"] || obj);
|
||||
};
|
||||
|
||||
exports.bar = bar;
|
||||
var foo = _interopRequire(_foo);
|
||||
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
@@ -117,6 +154,10 @@ export function bar() {
|
||||
|
||||
### Ignore
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules ignore
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
@@ -135,11 +176,52 @@ function bar() {
|
||||
}
|
||||
```
|
||||
|
||||
### System
|
||||
|
||||
```sh
|
||||
$ 6to5 --modules system
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```javascript
|
||||
import foo from "foo";
|
||||
|
||||
export function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```javascript
|
||||
System.register("bar", ["foo"], function (_export) {
|
||||
"use strict";
|
||||
|
||||
var __moduleName = "bar";
|
||||
|
||||
var foo;
|
||||
function bar() {
|
||||
return foo("foobar");
|
||||
}
|
||||
return {
|
||||
setters: [function (m) {
|
||||
foo = m.default;
|
||||
}],
|
||||
execute: function () {
|
||||
_export("bar", bar);
|
||||
}
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
## Custom
|
||||
|
||||
You can alternatively specify module names instead of one of the built-in types.
|
||||
|
||||
$ 6to5 --modules custom-module-formatter
|
||||
```sh
|
||||
$ 6to5 --modules custom-module-formatter
|
||||
```
|
||||
|
||||
**node_modules/custom-module-formatter/index.js**
|
||||
|
||||
@@ -155,7 +237,7 @@ ModuleFormatter.prototype.transform = function (ast) {
|
||||
// feel free to modify this however
|
||||
};
|
||||
|
||||
ModuleFormatter.prototype.import = function (node, nodes) {
|
||||
ModuleFormatter.prototype.importDeclaration = function (node, nodes) {
|
||||
// node is an ImportDeclaration
|
||||
};
|
||||
|
||||
@@ -164,7 +246,7 @@ ModuleFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
// node is an ImportDeclaration
|
||||
};
|
||||
|
||||
ModuleFormatter.prototype.export = function (node, nodes) {
|
||||
ModuleFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
// node is an ExportDeclaration
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@ Simply use the following option if you're using the [Node API](usage.md#node):
|
||||
|
||||
or the following flag if you're using the [CLI](usage.md#cli):
|
||||
|
||||
$ 6to5 --runtime
|
||||
```ssh
|
||||
$ 6to5 --runtime
|
||||
```
|
||||
|
||||
Then just include the runtime before your generated code.
|
||||
|
||||
@@ -26,7 +28,9 @@ Then just include the runtime before your generated code.
|
||||
|
||||
You can get the runtime via either:
|
||||
|
||||
$ 6to5-runtime
|
||||
```sh
|
||||
$ 6to5-runtime
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
@@ -45,7 +49,9 @@ argument:
|
||||
require("6to5").runtime("myCustomNamespace");
|
||||
```
|
||||
|
||||
$ 6to5-runtime myCustomNamespace
|
||||
```sh
|
||||
$ 6to5-runtime myCustomNamespace
|
||||
```
|
||||
|
||||
See [Options - runtime](usage.md#options) for documentation on changing the
|
||||
reference in generated code.
|
||||
|
||||
120
doc/playground.md
Normal file
120
doc/playground.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Playground
|
||||
|
||||
Playground is a proving ground for **possible** ES7 proposals.
|
||||
|
||||
**NOTE: These features are in no way endorsed by Ecma International and are not a part of ES6. They might become a part of ECMAScript in the future.**
|
||||
|
||||
## Usage
|
||||
|
||||
$ 6to5 --playground
|
||||
|
||||
```javascript
|
||||
to5.transform("code", { playground: true });
|
||||
```
|
||||
|
||||
**NOTE:** Enabling `playground` also enables [experimental support](experimental.md).
|
||||
|
||||
## Features
|
||||
|
||||
* [Memoization operator](#memoization-operator)
|
||||
* [Method binding](#method-binding)
|
||||
* [Object getter memoization](#object-getter-memoization)
|
||||
* [This shorthand](#this-shorthand)
|
||||
|
||||
### Memoization assignment operator
|
||||
|
||||
```javascript
|
||||
var obj = {};
|
||||
obj.x ?= 2;
|
||||
obj.x; // 2
|
||||
|
||||
obj = { x: 1 };
|
||||
obj.x ?= 2;
|
||||
obj.x; // 1
|
||||
|
||||
obj = { x: undefined }
|
||||
obj.x ?= 2;
|
||||
obj.x; // undefined
|
||||
```
|
||||
|
||||
```javascript
|
||||
var obj = {};
|
||||
obj.x ?= 2;
|
||||
```
|
||||
|
||||
equivalent to:
|
||||
|
||||
```javascript
|
||||
var obj = {};
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, "x")) obj.x = 2;
|
||||
```
|
||||
|
||||
### Method binding
|
||||
|
||||
```javascript
|
||||
var fn = obj#method;
|
||||
var fn = obj#method("foob");
|
||||
|
||||
["foo", "bar"].map(#toUpperCase); // ["FOO", "BAR"]
|
||||
[1.1234, 23.53245, 3].map(#toFixed(2)); // ["1.12", "23.53", "3.00"]
|
||||
```
|
||||
|
||||
equivalent to:
|
||||
|
||||
```javascript
|
||||
var fn = obj.method.bind(obj);
|
||||
var fn = obj.method.bind(obj, "foob");
|
||||
|
||||
["foo", "bar"].map(function (val) { return val.toUpperCase(); });
|
||||
[1.1234, 23.53245, 3].map(function (val) { return val.toFixed(2); });
|
||||
```
|
||||
|
||||
### Object getter memoization
|
||||
|
||||
```javascript
|
||||
var foo = {
|
||||
memo bar() {
|
||||
return complex();
|
||||
}
|
||||
};
|
||||
|
||||
class Foo {
|
||||
memo bar() {
|
||||
return complex();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascript
|
||||
var foo = {
|
||||
get bar() {
|
||||
if (this._barRan) return this._bar;
|
||||
this._barRan = true;
|
||||
return this._bar = complex();
|
||||
}
|
||||
};
|
||||
|
||||
class Foo {
|
||||
get bar() {
|
||||
if (this._barRan) return this._bar;
|
||||
this._barRan = true;
|
||||
return this._bar = complex();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**NOTE:** Memoised functions will return the result of the **first** execution, regardless of arguments.
|
||||
|
||||
### This shorthand
|
||||
|
||||
```javascript
|
||||
@foo
|
||||
```
|
||||
|
||||
equivalent to
|
||||
|
||||
```javascirpt
|
||||
this.foo
|
||||
```
|
||||
@@ -1,17 +1,33 @@
|
||||
# Plugins
|
||||
|
||||
- [Broccoli](https://github.com/very-geek/broccoli-6to5-transpiler)
|
||||
- [Browserify](https://github.com/6to5/6to5-browserify)
|
||||
- [Brunch](https://github.com/es128/6to5-brunch)
|
||||
- [Duo](https://github.com/bdo-labs/duo6to5)
|
||||
- [Connect](https://github.com/6to5/6to5-connect)
|
||||
- [Gobble](https://github.com/gobblejs/gobble-6to5)
|
||||
- [Gulp](https://github.com/sindresorhus/gulp-6to5)
|
||||
- [Grunt](https://github.com/sindresorhus/grunt-6to5)
|
||||
- [Jade](https://github.com/Apoxx/jade-6to5)
|
||||
## Build systems
|
||||
|
||||
- [Broccoli](https://github.com/6to5/broccoli-6to5-transpiler)
|
||||
- [Browserify](https://github.com/6to5/6to5ify)
|
||||
- [Brunch](https://github.com/6to5/6to5-brunch)
|
||||
- [Duo](https://github.com/6to5/duo6to5)
|
||||
- [Gobble](https://github.com/6to5/gobble-6to5)
|
||||
- [Gulp](https://github.com/6to5/gulp-6to5)
|
||||
- [Grunt](https://github.com/6to5/grunt-6to5)
|
||||
- [Sprockets](https://github.com/josh/sprockets-es6) or via [Browserify](https://github.com/6to5/6to5-rails)
|
||||
- [webpack](https://github.com/6to5/6to5-loader)
|
||||
|
||||
## Integrations
|
||||
|
||||
- [Isparta](https://github.com/douglasduteil/isparta) - Code coverage with `karma` and `instanbul` using 6to5
|
||||
- [JSXHint](https://github.com/STRML/JSXHint) - A wrapper around JSHint to allow linting of JSX files
|
||||
|
||||
## Bridges
|
||||
|
||||
- [Ruby](https://github.com/6to5/6to5-ruby)
|
||||
|
||||
## Testing
|
||||
|
||||
- [Jest](https://github.com/6to5/6to5-jest)
|
||||
- [JSXHint](https://github.com/STRML/JSXHint) (A wrapper around JSHint to allow linting of JSX files)
|
||||
- [Karma](https://github.com/shuhei/karma-6to5-preprocessor)
|
||||
- [Karma](https://github.com/6to5/karma-6to5-preprocessor)
|
||||
- [Mocha](https://github.com/6to5/6to5-mocha)
|
||||
- [Rails](https://github.com/josh/sprockets-es6) or via [browserify-rails](https://github.com/6to5/6to5-rails)
|
||||
- [webpack](https://github.com/Couto/6to5-loader)
|
||||
|
||||
## Misc
|
||||
|
||||
- [Connect](https://github.com/6to5/6to5-connect)
|
||||
- [Jade](https://github.com/6to5/jade-6to5)
|
||||
|
||||
@@ -1,17 +1,34 @@
|
||||
# Polyfill
|
||||
|
||||
6to5 includes a polyfill that includes the
|
||||
[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the
|
||||
[es6-shim](https://github.com/paulmillr/es6-shim) and
|
||||
[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills.
|
||||
6to5 includes a polyfill that includes a custom
|
||||
[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and
|
||||
[core.js](https://github.com/zloirock/core-js).
|
||||
|
||||
## Node
|
||||
This will emulate a full ES6 environment. This polyfill is automatically loaded
|
||||
when using [6to5-node](usage.md#node) and [6to5/register](usage.md#register-hook).
|
||||
|
||||
## Usage
|
||||
|
||||
### Node/Browserify
|
||||
|
||||
You need to include the polyfill require at the top the **entry point** to your
|
||||
application.
|
||||
|
||||
```javascript
|
||||
require("6to5/polyfill");
|
||||
```
|
||||
|
||||
## Browser
|
||||
Fortunately, this is automatically loaded when using:
|
||||
|
||||
```javascript
|
||||
require("6to5/register");
|
||||
```
|
||||
|
||||
### Browser
|
||||
|
||||
Available from the `browser-polyfill.js` file within the 6to5 directory of an
|
||||
npm release.
|
||||
npm release. This needs to be included **before** all your compiled 6to5 code.
|
||||
You can either prepend it to your compiled code or include it in a `<script>`
|
||||
before it.
|
||||
|
||||
**NOTE:** Do not `require` this via browserify etc, use `6to5/polyfill`.
|
||||
|
||||
@@ -12,5 +12,6 @@ To disable this behaviour add `react` to your blacklist:
|
||||
to5.transform("code", { blacklist: ["react"] });
|
||||
```
|
||||
|
||||
|
||||
$ 6to5 --blacklist react
|
||||
```sh
|
||||
$ 6to5 --blacklist react
|
||||
```
|
||||
|
||||
98
doc/usage.md
98
doc/usage.md
@@ -4,47 +4,67 @@
|
||||
|
||||
Compile the file `script.js` and output it to stdout.
|
||||
|
||||
$ 6to5 script.js
|
||||
```sh
|
||||
$ 6to5 script.js
|
||||
```
|
||||
|
||||
Compile the file `script.js` and output it to `script-compiled.js`.
|
||||
|
||||
$ 6to5 script.js --out-file script-compiled.js
|
||||
```sh
|
||||
$ 6to5 script.js --out-file script-compiled.js
|
||||
```
|
||||
|
||||
Compile the file `script.js` and output it to `script-compiled.js` and save a
|
||||
source map to `script-compiled.js.map`.
|
||||
|
||||
$ 6to5 script.js --source-maps --out-file script-compiled.js
|
||||
```sh
|
||||
$ 6to5 script.js --source-maps --out-file script-compiled.js
|
||||
```
|
||||
|
||||
Compile the file `script.js` and output it to `script-compiled.js` with a source
|
||||
map embedded in a comment at the bottom.
|
||||
|
||||
$ 6to5 script.js --source-maps-inline --out-file script-compiled.js
|
||||
```sh
|
||||
$ 6to5 script.js --source-maps-inline --out-file script-compiled.js
|
||||
```
|
||||
|
||||
Compile the entire `src` directory and output it to the `lib` directory.
|
||||
|
||||
$ 6to5 src --out-dir lib
|
||||
```sh
|
||||
$ 6to5 src --out-dir lib
|
||||
```
|
||||
|
||||
Compile the entire `src` directory and output it to the one concatenated file.
|
||||
|
||||
$ 6to5 src --out-file script-compiled.js
|
||||
```sh
|
||||
$ 6to5 src --out-file script-compiled.js
|
||||
```
|
||||
|
||||
Pipe a file in via stdin and output it to `script-compiled.js`
|
||||
|
||||
$ 6to5 --out-file script-compiled.js < script.js
|
||||
```sh
|
||||
$ 6to5 --out-file script-compiled.js < script.js
|
||||
```
|
||||
|
||||
### Node
|
||||
|
||||
Launch a repl.
|
||||
|
||||
$ 6to5-node
|
||||
```sh
|
||||
$ 6to5-node
|
||||
```
|
||||
|
||||
Evaluate code.
|
||||
|
||||
$ 6to5-node -e "class Test { }"
|
||||
```sh
|
||||
$ 6to5-node -e "class Test { }"
|
||||
```
|
||||
|
||||
Compile and run `test.js`.
|
||||
|
||||
$ 6to5-node test
|
||||
```sh
|
||||
$ 6to5-node test
|
||||
```
|
||||
|
||||
## Node
|
||||
|
||||
@@ -75,6 +95,15 @@ to5.transformFile("filename.js", options, function (err, result) {
|
||||
});
|
||||
```
|
||||
|
||||
### to5.transform.fromAst(ast, [code], [opts])
|
||||
|
||||
```javascript
|
||||
var result = to5.transform.fromAst(ast, "var a = 2;", opts);
|
||||
result.code;
|
||||
result.map;
|
||||
result.ast;
|
||||
```
|
||||
|
||||
#### Options
|
||||
|
||||
```javascript
|
||||
@@ -133,9 +162,47 @@ to5.transformFile("filename.js", options, function (err, result) {
|
||||
// Default: false
|
||||
runtime: true,
|
||||
|
||||
// Output comments in generated output
|
||||
// Enable support for experimental ES7 features
|
||||
// Default: false
|
||||
experimental: true,
|
||||
|
||||
// Set this to `false` if you don't want the transformed AST in the returned
|
||||
// result
|
||||
// Default: true
|
||||
comments: false
|
||||
ast: true,
|
||||
|
||||
// Set this to `false` if you don't want the transformed code in the returned
|
||||
// result
|
||||
// Default: true
|
||||
code: true,
|
||||
|
||||
format: {
|
||||
// Output comments in generated output
|
||||
// Default: true
|
||||
comments: true,
|
||||
|
||||
// Do not include superfluous whitespace characters and line terminators
|
||||
// Default: false
|
||||
compact: false,
|
||||
|
||||
indent: {
|
||||
// Preserve parentheses in new expressions that have no arguments
|
||||
// Default: true
|
||||
parentheses: true,
|
||||
|
||||
// Adjust the indentation of multiline comments to keep asterisks vertically aligned
|
||||
// Default: true
|
||||
adjustMultilineComment: true,
|
||||
|
||||
// Indent string
|
||||
// Default: " "
|
||||
style: " ",
|
||||
|
||||
// Base indent level
|
||||
// Default: 0
|
||||
base: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -143,7 +210,10 @@ to5.transformFile("filename.js", options, function (err, result) {
|
||||
|
||||
All subsequent files required by node with the extensions `.es6` and `.js` will
|
||||
be transformed by 6to5. The polyfill specified in [Polyfill](polyfill.md) is
|
||||
also required.
|
||||
also required; but this is automatically loaded when using:
|
||||
|
||||
Source maps are automatically configured so if any errors a thrown then line
|
||||
number info is mapped and you'll get the correct source location.
|
||||
|
||||
```javascript
|
||||
require("6to5/register");
|
||||
@@ -160,6 +230,8 @@ require("6to5/register")({
|
||||
});
|
||||
```
|
||||
|
||||
**NOTE:** Using 6to5-node or `require("6to5/register")`, 6to5 will check what features are available in the current environment and blacklists them if they're supported.
|
||||
|
||||
#### Options
|
||||
|
||||
```javascript
|
||||
|
||||
108
lib/6to5/file.js
108
lib/6to5/file.js
@@ -10,30 +10,39 @@ var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function File(opts) {
|
||||
this.opts = File.normaliseOptions(opts);
|
||||
this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||
|
||||
this.declarations = {};
|
||||
this.uids = {};
|
||||
this.ast = {};
|
||||
this.opts = File.normaliseOptions(opts);
|
||||
this.uids = {};
|
||||
this.ast = {};
|
||||
}
|
||||
|
||||
File.declarations = ["extends", "class-props", "slice", "apply-constructor",
|
||||
"tagged-template-literal", "interop-require"];
|
||||
File.declarations = [
|
||||
"inherits",
|
||||
"prototype-properties",
|
||||
"apply-constructor",
|
||||
"tagged-template-literal",
|
||||
"interop-require",
|
||||
"to-array",
|
||||
"object-without-properties",
|
||||
"has-own",
|
||||
"slice"
|
||||
];
|
||||
|
||||
File.normaliseOptions = function (opts) {
|
||||
opts = _.cloneDeep(opts || {});
|
||||
|
||||
_.defaults(opts, {
|
||||
whitespace: true,
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
comments: true,
|
||||
filename: "unknown",
|
||||
modules: "common",
|
||||
runtime: false,
|
||||
code: true
|
||||
experimental: false,
|
||||
playground: false,
|
||||
whitespace: true,
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
sourceMap: false,
|
||||
comments: true,
|
||||
filename: "unknown",
|
||||
modules: "common",
|
||||
runtime: false,
|
||||
code: true,
|
||||
ast: true
|
||||
});
|
||||
|
||||
// normalise windows path separators to unix
|
||||
@@ -63,12 +72,26 @@ File.normaliseOptions = function (opts) {
|
||||
opts.runtime = "to5Runtime";
|
||||
}
|
||||
|
||||
if (opts.playground) {
|
||||
opts.experimental = true;
|
||||
}
|
||||
|
||||
transform._ensureTransformerNames("blacklist", opts.blacklist);
|
||||
transform._ensureTransformerNames("whitelist", opts.whitelist);
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
File.prototype.toArray = function (node) {
|
||||
if (t.isArrayExpression(node)) {
|
||||
return node;
|
||||
} else if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
return t.callExpression(t.memberExpression(this.addDeclaration("slice"), t.identifier("call")), [node]);
|
||||
} else {
|
||||
return t.callExpression(this.addDeclaration("to-array"), [node]);
|
||||
}
|
||||
};
|
||||
|
||||
File.prototype.getModuleFormatter = function (type) {
|
||||
var ModuleFormatter = _.isFunction(type) ? type : transform.moduleFormatters[type];
|
||||
|
||||
@@ -78,7 +101,7 @@ File.prototype.getModuleFormatter = function (type) {
|
||||
}
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
throw new ReferenceError("unknown module formatter type " + type);
|
||||
throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type));
|
||||
}
|
||||
|
||||
return new ModuleFormatter(this);
|
||||
@@ -101,8 +124,10 @@ File.prototype.addDeclaration = function (name) {
|
||||
throw new ReferenceError("unknown declaration " + name);
|
||||
}
|
||||
|
||||
var declar = this.declarations[name];
|
||||
if (declar) return declar.uid;
|
||||
var program = this.ast.program;
|
||||
|
||||
var declar = program._declarations && program._declarations[name];
|
||||
if (declar) return declar.id;
|
||||
|
||||
var ref;
|
||||
var runtimeNamespace = this.opts.runtime;
|
||||
@@ -113,11 +138,12 @@ File.prototype.addDeclaration = function (name) {
|
||||
ref = util.template(name);
|
||||
}
|
||||
|
||||
var uid = t.identifier(this.generateUid(name));
|
||||
this.declarations[name] = {
|
||||
uid: uid,
|
||||
node: ref
|
||||
};
|
||||
var uid = this.generateUidIdentifier(name);
|
||||
this.scope.push({
|
||||
key: name,
|
||||
id: uid,
|
||||
init: ref
|
||||
});
|
||||
return uid;
|
||||
};
|
||||
|
||||
@@ -130,14 +156,16 @@ File.prototype.errorWithNode = function (node, msg, Error) {
|
||||
return err;
|
||||
};
|
||||
|
||||
File.prototype.parse = function (code) {
|
||||
File.prototype.addCode = function (code) {
|
||||
code = (code || "") + "";
|
||||
this.code = code;
|
||||
return this.parseShebang(code);
|
||||
};
|
||||
|
||||
File.prototype.parse = function (code) {
|
||||
var self = this;
|
||||
|
||||
this.code = code;
|
||||
|
||||
code = this.parseShebang(code);
|
||||
code = this.addCode(code);
|
||||
|
||||
return util.parse(this.opts, code, function (tree) {
|
||||
self.transform(tree);
|
||||
@@ -148,6 +176,7 @@ File.prototype.parse = function (code) {
|
||||
File.prototype.transform = function (ast) {
|
||||
this.ast = ast;
|
||||
this.scope = new Scope(ast.program);
|
||||
this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||
|
||||
var self = this;
|
||||
|
||||
@@ -160,15 +189,18 @@ File.prototype.generate = function () {
|
||||
var opts = this.opts;
|
||||
var ast = this.ast;
|
||||
|
||||
if (!opts.code) {
|
||||
return {
|
||||
code: "",
|
||||
map: null,
|
||||
ast: ast
|
||||
};
|
||||
}
|
||||
var result = {
|
||||
code: "",
|
||||
map: null,
|
||||
ast: null
|
||||
};
|
||||
|
||||
var result = generate(ast, opts, this.code);
|
||||
if (opts.ast) result.ast = ast;
|
||||
if (!opts.code) return result;
|
||||
|
||||
var _result = generate(ast, opts, this.code);
|
||||
result.code = _result.code;
|
||||
result.map = _result.map;
|
||||
|
||||
if (this.shebang) {
|
||||
// add back shebang
|
||||
@@ -179,8 +211,6 @@ File.prototype.generate = function () {
|
||||
result.code += "\n" + util.sourceMapToComment(result.map);
|
||||
}
|
||||
|
||||
result.ast = result;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Buffer.prototype.dedent = function () {
|
||||
};
|
||||
|
||||
Buffer.prototype.semicolon = function () {
|
||||
if (this.format.semicolons) this.push(";");
|
||||
this.push(";");
|
||||
};
|
||||
|
||||
Buffer.prototype.ensureSemicolon = function () {
|
||||
@@ -66,9 +66,7 @@ Buffer.prototype.removeLast = function (cha) {
|
||||
};
|
||||
|
||||
Buffer.prototype.newline = function (i, removeLast) {
|
||||
if (!this.buf) return;
|
||||
if (this.format.compact) return;
|
||||
if (this.endsWith("{\n")) return;
|
||||
|
||||
if (_.isBoolean(i)) {
|
||||
removeLast = i;
|
||||
@@ -76,6 +74,7 @@ Buffer.prototype.newline = function (i, removeLast) {
|
||||
}
|
||||
|
||||
if (_.isNumber(i)) {
|
||||
if (this.endsWith("{\n")) i--;
|
||||
if (this.endsWith(util.repeat(i, "\n"))) return;
|
||||
|
||||
var self = this;
|
||||
@@ -88,7 +87,10 @@ Buffer.prototype.newline = function (i, removeLast) {
|
||||
if (removeLast && this.isLast("\n")) this.removeLast("\n");
|
||||
|
||||
this.removeLast(" ");
|
||||
|
||||
// remove whitespace if last character was a newline
|
||||
this.buf = this.buf.replace(/\n +$/, "\n");
|
||||
|
||||
this._push("\n");
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ _.each(Buffer.prototype, function (fn, key) {
|
||||
CodeGenerator.normaliseOptions = function (opts) {
|
||||
return _.merge({
|
||||
parentheses: true,
|
||||
semicolons: true,
|
||||
comments: opts.comments == null || opts.comments,
|
||||
compact: false,
|
||||
indent: {
|
||||
@@ -53,10 +52,12 @@ CodeGenerator.generators = {
|
||||
comprehensions: require("./generators/comprehensions"),
|
||||
expressions: require("./generators/expressions"),
|
||||
statements: require("./generators/statements"),
|
||||
playground: require("./generators/playground"),
|
||||
classes: require("./generators/classes"),
|
||||
methods: require("./generators/methods"),
|
||||
modules: require("./generators/modules"),
|
||||
types: require("./generators/types"),
|
||||
flow: require("./generators/flow"),
|
||||
base: require("./generators/base"),
|
||||
jsx: require("./generators/jsx")
|
||||
};
|
||||
@@ -70,6 +71,12 @@ CodeGenerator.prototype.generate = function () {
|
||||
|
||||
this.print(ast);
|
||||
|
||||
var comments = [];
|
||||
_.each(ast.comments, function (comment) {
|
||||
if (!comment._displayed) comments.push(comment);
|
||||
});
|
||||
this._printComments(comments);
|
||||
|
||||
return {
|
||||
map: this.map.get(),
|
||||
code: this.buffer.get()
|
||||
@@ -131,6 +138,9 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
var needs = n.needsWhitespaceAfter;
|
||||
if (leading) needs = n.needsWhitespaceBefore;
|
||||
lines += needs(node, parent);
|
||||
|
||||
// generated nodes can't add starting file whitespace
|
||||
if (!self.buffer.get()) lines = 0;
|
||||
}
|
||||
|
||||
self.newline(lines);
|
||||
@@ -146,7 +156,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
|
||||
// only compute if this node needs parens if our parent has been changed
|
||||
// since acorn would've wrapped us in a ParanthesizedExpression
|
||||
var needsParens = parent !== node._parent && n.needsParens(node, parent);
|
||||
var needsParens = n.needsParens(node, parent);
|
||||
if (needsParens) this.push("(");
|
||||
|
||||
this[node.type](node, this.buildPrint(node), parent);
|
||||
@@ -160,7 +170,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
|
||||
this.printTrailingComments(node, parent);
|
||||
} else {
|
||||
throw new ReferenceError("unknown node " + node.type + " " + JSON.stringify(node));
|
||||
throw new ReferenceError("unknown node " + node.type);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -258,6 +268,14 @@ CodeGenerator.prototype._printComments = function (comments) {
|
||||
var self = this;
|
||||
|
||||
_.each(comments, function (comment) {
|
||||
// find the original comment in the ast and set it as displayed
|
||||
_.each(self.ast.comments, function (origComment) {
|
||||
if (origComment.start === comment.start) {
|
||||
origComment._displayed = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// whitespace before
|
||||
self.newline(self.whitespace.getNewlinesBefore(comment));
|
||||
|
||||
|
||||
@@ -18,12 +18,6 @@ exports.UnaryExpression = function (node, print) {
|
||||
print(node.argument);
|
||||
};
|
||||
|
||||
exports.ParenthesizedExpression = function (node, print) {
|
||||
this.push("(");
|
||||
print(node.expression);
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
exports.UpdateExpression = function (node, print) {
|
||||
if (node.prefix) {
|
||||
this.push(node.operator);
|
||||
@@ -98,8 +92,11 @@ exports.AssignmentExpression = function (node, print) {
|
||||
print(node.right);
|
||||
};
|
||||
|
||||
var SCIENTIFIC_NOTATION = /e/i;
|
||||
|
||||
exports.MemberExpression = function (node, print) {
|
||||
print(node.object);
|
||||
var obj = node.object;
|
||||
print(obj);
|
||||
|
||||
if (node.computed) {
|
||||
this.push("[");
|
||||
@@ -107,7 +104,7 @@ exports.MemberExpression = function (node, print) {
|
||||
this.push("]");
|
||||
} else {
|
||||
// 5..toFixed(2);
|
||||
if (t.isLiteral(node.object) && util.isInteger(node.object.value)) {
|
||||
if (t.isLiteral(obj) && util.isInteger(obj.value) && !SCIENTIFIC_NOTATION.test(obj.value.toString())) {
|
||||
this.push(".");
|
||||
}
|
||||
|
||||
|
||||
3
lib/6to5/generation/generators/flow.js
Normal file
3
lib/6to5/generation/generators/flow.js
Normal file
@@ -0,0 +1,3 @@
|
||||
exports.ClassProperty = function () {
|
||||
throw new Error("not implemented");
|
||||
};
|
||||
@@ -1,7 +1,14 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ImportSpecifier =
|
||||
exports.ImportSpecifier = function (node, print) {
|
||||
if (node.id && node.id.name === "default") {
|
||||
print(node.name);
|
||||
} else {
|
||||
return exports.ExportSpecifier.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ExportSpecifier = function (node, print) {
|
||||
print(node.id);
|
||||
if (node.name) {
|
||||
@@ -62,7 +69,9 @@ exports.ImportDeclaration = function (node, print) {
|
||||
self.push(", ");
|
||||
}
|
||||
|
||||
if (!spec.default && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) {
|
||||
var isDefault = spec.id && spec.id.name === "default";
|
||||
|
||||
if (!isDefault && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) {
|
||||
foundImportSpecifier = true;
|
||||
self.push("{ ");
|
||||
}
|
||||
|
||||
7
lib/6to5/generation/generators/playground.js
Normal file
7
lib/6to5/generation/generators/playground.js
Normal file
@@ -0,0 +1,7 @@
|
||||
var _ = require("lodash");
|
||||
|
||||
_.each(["BindMemberExpression", "BindFunctionExpression"], function (type) {
|
||||
exports[type] = function () {
|
||||
throw new ReferenceError("Trying to render non-standard playground node " + JSON.stringify(type));
|
||||
};
|
||||
});
|
||||
@@ -164,6 +164,12 @@ exports.VariableDeclaration = function (node, print, parent) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.PrivateDeclaration = function (node, print) {
|
||||
this.push("private ");
|
||||
print.join(node.declarations, { separator: ", " });
|
||||
this.semicolon();
|
||||
};
|
||||
|
||||
exports.VariableDeclarator = function (node, print) {
|
||||
if (node.init) {
|
||||
print(node.id);
|
||||
|
||||
@@ -4,11 +4,18 @@ exports.Identifier = function (node) {
|
||||
this.push(node.name);
|
||||
};
|
||||
|
||||
exports.SpreadElement = function (node, print) {
|
||||
exports.SpreadElement =
|
||||
exports.SpreadProperty = function (node, print) {
|
||||
this.push("...");
|
||||
print(node.argument);
|
||||
};
|
||||
|
||||
exports.VirtualPropertyExpression = function (node, print) {
|
||||
print(node.object);
|
||||
this.push("::");
|
||||
print(node.property);
|
||||
};
|
||||
|
||||
exports.ObjectExpression =
|
||||
exports.ObjectPattern = function (node, print) {
|
||||
var props = node.properties;
|
||||
@@ -77,8 +84,8 @@ exports.Literal = function (node) {
|
||||
if (type === "string") {
|
||||
val = JSON.stringify(val);
|
||||
|
||||
// escape unicode characters
|
||||
val = val.replace(/[\u007f-\uffff]/g, function (c) {
|
||||
// escape illegal js but valid json unicode characters
|
||||
val = val.replace(/[\u000A\u000D\u2028\u2029]/g, function (c) {
|
||||
return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4);
|
||||
});
|
||||
|
||||
|
||||
@@ -24,15 +24,7 @@ function Node(node, parent) {
|
||||
}
|
||||
|
||||
Node.prototype.isUserWhitespacable = function () {
|
||||
var parent = this.parent;
|
||||
var node = this.node;
|
||||
|
||||
if (t.isUserWhitespacable(node) ||
|
||||
t.isSequenceExpression(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return t.isUserWhitespacable(this.node);
|
||||
};
|
||||
|
||||
Node.prototype.needsWhitespace = function (type) {
|
||||
|
||||
@@ -92,13 +92,6 @@ exports.YieldExpression = function (node, parent) {
|
||||
t.isYieldExpression(parent);
|
||||
};
|
||||
|
||||
exports.Literal = function (node, parent) {
|
||||
// (1).valueOf()
|
||||
if (_.isNumber(node.value) && t.isMemberExpression(parent) && parent.object === node) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent) {
|
||||
return t.isExpressionStatement(parent);
|
||||
};
|
||||
|
||||
@@ -9,6 +9,10 @@ exports.before = {
|
||||
}
|
||||
},
|
||||
|
||||
SpreadProperty: function (node, parent) {
|
||||
return exports.before.nodes.Property(node, parent);
|
||||
},
|
||||
|
||||
SwitchCase: function (node, parent) {
|
||||
if (parent.cases[0] === node) {
|
||||
return 1;
|
||||
@@ -24,7 +28,13 @@ exports.before = {
|
||||
};
|
||||
|
||||
exports.after = {
|
||||
nodes: {},
|
||||
nodes: {
|
||||
AssignmentExpression: function (node) {
|
||||
if (t.isFunction(node.right)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
list: {
|
||||
VariableDeclaration: function (node) {
|
||||
|
||||
@@ -38,7 +38,11 @@ Whitespace.prototype.getNewlinesAfter = function (node) {
|
||||
}
|
||||
});
|
||||
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
if (endToken.type.type === "eof") {
|
||||
return 1;
|
||||
} else {
|
||||
return this.getNewlinesBetween(startToken, endToken);
|
||||
}
|
||||
};
|
||||
|
||||
Whitespace.prototype.getNewlinesBetween = function (startToken, endToken) {
|
||||
|
||||
@@ -3,6 +3,10 @@ var util = require("./util");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Transformer = require("./transformation/transformer");
|
||||
|
||||
exports.types = require("./types");
|
||||
|
||||
exports.runtime = require("./runtime");
|
||||
|
||||
exports.register = function (opts) {
|
||||
|
||||
@@ -1,28 +1,47 @@
|
||||
var t = require("./types");
|
||||
var _ = require("lodash");
|
||||
|
||||
// estraverse
|
||||
|
||||
var estraverse = require("estraverse");
|
||||
_.extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
|
||||
|
||||
// regenerator/recast/ast-types
|
||||
|
||||
var types = require("ast-types");
|
||||
var def = types.Type.def;
|
||||
var or = types.Type.or;
|
||||
|
||||
// Program wrapper
|
||||
def("File")
|
||||
.bases("Node")
|
||||
.build("program")
|
||||
.field("program", def("Program"));
|
||||
|
||||
// Non-standard Acorn type
|
||||
def("ParenthesizedExpression")
|
||||
.bases("Expression")
|
||||
.build("expression")
|
||||
.field("expression", def("Expression"));
|
||||
|
||||
// Same as ImportNamespaceSpecifier but `id` is `name`
|
||||
// Acorn - Same as ImportNamespaceSpecifier but `id` is `name`
|
||||
def("ImportBatchSpecifier")
|
||||
.bases("Specifier")
|
||||
.build("name")
|
||||
.field("name", def("Identifier"));
|
||||
|
||||
types.finalize();
|
||||
// Abstract references
|
||||
def("VirtualPropertyExpression")
|
||||
.bases("Expression")
|
||||
.build("object", "property")
|
||||
.field("object", def("Expression"))
|
||||
.field("property", or(def("Identifier"), def("Expression")));
|
||||
|
||||
var estraverse = require("estraverse");
|
||||
_.extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
|
||||
def("PrivateDeclaration")
|
||||
.bases("Declaration")
|
||||
.build("declarations")
|
||||
.field("declarations", [def("Identifier")]);
|
||||
|
||||
// Playground
|
||||
def("BindMemberExpression")
|
||||
.bases("Expression")
|
||||
.build("object", "property", "arguments")
|
||||
.field("object", def("Expression"))
|
||||
.field("property", or(def("Identifier"), def("Expression")))
|
||||
.field("arguments", [def("Expression")]);
|
||||
|
||||
def("BindFunctionExpression")
|
||||
.bases("Expression")
|
||||
.build("callee", "arguments")
|
||||
.field("callee", def("Expression"))
|
||||
.field("arguments", [def("Expression")]);
|
||||
|
||||
types.finalize();
|
||||
|
||||
@@ -1,6 +1,2 @@
|
||||
if (typeof Symbol === "undefined") {
|
||||
require("es6-symbol/implement");
|
||||
}
|
||||
|
||||
require("es6-shim");
|
||||
require("./transformation/transformers/generators/runtime");
|
||||
require("core-js/shim");
|
||||
require("regenerator/runtime");
|
||||
|
||||
@@ -3,6 +3,7 @@ require("./polyfill");
|
||||
var sourceMapSupport = require("source-map-support");
|
||||
var util = require("./util");
|
||||
var to5 = require("./index");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
sourceMapSupport.install({
|
||||
@@ -57,24 +58,44 @@ blacklistTest("unicodeRegex", function () { new RegExp("foo", "u"); });
|
||||
|
||||
//
|
||||
|
||||
var ignoreRegex = /node_modules/;
|
||||
var transformOpts = {};
|
||||
var ignoreRegex = /node_modules/;
|
||||
var onlyRegex;
|
||||
var whitelist = [];
|
||||
var exts = {};
|
||||
var maps = {};
|
||||
var old = require.extensions[".js"];
|
||||
var whitelist = [];
|
||||
var cache;
|
||||
var exts = {};
|
||||
var maps = {};
|
||||
var old = require.extensions[".js"];
|
||||
|
||||
var mtime = function (filename) {
|
||||
return +fs.statSync(filename).mtime;
|
||||
};
|
||||
|
||||
var loader = function (m, filename) {
|
||||
if ((ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename))) {
|
||||
return old.apply(this, arguments);
|
||||
}
|
||||
|
||||
var result = to5.transformFileSync(filename, {
|
||||
var result;
|
||||
|
||||
if (cache) {
|
||||
var cached = cache[filename];
|
||||
if (cached && cached.mtime === mtime(filename)) {
|
||||
result = cached;
|
||||
}
|
||||
}
|
||||
|
||||
result = result || to5.transformFileSync(filename, _.extend({
|
||||
whitelist: whitelist,
|
||||
blacklist: blacklist,
|
||||
sourceMap: true,
|
||||
modules: "commonInterop"
|
||||
});
|
||||
ast: false
|
||||
}, transformOpts));
|
||||
|
||||
if (cache) {
|
||||
result.mtime = mtime(filename);
|
||||
cache[filename] = result;
|
||||
}
|
||||
|
||||
maps[filename] = result.map;
|
||||
|
||||
@@ -107,6 +128,8 @@ module.exports = function (opts) {
|
||||
|
||||
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
|
||||
|
||||
if (opts.blacklist) blacklist = util.arrayify(opts.blacklist);
|
||||
if (opts.whitelist) whitelist = util.arrayify(opts.whitelist);
|
||||
if (opts.cache) cache = opts.cache;
|
||||
if (opts.cache === false) cache = null;
|
||||
|
||||
_.extend(transformOpts, opts);
|
||||
};
|
||||
|
||||
@@ -8,15 +8,13 @@ module.exports = function (namespace) {
|
||||
namespace = t.identifier(t.toIdentifier(namespace || "to5Runtime"));
|
||||
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [], t.blockStatement(body));
|
||||
var tree = t.program([t.expressionStatement(t.callExpression(container, []))]);
|
||||
|
||||
body.push(util.template("self-global", true));
|
||||
var container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
|
||||
var tree = t.program([t.expressionStatement(t.callExpression(container, [util.template("self-global")]))]);
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(
|
||||
namespace,
|
||||
t.assignmentExpression("=", t.memberExpression(t.identifier("self"), namespace), t.objectExpression([]))
|
||||
t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace), t.objectExpression([]))
|
||||
)
|
||||
]));
|
||||
|
||||
|
||||
1
lib/6to5/templates/abstract-expression-call.js
Normal file
1
lib/6to5/templates/abstract-expression-call.js
Normal file
@@ -0,0 +1 @@
|
||||
PROPERTY[Symbol.referenceGet](OBJECT).call(OBJECT)
|
||||
1
lib/6to5/templates/abstract-expression-delete.js
Normal file
1
lib/6to5/templates/abstract-expression-delete.js
Normal file
@@ -0,0 +1 @@
|
||||
PROPERTY[Symbol.referenceDelete](OBJECT)
|
||||
1
lib/6to5/templates/abstract-expression-get.js
Normal file
1
lib/6to5/templates/abstract-expression-get.js
Normal file
@@ -0,0 +1 @@
|
||||
PROPERTY[Symbol.referenceGet](OBJECT)
|
||||
1
lib/6to5/templates/abstract-expression-set.js
Normal file
1
lib/6to5/templates/abstract-expression-set.js
Normal file
@@ -0,0 +1 @@
|
||||
PROPERTY[Symbol.referenceSet](OBJECT, VALUE)
|
||||
@@ -1,5 +1,5 @@
|
||||
(function (Constructor, args) {
|
||||
var bindArgs = [null].concat(args);
|
||||
var Factory = Constructor.bind.apply(Constructor, bindArgs);
|
||||
return new Factory;
|
||||
var instance = Object.create(Constructor.prototype);
|
||||
var result = Constructor.apply(instance, args);
|
||||
return result != null && (typeof result == "object" || typeof result == "function") ? result : instance;
|
||||
});
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
var VARIABLE_NAME = SLICE_KEY.call(arguments, SLICE_ARG);
|
||||
@@ -1 +0,0 @@
|
||||
var VARIABLE_NAME = SLICE_KEY.call(arguments);
|
||||
@@ -1 +0,0 @@
|
||||
SLICE_KEY.call(arguments);
|
||||
@@ -1,2 +1,3 @@
|
||||
SUPER_NAME.apply(this, arguments);
|
||||
|
||||
if (SUPER_NAME) {
|
||||
SUPER_NAME.apply(this, arguments);
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
(function () {
|
||||
var CLASS_NAME = function () {
|
||||
|
||||
};
|
||||
|
||||
return CLASS_NAME;
|
||||
})()
|
||||
@@ -1 +0,0 @@
|
||||
exports.VARIABLE_NAME = OBJECT.KEY;
|
||||
1
lib/6to5/templates/exports-default-module-override.js
Normal file
1
lib/6to5/templates/exports-default-module-override.js
Normal file
@@ -0,0 +1 @@
|
||||
exports = module.exports = VALUE;
|
||||
1
lib/6to5/templates/exports-default-module.js
Normal file
1
lib/6to5/templates/exports-default-module.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = VALUE;
|
||||
@@ -1 +0,0 @@
|
||||
exports.default = VALUE;
|
||||
1
lib/6to5/templates/has-own.js
Normal file
1
lib/6to5/templates/has-own.js
Normal file
@@ -0,0 +1 @@
|
||||
Object.prototype.hasOwnProperty;
|
||||
@@ -1,5 +1,5 @@
|
||||
(function (child, parent) {
|
||||
child.prototype = Object.create(parent.prototype, {
|
||||
child.prototype = Object.create(parent && parent.prototype, {
|
||||
constructor: {
|
||||
value: child,
|
||||
enumerable: false,
|
||||
@@ -7,5 +7,5 @@
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
child.__proto__ = parent;
|
||||
if (parent) child.__proto__ = parent;
|
||||
})
|
||||
9
lib/6to5/templates/object-without-properties.js
Normal file
9
lib/6to5/templates/object-without-properties.js
Normal file
@@ -0,0 +1,9 @@
|
||||
(function (obj, keys) {
|
||||
var target = {};
|
||||
for (var i in obj) {
|
||||
if (keys.indexOf(i) >= 0) continue;
|
||||
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
|
||||
target[i] = obj[i];
|
||||
}
|
||||
return target;
|
||||
})
|
||||
@@ -1 +1 @@
|
||||
var self = typeof global === "undefined" ? window : global;
|
||||
typeof global === "undefined" ? self : global
|
||||
|
||||
6
lib/6to5/templates/system.js
Normal file
6
lib/6to5/templates/system.js
Normal file
@@ -0,0 +1,6 @@
|
||||
System.register(MODULE_NAME, MODULE_DEPENDENCIES, function (EXPORT_IDENTIFIER) {
|
||||
return {
|
||||
setters: SETTERS,
|
||||
execute: EXECUTE
|
||||
};
|
||||
});
|
||||
@@ -1,4 +1,6 @@
|
||||
(function (strings, raw) {
|
||||
return Object.defineProperties(strings, { raw: { value: raw } });
|
||||
return Object.freeze(Object.defineProperties(strings, {
|
||||
raw: { value: Object.freeze(raw) }
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
3
lib/6to5/templates/to-array.js
Normal file
3
lib/6to5/templates/to-array.js
Normal file
@@ -0,0 +1,3 @@
|
||||
(function (arr) {
|
||||
return Array.isArray(arr) ? arr : Array.from(arr);
|
||||
});
|
||||
198
lib/6to5/transformation/modules/_default.js
Normal file
198
lib/6to5/transformation/modules/_default.js
Normal file
@@ -0,0 +1,198 @@
|
||||
module.exports = DefaultFormatter;
|
||||
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function DefaultFormatter(file) {
|
||||
this.file = file;
|
||||
|
||||
this.localExports = this.getLocalExports();
|
||||
this.remapAssignments();
|
||||
}
|
||||
|
||||
DefaultFormatter.prototype.getLocalExports = function () {
|
||||
var localExports = {};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node) {
|
||||
var declar = node && node.declaration;
|
||||
if (t.isExportDeclaration(node) && declar && t.isStatement(declar)) {
|
||||
_.extend(localExports, t.getIds(declar, true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return localExports;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.remapExportAssignment = function (node) {
|
||||
return t.assignmentExpression(
|
||||
"=",
|
||||
node.left,
|
||||
t.assignmentExpression(
|
||||
node.operator,
|
||||
t.memberExpression(t.identifier("exports"), node.left),
|
||||
node.right
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.remapAssignments = function () {
|
||||
var localExports = this.localExports;
|
||||
var self = this;
|
||||
|
||||
var isLocalReference = function (node, scope) {
|
||||
var name = node.name;
|
||||
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.get(name, true);
|
||||
};
|
||||
|
||||
traverse(this.file.ast, {
|
||||
enter: function (node, parent, scope) {
|
||||
if (t.isUpdateExpression(node) && isLocalReference(node.argument, scope)) {
|
||||
this.stop();
|
||||
|
||||
// expand to long file assignment expression
|
||||
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
|
||||
|
||||
// remap this assignment expression
|
||||
var remapped = self.remapExportAssignment(assign);
|
||||
|
||||
// we don't need to change the result
|
||||
if (t.isExpressionStatement(parent) || node.prefix) {
|
||||
return remapped;
|
||||
}
|
||||
|
||||
var nodes = [];
|
||||
nodes.push(remapped);
|
||||
|
||||
var operator;
|
||||
if (node.operator === "--") {
|
||||
operator = "+";
|
||||
} else { // "++"
|
||||
operator = "-";
|
||||
}
|
||||
nodes.push(t.binaryExpression(operator, node.argument, t.literal(1)));
|
||||
|
||||
return t.sequenceExpression(nodes);
|
||||
}
|
||||
|
||||
if (t.isAssignmentExpression(node) && isLocalReference(node.left, scope)) {
|
||||
this.stop();
|
||||
return self.remapExportAssignment(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.getModuleName = function () {
|
||||
var opts = this.file.opts;
|
||||
var filenameRelative = opts.filenameRelative;
|
||||
var moduleName = "";
|
||||
|
||||
if (opts.moduleRoot) {
|
||||
moduleName = opts.moduleRoot + "/";
|
||||
}
|
||||
|
||||
if (!opts.filenameRelative) {
|
||||
return moduleName + opts.filename.replace(/^\//, "");
|
||||
}
|
||||
|
||||
if (opts.sourceRoot) {
|
||||
// remove sourceRoot from filename
|
||||
var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
|
||||
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
||||
}
|
||||
|
||||
// remove extension
|
||||
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
|
||||
|
||||
moduleName += filenameRelative;
|
||||
|
||||
return moduleName;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._pushStatement = function (ref, nodes) {
|
||||
if (t.isClass(ref) || t.isFunction(ref)) {
|
||||
if (ref.id) {
|
||||
nodes.push(t.toStatement(ref));
|
||||
ref = ref.id;
|
||||
}
|
||||
}
|
||||
|
||||
return ref;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._hoistExport = function (declar, assign) {
|
||||
if (t.isFunctionDeclaration(declar)) {
|
||||
assign._blockHoist = true;
|
||||
}
|
||||
|
||||
return assign;
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._exportSpecifier = function (getRef, specifier, node, nodes) {
|
||||
var inherits = false;
|
||||
if (node.specifiers.length === 1) inherits = node;
|
||||
|
||||
if (node.source) {
|
||||
if (t.isExportBatchSpecifier(specifier)) {
|
||||
// export * from "foo";
|
||||
nodes.push(this._exportsWildcard(getRef()));
|
||||
} else {
|
||||
// export { foo } from "test";
|
||||
nodes.push(this._exportsAssign(
|
||||
t.getSpecifierName(specifier),
|
||||
t.memberExpression(getRef(), specifier.id)
|
||||
));
|
||||
}
|
||||
} else {
|
||||
// export { foo };
|
||||
nodes.push(this._exportsAssign(t.getSpecifierName(specifier), specifier.id));
|
||||
}
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._exportsWildcard = function (objectIdentifier) {
|
||||
return util.template("exports-wildcard", {
|
||||
OBJECT: objectIdentifier
|
||||
}, true);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype._exportsAssign = function (id, init) {
|
||||
return util.template("exports-assign", {
|
||||
VALUE: init,
|
||||
KEY: id
|
||||
}, true);
|
||||
};
|
||||
|
||||
DefaultFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
var declar = node.declaration;
|
||||
|
||||
if (node.default) {
|
||||
nodes.push(
|
||||
this._exportsAssign(t.identifier("default"), this._pushStatement(declar, nodes))
|
||||
);
|
||||
} else {
|
||||
var assign;
|
||||
|
||||
if (t.isVariableDeclaration(declar)) {
|
||||
for (var i in declar.declarations) {
|
||||
var decl = declar.declarations[i];
|
||||
|
||||
decl.init = this._exportsAssign(decl.id, decl.init).expression;
|
||||
|
||||
var newDeclar = t.variableDeclaration(declar.kind, [decl]);
|
||||
if (i === "0") t.inherits(newDeclar, declar);
|
||||
nodes.push(newDeclar);
|
||||
}
|
||||
} else {
|
||||
assign = this._exportsAssign(declar.id, declar.id);
|
||||
|
||||
nodes.push(t.toStatement(declar));
|
||||
nodes.push(assign);
|
||||
|
||||
this._hoistExport(declar, assign);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,16 +1,28 @@
|
||||
module.exports = AMDFormatter;
|
||||
|
||||
var CommonJSFormatter = require("./common");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
var DefaultFormatter = require("./_default");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function AMDFormatter(file) {
|
||||
this.file = file;
|
||||
function AMDFormatter() {
|
||||
DefaultFormatter.apply(this, arguments);
|
||||
this.ids = {};
|
||||
}
|
||||
|
||||
util.inherits(AMDFormatter, CommonJSFormatter);
|
||||
util.inherits(AMDFormatter, DefaultFormatter);
|
||||
|
||||
AMDFormatter.prototype.buildDependencyLiterals = function () {
|
||||
var names = [];
|
||||
for (var name in this.ids) {
|
||||
names.push(t.literal(name));
|
||||
}
|
||||
return names;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrap the entire body in a `define` wrapper.
|
||||
*/
|
||||
|
||||
AMDFormatter.prototype.transform = function (ast) {
|
||||
var program = ast.program;
|
||||
@@ -18,10 +30,7 @@ AMDFormatter.prototype.transform = function (ast) {
|
||||
|
||||
// build an array of module names
|
||||
|
||||
var names = [t.literal("exports")];
|
||||
_.each(this.ids, function (id, name) {
|
||||
names.push(t.literal(name));
|
||||
});
|
||||
var names = [t.literal("exports")].concat(this.buildDependencyLiterals());
|
||||
names = t.arrayExpression(names);
|
||||
|
||||
// build up define container
|
||||
@@ -40,35 +49,17 @@ AMDFormatter.prototype.transform = function (ast) {
|
||||
program.body = [t.expressionStatement(call)];
|
||||
};
|
||||
|
||||
AMDFormatter.prototype.getModuleName = function () {
|
||||
var opts = this.file.opts;
|
||||
var filenameRelative = opts.filenameRelative;
|
||||
var moduleName = "";
|
||||
/**
|
||||
* Get the AMD module name that we'll prepend to the wrapper
|
||||
* to define this module
|
||||
*/
|
||||
|
||||
if (!opts.amdModuleIds) {
|
||||
AMDFormatter.prototype.getModuleName = function () {
|
||||
if (this.file.opts.amdModuleIds) {
|
||||
return DefaultFormatter.prototype.getModuleName.apply(this, arguments);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (opts.moduleRoot) {
|
||||
moduleName = opts.moduleRoot + "/";
|
||||
}
|
||||
|
||||
if (!opts.filenameRelative) {
|
||||
return moduleName + opts.filename.replace(/^\//, "");
|
||||
}
|
||||
|
||||
if (opts.sourceRoot) {
|
||||
// remove sourceRoot from filename
|
||||
var sourceRootRegEx = new RegExp("^" + opts.sourceRoot + "\/?");
|
||||
filenameRelative = filenameRelative.replace(sourceRootRegEx, "");
|
||||
}
|
||||
|
||||
// remove extension
|
||||
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
|
||||
|
||||
moduleName += filenameRelative;
|
||||
|
||||
return moduleName;
|
||||
};
|
||||
|
||||
AMDFormatter.prototype._push = function (node) {
|
||||
@@ -82,27 +73,22 @@ AMDFormatter.prototype._push = function (node) {
|
||||
}
|
||||
};
|
||||
|
||||
AMDFormatter.prototype.import = function (node) {
|
||||
AMDFormatter.prototype.importDeclaration = function (node) {
|
||||
this._push(node);
|
||||
};
|
||||
|
||||
AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
var key = t.getSpecifierName(specifier);
|
||||
var id = specifier.id;
|
||||
|
||||
// import foo from "foo";
|
||||
if (specifier.default) {
|
||||
id = t.identifier("default");
|
||||
}
|
||||
|
||||
var ref;
|
||||
var ref = this._push(node);
|
||||
|
||||
if (t.isImportBatchSpecifier(specifier)) {
|
||||
// import * as bar from "foo";
|
||||
ref = this._push(node);
|
||||
} else {
|
||||
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
|
||||
// import foo from "foo";
|
||||
ref = t.memberExpression(this._push(node), id, false);
|
||||
ref = t.callExpression(this.file.addDeclaration("interop-require"), [ref]);
|
||||
} else {
|
||||
// import {foo} from "foo";
|
||||
ref = t.memberExpression(ref, specifier.id, false);
|
||||
}
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
module.exports = CommonJSInteropFormatter;
|
||||
|
||||
var CommonJSFormatter = require("./common");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
function CommonJSInteropFormatter(file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
util.inherits(CommonJSInteropFormatter, CommonJSFormatter);
|
||||
|
||||
CommonJSInteropFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
var variableName = t.getSpecifierName(specifier);
|
||||
|
||||
// import foo from "foo";
|
||||
if (specifier.default) {
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(variableName,
|
||||
t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", {
|
||||
MODULE_NAME: node.source.raw
|
||||
})])
|
||||
)
|
||||
]));
|
||||
} else {
|
||||
CommonJSFormatter.prototype.importSpecifier.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
@@ -1,132 +1,82 @@
|
||||
module.exports = CommonJSFormatter;
|
||||
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var DefaultFormatter = require("./_default");
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
function CommonJSFormatter(file) {
|
||||
this.file = file;
|
||||
DefaultFormatter.apply(this, arguments);
|
||||
|
||||
var hasNonDefaultExports = false;
|
||||
traverse(file.ast, {
|
||||
enter: function (node) {
|
||||
if (t.isExportDeclaration(node) && !node.default) hasNonDefaultExports = true;
|
||||
}
|
||||
});
|
||||
this.hasNonDefaultExports = hasNonDefaultExports;
|
||||
}
|
||||
|
||||
CommonJSFormatter.prototype.import = function (node, nodes) {
|
||||
// import "foo";
|
||||
nodes.push(util.template("require", {
|
||||
//inherits: node,
|
||||
|
||||
MODULE_NAME: node.source.raw
|
||||
}, true));
|
||||
};
|
||||
util.inherits(CommonJSFormatter, DefaultFormatter);
|
||||
|
||||
CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
var variableName = t.getSpecifierName(specifier);
|
||||
|
||||
// import foo from "foo";
|
||||
if (specifier.default) {
|
||||
specifier.id = t.identifier("default");
|
||||
if (t.isSpecifierDefault(specifier)) {
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(variableName,
|
||||
t.callExpression(this.file.addDeclaration("interop-require"), [util.template("require", {
|
||||
MODULE_NAME: node.source
|
||||
})])
|
||||
)
|
||||
]));
|
||||
} else {
|
||||
// import foo from "foo";
|
||||
|
||||
var templateName = "require-assign";
|
||||
|
||||
// import * as bar from "foo";
|
||||
if (specifier.type !== "ImportBatchSpecifier") templateName += "-key";
|
||||
|
||||
nodes.push(util.template(templateName, {
|
||||
VARIABLE_NAME: variableName,
|
||||
MODULE_NAME: node.source,
|
||||
KEY: specifier.id
|
||||
}));
|
||||
}
|
||||
|
||||
var templateName = "require-assign";
|
||||
|
||||
// import * as bar from "foo";
|
||||
if (specifier.type !== "ImportBatchSpecifier") templateName += "-key";
|
||||
|
||||
nodes.push(util.template(templateName, {
|
||||
//inherits: node.specifiers.length === 1 && node,
|
||||
|
||||
VARIABLE_NAME: variableName,
|
||||
MODULE_NAME: node.source.raw,
|
||||
KEY: specifier.id
|
||||
}));
|
||||
};
|
||||
|
||||
CommonJSFormatter.prototype.export = function (node, nodes) {
|
||||
var declar = node.declaration;
|
||||
CommonJSFormatter.prototype.importDeclaration = function (node, nodes) {
|
||||
// import "foo";
|
||||
nodes.push(util.template("require", {
|
||||
MODULE_NAME: node.source
|
||||
}, true));
|
||||
};
|
||||
|
||||
CommonJSFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
if (node.default) {
|
||||
var ref = declar;
|
||||
var declar = node.declaration;
|
||||
|
||||
if (t.isClass(ref) || t.isFunction(ref)) {
|
||||
if (ref.id) {
|
||||
nodes.push(t.toStatement(ref));
|
||||
ref = ref.id;
|
||||
}
|
||||
}
|
||||
// module.exports = VALUE;
|
||||
var templateName = "exports-default-module";
|
||||
|
||||
nodes.push(util.template("exports-default", {
|
||||
//inherits: node,
|
||||
// exports = module.exports = VALUE;
|
||||
if (this.hasNonDefaultExports) templateName = "exports-default-module-override";
|
||||
|
||||
VALUE: ref
|
||||
}, true));
|
||||
var assign = util.template(templateName, {
|
||||
VALUE: this._pushStatement(declar, nodes)
|
||||
}, true);
|
||||
|
||||
// hoist to the top if this default is a function
|
||||
nodes.push(this._hoistExport(declar, assign));
|
||||
} else {
|
||||
var assign;
|
||||
|
||||
if (t.isVariableDeclaration(declar)) {
|
||||
var decl = declar.declarations[0];
|
||||
|
||||
if (decl.init) {
|
||||
decl.init = util.template("exports-assign", {
|
||||
//inherits: node,
|
||||
|
||||
VALUE: decl.init,
|
||||
KEY: decl.id
|
||||
});
|
||||
}
|
||||
|
||||
nodes.push(declar);
|
||||
} else {
|
||||
assign = util.template("exports-assign", {
|
||||
//inherits: node,
|
||||
|
||||
VALUE: declar.id,
|
||||
KEY: declar.id
|
||||
}, true);
|
||||
|
||||
nodes.push(t.toStatement(declar));
|
||||
nodes.push(assign);
|
||||
|
||||
if (t.isFunctionDeclaration(declar)) {
|
||||
assign._blockHoist = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CommonJSFormatter.prototype._exportSpecifier = function (getRef, specifier, node, nodes) {
|
||||
var variableName = t.getSpecifierName(specifier);
|
||||
|
||||
var inherits = false;
|
||||
if (node.specifiers.length === 1) inherits = node;
|
||||
|
||||
if (node.source) {
|
||||
if (t.isExportBatchSpecifier(specifier)) {
|
||||
// export * from "foo";
|
||||
nodes.push(util.template("exports-wildcard", {
|
||||
//inherits: inherits,
|
||||
|
||||
OBJECT: getRef()
|
||||
}, true));
|
||||
} else {
|
||||
// export { foo } from "test";
|
||||
nodes.push(util.template("exports-assign-key", {
|
||||
//inherits: inherits,
|
||||
|
||||
VARIABLE_NAME: variableName.name,
|
||||
OBJECT: getRef(),
|
||||
KEY: specifier.id
|
||||
}, true));
|
||||
}
|
||||
} else {
|
||||
// export { foo };
|
||||
nodes.push(util.template("exports-assign", {
|
||||
//inherits: inherits,
|
||||
|
||||
VALUE: specifier.id,
|
||||
KEY: variableName
|
||||
}, true));
|
||||
DefaultFormatter.prototype.exportDeclaration.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
CommonJSFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
|
||||
return this._exportSpecifier(function () {
|
||||
this._exportSpecifier(function () {
|
||||
return t.callExpression(t.identifier("require"), [node.source]);
|
||||
}, specifier, node, nodes);
|
||||
};
|
||||
|
||||
@@ -6,19 +6,13 @@ function IgnoreFormatter() {
|
||||
|
||||
}
|
||||
|
||||
IgnoreFormatter.prototype.import = function () {
|
||||
|
||||
};
|
||||
|
||||
IgnoreFormatter.prototype.importSpecifier = function () {
|
||||
|
||||
};
|
||||
|
||||
IgnoreFormatter.prototype.export = function (node, nodes) {
|
||||
IgnoreFormatter.prototype.exportDeclaration = function (node, nodes) {
|
||||
var declar = t.toStatement(node.declaration, true);
|
||||
if (declar) nodes.push(t.inherits(declar, node));
|
||||
};
|
||||
|
||||
IgnoreFormatter.prototype.importDeclaration =
|
||||
IgnoreFormatter.prototype.importSpecifier =
|
||||
IgnoreFormatter.prototype.exportSpecifier = function () {
|
||||
|
||||
};
|
||||
|
||||
85
lib/6to5/transformation/modules/system.js
Normal file
85
lib/6to5/transformation/modules/system.js
Normal file
@@ -0,0 +1,85 @@
|
||||
module.exports = SystemFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
var AMDFormatter = require("./amd");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function SystemFormatter(file) {
|
||||
this.exportIdentifier = file.generateUidIdentifier("export");
|
||||
this.noInteropRequire = true;
|
||||
|
||||
AMDFormatter.apply(this, arguments);
|
||||
|
||||
this.moduleNameLiteral = t.literal(this.getModuleName());
|
||||
}
|
||||
|
||||
util.inherits(SystemFormatter, AMDFormatter);
|
||||
|
||||
SystemFormatter.prototype.getModuleName = DefaultFormatter.prototype.getModuleName;
|
||||
|
||||
SystemFormatter.prototype._exportsWildcard = function (objectIdentifier) {
|
||||
var leftIdentifier = t.identifier("i");
|
||||
var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true);
|
||||
|
||||
var left = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(leftIdentifier)
|
||||
]);
|
||||
|
||||
var right = objectIdentifier;
|
||||
|
||||
var block = t.blockStatement([
|
||||
this.buildExportCall(leftIdentifier, valIdentifier)
|
||||
]);
|
||||
|
||||
return t.forInStatement(left, right, block);
|
||||
};
|
||||
|
||||
SystemFormatter.prototype._exportsAssign = function (id, init) {
|
||||
return this.buildExportCall(t.literal(id.name), init, true);
|
||||
};
|
||||
|
||||
SystemFormatter.prototype.remapExportAssignment = function (node) {
|
||||
return this.buildExportCall(t.literal(node.left.name), node);
|
||||
};
|
||||
|
||||
SystemFormatter.prototype.buildExportCall = function (id, init, isStatement) {
|
||||
var call = t.callExpression(this.exportIdentifier, [id, init]);
|
||||
if (isStatement) {
|
||||
return t.expressionStatement(call);
|
||||
} else {
|
||||
return call;
|
||||
}
|
||||
};
|
||||
|
||||
SystemFormatter.prototype.buildRunnerSetters = function () {
|
||||
return t.arrayExpression(_.map(this.ids, function (uid) {
|
||||
var moduleIdentifier = t.identifier("m");
|
||||
|
||||
return t.functionExpression(null, [moduleIdentifier], t.blockStatement([
|
||||
t.assignmentExpression("=", uid, moduleIdentifier)
|
||||
]));
|
||||
}));
|
||||
};
|
||||
|
||||
SystemFormatter.prototype.transform = function (ast) {
|
||||
var program = ast.program;
|
||||
|
||||
var runner = util.template("system", {
|
||||
MODULE_NAME: this.moduleNameLiteral,
|
||||
MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()),
|
||||
EXPORT_IDENTIFIER: this.exportIdentifier,
|
||||
SETTERS: this.buildRunnerSetters(),
|
||||
EXECUTE: t.functionExpression(null, [], t.blockStatement(program.body))
|
||||
}, true);
|
||||
|
||||
if (!_.isEmpty(this.ids)) {
|
||||
var handlerBody = runner.expression.arguments[2].body.body;
|
||||
handlerBody.unshift(t.variableDeclaration("var", _.map(this.ids, function (uid) {
|
||||
return t.variableDeclarator(uid);
|
||||
})));
|
||||
}
|
||||
|
||||
program.body = [runner];
|
||||
};
|
||||
@@ -18,9 +18,9 @@ UMDFormatter.prototype.transform = function (ast) {
|
||||
// build an array of module names
|
||||
|
||||
var names = [];
|
||||
_.each(this.ids, function (id, name) {
|
||||
for (var name in this.ids) {
|
||||
names.push(t.literal(name));
|
||||
});
|
||||
}
|
||||
|
||||
// factory
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ module.exports = transform;
|
||||
|
||||
var Transformer = require("./transformer");
|
||||
var File = require("../file");
|
||||
var util = require("../util");
|
||||
var _ = require("lodash");
|
||||
|
||||
function transform(code, opts) {
|
||||
@@ -9,58 +10,84 @@ function transform(code, opts) {
|
||||
return file.parse(code);
|
||||
}
|
||||
|
||||
transform.fromAst = function (ast, code, opts) {
|
||||
ast = util.normaliseAst(ast);
|
||||
|
||||
var file = new File(opts);
|
||||
file.addCode(code);
|
||||
file.transform(ast);
|
||||
return file.generate();
|
||||
};
|
||||
|
||||
transform._ensureTransformerNames = function (type, keys) {
|
||||
_.each(keys, function (key) {
|
||||
for (var i in keys) {
|
||||
var key = keys[i];
|
||||
if (!_.has(transform.transformers, key)) {
|
||||
throw new ReferenceError("unknown transformer " + key + " specified in " + type);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
transform.transformers = {};
|
||||
|
||||
transform.moduleFormatters = {
|
||||
common: require("./modules/common"),
|
||||
commonInterop: require("./modules/common-interop"),
|
||||
ignore: require("./modules/ignore"),
|
||||
amd: require("./modules/amd"),
|
||||
umd: require("./modules/umd")
|
||||
common: require("./modules/common"),
|
||||
system: require("./modules/system"),
|
||||
ignore: require("./modules/ignore"),
|
||||
amd: require("./modules/amd"),
|
||||
umd: require("./modules/umd")
|
||||
};
|
||||
|
||||
_.each({
|
||||
modules: require("./transformers/modules"),
|
||||
propertyNameShorthand: require("./transformers/property-name-shorthand"),
|
||||
arrayComprehension: require("./transformers/array-comprehension"),
|
||||
generatorComprehension: require("./transformers/generator-comprehension"),
|
||||
arrowFunctions: require("./transformers/arrow-functions"),
|
||||
classes: require("./transformers/classes"),
|
||||
// spec
|
||||
specBlockHoistFunctions: require("./transformers/spec-block-hoist-functions"),
|
||||
specNoForInOfAssignment: require("./transformers/spec-no-for-in-of-assignment"),
|
||||
specNoDuplicateProperties: require("./transformers/spec-no-duplicate-properties"),
|
||||
|
||||
_propertyLiterals: require("./transformers/_property-literals"),
|
||||
computedPropertyNames: require("./transformers/computed-property-names"),
|
||||
// playground
|
||||
methodBinding: require("./transformers/playground-method-binding"),
|
||||
memoizationOperator: require("./transformers/playground-memoization-operator"),
|
||||
objectGetterMemoization: require("./transformers/playground-object-getter-memoization"),
|
||||
|
||||
spread: require("./transformers/spread"),
|
||||
templateLiterals: require("./transformers/template-literals"),
|
||||
propertyMethodAssignment: require("./transformers/property-method-assignment"),
|
||||
defaultParameters: require("./transformers/default-parameters"),
|
||||
restParameters: require("./transformers/rest-parameters"),
|
||||
destructuring: require("./transformers/destructuring"),
|
||||
forOf: require("./transformers/for-of"),
|
||||
unicodeRegex: require("./transformers/unicode-regex"),
|
||||
react: require("./transformers/react"),
|
||||
modules: require("./transformers/es6-modules"),
|
||||
propertyNameShorthand: require("./transformers/es6-property-name-shorthand"),
|
||||
arrayComprehension: require("./transformers/es7-array-comprehension"),
|
||||
generatorComprehension: require("./transformers/es7-generator-comprehension"),
|
||||
arrowFunctions: require("./transformers/es6-arrow-functions"),
|
||||
classes: require("./transformers/es6-classes"),
|
||||
|
||||
constants: require("./transformers/constants"),
|
||||
letScoping: require("./transformers/let-scoping"),
|
||||
computedPropertyNames: require("./transformers/es6-computed-property-names"),
|
||||
|
||||
generators: require("./transformers/generators"),
|
||||
objectSpread: require("./transformers/es7-object-spread"),
|
||||
exponentiationOperator: require("./transformers/es7-exponentiation-operator"),
|
||||
spread: require("./transformers/es6-spread"),
|
||||
templateLiterals: require("./transformers/es6-template-literals"),
|
||||
propertyMethodAssignment: require("./transformers/es5-property-method-assignment"),
|
||||
destructuring: require("./transformers/es6-destructuring"),
|
||||
defaultParameters: require("./transformers/es6-default-parameters"),
|
||||
forOf: require("./transformers/es6-for-of"),
|
||||
unicodeRegex: require("./transformers/es6-unicode-regex"),
|
||||
abstractReferences: require("./transformers/es7-abstract-references"),
|
||||
|
||||
constants: require("./transformers/es6-constants"),
|
||||
letScoping: require("./transformers/es6-let-scoping"),
|
||||
|
||||
_blockHoist: require("./transformers/_block-hoist"),
|
||||
|
||||
generators: require("./transformers/es6-generators"),
|
||||
restParameters: require("./transformers/es6-rest-parameters"),
|
||||
|
||||
_declarations: require("./transformers/_declarations"),
|
||||
|
||||
// wrap up
|
||||
_aliasFunctions: require("./transformers/_alias-functions"),
|
||||
|
||||
useStrict: require("./transformers/use-strict"),
|
||||
_moduleFormatter: require("./transformers/_module-formatter"),
|
||||
|
||||
_memberExpressionKeywords: require("./transformers/_member-expression-keywords"),
|
||||
_moduleFormatter: require("./transformers/_module-formatter")
|
||||
// spec
|
||||
specPropertyLiterals: require("./transformers/spec-property-literals"),
|
||||
specMemberExpressionLiterals: require("./transformers/spec-member-expression-literals")
|
||||
}, function (transformer, key) {
|
||||
transform.transformers[key] = new Transformer(key, transformer);
|
||||
});
|
||||
|
||||
@@ -4,8 +4,9 @@ var traverse = require("../traverse");
|
||||
var t = require("../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
function Transformer(key, transformer) {
|
||||
function Transformer(key, transformer, opts) {
|
||||
this.transformer = Transformer.normalise(transformer);
|
||||
this.opts = opts || {};
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@@ -18,37 +19,38 @@ Transformer.normalise = function (transformer) {
|
||||
if (type[0] === "_") return;
|
||||
if (_.isFunction(fns)) fns = { enter: fns };
|
||||
transformer[type] = fns;
|
||||
|
||||
var aliases = t.FLIPPED_ALIAS_KEYS[type];
|
||||
if (aliases) {
|
||||
_.each(aliases, function (alias) {
|
||||
transformer[alias] = fns;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return transformer;
|
||||
};
|
||||
|
||||
Transformer.prototype.astRun = function (file, key) {
|
||||
var transformer = this.transformer;
|
||||
var ast = file.ast;
|
||||
|
||||
if (transformer.ast && transformer.ast[key]) {
|
||||
transformer.ast[key](ast, file);
|
||||
}
|
||||
};
|
||||
|
||||
Transformer.prototype.transform = function (file) {
|
||||
if (!this.canRun(file)) return;
|
||||
|
||||
var transformer = this.transformer;
|
||||
var ast = file.ast;
|
||||
|
||||
var astRun = function (key) {
|
||||
if (transformer.ast && transformer.ast[key]) {
|
||||
transformer.ast[key](ast, file);
|
||||
}
|
||||
};
|
||||
|
||||
astRun("enter");
|
||||
this.astRun(file, "enter");
|
||||
|
||||
var build = function (exit) {
|
||||
return function (node, parent, scope) {
|
||||
// add any node type aliases that exist
|
||||
var types = [node.type].concat(t.ALIAS_KEYS[node.type] || []);
|
||||
|
||||
var fns = transformer.all;
|
||||
|
||||
_.each(types, function (type) {
|
||||
fns = transformer[type] || fns;
|
||||
});
|
||||
|
||||
// this transformer cannot deal with this node type
|
||||
var fns = transformer[node.type];
|
||||
if (!fns) return;
|
||||
|
||||
var fn = fns.enter;
|
||||
@@ -64,7 +66,7 @@ Transformer.prototype.transform = function (file) {
|
||||
exit: build(true)
|
||||
});
|
||||
|
||||
astRun("exit");
|
||||
this.astRun(file, "exit");
|
||||
};
|
||||
|
||||
Transformer.prototype.canRun = function (file) {
|
||||
|
||||
@@ -15,38 +15,42 @@ var go = function (getBody, node, file, scope) {
|
||||
|
||||
// traverse the function and find all alias functions so we can alias
|
||||
// `arguments` and `this` if necessary
|
||||
traverse(node, function (node) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return false;
|
||||
} else {
|
||||
return;
|
||||
traverse(node, {
|
||||
enter: function (node) {
|
||||
if (!node._aliasFunction) {
|
||||
if (t.isFunction(node)) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return false;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return false;
|
||||
|
||||
var getId;
|
||||
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
getId = getArgumentsId;
|
||||
} else if (t.isThisExpression(node)) {
|
||||
getId = getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
traverse(node, function (node, parent) {
|
||||
if (t.isFunction(node) && !node._aliasFunction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node._ignoreAliasFunctions) return;
|
||||
|
||||
var getId;
|
||||
|
||||
if (t.isIdentifier(node) && node.name === "arguments") {
|
||||
getId = getArgumentsId;
|
||||
} else if (t.isThisExpression(node)) {
|
||||
getId = getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.isReferenced(node, parent)) return getId();
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
var body;
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (ast, file) {
|
||||
var body = ast.program.body;
|
||||
exports.BlockStatement =
|
||||
exports.Program = function (node) {
|
||||
var kinds = {};
|
||||
var kind;
|
||||
|
||||
for (var i in file.declarations) {
|
||||
var declar = file.declarations[i];
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(declar.uid, declar.node)
|
||||
]));
|
||||
for (var i in node._declarations) {
|
||||
var declar = node._declarations[i];
|
||||
|
||||
kind = declar.kind || "var";
|
||||
var declarNode = t.variableDeclarator(declar.id, declar.init);
|
||||
|
||||
if (!declar.init) {
|
||||
kinds[kind] = kinds[kind] || [];
|
||||
kinds[kind].push(declarNode);
|
||||
} else {
|
||||
node.body.unshift(t.variableDeclaration(kind, [declarNode]));
|
||||
}
|
||||
}
|
||||
|
||||
for (kind in kinds) {
|
||||
node.body.unshift(t.variableDeclaration(kind, kinds[kind]));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
var esutils = require("esutils");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.MemberExpression = function (node) {
|
||||
var prop = node.property;
|
||||
if (t.isIdentifier(prop) && esutils.keyword.isKeywordES6(prop.name, true)) {
|
||||
node.property = t.literal(prop.name);
|
||||
node.computed = true;
|
||||
}
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
var esutils = require("esutils");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Property = function (node) {
|
||||
// ignore key literals that are valid identifiers
|
||||
var key = node.key;
|
||||
if (t.isLiteral(key) && _.isString(key.value) && esutils.keyword.isIdentifierName(key.value)) {
|
||||
key.type = "Identifier";
|
||||
key.name = key.value;
|
||||
delete key.value;
|
||||
|
||||
node.computed = false;
|
||||
}
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Program =
|
||||
exports.BlockStatement =
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement =
|
||||
exports.ForStatement = function (node, parent, file) {
|
||||
var constants = {};
|
||||
|
||||
var check = function (parent, names) {
|
||||
_.each(names, function (nameNode, name) {
|
||||
if (!_.has(constants, name)) return;
|
||||
if (parent && t.isBlockStatement(parent) && parent !== constants[name]) return;
|
||||
|
||||
throw file.errorWithNode(nameNode, name + " is read-only");
|
||||
});
|
||||
};
|
||||
|
||||
var getIds = function (node) {
|
||||
return t.getIds(node, true, ["MemberExpression"]);
|
||||
};
|
||||
|
||||
_.each(node.body, function (child, parent) {
|
||||
if (child && t.isVariableDeclaration(child, { kind: "const" })) {
|
||||
_.each(child.declarations, function (declar) {
|
||||
_.each(getIds(declar), function (nameNode, name) {
|
||||
var names = {};
|
||||
names[name] = nameNode;
|
||||
check(parent, names);
|
||||
|
||||
constants[name] = parent;
|
||||
});
|
||||
|
||||
declar._ignoreConstant = true;
|
||||
});
|
||||
|
||||
child._ignoreConstant = true;
|
||||
child.kind = "let";
|
||||
}
|
||||
});
|
||||
|
||||
if (_.isEmpty(constants)) return;
|
||||
|
||||
traverse(node, function (child, parent) {
|
||||
if (child._ignoreConstant) return;
|
||||
if (t.isVariableDeclaration(child)) return;
|
||||
|
||||
if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) {
|
||||
check(parent, getIds(child));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
var util = require("../../util");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Property = function (node) {
|
||||
if (node.method) node.method = false;
|
||||
@@ -7,9 +6,11 @@ exports.Property = function (node) {
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var mutatorMap = {};
|
||||
var hasAny = false;
|
||||
|
||||
node.properties = node.properties.filter(function (prop) {
|
||||
if (prop.kind === "get" || prop.kind === "set") {
|
||||
hasAny = true;
|
||||
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value);
|
||||
return false;
|
||||
} else {
|
||||
@@ -17,7 +18,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
}
|
||||
});
|
||||
|
||||
if (_.isEmpty(mutatorMap)) return;
|
||||
if (!hasAny) return;
|
||||
|
||||
var objId = util.getUid(parent, file);
|
||||
|
||||
@@ -3,7 +3,7 @@ var t = require("../../types");
|
||||
exports.ArrowFunctionExpression = function (node) {
|
||||
t.ensureBlock(node);
|
||||
|
||||
node._aliasFunction = true;
|
||||
node._aliasFunction = "arrow";
|
||||
node.expression = false;
|
||||
node.type = "FunctionExpression";
|
||||
|
||||
@@ -1,23 +1,38 @@
|
||||
var traverse = require("../../traverse");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, file, scope) {
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(node.id, new Class(node, file, scope).run())
|
||||
]);
|
||||
var closure = true;
|
||||
if (t.isProgram(parent) || t.isBlockStatement(parent)) {
|
||||
closure = false;
|
||||
}
|
||||
|
||||
var factory = new Class(node, file, scope, closure);
|
||||
var newNode = factory.run();
|
||||
if (factory.closure) {
|
||||
if (closure) {
|
||||
// declaration in an expression context...
|
||||
// export default class Foo {}
|
||||
scope.push({
|
||||
kind: "var",
|
||||
key: node.id.key,
|
||||
id: node.id
|
||||
});
|
||||
return t.assignmentExpression("=", node.id, newNode);
|
||||
} else {
|
||||
// likely has a PrivateDeclaration etc
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(node.id, newNode)
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
return newNode;
|
||||
}
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, file, scope) {
|
||||
return new Class(node, file, scope).run();
|
||||
};
|
||||
|
||||
var getMemberExpressionObject = function (node) {
|
||||
while (t.isMemberExpression(node)) {
|
||||
node = node.object;
|
||||
}
|
||||
return node;
|
||||
return new Class(node, file, scope, true).run();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -26,12 +41,17 @@ var getMemberExpressionObject = function (node) {
|
||||
* @param {Node} node
|
||||
* @param {File} file
|
||||
* @param {Scope} scope
|
||||
* @param {Boolean} closure
|
||||
*/
|
||||
|
||||
function Class(node, file, scope) {
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
this.file = file;
|
||||
function Class(node, file, scope, closure) {
|
||||
this.closure = closure;
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
this.file = file;
|
||||
|
||||
this.hasInstanceMutators = false;
|
||||
this.hasStaticMutators = false;
|
||||
|
||||
this.instanceMutatorMap = {};
|
||||
this.staticMutatorMap = {};
|
||||
@@ -47,50 +67,61 @@ function Class(node, file, scope) {
|
||||
*/
|
||||
|
||||
Class.prototype.run = function () {
|
||||
var superClassArgument = this.superName;
|
||||
var superClassCallee = this.superName;
|
||||
var superName = this.superName;
|
||||
var className = this.className;
|
||||
var file = this.file;
|
||||
var superName = this.superName;
|
||||
var className = this.className;
|
||||
var file = this.file;
|
||||
|
||||
if (superName) {
|
||||
if (t.isMemberExpression(superName)) {
|
||||
superClassArgument = superClassCallee = getMemberExpressionObject(superName);
|
||||
} else if (!t.isIdentifier(superName)) {
|
||||
superClassArgument = superName;
|
||||
superClassCallee = superName = file.generateUidIdentifier("ref", this.scope);
|
||||
}
|
||||
//
|
||||
|
||||
var body = this.body = [];
|
||||
|
||||
var constructor = t.functionExpression(null, [], t.blockStatement([]));
|
||||
if (this.node.id) constructor.id = className;
|
||||
this.constructor = constructor;
|
||||
|
||||
body.push(t.variableDeclaration("let", [
|
||||
t.variableDeclarator(className, constructor)
|
||||
]));
|
||||
|
||||
//
|
||||
|
||||
if (superName && t.isDynamic(superName)) {
|
||||
// so we're only evaluating it once
|
||||
var superRefName = "super";
|
||||
if (className) superRefName = className.name + "Super";
|
||||
|
||||
var superRef = file.generateUidIdentifier(superRefName, this.scope);
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(superRef, superName)
|
||||
]));
|
||||
superName = superRef;
|
||||
}
|
||||
|
||||
this.superName = superName;
|
||||
|
||||
var container = util.template("class", {
|
||||
CLASS_NAME: className
|
||||
});
|
||||
|
||||
var block = container.callee.expression.body;
|
||||
var body = this.body = block.body;
|
||||
var constructor = this.constructor = body[0].declarations[0].init;
|
||||
|
||||
if (this.node.id) constructor.id = className;
|
||||
|
||||
var returnStatement = body.pop();
|
||||
//
|
||||
|
||||
if (superName) {
|
||||
body.push(t.expressionStatement(t.callExpression(file.addDeclaration("extends"), [className, superName])));
|
||||
|
||||
container.arguments.push(superClassArgument);
|
||||
container.callee.expression.params.push(superClassCallee);
|
||||
body.push(t.expressionStatement(t.callExpression(file.addDeclaration("inherits"), [className, superName])));
|
||||
}
|
||||
|
||||
this.buildBody();
|
||||
|
||||
if (body.length === 1) {
|
||||
// only a constructor so no need for a closure container
|
||||
return constructor;
|
||||
t.inheritsComments(body[0], this.node);
|
||||
|
||||
if (this.closure) {
|
||||
if (body.length === 1) {
|
||||
// only a constructor so no need for a closure container
|
||||
return constructor;
|
||||
} else {
|
||||
body.push(t.returnStatement(className));
|
||||
return t.callExpression(
|
||||
t.functionExpression(null, [], t.blockStatement(body)),
|
||||
[]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
body.push(returnStatement);
|
||||
return container;
|
||||
return body;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -106,15 +137,21 @@ Class.prototype.buildBody = function () {
|
||||
var body = this.body;
|
||||
var self = this;
|
||||
|
||||
_.each(classBody, function (node) {
|
||||
self.replaceInstanceSuperReferences(node);
|
||||
for (var i in classBody) {
|
||||
var node = classBody[i];
|
||||
if (t.isMethodDefinition(node)) {
|
||||
self.replaceInstanceSuperReferences(node);
|
||||
|
||||
if (node.key.name === "constructor") {
|
||||
self.pushConstructor(node);
|
||||
} else {
|
||||
self.pushMethod(node);
|
||||
if (node.key.name === "constructor") {
|
||||
self.pushConstructor(node);
|
||||
} else {
|
||||
self.pushMethod(node);
|
||||
}
|
||||
} else if (t.isPrivateDeclaration(node)) {
|
||||
self.closure = true;
|
||||
body.unshift(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.hasConstructor && superName) {
|
||||
constructor.body.body.push(util.template("class-super-constructor-call", {
|
||||
@@ -125,7 +162,7 @@ Class.prototype.buildBody = function () {
|
||||
var instanceProps;
|
||||
var staticProps;
|
||||
|
||||
if (!_.isEmpty(this.instanceMutatorMap)) {
|
||||
if (this.hasInstanceMutators) {
|
||||
var protoId = util.template("prototype-identifier", {
|
||||
CLASS_NAME: className
|
||||
});
|
||||
@@ -133,7 +170,7 @@ Class.prototype.buildBody = function () {
|
||||
instanceProps = util.buildDefineProperties(this.instanceMutatorMap, protoId);
|
||||
}
|
||||
|
||||
if (!_.isEmpty(this.staticMutatorMap)) {
|
||||
if (this.hasStaticMutators) {
|
||||
staticProps = util.buildDefineProperties(this.staticMutatorMap, className);
|
||||
}
|
||||
|
||||
@@ -144,7 +181,7 @@ Class.prototype.buildBody = function () {
|
||||
if (instanceProps) args.push(instanceProps);
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addDeclaration("class-props"), args)
|
||||
t.callExpression(this.file.addDeclaration("prototype-properties"), args)
|
||||
));
|
||||
}
|
||||
};
|
||||
@@ -158,17 +195,29 @@ Class.prototype.buildBody = function () {
|
||||
Class.prototype.pushMethod = function (node) {
|
||||
var methodName = node.key;
|
||||
|
||||
var mutatorMap = this.instanceMutatorMap;
|
||||
if (node.static) mutatorMap = this.staticMutatorMap;
|
||||
|
||||
var kind = node.kind;
|
||||
|
||||
if (kind === "") {
|
||||
kind = "value";
|
||||
util.pushMutatorMap(mutatorMap, methodName, "writable", t.identifier("true"));
|
||||
}
|
||||
// method
|
||||
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node);
|
||||
var className = this.className;
|
||||
if (!node.static) className = t.memberExpression(className, t.identifier("prototype"));
|
||||
methodName = t.memberExpression(className, methodName, node.computed);
|
||||
|
||||
var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value));
|
||||
t.inheritsComments(expr, node);
|
||||
this.body.push(expr);
|
||||
} else {
|
||||
// mutator
|
||||
var mutatorMap = this.instanceMutatorMap;
|
||||
if (node.static) {
|
||||
this.hasStaticMutators = true;
|
||||
mutatorMap = this.staticMutatorMap;
|
||||
} else {
|
||||
this.hasInstanceMutators = true;
|
||||
}
|
||||
util.pushMutatorMap(mutatorMap, methodName, kind, node);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -223,17 +272,19 @@ Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
|
||||
var method = methodNode.value;
|
||||
var self = this;
|
||||
|
||||
traverse(method, function (node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return self.superIdentifier(methodNode, node, parent);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (callee.object.name !== "super") return;
|
||||
traverse(method, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
return self.superIdentifier(methodNode, 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);
|
||||
callee.property = t.memberExpression(callee.property, t.identifier("call"));
|
||||
node.arguments.unshift(t.thisExpression());
|
||||
// super.test(); -> ClassName.prototype.MethodName.call(this);
|
||||
callee.property = t.memberExpression(callee.property, t.identifier("call"));
|
||||
node.arguments.unshift(t.thisExpression());
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -253,6 +304,7 @@ Class.prototype.pushConstructor = function (method) {
|
||||
var fn = method.value;
|
||||
|
||||
this.hasConstructor = true;
|
||||
|
||||
t.inherits(construct, fn);
|
||||
t.inheritsComments(construct, method);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.ObjectExpression = function (node, parent, file) {
|
||||
var hasComputed = false;
|
||||
@@ -26,12 +25,13 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
OBJECT: node
|
||||
});
|
||||
|
||||
var containerCallee = container.callee.expression;
|
||||
var containerCallee = container.callee;
|
||||
var containerBody = containerCallee.body.body;
|
||||
|
||||
containerCallee._aliasFunction = true;
|
||||
|
||||
_.each(computed, function (prop) {
|
||||
for (var i in computed) {
|
||||
var prop = computed[i];
|
||||
containerBody.unshift(
|
||||
t.expressionStatement(
|
||||
t.assignmentExpression(
|
||||
@@ -41,7 +41,7 @@ exports.ObjectExpression = function (node, parent, file) {
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return container;
|
||||
};
|
||||
82
lib/6to5/transformation/transformers/es6-constants.js
Normal file
82
lib/6to5/transformation/transformers/es6-constants.js
Normal file
@@ -0,0 +1,82 @@
|
||||
var traverse = require("../../traverse");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Program =
|
||||
exports.BlockStatement =
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement =
|
||||
exports.ForStatement = function (node, parent, file) {
|
||||
var hasConstants = false;
|
||||
var constants = {};
|
||||
|
||||
/**
|
||||
* Check the results of `util.getIds` as `names` generated from a
|
||||
* node against it's parent.
|
||||
*/
|
||||
|
||||
var check = function (parent, names, scope) {
|
||||
for (var name in names) {
|
||||
var nameNode = names[name];
|
||||
if (!_.has(constants, name)) continue;
|
||||
if (parent && t.isBlockStatement(parent) && parent !== constants[name]) continue;
|
||||
|
||||
if (scope) {
|
||||
var defined = scope.get(name);
|
||||
if (defined && defined === nameNode) continue;
|
||||
}
|
||||
|
||||
throw file.errorWithNode(nameNode, name + " is read-only");
|
||||
}
|
||||
};
|
||||
|
||||
var getIds = function (node) {
|
||||
return t.getIds(node, true, ["MemberExpression"]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Collect all constants in this scope.
|
||||
*/
|
||||
|
||||
_.each(node.body, function (child, parent) {
|
||||
if (t.isExportDeclaration(child)) {
|
||||
child = child.declaration;
|
||||
}
|
||||
|
||||
if (t.isVariableDeclaration(child, { kind: "const" })) {
|
||||
for (var i in child.declarations) {
|
||||
var declar = child.declarations[i];
|
||||
|
||||
var ids = getIds(declar);
|
||||
for (var name in ids) {
|
||||
var nameNode = ids[name];
|
||||
|
||||
var names = {};
|
||||
names[name] = nameNode;
|
||||
check(parent, names);
|
||||
|
||||
constants[name] = parent;
|
||||
hasConstants = true;
|
||||
}
|
||||
|
||||
declar._ignoreConstant = true;
|
||||
}
|
||||
|
||||
child._ignoreConstant = true;
|
||||
child.kind = "let";
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasConstants) return;
|
||||
|
||||
traverse(node, {
|
||||
enter: function (child, parent, scope) {
|
||||
if (child._ignoreConstant) return;
|
||||
if (t.isVariableDeclaration(child)) return;
|
||||
|
||||
if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) {
|
||||
check(parent, getIds(child), scope);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -11,10 +11,13 @@ exports.Function = function (node, parent, file, scope) {
|
||||
return t.getIds(param);
|
||||
});
|
||||
|
||||
var closure = false;
|
||||
var iife = false;
|
||||
var i;
|
||||
var def;
|
||||
|
||||
_.each(node.defaults, function (def, i) {
|
||||
if (!def) return;
|
||||
for (i in node.defaults) {
|
||||
def = node.defaults[i];
|
||||
if (!def) continue;
|
||||
|
||||
var param = node.params[i];
|
||||
|
||||
@@ -24,38 +27,39 @@ exports.Function = function (node, parent, file, scope) {
|
||||
var check = function (node, parent) {
|
||||
if (!t.isIdentifier(node) || !t.isReferenced(node, parent)) return;
|
||||
|
||||
if (_.contains(ids, node.name)) {
|
||||
if (ids.indexOf(node.name) >= 0) {
|
||||
throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
|
||||
}
|
||||
|
||||
if (scope.has(node.name)) {
|
||||
closure = true;
|
||||
iife = true;
|
||||
}
|
||||
};
|
||||
|
||||
check(def, node);
|
||||
traverse(def, check);
|
||||
traverse(def, { enter: check });
|
||||
});
|
||||
|
||||
// we're accessing a variable that's already defined within this function
|
||||
var has = scope.get(param.name);
|
||||
if (has && !_.contains(node.params, has)) {
|
||||
closure = true;
|
||||
if (has && node.params.indexOf(has) < 0) {
|
||||
iife = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var body = [];
|
||||
|
||||
_.each(node.defaults, function (def, i) {
|
||||
if (!def) return;
|
||||
for (i in node.defaults) {
|
||||
def = node.defaults[i];
|
||||
if (!def) continue;
|
||||
|
||||
body.push(util.template("if-undefined-set-to", {
|
||||
VARIABLE: node.params[i],
|
||||
DEFAULT: def
|
||||
}, true));
|
||||
});
|
||||
}
|
||||
|
||||
if (closure) {
|
||||
if (iife) {
|
||||
var container = t.functionExpression(null, [], node.body, node.generator);
|
||||
container._aliasFunction = true;
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
// TODO: Clean up
|
||||
|
||||
var buildVariableAssign = function (kind, id, init) {
|
||||
if (kind === false) {
|
||||
var t = require("../../types");
|
||||
|
||||
var buildVariableAssign = function (opts, id, init) {
|
||||
var op = opts.operator;
|
||||
if (t.isMemberExpression(id)) op = "=";
|
||||
|
||||
if (op) {
|
||||
return t.expressionStatement(t.assignmentExpression("=", id, init));
|
||||
} else {
|
||||
return t.variableDeclaration(kind, [
|
||||
return t.variableDeclaration(opts.kind, [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
}
|
||||
@@ -17,46 +20,65 @@ var push = function (opts, nodes, elem, parentId) {
|
||||
pushObjectPattern(opts, nodes, elem, parentId);
|
||||
} else if (t.isArrayPattern(elem)) {
|
||||
pushArrayPattern(opts, nodes, elem, parentId);
|
||||
} else if (t.isMemberExpression(elem)) {
|
||||
nodes.push(buildVariableAssign(false, elem, parentId));
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(opts.kind, elem, parentId));
|
||||
nodes.push(buildVariableAssign(opts, elem, parentId));
|
||||
}
|
||||
};
|
||||
|
||||
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
|
||||
_.each(pattern.properties, function (prop) {
|
||||
var pattern2 = prop.value;
|
||||
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
|
||||
for (var i in pattern.properties) {
|
||||
var prop = pattern.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
// get all the keys that appear in this object before the current spread
|
||||
var keys = [];
|
||||
for (var i2 in pattern.properties) {
|
||||
var prop2 = pattern.properties[i2];
|
||||
|
||||
if (t.isPattern(pattern2)) {
|
||||
push(opts, nodes, pattern2, patternId2);
|
||||
if (i2 >= i) break;
|
||||
if (t.isSpreadProperty(prop2)) continue;
|
||||
|
||||
var key = prop2.key;
|
||||
if (t.isIdentifier(key)) {
|
||||
key = t.literal(prop2.key.name);
|
||||
}
|
||||
keys.push(key);
|
||||
}
|
||||
keys = t.arrayExpression(keys);
|
||||
|
||||
var value = t.callExpression(opts.file.addDeclaration("object-without-properties"), [parentId, keys]);
|
||||
nodes.push(buildVariableAssign(opts, prop.argument, value));
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(opts.kind, pattern2, patternId2));
|
||||
var pattern2 = prop.value;
|
||||
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
|
||||
|
||||
if (t.isPattern(pattern2)) {
|
||||
push(opts, nodes, pattern2, patternId2);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(opts, pattern2, patternId2));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
var _parentId = opts.file.generateUidIdentifier("ref", opts.scope);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(_parentId, util.template("array-from", {
|
||||
VALUE: parentId
|
||||
}))
|
||||
t.variableDeclarator(_parentId, opts.file.toArray(parentId))
|
||||
]));
|
||||
parentId = _parentId;
|
||||
|
||||
_.each(pattern.elements, function (elem, i) {
|
||||
if (!elem) return;
|
||||
for (var i in pattern.elements) {
|
||||
var elem = pattern.elements[i];
|
||||
if (!elem) continue;
|
||||
|
||||
i = +i;
|
||||
|
||||
var newPatternId;
|
||||
|
||||
if (t.isSpreadElement(elem)) {
|
||||
newPatternId = util.template("array-from", {
|
||||
VALUE: parentId
|
||||
});
|
||||
newPatternId = opts.file.toArray(parentId);
|
||||
|
||||
if (+i > 0) {
|
||||
if (i > 0) {
|
||||
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
|
||||
}
|
||||
|
||||
@@ -66,7 +88,7 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
}
|
||||
|
||||
push(opts, nodes, elem, newPatternId);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var pushPattern = function (opts) {
|
||||
@@ -161,7 +183,7 @@ exports.ExpressionStatement = function (node, parent, file, scope) {
|
||||
]));
|
||||
|
||||
push({
|
||||
kind: false,
|
||||
operator: expr.operator,
|
||||
file: file,
|
||||
scope: scope
|
||||
}, nodes, expr.left, ref);
|
||||
@@ -169,47 +191,72 @@ exports.ExpressionStatement = function (node, parent, file, scope) {
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, file) {
|
||||
exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
if (parent.type === "ExpressionStatement") return;
|
||||
if (!t.isPattern(node.left)) return;
|
||||
throw file.errorWithNode(node, "AssignmentExpression destructuring outside of a ExpressionStatement is forbidden due to current 6to5 limitations");
|
||||
|
||||
var tempName = file.generateUid("temp", scope);
|
||||
var ref = t.identifier(tempName);
|
||||
scope.push({
|
||||
key: tempName,
|
||||
id: ref
|
||||
});
|
||||
|
||||
var nodes = [];
|
||||
nodes.push(t.assignmentExpression("=", ref, node.right));
|
||||
|
||||
push({
|
||||
operator: node.operator,
|
||||
file: file,
|
||||
scope: scope
|
||||
}, nodes, node.left, ref);
|
||||
|
||||
nodes.push(ref);
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
|
||||
|
||||
var nodes = [];
|
||||
var i;
|
||||
var declar;
|
||||
|
||||
var hasPattern = false;
|
||||
_.each(node.declarations, function (declar) {
|
||||
for (i in node.declarations) {
|
||||
declar = node.declarations[i];
|
||||
if (t.isPattern(declar.id)) {
|
||||
hasPattern = true;
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!hasPattern) return;
|
||||
|
||||
_.each(node.declarations, function (declar) {
|
||||
for (i in node.declarations) {
|
||||
declar = node.declarations[i];
|
||||
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
var opts = {
|
||||
kind: node.kind,
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: patternId,
|
||||
file: file,
|
||||
scope: scope
|
||||
};
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
pushPattern({
|
||||
kind: node.kind,
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: patternId,
|
||||
file: file,
|
||||
scope: scope
|
||||
});
|
||||
pushPattern(opts);
|
||||
} else {
|
||||
nodes.push(buildVariableAssign(node.kind, declar.id, declar.init));
|
||||
nodes.push(buildVariableAssign(opts, declar.id, declar.init));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
|
||||
var declar;
|
||||
|
||||
_.each(nodes, function (node) {
|
||||
for (i in nodes) {
|
||||
node = nodes[i];
|
||||
declar = declar || t.variableDeclaration(node.kind, []);
|
||||
|
||||
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
|
||||
@@ -217,11 +264,10 @@ exports.VariableDeclaration = function (node, parent, file, scope) {
|
||||
}
|
||||
|
||||
declar.declarations = declar.declarations.concat(node.declarations);
|
||||
});
|
||||
}
|
||||
|
||||
return declar;
|
||||
}
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@ exports.ForOfStatement = function (node, parent, file, scope) {
|
||||
OBJECT: node.right
|
||||
});
|
||||
|
||||
t.inheritsComments(node2, node);
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node2.body;
|
||||
1
lib/6to5/transformation/transformers/es6-generators.js
Normal file
1
lib/6to5/transformation/transformers/es6-generators.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("regenerator").transform;
|
||||
@@ -3,33 +3,40 @@ var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var isLet = function (node) {
|
||||
var isLet = function (node, parent) {
|
||||
if (!t.isVariableDeclaration(node)) return false;
|
||||
if (node._let) return true;
|
||||
if (node.kind !== "let") return false;
|
||||
|
||||
// https://github.com/6to5/6to5/issues/255
|
||||
if (!t.isFor(parent) || t.isFor(parent) && parent.left !== node) {
|
||||
_.each(node.declarations, function (declar) {
|
||||
declar.init = declar.init || t.identifier("undefined");
|
||||
});
|
||||
}
|
||||
|
||||
node._let = true;
|
||||
node.kind = "var";
|
||||
return true;
|
||||
};
|
||||
|
||||
var isVar = function (node) {
|
||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node);
|
||||
var isVar = function (node, parent) {
|
||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
|
||||
};
|
||||
|
||||
var standardiseLets = function (declars) {
|
||||
_.each(declars, function (declar) {
|
||||
delete declar._let;
|
||||
});
|
||||
for (var i in declars) {
|
||||
delete declars[i]._let;
|
||||
}
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node) {
|
||||
isLet(node);
|
||||
exports.VariableDeclaration = function (node, parent) {
|
||||
isLet(node, parent);
|
||||
};
|
||||
|
||||
exports.For = function (node, parent, file, scope) {
|
||||
exports.Loop = function (node, parent, file, scope) {
|
||||
var init = node.left || node.init;
|
||||
if (isLet(init)) {
|
||||
if (isLet(init, node)) {
|
||||
t.ensureBlock(node);
|
||||
node.body._letDeclars = [init];
|
||||
}
|
||||
@@ -49,7 +56,7 @@ exports.For = function (node, parent, file, scope) {
|
||||
};
|
||||
|
||||
exports.BlockStatement = function (block, parent, file, scope) {
|
||||
if (!t.isFor(parent)) {
|
||||
if (!t.isLoop(parent)) {
|
||||
var letScoping = new LetScoping(false, block, parent, file, scope);
|
||||
letScoping.run();
|
||||
}
|
||||
@@ -58,19 +65,19 @@ exports.BlockStatement = function (block, parent, file, scope) {
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Boolean|Node} forParent
|
||||
* @param {Boolean|Node} loopParent
|
||||
* @param {Node} block
|
||||
* @param {Node} parent
|
||||
* @param {File} file
|
||||
* @param {Scope} scope
|
||||
*/
|
||||
|
||||
function LetScoping(forParent, block, parent, file, scope) {
|
||||
this.forParent = forParent;
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
this.block = block;
|
||||
this.file = file;
|
||||
function LetScoping(loopParent, block, parent, file, scope) {
|
||||
this.loopParent = loopParent;
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
this.block = block;
|
||||
this.file = file;
|
||||
|
||||
this.letReferences = {};
|
||||
this.body = [];
|
||||
@@ -106,7 +113,7 @@ LetScoping.prototype.run = function () {
|
||||
|
||||
// if we're inside of a for loop then we search to see if there are any
|
||||
// `break`s, `continue`s, `return`s etc
|
||||
this.has = this.checkFor();
|
||||
this.has = this.checkLoop();
|
||||
|
||||
// hoist var references to retain scope
|
||||
this.hoistVarDeclarations();
|
||||
@@ -158,7 +165,7 @@ LetScoping.prototype.remap = function () {
|
||||
var replacements = this.info.duplicates;
|
||||
var block = this.block;
|
||||
|
||||
if (_.isEmpty(replacements)) return;
|
||||
if (!this.info.hasDuplicates) return;
|
||||
|
||||
var replace = function (node, parent, scope) {
|
||||
if (!t.isIdentifier(node)) return;
|
||||
@@ -169,17 +176,17 @@ LetScoping.prototype.remap = function () {
|
||||
|
||||
var traverseReplace = function (node, parent) {
|
||||
replace(node, parent);
|
||||
traverse(node, replace);
|
||||
traverse(node, { enter: replace });
|
||||
};
|
||||
|
||||
var forParent = this.forParent;
|
||||
if (forParent) {
|
||||
traverseReplace(forParent.right, forParent);
|
||||
traverseReplace(forParent.test, forParent);
|
||||
traverseReplace(forParent.update, forParent);
|
||||
var loopParent = this.loopParent;
|
||||
if (loopParent) {
|
||||
traverseReplace(loopParent.right, loopParent);
|
||||
traverseReplace(loopParent.test, loopParent);
|
||||
traverseReplace(loopParent.update, loopParent);
|
||||
}
|
||||
|
||||
traverse(block, replace);
|
||||
traverse(block, { enter: replace });
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -206,6 +213,8 @@ LetScoping.prototype.getInfo = function () {
|
||||
// all references with it
|
||||
duplicates: {},
|
||||
|
||||
hasDuplicates: false,
|
||||
|
||||
// array of `Identifier` names of let variables that are accessible within
|
||||
// the current block
|
||||
keys: []
|
||||
@@ -218,75 +227,83 @@ LetScoping.prototype.getInfo = function () {
|
||||
// there's a variable with this exact name in an upper scope so we need
|
||||
// to generate a new name
|
||||
opts.duplicates[key] = id.name = file.generateUid(key, scope);
|
||||
opts.hasDuplicates = true;
|
||||
}
|
||||
};
|
||||
|
||||
_.each(opts.declarators, function (declar) {
|
||||
var i;
|
||||
var declar;
|
||||
|
||||
for (i in opts.declarators) {
|
||||
declar = opts.declarators[i];
|
||||
opts.declarators.push(declar);
|
||||
|
||||
var keys = t.getIds(declar, true);
|
||||
_.each(keys, duplicates);
|
||||
keys = _.keys(keys);
|
||||
keys = Object.keys(keys);
|
||||
|
||||
opts.outsideKeys = opts.outsideKeys.concat(keys);
|
||||
opts.keys = opts.keys.concat(keys);
|
||||
});
|
||||
}
|
||||
|
||||
_.each(block.body, function (declar) {
|
||||
if (!isLet(declar)) return;
|
||||
for (i in block.body) {
|
||||
declar = block.body[i];
|
||||
if (!isLet(declar, block)) continue;
|
||||
|
||||
_.each(t.getIds(declar, true), function (id, key) {
|
||||
duplicates(id, key);
|
||||
opts.keys.push(key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
/**
|
||||
* If we're inside of a `For*Statement` then traverse it and check if it has one
|
||||
* of the following node types `ReturnStatement`, `BreakStatement`,
|
||||
* If we're inside of a loop then traverse it and check if it has one of
|
||||
* the following node types `ReturnStatement`, `BreakStatement`,
|
||||
* `ContinueStatement` and replace it with a return value that we can track
|
||||
* later on.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
LetScoping.prototype.checkFor = function () {
|
||||
LetScoping.prototype.checkLoop = function () {
|
||||
var has = {
|
||||
hasContinue: false,
|
||||
hasReturn: false,
|
||||
hasBreak: false,
|
||||
};
|
||||
|
||||
var forParent = this.forParent;
|
||||
traverse(this.block, {
|
||||
enter: function (node, parent) {
|
||||
var replace;
|
||||
|
||||
traverse(this.block, function (node) {
|
||||
var replace;
|
||||
|
||||
if (t.isFunction(node) || t.isFor(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (forParent && node && !node.label) {
|
||||
if (t.isBreakStatement(node)) {
|
||||
has.hasBreak = true;
|
||||
replace = t.returnStatement(t.literal("break"));
|
||||
} else if (t.isContinueStatement(node)) {
|
||||
has.hasContinue = true;
|
||||
replace = t.returnStatement(t.literal("continue"));
|
||||
if (t.isFunction(node) || t.isLoop(node)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isReturnStatement(node)) {
|
||||
has.hasReturn = true;
|
||||
replace = t.returnStatement(t.objectExpression([
|
||||
t.property("init", t.identifier("v"), node.argument || t.identifier("undefined"))
|
||||
]));
|
||||
}
|
||||
if (node && !node.label) {
|
||||
if (t.isBreakStatement(node)) {
|
||||
if (t.isSwitchCase(parent)) return;
|
||||
|
||||
if (replace) return t.inherits(replace, node);
|
||||
has.hasBreak = true;
|
||||
replace = t.returnStatement(t.literal("break"));
|
||||
} else if (t.isContinueStatement(node)) {
|
||||
has.hasContinue = true;
|
||||
replace = t.returnStatement(t.literal("continue"));
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isReturnStatement(node)) {
|
||||
has.hasReturn = true;
|
||||
replace = t.returnStatement(t.objectExpression([
|
||||
t.property("init", t.identifier("v"), node.argument || t.identifier("undefined"))
|
||||
]));
|
||||
}
|
||||
|
||||
if (replace) return t.inherits(replace, node);
|
||||
}
|
||||
});
|
||||
|
||||
return has;
|
||||
@@ -299,19 +316,21 @@ LetScoping.prototype.checkFor = function () {
|
||||
|
||||
LetScoping.prototype.hoistVarDeclarations = function () {
|
||||
var self = this;
|
||||
traverse(this.block, function (node) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init)) {
|
||||
node.init = t.sequenceExpression(self.pushDeclar(node.init));
|
||||
traverse(this.block, {
|
||||
enter: function (node, parent) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init, node)) {
|
||||
node.init = t.sequenceExpression(self.pushDeclar(node.init));
|
||||
}
|
||||
} else if (t.isFor(node)) {
|
||||
if (isVar(node.left, node)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node, parent)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return false;
|
||||
}
|
||||
} else if (t.isFor(node)) {
|
||||
if (isVar(node.left)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -344,31 +363,35 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
|
||||
// traverse through this block, stopping on functions and checking if they
|
||||
// contain any outside let references
|
||||
traverse(this.block, function (node, parent, scope) {
|
||||
if (t.isFunction(node)) {
|
||||
traverse(node, function (node, parent) {
|
||||
// not an identifier so we have no use
|
||||
if (!t.isIdentifier(node)) return;
|
||||
traverse(this.block, {
|
||||
enter: function (node, parent, scope) {
|
||||
if (t.isFunction(node)) {
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
// not an identifier so we have no use
|
||||
if (!t.isIdentifier(node)) return;
|
||||
|
||||
// not a direct reference
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
// not a direct reference
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
if (scope.hasOwn(node.name)) return;
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
if (scope.hasOwn(node.name)) return;
|
||||
|
||||
closurify = true;
|
||||
closurify = true;
|
||||
|
||||
// this key doesn't appear just outside our scope
|
||||
if (!_.contains(self.info.outsideKeys, node.name)) return;
|
||||
// this key doesn't appear just outside our scope
|
||||
if (!_.contains(self.info.outsideKeys, node.name)) return;
|
||||
|
||||
// push this badboy
|
||||
self.letReferences[node.name] = node;
|
||||
});
|
||||
// push this badboy
|
||||
self.letReferences[node.name] = node;
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
} else if (t.isFor(node)) {
|
||||
return false;
|
||||
return false;
|
||||
} else if (t.isLoop(node)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -390,12 +413,13 @@ LetScoping.prototype.pushDeclar = function (node) {
|
||||
|
||||
var replace = [];
|
||||
|
||||
_.each(node.declarations, function (declar) {
|
||||
if (!declar.init) return;
|
||||
for (var i in node.declarations) {
|
||||
var declar = node.declarations[i];
|
||||
if (!declar.init) continue;
|
||||
|
||||
var expr = t.assignmentExpression("=", declar.id, declar.init);
|
||||
replace.push(t.inherits(expr, declar));
|
||||
});
|
||||
}
|
||||
|
||||
return replace;
|
||||
};
|
||||
@@ -430,7 +454,7 @@ LetScoping.prototype.buildHas = function (ret, call) {
|
||||
t.variableDeclarator(ret, call)
|
||||
]));
|
||||
|
||||
var forParent = this.forParent;
|
||||
var loopParent = this.loopParent;
|
||||
var retCheck;
|
||||
var has = this.has;
|
||||
var cases = [];
|
||||
@@ -445,7 +469,7 @@ LetScoping.prototype.buildHas = function (ret, call) {
|
||||
if (has.hasBreak || has.hasContinue) {
|
||||
// ensure that the parent has a label as we're building a switch and we
|
||||
// need to be able to access it
|
||||
var label = forParent.label = forParent.label || this.file.generateUidIdentifier("loop", this.scope);
|
||||
var label = loopParent.label = loopParent.label || this.file.generateUidIdentifier("loop", this.scope);
|
||||
|
||||
if (has.hasBreak) {
|
||||
cases.push(t.switchCase(t.literal("break"), [t.breakStatement(label)]));
|
||||
50
lib/6to5/transformation/transformers/es6-modules.js
Normal file
50
lib/6to5/transformation/transformers/es6-modules.js
Normal file
@@ -0,0 +1,50 @@
|
||||
var t = require("../../types");
|
||||
|
||||
var inheritsComments = function (node, nodes) {
|
||||
if (nodes.length) {
|
||||
t.inheritsComments(nodes[0], node);
|
||||
}
|
||||
};
|
||||
|
||||
exports.ImportDeclaration = function (node, parent, file) {
|
||||
var nodes = [];
|
||||
|
||||
if (node.specifiers.length) {
|
||||
if (!file.moduleFormatter.importSpecifier) return;
|
||||
for (var i in node.specifiers) {
|
||||
file.moduleFormatter.importSpecifier(node.specifiers[i], node, nodes, parent);
|
||||
}
|
||||
} else {
|
||||
if (!file.moduleFormatter.importDeclaration) return;
|
||||
file.moduleFormatter.importDeclaration(node, nodes, parent);
|
||||
}
|
||||
|
||||
inheritsComments(node, nodes);
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.ExportDeclaration = function (node, parent, file) {
|
||||
var nodes = [];
|
||||
|
||||
if (node.declaration) {
|
||||
// make sure variable exports have an initialiser
|
||||
// this is done here to avoid duplicating it in the module formatters
|
||||
if (t.isVariableDeclaration(node.declaration)) {
|
||||
var declar = node.declaration.declarations[0];
|
||||
declar.init = declar.init || t.identifier("undefined");
|
||||
}
|
||||
|
||||
if (!file.moduleFormatter.exportDeclaration) return;
|
||||
file.moduleFormatter.exportDeclaration(node, nodes, parent);
|
||||
} else {
|
||||
if (!file.moduleFormatter.exportSpecifier) return;
|
||||
for (var i in node.specifiers) {
|
||||
file.moduleFormatter.exportSpecifier(node.specifiers[i], node, nodes, parent);
|
||||
}
|
||||
}
|
||||
|
||||
inheritsComments(node, nodes);
|
||||
|
||||
return nodes;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.Property = function (node) {
|
||||
if (!node.shorthand) return;
|
||||
node.shorthand = false;
|
||||
node.key = t.removeComments(_.clone(node.key));
|
||||
};
|
||||
22
lib/6to5/transformation/transformers/es6-rest-parameters.js
Normal file
22
lib/6to5/transformation/transformers/es6-rest-parameters.js
Normal file
@@ -0,0 +1,22 @@
|
||||
var t = require("../../types");
|
||||
|
||||
exports.Function = function (node, parent, file) {
|
||||
if (!node.rest) return;
|
||||
|
||||
var rest = node.rest;
|
||||
delete node.rest;
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var call = file.toArray(t.identifier("arguments"));
|
||||
|
||||
if (node.params.length) {
|
||||
call.arguments.push(t.literal(node.params.length));
|
||||
}
|
||||
|
||||
call._ignoreAliasFunctions = true;
|
||||
|
||||
node.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(rest, call)
|
||||
]));
|
||||
};
|
||||
@@ -1,29 +1,19 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
var t = require("../../types");
|
||||
|
||||
var getSpreadLiteral = function (spread) {
|
||||
var literal = spread.argument;
|
||||
if (!t.isArrayExpression(literal)) {
|
||||
literal = util.template("array-from", {
|
||||
VALUE: literal
|
||||
});
|
||||
}
|
||||
return literal;
|
||||
var getSpreadLiteral = function (spread, file) {
|
||||
return file.toArray(spread.argument);
|
||||
};
|
||||
|
||||
var hasSpread = function (nodes) {
|
||||
var has = false;
|
||||
_.each(nodes, function (node) {
|
||||
if (t.isSpreadElement(node)) {
|
||||
has = true;
|
||||
return false;
|
||||
for (var i in nodes) {
|
||||
if (t.isSpreadElement(nodes[i])) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return has;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
var build = function (props) {
|
||||
var build = function (props, file) {
|
||||
var nodes = [];
|
||||
|
||||
var _props = [];
|
||||
@@ -34,33 +24,37 @@ var build = function (props) {
|
||||
_props = [];
|
||||
};
|
||||
|
||||
_.each(props, function (prop) {
|
||||
for (var i in props) {
|
||||
var prop = props[i];
|
||||
if (t.isSpreadElement(prop)) {
|
||||
push();
|
||||
nodes.push(getSpreadLiteral(prop));
|
||||
nodes.push(getSpreadLiteral(prop, file));
|
||||
} else {
|
||||
_props.push(prop);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
push();
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.ArrayExpression = function (node) {
|
||||
exports.ArrayExpression = function (node, parent, file) {
|
||||
var elements = node.elements;
|
||||
if (!hasSpread(elements)) return;
|
||||
|
||||
var nodes = build(elements);
|
||||
var nodes = build(elements, file);
|
||||
var first = nodes.shift();
|
||||
|
||||
if (!nodes.length) return first;
|
||||
if (!t.isArrayExpression(first)) {
|
||||
nodes.unshift(first);
|
||||
first = t.arrayExpression([]);
|
||||
}
|
||||
|
||||
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node) {
|
||||
exports.CallExpression = function (node, parent, file, scope) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
@@ -68,7 +62,12 @@ exports.CallExpression = function (node) {
|
||||
|
||||
node.arguments = [];
|
||||
|
||||
var nodes = build(args);
|
||||
var nodes;
|
||||
if (args.length === 1 && args[0].argument.name === 'arguments') {
|
||||
nodes = [args[0].argument];
|
||||
} else {
|
||||
nodes = build(args, file);
|
||||
}
|
||||
var first = nodes.shift();
|
||||
|
||||
if (nodes.length) {
|
||||
@@ -78,10 +77,16 @@ exports.CallExpression = function (node) {
|
||||
}
|
||||
|
||||
var callee = node.callee;
|
||||
var temp;
|
||||
|
||||
if (t.isMemberExpression(callee)) {
|
||||
contextLiteral = callee.object;
|
||||
|
||||
if (t.isDynamic(contextLiteral)) {
|
||||
temp = contextLiteral = scope.generateTemp(file);
|
||||
callee.object = t.assignmentExpression("=", temp, callee.object);
|
||||
}
|
||||
|
||||
if (callee.computed) {
|
||||
callee.object = t.memberExpression(callee.object, callee.property, true);
|
||||
callee.property = t.identifier("apply");
|
||||
@@ -100,7 +105,7 @@ exports.NewExpression = function (node, parent, file) {
|
||||
var args = node.arguments;
|
||||
if (!hasSpread(args)) return;
|
||||
|
||||
var nodes = build(args);
|
||||
var nodes = build(args, file);
|
||||
var first = nodes.shift();
|
||||
|
||||
if (nodes.length) {
|
||||
@@ -1,5 +1,4 @@
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var buildBinaryExpression = function (left, right) {
|
||||
return t.binaryExpression("+", left, right);
|
||||
@@ -12,10 +11,11 @@ exports.TaggedTemplateExpression = function (node, parent, file) {
|
||||
var strings = [];
|
||||
var raw = [];
|
||||
|
||||
_.each(quasi.quasis, function (elem) {
|
||||
for (var i in quasi.quasis) {
|
||||
var elem = quasi.quasis[i];
|
||||
strings.push(t.literal(elem.value.cooked));
|
||||
raw.push(t.literal(elem.value.raw));
|
||||
});
|
||||
}
|
||||
|
||||
args.push(t.callExpression(file.addDeclaration("tagged-template-literal"), [
|
||||
t.arrayExpression(strings),
|
||||
@@ -29,27 +29,27 @@ exports.TaggedTemplateExpression = function (node, parent, file) {
|
||||
|
||||
exports.TemplateLiteral = function (node) {
|
||||
var nodes = [];
|
||||
var i;
|
||||
|
||||
_.each(node.quasis, function (elem) {
|
||||
nodes.push(t.literal(elem.value.raw));
|
||||
for (i in node.quasis) {
|
||||
var elem = node.quasis[i];
|
||||
|
||||
nodes.push(t.literal(elem.value.cooked));
|
||||
|
||||
var expr = node.expressions.shift();
|
||||
if (expr) {
|
||||
if (t.isBinary(expr)) expr = t.parenthesizedExpression(expr);
|
||||
nodes.push(expr);
|
||||
}
|
||||
});
|
||||
if (expr) nodes.push(expr);
|
||||
}
|
||||
|
||||
if (nodes.length > 1) {
|
||||
// remove redundant '' at the end of the expression
|
||||
var last = _.last(nodes);
|
||||
var last = nodes[nodes.length - 1];
|
||||
if (t.isLiteral(last, { value: "" })) nodes.pop();
|
||||
|
||||
var root = buildBinaryExpression(nodes.shift(), nodes.shift());
|
||||
|
||||
_.each(nodes, function (node) {
|
||||
root = buildBinaryExpression(root, node);
|
||||
});
|
||||
for (i in nodes) {
|
||||
root = buildBinaryExpression(root, nodes[i]);
|
||||
}
|
||||
|
||||
return root;
|
||||
} else {
|
||||
@@ -6,7 +6,7 @@ exports.Literal = function (node) {
|
||||
if (!regex) return;
|
||||
|
||||
var flags = regex.flags.split("");
|
||||
if (!_.contains(regex.flags, "u")) return;
|
||||
if (regex.flags.indexOf("u") < 0) return;
|
||||
_.pull(flags, "u");
|
||||
|
||||
regex.pattern = rewritePattern(regex.pattern, regex.flags);
|
||||
115
lib/6to5/transformation/transformers/es7-abstract-references.js
Normal file
115
lib/6to5/transformation/transformers/es7-abstract-references.js
Normal file
@@ -0,0 +1,115 @@
|
||||
// https://github.com/zenparsing/es-abstract-refs
|
||||
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
var container = function (parent, call, ret) {
|
||||
if (t.isExpressionStatement(parent)) {
|
||||
// we don't need to worry about return values
|
||||
return call;
|
||||
} else {
|
||||
var exprs = [];
|
||||
if (t.isSequenceExpression(call)) {
|
||||
exprs = call.expressions;
|
||||
} else {
|
||||
exprs.push(call);
|
||||
}
|
||||
exprs.push(ret);
|
||||
return t.sequenceExpression(exprs);
|
||||
}
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, file, scope) {
|
||||
var left = node.left;
|
||||
if (!t.isVirtualPropertyExpression(left)) return;
|
||||
|
||||
var value = node.right;
|
||||
var temp;
|
||||
|
||||
// we need to return `node.right`
|
||||
if (!t.isExpressionStatement(parent)) {
|
||||
// `node.right` isn't a simple identifier so we need to reference it
|
||||
if (t.isDynamic(value)) {
|
||||
temp = value = scope.generateTemp(file);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.operator !== "=") {
|
||||
value = t.binaryExpression(
|
||||
node.operator[0],
|
||||
util.template("abstract-expression-get", {
|
||||
PROPERTY: node.property,
|
||||
OBJECT: node.object
|
||||
}),
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
var call = util.template("abstract-expression-set", {
|
||||
PROPERTY: left.property,
|
||||
OBJECT: left.object,
|
||||
VALUE: value
|
||||
});
|
||||
|
||||
if (temp) {
|
||||
call = t.sequenceExpression([
|
||||
t.assignmentExpression("=", temp, node.right),
|
||||
call
|
||||
]);
|
||||
}
|
||||
|
||||
return container(parent, call, value);
|
||||
};
|
||||
|
||||
exports.UnaryExpression = function (node, parent) {
|
||||
var arg = node.argument;
|
||||
if (!t.isVirtualPropertyExpression(arg)) return;
|
||||
if (node.operator !== "delete") return;
|
||||
|
||||
var call = util.template("abstract-expression-delete", {
|
||||
PROPERTY: arg.property,
|
||||
OBJECT: arg.object
|
||||
});
|
||||
|
||||
return container(parent, call, t.literal(true));
|
||||
};
|
||||
|
||||
exports.CallExpression = function (node, parent, file, scope) {
|
||||
var callee = node.callee;
|
||||
if (!t.isVirtualPropertyExpression(callee)) return;
|
||||
|
||||
var temp;
|
||||
if (t.isDynamic(callee.object)) {
|
||||
// we need to save `callee.object` so we can call it again
|
||||
temp = scope.generateTemp(file);
|
||||
}
|
||||
|
||||
var call = util.template("abstract-expression-call", {
|
||||
PROPERTY: callee.property,
|
||||
OBJECT: temp || callee.object
|
||||
});
|
||||
|
||||
call.arguments = call.arguments.concat(node.arguments);
|
||||
|
||||
if (temp) {
|
||||
return t.sequenceExpression([
|
||||
t.assignmentExpression("=", temp, callee.object),
|
||||
call
|
||||
]);
|
||||
} else {
|
||||
return call;
|
||||
}
|
||||
};
|
||||
|
||||
exports.VirtualPropertyExpression = function (node) {
|
||||
return util.template("abstract-expression-get", {
|
||||
PROPERTY: node.property,
|
||||
OBJECT: node.object
|
||||
});
|
||||
};
|
||||
|
||||
exports.PrivateDeclaration = function (node) {
|
||||
return t.variableDeclaration("const", node.declarations.map(function (id) {
|
||||
return t.variableDeclarator(id, t.newExpression(t.identifier("WeakMap"), []));
|
||||
}));
|
||||
};
|
||||
@@ -1,8 +1,7 @@
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var _ = require("lodash");
|
||||
|
||||
var singleArrayExpression = function (node) {
|
||||
var single = function (node, file) {
|
||||
var block = node.blocks[0];
|
||||
|
||||
var templateName = "array-expression-comprehension-map";
|
||||
@@ -11,15 +10,17 @@ var singleArrayExpression = function (node) {
|
||||
var result = util.template(templateName, {
|
||||
STATEMENT: node.body,
|
||||
FILTER: node.filter,
|
||||
ARRAY: block.right,
|
||||
ARRAY: file.toArray(block.right),
|
||||
KEY: block.left
|
||||
});
|
||||
|
||||
_.each([result.callee.object, result], function (call) {
|
||||
var aliasPossibles = [result.callee.object, result];
|
||||
for (var i in aliasPossibles) {
|
||||
var call = aliasPossibles[i];
|
||||
if (t.isCallExpression(call)) {
|
||||
call.arguments[0]._aliasFunction = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
@@ -32,7 +33,7 @@ var multiple = function (node, file) {
|
||||
});
|
||||
container.callee.expression._aliasFunction = true;
|
||||
|
||||
var block = container.callee.expression.body;
|
||||
var block = container.callee.body;
|
||||
var body = block.body;
|
||||
|
||||
var returnStatement = body.pop();
|
||||
@@ -73,8 +74,8 @@ exports._build = function (node, buildBody) {
|
||||
exports.ComprehensionExpression = function (node, parent, file) {
|
||||
if (node.generator) return;
|
||||
|
||||
if (node.blocks.length === 1 && t.isArrayExpression(node.blocks[0].right)) {
|
||||
return singleArrayExpression(node);
|
||||
if (node.blocks.length === 1) {
|
||||
return single(node, file);
|
||||
} else {
|
||||
return multiple(node, file);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// https://github.com/rwaldron/exponentiation-operator
|
||||
|
||||
var t = require("../../types");
|
||||
var pow = t.memberExpression(t.identifier("Math"), t.identifier("pow"));
|
||||
|
||||
exports.AssignmentExpression = function (node) {
|
||||
if (node.operator !== "**=") return;
|
||||
node.operator = "=";
|
||||
node.right = t.callExpression(pow, [node.left, node.right]);
|
||||
};
|
||||
|
||||
exports.BinaryExpression = function (node) {
|
||||
if (node.operator !== "**") return;
|
||||
|
||||
return t.callExpression(pow, [node.left, node.right]);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
var arrayComprehension = require("./array-comprehension");
|
||||
var arrayComprehension = require("./es7-array-comprehension");
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ComprehensionExpression = function (node) {
|
||||
@@ -6,6 +6,7 @@ exports.ComprehensionExpression = function (node) {
|
||||
|
||||
var body = [];
|
||||
var container = t.functionExpression(null, [], t.blockStatement(body), true);
|
||||
container._aliasFunction = true;
|
||||
|
||||
body.push(arrayComprehension._build(node, function () {
|
||||
return t.expressionStatement(t.yieldExpression(node.body));
|
||||
44
lib/6to5/transformation/transformers/es7-object-spread.js
Normal file
44
lib/6to5/transformation/transformers/es7-object-spread.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// https://github.com/sebmarkbage/ecmascript-rest-spread
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports.ObjectExpression = function (node) {
|
||||
var hasSpread = false;
|
||||
var i;
|
||||
var prop;
|
||||
for (i in node.properties) {
|
||||
prop = node.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
hasSpread = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasSpread) return;
|
||||
|
||||
var args = [];
|
||||
var props = [];
|
||||
|
||||
var push = function () {
|
||||
if (!props.length) return;
|
||||
args.push(t.objectExpression(props));
|
||||
props = [];
|
||||
};
|
||||
|
||||
for (i in node.properties) {
|
||||
prop = node.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
push();
|
||||
args.push(prop.argument);
|
||||
} else {
|
||||
props.push(prop);
|
||||
}
|
||||
}
|
||||
|
||||
push();
|
||||
|
||||
if (!t.isObjectExpression(args[0])) {
|
||||
args.unshift(t.objectExpression([]));
|
||||
}
|
||||
|
||||
return t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), args);
|
||||
};
|
||||
@@ -1,204 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* https://raw.github.com/facebook/regenerator/master/LICENSE file. An
|
||||
* additional grant of patent rights can be found in the PATENTS file in
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var loc = require("../util").loc;
|
||||
var t = require("../../../../types");
|
||||
|
||||
exports.ParenthesizedExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(this.explodeExpression(path.get("expression")));
|
||||
};
|
||||
|
||||
exports.MemberExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.memberExpression(
|
||||
this.explodeExpression(path.get("object")),
|
||||
expr.computed ? explodeViaTempVar(null, path.get("property")) : expr.property,
|
||||
expr.computed
|
||||
));
|
||||
};
|
||||
|
||||
exports.CallExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
var oldCalleePath = path.get("callee");
|
||||
var newCallee = this.explodeExpression(oldCalleePath);
|
||||
|
||||
// If the callee was not previously a MemberExpression, then the
|
||||
// CallExpression was "unqualified," meaning its `this` object should
|
||||
// be the global object. If the exploded expression has become a
|
||||
// MemberExpression, then we need to force it to be unqualified by
|
||||
// using the (0, object.property)(...) trick; otherwise, it will
|
||||
// receive the object of the MemberExpression as its `this` object.
|
||||
if (!t.isMemberExpression(oldCalleePath.node) && t.isMemberExpression(newCallee)) {
|
||||
newCallee = t.sequenceExpression([
|
||||
t.literal(0),
|
||||
newCallee
|
||||
]);
|
||||
}
|
||||
|
||||
return finish(t.callExpression(
|
||||
newCallee,
|
||||
path.get("arguments").map(function (argPath) {
|
||||
return explodeViaTempVar(null, argPath);
|
||||
})
|
||||
));
|
||||
};
|
||||
|
||||
exports.NewExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.newExpression(
|
||||
explodeViaTempVar(null, path.get("callee")),
|
||||
path.get("arguments").map(function (argPath) {
|
||||
return explodeViaTempVar(null, argPath);
|
||||
})
|
||||
));
|
||||
};
|
||||
|
||||
exports.ObjectExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.objectExpression(
|
||||
path.get("properties").map(function (propPath) {
|
||||
return t.property(
|
||||
propPath.value.kind,
|
||||
propPath.value.key,
|
||||
explodeViaTempVar(null, propPath.get("value"))
|
||||
);
|
||||
})
|
||||
));
|
||||
};
|
||||
|
||||
exports.ArrayExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.arrayExpression(
|
||||
path.get("elements").map(function (elemPath) {
|
||||
return explodeViaTempVar(null, elemPath);
|
||||
})
|
||||
));
|
||||
};
|
||||
|
||||
exports.SequenceExpression = function (expr, path, explodeViaTempVar, finish, ignoreResult) {
|
||||
var lastIndex = expr.expressions.length - 1;
|
||||
var self = this;
|
||||
var result;
|
||||
|
||||
path.get("expressions").each(function (exprPath) {
|
||||
if (exprPath.name === lastIndex) {
|
||||
result = self.explodeExpression(exprPath, ignoreResult);
|
||||
} else {
|
||||
self.explodeExpression(exprPath, true);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
exports.LogicalExpression = function (expr, path, explodeViaTempVar, finish, ignoreResult) {
|
||||
var after = loc();
|
||||
var result;
|
||||
|
||||
if (!ignoreResult) {
|
||||
result = this.makeTempVar();
|
||||
}
|
||||
|
||||
var left = explodeViaTempVar(result, path.get("left"));
|
||||
|
||||
if (expr.operator === "&&") {
|
||||
this.jumpIfNot(left, after);
|
||||
} else {
|
||||
assert.strictEqual(expr.operator, "||");
|
||||
this.jumpIf(left, after);
|
||||
}
|
||||
|
||||
explodeViaTempVar(result, path.get("right"), ignoreResult);
|
||||
|
||||
this.mark(after);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
exports.ConditionalExpression = function (expr, path, explodeViaTempVar, finish, ignoreResult) {
|
||||
var elseLoc = loc();
|
||||
var after = loc();
|
||||
var test = this.explodeExpression(path.get("test"));
|
||||
var result;
|
||||
|
||||
this.jumpIfNot(test, elseLoc);
|
||||
|
||||
if (!ignoreResult) {
|
||||
result = this.makeTempVar();
|
||||
}
|
||||
|
||||
explodeViaTempVar(result, path.get("consequent"), ignoreResult);
|
||||
this.jump(after);
|
||||
|
||||
this.mark(elseLoc);
|
||||
explodeViaTempVar(result, path.get("alternate"), ignoreResult);
|
||||
|
||||
this.mark(after);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
exports.UnaryExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.unaryExpression(
|
||||
expr.operator,
|
||||
// Can't (and don't need to) break up the syntax of the argument.
|
||||
// Think about delete a[b].
|
||||
this.explodeExpression(path.get("argument")),
|
||||
!!expr.prefix
|
||||
));
|
||||
};
|
||||
|
||||
exports.BinaryExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.binaryExpression(
|
||||
expr.operator,
|
||||
explodeViaTempVar(null, path.get("left")),
|
||||
explodeViaTempVar(null, path.get("right"))
|
||||
));
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.assignmentExpression(
|
||||
expr.operator,
|
||||
this.explodeExpression(path.get("left")),
|
||||
this.explodeExpression(path.get("right"))
|
||||
));
|
||||
};
|
||||
|
||||
exports.UpdateExpression = function (expr, path, explodeViaTempVar, finish) {
|
||||
return finish(t.updateExpression(
|
||||
expr.operator,
|
||||
this.explodeExpression(path.get("argument")),
|
||||
expr.prefix
|
||||
));
|
||||
};
|
||||
|
||||
exports.YieldExpression = function (expr, path) {
|
||||
var after = loc();
|
||||
var arg = expr.argument && this.explodeExpression(path.get("argument"));
|
||||
var result;
|
||||
|
||||
if (arg && expr.delegate) {
|
||||
result = this.makeTempVar();
|
||||
|
||||
this.emit(t.returnStatement(t.callExpression(
|
||||
this.contextProperty("delegateYield"), [
|
||||
arg,
|
||||
t.literal(result.property.name),
|
||||
after
|
||||
]
|
||||
)));
|
||||
|
||||
this.mark(after);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
this.emitAssign(this.contextProperty("next"), after);
|
||||
this.emit(t.returnStatement(arg || null));
|
||||
this.mark(after);
|
||||
|
||||
return this.contextProperty("sent");
|
||||
};
|
||||
@@ -1,334 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2014, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* https://raw.github.com/facebook/regenerator/master/LICENSE file. An
|
||||
* additional grant of patent rights can be found in the PATENTS file in
|
||||
* the same directory.
|
||||
*/
|
||||
|
||||
var assert = require("assert");
|
||||
var types = require("ast-types");
|
||||
var leap = require("../leap");
|
||||
var util = require("../util");
|
||||
var t = require("../../../../types");
|
||||
|
||||
var runtimeKeysMethod = util.runtimeProperty("keys");
|
||||
var loc = util.loc;
|
||||
|
||||
exports.ExpressionStatement = function (path) {
|
||||
this.explodeExpression(path.get("expression"), true);
|
||||
};
|
||||
|
||||
exports.LabeledStatement = function (path, stmt) {
|
||||
this.explodeStatement(path.get("body"), stmt.label);
|
||||
};
|
||||
|
||||
exports.WhileStatement = function (path, stmt, labelId) {
|
||||
var before = loc();
|
||||
var after = loc();
|
||||
|
||||
this.mark(before);
|
||||
this.jumpIfNot(this.explodeExpression(path.get("test")), after);
|
||||
this.leapManager.withEntry(
|
||||
new leap.LoopEntry(after, before, labelId),
|
||||
function () { this.explodeStatement(path.get("body")); }
|
||||
);
|
||||
this.jump(before);
|
||||
this.mark(after);
|
||||
};
|
||||
|
||||
exports.DoWhileStatement = function (path, stmt, labelId) {
|
||||
var first = loc();
|
||||
var test = loc();
|
||||
var after = loc();
|
||||
|
||||
this.mark(first);
|
||||
this.leapManager.withEntry(
|
||||
new leap.LoopEntry(after, test, labelId),
|
||||
function () { this.explode(path.get("body")); }
|
||||
);
|
||||
this.mark(test);
|
||||
this.jumpIf(this.explodeExpression(path.get("test")), first);
|
||||
this.mark(after);
|
||||
};
|
||||
|
||||
exports.ForStatement = function (path, stmt, labelId) {
|
||||
var head = loc();
|
||||
var update = loc();
|
||||
var after = loc();
|
||||
|
||||
if (stmt.init) {
|
||||
// We pass true here to indicate that if stmt.init is an expression
|
||||
// then we do not care about its result.
|
||||
this.explode(path.get("init"), true);
|
||||
}
|
||||
|
||||
this.mark(head);
|
||||
|
||||
if (stmt.test) {
|
||||
this.jumpIfNot(this.explodeExpression(path.get("test")), after);
|
||||
} else {
|
||||
// No test means continue unconditionally.
|
||||
}
|
||||
|
||||
this.leapManager.withEntry(
|
||||
new leap.LoopEntry(after, update, labelId),
|
||||
function () { this.explodeStatement(path.get("body")); }
|
||||
);
|
||||
|
||||
this.mark(update);
|
||||
|
||||
if (stmt.update) {
|
||||
// We pass true here to indicate that if stmt.update is an
|
||||
// expression then we do not care about its result.
|
||||
this.explode(path.get("update"), true);
|
||||
}
|
||||
|
||||
this.jump(head);
|
||||
|
||||
this.mark(after);
|
||||
};
|
||||
|
||||
exports.ForInStatement = function (path, stmt, labelId) {
|
||||
t.assertIdentifier(stmt.left);
|
||||
|
||||
var head = loc();
|
||||
var after = loc();
|
||||
|
||||
var keyIterNextFn = this.makeTempVar();
|
||||
this.emitAssign(
|
||||
keyIterNextFn,
|
||||
t.callExpression(
|
||||
runtimeKeysMethod,
|
||||
[this.explodeExpression(path.get("right"))]
|
||||
)
|
||||
);
|
||||
|
||||
this.mark(head);
|
||||
|
||||
var keyInfoTmpVar = this.makeTempVar();
|
||||
this.jumpIf(
|
||||
t.memberExpression(
|
||||
t.assignmentExpression(
|
||||
"=",
|
||||
keyInfoTmpVar,
|
||||
t.callExpression(keyIterNextFn, [])
|
||||
),
|
||||
t.identifier("done"),
|
||||
false
|
||||
),
|
||||
after
|
||||
);
|
||||
|
||||
this.emitAssign(
|
||||
stmt.left,
|
||||
t.memberExpression(
|
||||
keyInfoTmpVar,
|
||||
t.identifier("value"),
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
this.leapManager.withEntry(
|
||||
new leap.LoopEntry(after, head, labelId),
|
||||
function () { this.explodeStatement(path.get("body")); }
|
||||
);
|
||||
|
||||
this.jump(head);
|
||||
|
||||
this.mark(after);
|
||||
};
|
||||
|
||||
exports.BreakStatement = function (path, stmt) {
|
||||
this.emitAbruptCompletion({
|
||||
type: "break",
|
||||
target: this.leapManager.getBreakLoc(stmt.label)
|
||||
});
|
||||
};
|
||||
|
||||
exports.ContinueStatement = function (path, stmt) {
|
||||
this.emitAbruptCompletion({
|
||||
type: "continue",
|
||||
target: this.leapManager.getContinueLoc(stmt.label)
|
||||
});
|
||||
};
|
||||
|
||||
exports.SwitchStatement = function (path, stmt) {
|
||||
// Always save the discriminant into a temporary variable in case the
|
||||
// test expressions overwrite values like context.sent.
|
||||
var disc = this.emitAssign(
|
||||
this.makeTempVar(),
|
||||
this.explodeExpression(path.get("discriminant"))
|
||||
);
|
||||
|
||||
var after = loc();
|
||||
var defaultLoc = loc();
|
||||
var condition = defaultLoc;
|
||||
var caseLocs = [];
|
||||
var self = this;
|
||||
|
||||
// If there are no cases, .cases might be undefined.
|
||||
var cases = stmt.cases || [];
|
||||
|
||||
for (var i = cases.length - 1; i >= 0; --i) {
|
||||
var c = cases[i];
|
||||
t.assertSwitchCase(c);
|
||||
|
||||
if (c.test) {
|
||||
condition = t.conditionalExpression(
|
||||
t.binaryExpression("===", disc, c.test),
|
||||
caseLocs[i] = loc(),
|
||||
condition
|
||||
);
|
||||
} else {
|
||||
caseLocs[i] = defaultLoc;
|
||||
}
|
||||
}
|
||||
|
||||
this.jump(this.explodeExpression(
|
||||
new types.NodePath(condition, path, "discriminant")
|
||||
));
|
||||
|
||||
this.leapManager.withEntry(
|
||||
new leap.SwitchEntry(after),
|
||||
function () {
|
||||
path.get("cases").each(function (casePath) {
|
||||
var i = casePath.name;
|
||||
|
||||
self.mark(caseLocs[i]);
|
||||
|
||||
casePath.get("consequent").each(
|
||||
self.explodeStatement,
|
||||
self
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
this.mark(after);
|
||||
if (defaultLoc.value === -1) {
|
||||
this.mark(defaultLoc);
|
||||
assert.strictEqual(after.value, defaultLoc.value);
|
||||
}
|
||||
};
|
||||
|
||||
exports.IfStatement = function (path, stmt) {
|
||||
var elseLoc = stmt.alternate && loc();
|
||||
var after = loc();
|
||||
|
||||
this.jumpIfNot(
|
||||
this.explodeExpression(path.get("test")),
|
||||
elseLoc || after
|
||||
);
|
||||
|
||||
this.explodeStatement(path.get("consequent"));
|
||||
|
||||
if (elseLoc) {
|
||||
this.jump(after);
|
||||
this.mark(elseLoc);
|
||||
this.explodeStatement(path.get("alternate"));
|
||||
}
|
||||
|
||||
this.mark(after);
|
||||
};
|
||||
|
||||
exports.ReturnStatement = function (path) {
|
||||
this.emitAbruptCompletion({
|
||||
type: "return",
|
||||
value: this.explodeExpression(path.get("argument"))
|
||||
});
|
||||
};
|
||||
|
||||
exports.TryStatement = function (path, stmt) {
|
||||
var after = loc();
|
||||
var self = this;
|
||||
|
||||
var handler = stmt.handler;
|
||||
if (!handler && stmt.handlers) {
|
||||
handler = stmt.handlers[0] || null;
|
||||
}
|
||||
|
||||
var catchLoc = handler && loc();
|
||||
var catchEntry = catchLoc && new leap.CatchEntry(
|
||||
catchLoc,
|
||||
handler.param
|
||||
);
|
||||
|
||||
var finallyLoc = stmt.finalizer && loc();
|
||||
var finallyEntry = finallyLoc && new leap.FinallyEntry(finallyLoc);
|
||||
|
||||
var tryEntry = new leap.TryEntry(
|
||||
this.getUnmarkedCurrentLoc(),
|
||||
catchEntry,
|
||||
finallyEntry
|
||||
);
|
||||
|
||||
this.tryEntries.push(tryEntry);
|
||||
this.updateContextPrevLoc(tryEntry.firstLoc);
|
||||
|
||||
this.leapManager.withEntry(tryEntry, function () {
|
||||
this.explodeStatement(path.get("block"));
|
||||
|
||||
if (catchLoc) {
|
||||
if (finallyLoc) {
|
||||
// If we have both a catch block and a finally block, then
|
||||
// because we emit the catch block first, we need to jump over
|
||||
// it to the finally block.
|
||||
this.jump(finallyLoc);
|
||||
|
||||
} else {
|
||||
// If there is no finally block, then we need to jump over the
|
||||
// catch block to the fall-through location.
|
||||
this.jump(after);
|
||||
}
|
||||
|
||||
this.updateContextPrevLoc(self.mark(catchLoc));
|
||||
|
||||
var bodyPath = path.get("handler", "body");
|
||||
var safeParam = this.makeTempVar();
|
||||
this.clearPendingException(tryEntry.firstLoc, safeParam);
|
||||
|
||||
var catchScope = bodyPath.scope;
|
||||
var catchParamName = handler.param.name;
|
||||
t.assertCatchClause(catchScope.node);
|
||||
assert.strictEqual(catchScope.lookup(catchParamName), catchScope);
|
||||
|
||||
types.visit(bodyPath, {
|
||||
visitIdentifier: function (path) {
|
||||
if (path.value.name === catchParamName &&
|
||||
path.scope.lookup(catchParamName) === catchScope) {
|
||||
return safeParam;
|
||||
}
|
||||
this.traverse(path);
|
||||
}
|
||||
});
|
||||
|
||||
this.leapManager.withEntry(catchEntry, function () {
|
||||
this.explodeStatement(bodyPath);
|
||||
});
|
||||
}
|
||||
|
||||
if (finallyLoc) {
|
||||
this.updateContextPrevLoc(this.mark(finallyLoc));
|
||||
|
||||
this.leapManager.withEntry(finallyEntry, function () {
|
||||
this.explodeStatement(path.get("finalizer"));
|
||||
});
|
||||
|
||||
this.emit(t.callExpression(
|
||||
this.contextProperty("finish"),
|
||||
[finallyEntry.firstLoc]
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
this.mark(after);
|
||||
};
|
||||
|
||||
exports.ThrowStatement = function (path) {
|
||||
this.emit(t.throwStatement(
|
||||
this.explodeExpression(path.get("argument"))
|
||||
));
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user