Compare commits

...

192 Commits

Author SHA1 Message Date
Sebastian McKenzie
caf38e1962 v3.5.1 2015-02-08 21:04:05 +11:00
Sebastian McKenzie
4ccbee4639 fix linting errors 2015-02-08 20:59:48 +11:00
Sebastian McKenzie
84196a3a07 add 3.5.1 changelog 2015-02-08 20:57:58 +11:00
Ingvar Stepanyan
29361c055a Fix #718. 2015-02-08 11:56:39 +02:00
Sebastian McKenzie
4277265591 Merge branch 'master' of github.com:6to5/6to5 2015-02-08 20:40:47 +11:00
Sebastian McKenzie
812a2b315d bump acorn-6to5 2015-02-08 20:40:30 +11:00
Ingvar Stepanyan
0a1724fc3f Remove no more needed returnBlock helper. 2015-02-08 11:31:19 +02:00
Sebastian McKenzie
bcc9e016b1 only evaluate object destructuring pattern once 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
4ea0175ca7 simplify set template 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
799445c745 add property method assignment wrapper generator template 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
481ea12999 add cleanup internal transformer 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
de6b608dda add _declarations and _scopeInfo to t.inherits 2015-02-08 20:23:21 +11:00
Sebastian McKenzie
606f813822 enable traceur test suite by default 2015-02-08 20:23:21 +11:00
Sebastian McKenzie
e06c8cd106 support generators in nameMethod helper 2015-02-08 20:23:21 +11:00
Ingvar Stepanyan
9e3c67a8a2 Clean up functionChildrenVisitor a bit. 2015-02-08 10:53:09 +02:00
Ingvar Stepanyan
91362f80b1 Clean up transformations after #714.
Since now we have runtime helper, we don't need
expression -> statement conversions anymore.
2015-02-08 10:40:03 +02:00
Sebastian McKenzie
cde988f99f update 3.5.0 changelog 2015-02-08 16:53:33 +11:00
Sebastian McKenzie
9ec0854659 3.5.0 2015-02-08 16:37:13 +11:00
Sebastian McKenzie
bb17571e56 v3.5.0 2015-02-08 16:35:45 +11:00
Sebastian McKenzie
9161af58c0 fix linting errors 2015-02-08 16:32:08 +11:00
Sebastian McKenzie
e39f4e8025 update 3.5.0 changelog 2015-02-08 16:31:24 +11:00
Sebastian McKenzie
f5e9909e71 Merge pull request #716 from daliwali/master
Make `__esModule` property not enumerable
2015-02-08 16:30:26 +11:00
Sebastian McKenzie
46913fc55f add 3.5.0 changelog 2015-02-08 16:22:12 +11:00
Dali Zheng
d358a86e98 make __esModule property not enumerable 2015-02-07 21:19:11 -08:00
Sebastian McKenzie
055545980c update traceur test runner 2015-02-08 16:19:05 +11:00
Sebastian McKenzie
6fd7f9868e upgrade acorn-6to5 2015-02-08 16:18:54 +11:00
Sebastian McKenzie
e8184a9bc5 fix browser api location in browser test 2015-02-08 14:34:43 +11:00
Sebastian McKenzie
f74de3ef55 move destructuring and parameters.rest transformer to above blockScoping 2015-02-08 14:34:34 +11:00
Sebastian McKenzie
9624f8287d add checkNode to block scoped functions transformer 2015-02-08 14:34:10 +11:00
Sebastian McKenzie
e42d5a889e make destructuring in catch clauses block scoped and add support for non-variable destructuring in for-in/of heads 2015-02-08 14:33:55 +11:00
Sebastian McKenzie
4c8e6481b6 make default parameters iife invocation less serious 2015-02-08 09:54:24 +11:00
Sebastian McKenzie
0867df2691 fix ForOf block body not properly inheriting declarations 2015-02-08 09:50:12 +11:00
Sebastian McKenzie
b06f99ab30 add iife detection to non-identifier params in default parameters 2015-02-08 09:37:06 +11:00
Sebastian McKenzie
9afa3f6b58 add opts param to t.isReferencedIdentifier 2015-02-08 09:31:41 +11:00
Sebastian McKenzie
785cb4b72f allow optional transformer to be set via the whitelist 2015-02-08 09:31:30 +11:00
Sebastian McKenzie
dabe69856a add additional checks to transformers 2015-02-08 09:31:19 +11:00
Sebastian McKenzie
24e70802b5 fix block scoped tracking in functions - fixes #710 2015-02-08 09:31:04 +11:00
Sebastian McKenzie
c1ba55a52d Merge pull request #714 from RReverser/master
Added complete TCO (tail call optimization).
2015-02-08 08:55:19 +11:00
Ingvar Stepanyan
4c318166e1 Added complete TCO (tail call optimization).
Works across functions and generates simpler and faster code than #701.
Works even across files when used in conjunction with `runtime` option.

Closes #256.
2015-02-07 22:22:38 +02:00
Sebastian McKenzie
c0af67eca1 add support for super in object literals - fixes #411 2015-02-08 02:01:17 +11:00
Sebastian McKenzie
eb14f1da00 implement optional TDZ - fixes #563 2015-02-08 01:27:22 +11:00
Sebastian McKenzie
3361b81658 expose parentPath 2015-02-08 01:27:00 +11:00
Sebastian McKenzie
a15f218e9b dump code to esvalid errors 2015-02-08 01:26:46 +11:00
Sebastian McKenzie
067cf43f52 fix File::addHelper unknown helper error message 2015-02-08 00:01:26 +11:00
Sebastian McKenzie
689ce048e6 remove tail call exec test 2015-02-07 23:52:41 +11:00
Sebastian McKenzie
8a143bf957 use a template in tail call transformer - @RReverser 2015-02-07 23:52:35 +11:00
Sebastian McKenzie
9f7bcf585d remove dead TraversalContext code 2015-02-07 23:51:05 +11:00
Sebastian McKenzie
f9efd8a272 fix error message in File::addHelper 2015-02-07 23:50:56 +11:00
Sebastian McKenzie
8cd2326ff9 Merge branch 'master' of github.com:6to5/6to5 2015-02-07 23:37:51 +11:00
Sebastian McKenzie
eb1ae70bfa Merge pull request #701 from RReverser/master
Add tail recursion optimization.
2015-02-07 23:37:43 +11:00
Ingvar Stepanyan
24ef81908c Increase test timeout for Travis. 2015-02-07 14:34:23 +02:00
Ingvar Stepanyan
b53b41cef3 Provide placeholders for proper function length. 2015-02-07 14:26:03 +02:00
Sebastian McKenzie
ad245ed46a 3.4.1 2015-02-07 19:48:59 +11:00
Sebastian McKenzie
3f6199493e v3.4.1 2015-02-07 19:48:28 +11:00
Sebastian McKenzie
e06aac4783 Revert "make export { foo as default }; trigger common interop"
This reverts commit 07c7b5b419.
2015-02-07 19:40:49 +11:00
Sebastian McKenzie
6a5adfe338 update 3.4.1 changelog 2015-02-07 19:40:29 +11:00
Sebastian McKenzie
07c7b5b419 make export { foo as default }; trigger common interop 2015-02-07 19:29:59 +11:00
Sebastian McKenzie
7f985fe08a fix incorrect strict module formatter variable - fixes #706 2015-02-07 19:29:32 +11:00
Sebastian McKenzie
38f02a6429 add 3.4.1 changelog 2015-02-07 19:19:55 +11:00
Sebastian McKenzie
f943bdcac0 Merge branch 'master' of github.com:6to5/6to5 2015-02-07 19:18:29 +11:00
Sebastian McKenzie
8dc634edfc add options to require cache key - fixes #707 2015-02-07 19:18:12 +11:00
Sebastian McKenzie
05b9cf17f0 Merge pull request #708 from tricknotes/avoid-conflict
Switch short option of `--module-ids` from `-i` to `-M`
2015-02-07 19:12:22 +11:00
Ryunosuke SATO
69bbe89616 Switch short option of --module-ids from -i to -M
`-i` conflicts with `--optional` option.

```
$ bin/6to5/index.js --help | grep "\-i,"
    -i, --optional [list]        List of optional transformers to enable
    -i, --module-ids             Insert module id in modules
```
2015-02-07 16:37:38 +09:00
Sebastian McKenzie
6b49958f7c Merge branch 'master' of github.com:6to5/6to5 2015-02-07 15:59:15 +11:00
Sebastian McKenzie
e75ce94578 move reactCompat option onto an optional transformer 2015-02-07 15:59:00 +11:00
Sebastian McKenzie
f666473724 Merge pull request #705 from cesarandreu/patch-2
Add 6to5-runtime README
2015-02-07 13:54:58 +11:00
Cesar Andreu
ae817e3c9c Add 6to5-runtime README 2015-02-06 18:53:42 -08:00
Sebastian McKenzie
2e9352de14 3.4.0 2015-02-07 10:44:06 +11:00
Sebastian McKenzie
1e9e55ddef fix browser build location in makefile 2015-02-07 10:42:28 +11:00
Sebastian McKenzie
0799ed7116 v3.4.0 2015-02-07 10:41:38 +11:00
Sebastian McKenzie
5537250d4f fix linting errors 2015-02-07 10:40:01 +11:00
Sebastian McKenzie
7ada50937b add 3.4.0 changelog 2015-02-07 10:39:24 +11:00
Sebastian McKenzie
f2ae88af93 add commonStandard module formatter - fixes #675
will be merged into strict formatters in next major
TODO: rewrite all module formatters as they've gotten out of han
2015-02-07 10:31:52 +11:00
Sebastian McKenzie
726451f86f reverts d6b39bc89b 2015-02-07 09:54:18 +11:00
Sebastian McKenzie
306cfc6328 fix 3.3.12 changelog misspelling 2015-02-07 09:53:18 +11:00
Sebastian McKenzie
a051a47048 reorder types requires 2015-02-07 08:11:42 +11:00
Ingvar Stepanyan
5b2216b348 Add tail recursion optimization.
As per ES6, VMs should perform tail call optimization and prevent growth of call stack.
This adds tail call optimization for recursion case (when function has explicit name and calls itself in `return`).
Cross-function optimization is not currently performed as it's more complicated and requires value tracking.
2015-02-06 16:34:35 +02:00
Sebastian McKenzie
ad60d49611 fix bindingEquals in constants transformer 2015-02-06 23:35:19 +11:00
Sebastian McKenzie
a6d1a5a724 add bindingEquals, typeEquals, referenceEquals helper methods to Scope 2015-02-06 23:07:10 +11:00
Sebastian McKenzie
399d835285 fix linting errors 2015-02-06 23:06:54 +11:00
Sebastian McKenzie
b66367ddde change namespace of minification.propertyLiterals and minifciation.memberExpressionLiterals to es3 2015-02-06 22:42:16 +11:00
Sebastian McKenzie
37d29b7a6f clean up function scope collection - @RReverser 2015-02-06 22:04:13 +11:00
Sebastian McKenzie
1e708fb373 fix traverse test 2015-02-06 01:59:45 +11:00
Sebastian McKenzie
76ae1682a3 remove context arg in favor of this, rename TraversalIteration to TraversalPath, and remove ast handlers 2015-02-06 01:47:43 +11:00
Sebastian McKenzie
2ef0aa95c5 clean up indentation 2015-02-06 01:17:42 +11:00
Sebastian McKenzie
9cbb49c6b2 don't return the sourcemap when inline is requested - 6to5/grunt-6to5#18 2015-02-05 22:25:33 +11:00
Sebastian McKenzie
f04a734838 fix module ids shorthand arg - fixes #696 2015-02-05 22:19:39 +11:00
Sebastian McKenzie
beb5ccab25 split up traversal so it's easier to maintain and extend later on 2015-02-05 19:42:08 +11:00
Sebastian McKenzie
b8f8f24e82 add newline to es6 destructuring member expression test 2015-02-05 19:41:53 +11:00
Sebastian McKenzie
c35a007401 simplify replace supers helper 2015-02-05 19:41:37 +11:00
Sebastian McKenzie
e639c82f2f fix internal refactoring... 2015-02-05 14:08:02 +11:00
Sebastian McKenzie
f365cc1248 more internal rearchitecturing 2015-02-05 14:05:15 +11:00
Sebastian McKenzie
2b75c67448 better scope traversal inferType todo comments 2015-02-05 11:16:13 +11:00
Sebastian McKenzie
e5e9ae7e0f v3.3.12 2015-02-05 10:32:14 +11:00
Sebastian McKenzie
009422e997 add 3.3.12 changelog 2015-02-05 10:15:15 +11:00
Sebastian McKenzie
386e221a0f don't override core supported member expressions if there's a local binding 2015-02-05 09:53:12 +11:00
Sebastian McKenzie
58db94401e 3.3.11 2015-02-05 08:53:29 +11:00
Sebastian McKenzie
f9be9bab89 v3.3.11 2015-02-05 08:37:28 +11:00
Sebastian McKenzie
dc7e963c9f style fixes 2015-02-05 08:27:59 +11:00
Sebastian McKenzie
a786f39b1b 3.3.10 2015-02-04 23:26:12 +11:00
Sebastian McKenzie
95cf793df4 v3.3.10 2015-02-04 23:25:42 +11:00
Sebastian McKenzie
ea2ad96089 update 3.3.10 changelog 2015-02-04 23:24:13 +11:00
Sebastian McKenzie
4b2cf2e2c5 fix styling errors 2015-02-04 23:24:08 +11:00
Sebastian McKenzie
23b8c72e9a remove unused traverse requires 2015-02-04 23:22:26 +11:00
Sebastian McKenzie
80876a2c0a add 3.3.10 changelog 2015-02-04 23:20:53 +11:00
Sebastian McKenzie
c923010292 fix source map tests 2015-02-04 23:20:47 +11:00
Sebastian McKenzie
c84af909f7 track end of node positions for sourcemaps - fixes douglasduteil/isparta#8 2015-02-04 23:10:54 +11:00
Sebastian McKenzie
d6b39bc89b HomeObject isn't dynamic - fixes #690 2015-02-04 18:47:58 +11:00
Sebastian McKenzie
39fe737cb6 rename es7.objectSpread transformer to es7.objectRestSpread 2015-02-04 18:35:43 +11:00
Sebastian McKenzie
37ef976515 more cleanup of the destructuring transformer 2015-02-04 18:21:10 +11:00
Sebastian McKenzie
fa5a3022d4 clean up destructuring transformer 2015-02-04 17:48:27 +11:00
Sebastian McKenzie
58bed088f5 throw an error when destructuring a null or undefined value on an empty object pattern - fixes #681 2015-02-04 17:35:24 +11:00
Sebastian McKenzie
4f023e83f8 refactor traversals that have scopes to use the scope helper method 2015-02-04 13:25:23 +11:00
Sebastian McKenzie
7d950cd60a i made the javascripts faster with a transformer prepass to check what transformers actually have to be ran 2015-02-04 12:56:34 +11:00
Sebastian McKenzie
ffc9244f88 make #683 more inline with the official jsx compiler 2015-02-04 10:38:35 +11:00
Sebastian McKenzie
6ede3986c7 Merge branch 'master' of github.com:6to5/6to5 2015-02-04 10:23:29 +11:00
Sebastian McKenzie
5a81d22167 Merge pull request #683 from caseywebdev/concat-string-literals
Concatenate adjacent string literals in JSX
2015-02-04 10:22:51 +11:00
Sebastian McKenzie
2bf2e26a64 3.3.9 2015-02-04 10:15:19 +11:00
Sebastian McKenzie
ee466e90ca v3.3.9 2015-02-04 10:13:10 +11:00
Sebastian McKenzie
911e3939b9 remove class-super-constructor-call-check helper 2015-02-04 10:08:55 +11:00
Sebastian McKenzie
ca6f8e9a96 v3.3.8 2015-02-04 10:07:50 +11:00
Sebastian McKenzie
55f2cffc22 fix linting errors 2015-02-04 10:05:20 +11:00
Sebastian McKenzie
ca482b79ad add 3.3.8 changelog 2015-02-04 10:04:03 +11:00
Sebastian McKenzie
b1f0ecf244 update class super constructor inheritance tests 2015-02-04 10:03:57 +11:00
Sebastian McKenzie
36fa174901 change instance reference to this in class super constructor call template - fixes #689 2015-02-04 10:03:15 +11:00
Sebastian McKenzie
e8dc4628ae better handle spaces in IfStatement generator 2015-02-04 08:40:23 +11:00
Sebastian McKenzie
7a0dbb0203 fix node removal 2015-02-04 08:39:54 +11:00
Sebastian McKenzie
8d81a382f7 inline back the super constructor call helper - fixes #684 2015-02-04 08:39:45 +11:00
Sebastian McKenzie
86fbba08d8 add concise format option 2015-02-04 08:39:17 +11:00
Sebastian McKenzie
23c6e7e168 fix incorrect getThisReference bind - fixes #688 2015-02-04 08:26:18 +11:00
Sebastian McKenzie
c35f041091 simplify to.isFalsyExpression method 2015-02-04 08:25:40 +11:00
Sebastian McKenzie
618c6a8e67 add isLiteral to inferType 2015-02-04 08:25:15 +11:00
Sebastian McKenzie
23429f7b7f remove blank optimization 2015-02-04 08:25:00 +11:00
Sebastian McKenzie
d6052b483a add 6to5-minify to package.json 2015-02-04 08:24:53 +11:00
Sebastian McKenzie
3b3255a964 delegate removal of nodes in traversal to exitNode 2015-02-04 08:24:38 +11:00
Sebastian McKenzie
49847e70af add some minification transformers 2015-02-04 08:23:58 +11:00
Sebastian McKenzie
c228d76e44 add 6to5-minify 2015-02-04 08:23:49 +11:00
Casey Foster
2562b0c201 Concatenate adjacent string literals in JSX 2015-02-03 10:46:54 -06:00
Sebastian McKenzie
6da6bc3eb8 remove callExpression type inferrence 2015-02-03 22:32:00 +11:00
Sebastian McKenzie
bbcfc3c9f2 3.3.7 2015-02-03 22:29:09 +11:00
Sebastian McKenzie
12b1de7c9d v3.3.7 2015-02-03 22:27:37 +11:00
Sebastian McKenzie
721636f475 add 3.3.7 changelog 2015-02-03 22:25:33 +11:00
Sebastian McKenzie
4c94941ceb force .js extension when writing files to directories with 6to5 2015-02-03 22:25:27 +11:00
Sebastian McKenzie
f06535e915 rename Scope.init to Scope.crawl 2015-02-03 22:22:36 +11:00
Sebastian McKenzie
389914c427 add use-strict to valid node flags - fixes #667 2015-02-03 22:21:55 +11:00
Sebastian McKenzie
c7f5715d8e fix boolean stripping from 6to5-node - fixes #679 2015-02-03 22:21:09 +11:00
Sebastian McKenzie
29f866525e clean up scope tracking and add some simple flow type tracking and inferrence #653 2015-02-03 21:06:21 +11:00
Sebastian McKenzie
de61455a55 3.3.5 2015-02-03 21:05:36 +11:00
Sebastian McKenzie
fd579a8772 v3.3.5 2015-02-03 20:13:43 +11:00
Sebastian McKenzie
8e708906a8 fix linting errors 2015-02-03 20:11:38 +11:00
Sebastian McKenzie
b7680059c8 add 3.3.5 changelog 2015-02-03 20:09:45 +11:00
Sebastian McKenzie
239369314c more scope refactoring - fixes #676 2015-02-03 20:06:27 +11:00
Sebastian McKenzie
f2d1fc47d1 Merge branch 'master' of github.com:6to5/6to5 2015-02-03 19:55:29 +11:00
Sebastian McKenzie
aab35736c5 Merge pull request #677 from jayphelps/merica
First pass at converting identifiers/words from en-au -> en-us
2015-02-03 19:37:33 +11:00
Sebastian McKenzie
a9405e5e80 clean up scope API 2015-02-03 19:33:32 +11:00
Jay Phelps
9880990fa7 First pass at converting identifiers/words from en-au -> en-us 2015-02-03 00:08:43 -08:00
Sebastian McKenzie
6674611b26 Merge pull request #674 from johlrich/patch-1
Change getModuleName regex to only remove extenion
2015-02-03 17:54:04 +11:00
Jonathan
e92ec6aba7 Change getModuleName regex to only remove extenion
Given a names like: "some.module.js" and "some.other.module.js" the current regex in DefaultFormatter.prototype.getModuleName will overmatch and only return "some" as the module name in both cases.

Changing the . character class to \w will make sure it does not pick up additional sections and returns "some.module" and "some.other.module" for the names
2015-02-03 01:52:24 -05:00
Sebastian McKenzie
1801b725bd remove stupid jscs rules (they don't take into account reserved words ugh) and let jshint handle them 2015-02-03 15:35:44 +11:00
Sebastian McKenzie
72de8f5c9b fix class tests to reflect new call behaviour 2015-02-03 15:35:24 +11:00
Sebastian McKenzie
895d965568 fix linting errors 2015-02-03 15:17:33 +11:00
Sebastian McKenzie
3a11c7d46b as per "ES6 February 2, 2015 Draft Rev 32" "Constructors defined using class definition syntax throw when called as functions" 2015-02-03 15:16:16 +11:00
Sebastian McKenzie
92d9b3ff5f make it illegal to export a __esModule property - #673 2015-02-03 14:41:11 +11:00
Sebastian McKenzie
630f1717f0 clean up scope collision tracking and constants transformer - fixes #331 2015-02-03 13:20:52 +11:00
Sebastian McKenzie
e6e93840a6 check for scope collisions in constants transformer - fixes #331 2015-02-03 12:03:38 +11:00
Sebastian McKenzie
b2ad79cf88 rename t.getDeclarations to the WAY more reflective t.getBindingIdentifiers 2015-02-03 12:03:21 +11:00
Sebastian McKenzie
706797eb47 rename LetScoping to BlockScoping 2015-02-03 10:23:56 +11:00
Sebastian McKenzie
4163d1372a fix istanbul interop - closes #660 2015-02-03 10:23:47 +11:00
Sebastian McKenzie
4413da8d6e fix up whitespace on non empty last line JSX literals - fixes #668 2015-02-03 09:31:30 +11:00
Sebastian McKenzie
8e23d623c8 split up util.pushMutatorMap and util.buildDefineProperties 2015-02-03 09:30:52 +11:00
Sebastian McKenzie
e712c5225b use the current file basename for the displayName of export default React.createClass - 6to5/6to5-sublime#21 2015-02-02 23:48:03 +11:00
Sebastian McKenzie
8bdb723004 3.3.4 2015-02-02 21:37:11 +11:00
Sebastian McKenzie
9f912f548e v3.3.4 2015-02-02 21:36:04 +11:00
Sebastian McKenzie
41d721e372 fix source map tests 2015-02-02 21:32:45 +11:00
Sebastian McKenzie
df6ffe025c remove camelcase rule from jscs and let jshint handle it 2015-02-02 21:19:23 +11:00
Sebastian McKenzie
28b6b4af44 fix linting errors 2015-02-02 21:17:54 +11:00
Sebastian McKenzie
9e80071caa add 3.3.4 changelog 2015-02-02 21:16:53 +11:00
Sebastian McKenzie
0da4303358 remove automatic --harmony flag from 6to5-node 2015-02-02 21:14:23 +11:00
Sebastian McKenzie
83e225f30a simplify source maps, fixes weird tracking bug - fixes #658 2015-02-02 21:14:14 +11:00
Sebastian McKenzie
420505ca40 remove console.log debug 2015-02-02 21:13:40 +11:00
Sebastian McKenzie
f9a26fd903 better optimisation base 2015-02-02 20:28:34 +11:00
Sebastian McKenzie
ca0539190e add some monkeypatched istanbul interop - closes #660 2015-02-02 20:28:24 +11:00
Sebastian McKenzie
2e3226b520 fix 3.3.3 changelog sections 2015-02-02 10:55:49 +11:00
Sebastian McKenzie
7959852eeb 3.3.3 2015-02-02 10:55:43 +11:00
Sebastian McKenzie
c129eba712 v3.3.3 2015-02-02 10:52:56 +11:00
Sebastian McKenzie
0e2d7fa941 remove throw expectation on undefiend this tests 2015-02-02 10:50:29 +11:00
Sebastian McKenzie
0b33a62032 fix linting errors 2015-02-02 10:48:18 +11:00
Sebastian McKenzie
6919ed2b34 add 3.3.3 changelog 2015-02-02 10:46:44 +11:00
Sebastian McKenzie
435320e3f9 selfContainify regenerator runtime when building 6to5-runtime - fixes #659 2015-02-02 10:45:26 +11:00
Sebastian McKenzie
7b846af965 3.3.2 2015-02-02 10:45:05 +11:00
Sebastian McKenzie
18b836c16a add allowPartial option to t.buildMatchMemberExpression, fix t.isReferenced on Property nodes - fixes #656 2015-02-02 10:44:56 +11:00
Sebastian McKenzie
fb360039ce remap top level this to undefined - #562 2015-02-02 10:44:17 +11:00
293 changed files with 3793 additions and 2321 deletions

View File

@@ -6,6 +6,6 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.js]
[*.{js,json}]
indent_style = space
indent_size = 2

View File

@@ -14,7 +14,6 @@
},
"disallowSpacesInsideArrayBrackets": true,
"disallowSpacesInsideParentheses": true,
"disallowQuotedKeysInObjects": true,
"disallowSpaceAfterObjectKeys": true,
"disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpaceBeforePostfixUnaryOperators": true,
@@ -33,10 +32,8 @@
"requireCommaBeforeLineBreak": true,
"requireSpaceBeforeBinaryOperators": true,
"requireSpaceAfterBinaryOperators": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"requireLineFeedAtFileEnd": true,
"requireCapitalizedConstructors": true,
"requireDotNotation": true,
"requireSpacesInForStatement": true,
"requireCurlyBraces": [
"do"
@@ -52,7 +49,8 @@
"return",
"try",
"catch",
"typeof"
"typeof",
"function"
],
"validateLineBreaks": "LF",
"validateQuoteMarks": "\"",

View File

@@ -2,6 +2,7 @@
"esnext": true,
"indent": 2,
"freeze": true,
"validthis": true,
"camelcase": true,
"unused": true,
"eqnull": true,

View File

@@ -11,6 +11,107 @@
_Note: Gaps between patch versions are faulty/broken releases._
## 3.5.1
* **Polish**
* Allow tail calls to work across files without the runtime.
* **Internal**
* Upgrade `acorn-6to5`.
## 3.5.0
* **Bug Fix**
* Destructuring patterns as the left operator in `ForInStatement`/`ForOfStatement`.
* **Polish**
* Make default parameter IIFE invocation smarter.
* Make `__esModule` flag non-enumerable. Thanks [@daliwali](https://github.com/daliwali)!
* **Internal**
* More performance improvements.
* Parsing is now ~30% faster thanks to [marijnh/acorn@7264bc0178e7e6af7cfe02e9e0c6b26ee0e6007f](https://github.com/marijnh/acorn/commit/7264bc0178e7e6af7cfe02e9e0c6b26ee0e6007f).
* **New Feature**
* Optional `es6.blockScopingTDZ` is now completely functional and handles all edgecases.
* `super` in object literals.
* Tail call optimisation. Thanks [@RReverser](https://github.com/RReverser)!
## 3.4.1
* **Bug Fix**
* Fix conflicting `--module-ids` shorthand arg in `$ 6to5`.
* Add require hook options to cache key.
* Fix strict module formatter.
## 3.4.0
* **New Feature**
* Add `commonStandard` module formatter.
* **Bug Fix**
* Fix conflicting `--module-ids` shorthand arg in `$ 6to5`.
* **Internal**
* Lots of internal refactoring with scope tracking and traversal.
* **Polish**
* Don't return `map` in the API result if `sourceMap` was set to `"inline"`.
## 3.3.12
* **Bug Fix**
* Don't override `MemberExpression`s with `core-js` in `selfContained` if a local binding exists.
## 3.3.11
* **Bug Fix**
* Fix the require cache.
## 3.3.10
* **Internal**
* Restructure transformers so they're only ran if the AST contains nodes that they need to worry about. Improves transpilation speed significantly.
* **Bug Fix**
* Fix source maps not tracking end of node locations.
* **Spec Compliancy**
* Use static super references as the home object is actually done at definition time.
* **Polish**
* Force the `es6.destructuring` transformer to be whitelisted when the `es7.objectSpread` transformer is.
* Join sibling string literals when creating JSX.
## 3.3.9
* **Bug Fix**
* Fix super inside of functions.
* Fix super constructor inheritance.
## 3.3.7
* **Bug Fix**
* Add `--use-strict` to valid node flags in `6to5-node`.
* Fix booleans not being properly stripped from the arguments in `6to5-node`.
* Force `.js` extension when writing files to directories with `6to5`.
## 3.3.5
* **Bug Fix**
* Fix block scoping inside of while loops.
* Make module name regex more conservative. Thanks [@johlrich](https://github.com/johlrich)!
* Fix block scoping of constants.
* Fix istanbul interop.
* Make JSX transforming more inline with the official transformer with spaces after non-empty last lines.
* **Polish**
* Make it illegal to export a property called `__esModule`.
## 3.3.4
* **Polish**
* Add istanbul `require` interop.
* **Bug Fix**
* Fix incorrect source map column tracking in specific scenarios.
## 3.3.3
* **Polish**
* Remap top level `this` to `undefined` instead of throwing an error.
* **Bug Fix**
* Run `selfContained` transformer over the regenerator runtime when building `6to5-runtime`.
* Fix `t.isReferenced` not properly allowing `value` nodes.
## 3.3.1
* **Bug Fix**
@@ -318,8 +419,8 @@ _Note: Gaps between patch versions are faulty/broken releases._
* **Polish**
* Rest parameters now allocate the array before populating.
* **Internal**
* `for...in` loops have been changed to optimised `for` loops - better performance and no enumeration of protoype keys.
* Parts of the code generator have now been optimised thanks to [gaearon](https://github.com/gaearon).
* `for...in` loops have been changed to optimized `for` loops - better performance and no enumeration of protoype keys.
* Parts of the code generator have now been optimized thanks to [gaearon](https://github.com/gaearon).
## 2.12.3
@@ -342,7 +443,7 @@ _Note: Gaps between patch versions are faulty/broken releases._
* **Bug Fix**
* Support non-string JSX literals.
* **New Feature**
* Loose mode for some transformers that enables non-spec behaviour.
* Loose mode for some transformers that enables non-spec behavior.
* **Internal**
* Uglify `--mangle sort` has been added to the build script, cutting minified scripts in half.
@@ -780,7 +881,7 @@ _Note: Gaps between patch versions are faulty/broken releases._
## 1.13.2
* Optimise `Array.from` usage by adding a helper method.
* Optimize `Array.from` usage by adding a helper method.
* Upgrade `acorn-6to5`.
## 1.13.1

View File

@@ -18,7 +18,7 @@ build:
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
node $(BROWSERIFY_CMD) lib/6to5/api/browser.js -s to5 >dist/6to5.js
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
node bin/6to5-runtime >dist/runtime.js
@@ -92,7 +92,7 @@ publish:
make publish-core
make publish-runtime
rm -rf templates.json browser.js browser-polyfill.js
rm -rf templates.json browser.js browser-polyfill.js runtime.js
publish-runtime:
cd packages; \

View File

@@ -1,3 +1,3 @@
# Notes
* Wildcard exports/imports wont normalise if `export default` is a non-object. See [#224](https://github.com/6to5/6to5/issues/224).
* Wildcard exports/imports wont normalize if `export default` is a non-object. See [#224](https://github.com/6to5/6to5/issues/224).

7
bin/6to5-minify Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env node
var opts = require("./6to5").opts;
opts.optional = (opts.optional || []).concat("minification");
opts.format = {
compact: true
};

View File

@@ -5,7 +5,7 @@
* when found, before invoking the "real" _6to5-node(1) executable.
*/
var args = ["--harmony", __dirname + "/_6to5-node"];
var args = [__dirname + "/_6to5-node"];
process.argv.slice(2).forEach(function(arg){
var flag = arg.split("=")[0];
@@ -35,6 +35,7 @@ process.argv.slice(2).forEach(function(arg){
case "--prof":
case "--throw-deprecation":
case "--trace-deprecation":
case "--use-strict":
args.unshift(arg);
break;

View File

@@ -11,6 +11,9 @@ module.exports = function (commander, filenames, opts) {
}
var write = function (src, relative) {
// remove extension and then append back on .js
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
var dest = path.join(commander.outDir, relative);
var data = util.compile(src, { sourceMapName: dest });

View File

@@ -23,7 +23,7 @@ commander.option("-L, --loose [list]", "List of transformers to enable loose mod
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
commander.option("-c, --remove-comments", "Remove comments from the compiled code", false);
commander.option("-m, --module-ids", "Insert module id in modules", false);
commander.option("-M, --module-ids", "Insert module id in modules", false);
commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code");
commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false);
@@ -114,12 +114,17 @@ exports.opts = {
loose: commander.loose
};
var fn;
setTimeout(function () {
// this is just a hack to give `6to5-minify` and other files including this
// time to modify `exports.opts`
if (commander.outDir) {
fn = require("./dir");
} else {
fn = require("./file");
}
var fn;
fn(commander, filenames, exports.opts);
if (commander.outDir) {
fn = require("./dir");
} else {
fn = require("./file");
}
fn(commander, filenames, exports.opts);
}, 0);

View File

@@ -2,7 +2,7 @@ var readdir = require("fs-readdir-recursive");
var index = require("./index");
var util = require("../../lib/6to5/util");
var path = require("path");
var to5 = require("../../lib/6to5");
var to5 = require("../../lib/6to5/api/node");
var fs = require("fs");
var _ = require("lodash");

View File

@@ -4,7 +4,7 @@ var commander = require("commander");
var Module = require("module");
var path = require("path");
var repl = require("repl");
var to5 = require("../lib/6to5");
var to5 = require("../lib/6to5/api/node");
var util = require("../lib/6to5/util");
var vm = require("vm");
var _ = require("lodash");
@@ -72,7 +72,8 @@ if (program.eval || program.print) {
}
if (arg[0] === "-") {
if (program[arg.slice(2)]) {
var parsedArg = program[arg.slice(2)];
if (parsedArg && parsedArg !== true) {
ignoreNext = true;
}
} else {

View File

@@ -1,8 +1,8 @@
"use strict";
var transform = module.exports = require("./transformation");
var transform = module.exports = require("../transformation");
transform.version = require("../../package").version;
transform.version = require("../../../package").version;
transform.transform = transform;

View File

@@ -1,24 +1,24 @@
"use strict";
var transform = require("./transformation");
var util = require("./util");
var fs = require("fs");
var isFunction = require("lodash/lang/isFunction");
var transform = require("../transformation");
var util = require("../util");
var fs = require("fs");
exports.version = require("../../package").version;
exports.version = require("../../../package").version;
exports.runtime = require("./build-runtime");
exports.runtime = require("../build-runtime");
exports.types = require("./types");
exports.types = require("../types");
exports.register = function (opts) {
var register = require("./register");
var register = require("./register/node");
if (opts != null) register(opts);
return register;
};
exports.polyfill = function () {
require("./polyfill");
require("../polyfill");
};
exports.canCompile = util.canCompile;

View File

@@ -4,4 +4,4 @@
module.exports = function () {};
require("./polyfill");
require("../../polyfill");

View File

@@ -12,14 +12,6 @@ exports.save = function () {
};
exports.load = function () {
if (!fs.existsSync(FILENAME)) return;
try {
data = JSON.parse(fs.readFileSync(FILENAME));
} catch (err) {
return;
}
process.on("exit", exports.save);
var sigint = function () {
@@ -29,6 +21,14 @@ exports.load = function () {
};
process.on("SIGINT", sigint);
if (!fs.existsSync(FILENAME)) return;
try {
data = JSON.parse(fs.readFileSync(FILENAME));
} catch (err) {
return;
}
};
exports.get = function () {

View File

@@ -0,0 +1,152 @@
"use strict";
require("../../polyfill");
var sourceMapSupport = require("source-map-support");
var registerCache = require("./cache");
var extend = require("lodash/object/extend");
var each = require("lodash/collection/each");
var util = require("../../util");
var to5 = require("../node");
var fs = require("fs");
sourceMapSupport.install({
retrieveSourceMap: function (source) {
var map = maps && maps[source];
if (map) {
return {
url: null,
map: map
};
} else {
return null;
}
}
});
//
registerCache.load();
var cache = registerCache.get();
//
var transformOpts = {};
var ignoreRegex = /node_modules/;
var onlyRegex;
var exts = {};
var maps = {};
var mtime = function (filename) {
return +fs.statSync(filename).mtime;
};
var compile = function (filename) {
var result;
var cacheKey = filename + ":" + JSON.stringify(transformOpts);
if (cache) {
var cached = cache[cacheKey];
if (cached && cached.mtime === mtime(filename)) {
result = cached;
}
}
if (!result) {
result = to5.transformFileSync(filename, extend({
sourceMap: true,
ast: false
}, transformOpts));
}
if (cache) {
result.mtime = mtime(filename);
cache[cacheKey] = result;
}
maps[filename] = result.map;
return result.code;
};
var shouldIgnore = function (filename) {
return (ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename));
};
var istanbulMonkey = {};
if (process.env.running_under_istanbul) { // jshint ignore:line
// we need to monkey patch fs.readFileSync so we can hook into
// what istanbul gets, it's extremely dirty but it's the only way
var _readFileSync = fs.readFileSync;
fs.readFileSync = function (filename) {
if (istanbulMonkey[filename]) {
delete istanbulMonkey[filename];
var code = compile(filename);
istanbulMonkey[filename] = true;
return code;
} else {
return _readFileSync.apply(this, arguments);
}
};
}
var istanbulLoader = function (m, filename, old) {
istanbulMonkey[filename] = true;
old(m, filename);
};
var normalLoader = function (m, filename) {
m._compile(compile(filename), filename);
};
var registerExtension = function (ext) {
var old = require.extensions[ext];
var loader = normalLoader;
if (process.env.running_under_istanbul) loader = istanbulLoader; // jshint ignore:line
require.extensions[ext] = function (m, filename) {
if (shouldIgnore(filename)) {
old(m, filename);
} else {
loader(m, filename, old);
}
};
};
var hookExtensions = function (_exts) {
each(exts, function (old, ext) {
require.extensions[ext] = old;
});
exts = {};
each(_exts, function (ext) {
exts[ext] = require.extensions[ext];
registerExtension(ext);
});
};
hookExtensions(util.canCompile.EXTENSIONS);
module.exports = function (opts) {
// normalize options
opts = opts || {};
if (opts.only != null) onlyRegex = util.regexify(opts.only);
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
if (opts.cache === false) cache = null;
delete opts.extensions;
delete opts.ignore;
delete opts.cache;
delete opts.only;
extend(transformOpts, opts);
};

View File

@@ -1,4 +1,4 @@
var File = require("./file");
var File = require("./transformation/file");
var util = require("./util");
var each = require("lodash/collection/each");
var t = require("./types");

View File

@@ -1,7 +1,7 @@
module.exports = detect;
var SYNTAX_KEYS = require("./syntax-keys");
var traverse = require("../traverse");
var traverse = require("../traversal");
var visitors = traverse.explode(require("./visitors"));
function detect(ast) {

View File

@@ -2,10 +2,10 @@
module.exports = Buffer;
var util = require("../util");
var isNumber = require("lodash/lang/isNumber");
var isBoolean = require("lodash/lang/isBoolean");
var contains = require("lodash/collection/contains");
var isNumber = require("lodash/lang/isNumber");
var util = require("../util");
function Buffer(position, format) {
this.position = position;
@@ -19,7 +19,7 @@ Buffer.prototype.get = function () {
};
Buffer.prototype.getIndent = function () {
if (this.format.compact) {
if (this.format.compact || this.format.concise) {
return "";
} else {
return util.repeat(this._indent, this.format.indent.style);
@@ -53,10 +53,12 @@ Buffer.prototype.rightBrace = function () {
Buffer.prototype.keyword = function (name) {
this.push(name);
this.push(" ");
this.space();
};
Buffer.prototype.space = function () {
if (this.format.compact) return;
if (this.buf && !this.isLast([" ", "\n"])) {
this.push(" ");
}
@@ -70,7 +72,7 @@ Buffer.prototype.removeLast = function (cha) {
};
Buffer.prototype.newline = function (i, removeLast) {
if (this.format.compact) {
if (this.format.compact || this.format.concise) {
this.space();
return;
}

View File

@@ -17,7 +17,7 @@ exports.UnaryExpression = function (node, print) {
}
this.push(node.operator);
if (hasSpace) this.space();
if (hasSpace) this.push(" ");
print(node.argument);
};
@@ -33,9 +33,13 @@ exports.UpdateExpression = function (node, print) {
exports.ConditionalExpression = function (node, print) {
print(node.test);
this.push(" ? ");
this.space();
this.push("?");
this.space();
print(node.consequent);
this.push(" : ");
this.space();
this.push(":");
this.space();
print(node.alternate);
};
@@ -44,13 +48,13 @@ exports.NewExpression = function (node, print) {
print(node.callee);
if (node.arguments.length || this.format.parentheses) {
this.push("(");
print.join(node.arguments, { separator: ", " });
print.list(node.arguments);
this.push(")");
}
};
exports.SequenceExpression = function (node, print) {
print.join(node.expressions, { separator: ", " });
print.list(node.expressions);
};
exports.ThisExpression = function () {
@@ -72,9 +76,7 @@ exports.CallExpression = function (node, print) {
separator += " ";
}
print.join(node.arguments, {
separator: separator
});
print.list(node.arguments, { separator: separator });
if (node._prettyCall) {
this.newline();
@@ -115,10 +117,11 @@ exports.BinaryExpression =
exports.LogicalExpression =
exports.AssignmentPattern =
exports.AssignmentExpression = function (node, print) {
// todo: add cases where the spaces can be dropped when in compact mode
print(node.left);
this.space();
this.push(" ");
this.push(node.operator);
this.space();
this.push(" ");
print(node.right);
};

View File

@@ -75,6 +75,4 @@ exports.JSXClosingElement = function (node, print) {
this.push(">");
};
exports.JSXEmptyExpression = function () {
};
exports.JSXEmptyExpression = function () {};

View File

@@ -4,11 +4,7 @@ var t = require("../../types");
exports._params = function (node, print) {
this.push("(");
print.join(node.params, {
separator: ", "
});
print.list(node.params);
this.push(")");
};
@@ -45,11 +41,14 @@ exports.FunctionExpression = function (node, print) {
if (node.async) this.push("async ");
this.push("function");
if (node.generator) this.push("*");
this.push(" ");
if (node.id) {
this.space();
this.push(" ");
print(node.id);
} else {
this.space();
}
this._params(node, print);
this.space();
print(node.body);

View File

@@ -23,6 +23,11 @@ exports.IfStatement = function (node, print) {
if (node.alternate) {
if (this.isLast("}")) this.push(" ");
this.keyword("else");
if (this.format.format && !t.isBlockStatement(node.alternate)) {
this.push(" ");
}
print.indentOnComments(node.alternate);
}
};
@@ -190,7 +195,7 @@ exports.VariableDeclaration = function (node, print, parent) {
sep += " ";
}
print.join(node.declarations, { separator: sep });
print.list(node.declarations, { separator: sep });
if (!t.isFor(parent)) {
this.semicolon();

View File

@@ -27,7 +27,7 @@ exports.ObjectPattern = function (node, print) {
this.push("{");
this.space();
print.join(props, { separator: ", ", indent: true });
print.list(props, { indent: true });
this.space();
this.push("}");
@@ -49,7 +49,8 @@ exports.Property = function (node, print) {
if (node.shorthand) return;
}
this.push(": ");
this.push(":");
this.space();
print(node.value);
}
};
@@ -71,7 +72,7 @@ exports.ArrayPattern = function (node, print) {
// both (all) of the holes.
self.push(",");
} else {
if (i > 0) self.push(" ");
if (i > 0 && !self.format.compact) self.push(" ");
print(elem);
if (i < len - 1) self.push(",");
}
@@ -93,8 +94,10 @@ exports.Literal = function (node) {
});
this.push(val);
} else if (type === "boolean" || type === "number") {
this.push(JSON.stringify(val));
} else if (type === "number") {
this.push(val + "");
} else if (type === "boolean") {
this.push(val ? "true" : "false");
} else if (node.regex) {
this.push("/" + node.regex.pattern + "/" + node.regex.flags);
} else if (val === null) {

View File

@@ -12,19 +12,20 @@ var Whitespace = require("./whitespace");
var SourceMap = require("./source-map");
var Position = require("./position");
var Buffer = require("./buffer");
var extend = require("lodash/object/extend");
var merge = require("lodash/object/merge");
var each = require("lodash/collection/each");
var util = require("../util");
var n = require("./node");
var t = require("../types");
var each = require("lodash/collection/each");
var extend = require("lodash/object/extend");
var merge = require("lodash/object/merge");
function CodeGenerator(ast, opts, code) {
opts = opts || {};
this.comments = ast.comments || [];
this.tokens = ast.tokens || [];
this.format = CodeGenerator.normaliseOptions(code, opts);
this.format = CodeGenerator.normalizeOptions(code, opts);
this.opts = opts;
this.ast = ast;
this.whitespace = new Whitespace(this.tokens, this.comments);
@@ -39,7 +40,7 @@ each(Buffer.prototype, function (fn, key) {
};
});
CodeGenerator.normaliseOptions = function (code, opts) {
CodeGenerator.normalizeOptions = function (code, opts) {
var style = " ";
if (code) {
var indent = detectIndent(code).indent;
@@ -50,6 +51,7 @@ CodeGenerator.normaliseOptions = function (code, opts) {
parentheses: true,
comments: opts.comments == null || opts.comments,
compact: false,
concise: false,
indent: {
adjustMultilineComment: true,
style: style,
@@ -111,6 +113,16 @@ CodeGenerator.prototype.buildPrint = function (parent) {
return self.printJoin(print, nodes, opts);
};
print.list = function (items, opts) {
opts = opts || {};
var sep = opts.separator || ", ";
if (self.format.compact) sep = ",";
opts.separator = sep;
print.join(items, opts);
};
print.block = function (node) {
return self.printBlock(print, node);
};
@@ -129,9 +141,9 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
node._compact = true;
}
var oldCompact = this.format.compact;
var oldConcise = this.format.concise;
if (node._compact) {
this.format.compact = true;
this.format.concise = true;
}
var self = this;
@@ -199,7 +211,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
throw new ReferenceError("unknown node of type " + JSON.stringify(node.type) + " with constructor " + JSON.stringify(node && node.constructor.name));
}
this.format.compact = oldCompact;
this.format.concise = oldConcise;
};
CodeGenerator.prototype.printJoin = function (print, nodes, opts) {

View File

@@ -48,8 +48,6 @@ SourceMap.prototype.mark = function (node, type) {
var original = loc[type];
if (generated.line === original.line && generated.column === original.column) return; // nothing to map
map.addMapping({
source: this.opts.sourceFileName,
generated: generated,

View File

@@ -0,0 +1,9 @@
var t = require("../types");
module.exports = function (ast, comments, tokens) {
if (ast && ast.type === "Program") {
return t.file(ast, comments || [], tokens || []);
} else {
throw new Error("Not a valid ast?");
}
};

49
lib/6to5/helpers/parse.js Normal file
View File

@@ -0,0 +1,49 @@
var normalizeAst = require("./normalize-ast");
var estraverse = require("estraverse");
var codeFrame = require("./code-frame");
var acorn = require("acorn-6to5");
module.exports = function (opts, code, callback) {
try {
var comments = [];
var tokens = [];
var ast = acorn.parse(code, {
allowImportExportEverywhere: opts.allowImportExportEverywhere,
allowReturnOutsideFunction: !opts._anal,
ecmaVersion: opts.experimental ? 7 : 6,
playground: opts.playground,
strictMode: opts.strictMode,
onComment: comments,
locations: true,
onToken: tokens,
ranges: true
});
estraverse.attachComments(ast, comments, tokens);
ast = normalizeAst(ast, comments, tokens);
if (callback) {
return callback(ast);
} else {
return ast;
}
} catch (err) {
if (!err._6to5) {
err._6to5 = true;
var message = opts.filename + ": " + err.message;
var loc = err.loc;
if (loc) {
var frame = codeFrame(code, loc.line, loc.column + 1);
message += frame;
}
if (err.stack) err.stack = err.stack.replace(err.message, message);
err.message = message;
}
throw err;
}
};

View File

@@ -1,7 +1,7 @@
"use strict";
var t = require("./types");
var extend = require("lodash/object/extend");
var t = require("./types");
require("./types/node");

View File

@@ -1,108 +0,0 @@
"use strict";
require("./polyfill");
var sourceMapSupport = require("source-map-support");
var registerCache = require("./register-cache");
var util = require("./util");
var to5 = require("./index");
var fs = require("fs");
var extend = require("lodash/object/extend");
var each = require("lodash/collection/each");
sourceMapSupport.install({
retrieveSourceMap: function (source) {
var map = maps && maps[source];
if (map) {
return {
url: null,
map: map
};
} else {
return null;
}
}
});
//
registerCache.load();
var cache = registerCache.get();
//
var transformOpts = {};
var ignoreRegex = /node_modules/;
var onlyRegex;
var whitelist = [];
var exts = {};
var maps = {};
var old = require.extensions[".js"];
var mtime = function (filename) {
return +fs.statSync(filename).mtime;
};
var loader = function (m, filename) {
if ((ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename))) {
return old.apply(this, arguments);
}
var result;
if (cache) {
var cached = cache[filename];
if (cached && cached.mtime === mtime(filename)) {
result = cached;
}
}
result = result || to5.transformFileSync(filename, extend({
whitelist: whitelist,
sourceMap: true,
ast: false
}, transformOpts));
if (cache) {
result.mtime = mtime(filename);
cache[filename] = result;
}
maps[filename] = result.map;
m._compile(result.code, filename);
};
var hookExtensions = function (_exts) {
each(exts, function (old, ext) {
require.extensions[ext] = old;
});
exts = {};
each(_exts, function (ext) {
exts[ext] = require.extensions[ext];
require.extensions[ext] = loader;
});
};
hookExtensions(util.canCompile.EXTENSIONS);
module.exports = function (opts) {
// normalise options
opts = opts || {};
if (opts.only != null) onlyRegex = util.regexify(opts.only);
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
if (opts.cache === false) cache = null;
delete opts.extensions;
delete opts.ignore;
delete opts.cache;
delete opts.only;
extend(transformOpts, opts);
};

View File

@@ -4,16 +4,18 @@ module.exports = File;
var SHEBANG_REGEX = /^\#\!.*/;
var transform = require("./transformation");
var generate = require("./generation");
var clone = require("./helpers/clone");
var Scope = require("./traverse/scope");
var util = require("./util");
var t = require("./types");
var contains = require("lodash/collection/contains");
var each = require("lodash/collection/each");
var defaults = require("lodash/object/defaults");
var isFunction = require("lodash/lang/isFunction");
var transform = require("./index");
var generate = require("../generation");
var defaults = require("lodash/object/defaults");
var contains = require("lodash/collection/contains");
var clone = require("../helpers/clone");
var parse = require("../helpers/parse");
var Scope = require("../traversal/scope");
var util = require("../util");
var path = require("path");
var each = require("lodash/collection/each");
var t = require("../types");
function File(opts) {
this.dynamicImportIds = {};
@@ -24,7 +26,7 @@ function File(opts) {
this.data = {};
this.lastStatements = [];
this.opts = this.normaliseOptions(opts);
this.opts = this.normalizeOptions(opts);
this.ast = {};
this.buildTransformers();
@@ -50,7 +52,12 @@ File.helpers = [
"typeof",
"extends",
"get",
"set"
"set",
"class-call-check",
"object-destructuring-empty",
"temporal-undefined",
"temporal-assert-defined",
"tail-call"
];
File.validOptions = [
@@ -85,7 +92,7 @@ File.validOptions = [
"accept"
];
File.prototype.normaliseOptions = function (opts) {
File.prototype.normalizeOptions = function (opts) {
opts = clone(opts);
for (var key in opts) {
@@ -115,9 +122,11 @@ File.prototype.normaliseOptions = function (opts) {
ast: true
});
// normalise windows path separators to unix
// normalize windows path separators to unix
opts.filename = opts.filename.replace(/\\/g, "/");
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
opts.blacklist = util.arrayify(opts.blacklist);
opts.whitelist = util.arrayify(opts.whitelist);
opts.optional = util.arrayify(opts.optional);
@@ -154,8 +163,14 @@ File.prototype.normaliseOptions = function (opts) {
opts.blacklist = transform._ensureTransformerNames("blacklist", opts.blacklist);
opts.whitelist = transform._ensureTransformerNames("whitelist", opts.whitelist);
opts.optional = transform._ensureTransformerNames("optional", opts.optional);
opts.loose = transform._ensureTransformerNames("loose", opts.loose);
opts.optional = transform._ensureTransformerNames("optional", opts.optional);
opts.loose = transform._ensureTransformerNames("loose", opts.loose);
if (opts.reactCompat) {
opts.optional.push("reactCompat");
console.error("The reactCompat option has been moved into the optional transformer " +
"`reactCompat` - backwards compatibility will be removed in v4.0.0");
}
return opts;
};
@@ -177,6 +192,7 @@ File.prototype.buildTransformers = function () {
if (pass.canRun(file)) {
stack.push(pass);
if (transformer.secondPass) {
secondaryStack.push(pass);
}
@@ -191,6 +207,12 @@ File.prototype.buildTransformers = function () {
this.transformers = transformers;
};
File.prototype.debug = function (msg) {
var parts = this.opts.filename;
if (msg) parts += ": " + msg;
util.debug(parts);
};
File.prototype.toArray = function (node, i) {
if (t.isArrayExpression(node)) {
return node;
@@ -278,7 +300,7 @@ File.prototype.isConsequenceExpressionStatement = function (node) {
File.prototype.addHelper = function (name) {
if (!contains(File.helpers, name)) {
throw new ReferenceError("unknown declaration " + name);
throw new ReferenceError("Unknown helper " + name);
}
var program = this.ast.program;
@@ -328,16 +350,14 @@ File.prototype.parse = function (code) {
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
//opts.strictMode = this.transformers.useStrict.canRun();
return util.parse(opts, code, function (tree) {
return parse(opts, code, function (tree) {
self.transform(tree);
return self.generate();
});
};
File.prototype.transform = function (ast) {
var self = this;
util.debug(this.opts.filename);
this.debug();
this.ast = ast;
this.lastStatements = t.getLastStatements(ast.program);
@@ -348,19 +368,49 @@ File.prototype.transform = function (ast) {
modFormatter.init();
}
var astRun = function (key) {
each(self.transformerStack, function (pass) {
pass.astRun(key);
});
};
this.checkNode(ast);
astRun("enter");
this.call("pre");
each(this.transformerStack, function (pass) {
pass.transform();
});
astRun("exit");
this.call("post");
};
File.prototype.call = function (key) {
var stack = this.transformerStack;
for (var i = 0; i < stack.length; i++) {
var transformer = stack[i].transformer;
if (transformer[key]) {
transformer[key](this);
}
}
};
var checkTransformerVisitor = {
enter: function (node, parent, scope, state) {
checkNode(state.stack, node, scope);
}
};
var checkNode = function (stack, node, scope) {
each(stack, function (pass) {
if (pass.shouldRun) return;
pass.checkNode(node, scope);
});
};
File.prototype.checkNode = function (node, scope) {
var stack = this.transformerStack;
scope = scope || this.scope;
checkNode(stack, node, scope);
scope.traverse(node, checkTransformerVisitor, {
stack: stack
});
};
File.prototype.generate = function () {
@@ -387,6 +437,7 @@ File.prototype.generate = function () {
if (opts.sourceMap === "inline") {
result.code += "\n" + util.sourceMapToComment(result.map);
result.map = null;
}
return result;
@@ -402,14 +453,14 @@ File.prototype.generateUid = function (name, scope) {
do {
uid = this._generateUid(name, i);
i++;
} while (scope.has(uid));
} while (scope.hasReference(uid));
return uid;
};
File.prototype.generateUidIdentifier = function (name, scope) {
scope = scope || this.scope;
var id = t.identifier(this.generateUid(name, scope));
scope.add(id);
scope.addDeclarationToFunctionScope("var", id);
return id;
};

View File

@@ -12,7 +12,7 @@ module.exports = function (exports, opts) {
return t.assignmentExpression("=", left, right);
};
exports.ExpressionStatement = function (node, parent, scope, context, file) {
exports.ExpressionStatement = function (node, parent, scope, file) {
// hit the `AssignmentExpression` one below
if (file.isConsequenceExpressionStatement(node)) return;
@@ -29,7 +29,7 @@ module.exports = function (exports, opts) {
return nodes;
};
exports.AssignmentExpression = function (node, parent, scope, context, file) {
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!isAssignment(node)) return;
var nodes = [];

View File

@@ -8,7 +8,7 @@ module.exports = function (exports, opts) {
return t.assignmentExpression("=", left, right);
};
exports.ExpressionStatement = function (node, parent, scope, context, file) {
exports.ExpressionStatement = function (node, parent, scope, file) {
// hit the `AssignmentExpression` one below
if (file.isConsequenceExpressionStatement(node)) return;
@@ -27,7 +27,7 @@ module.exports = function (exports, opts) {
return nodes;
};
exports.AssignmentExpression = function (node, parent, scope, context, file) {
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!opts.is(node, file)) return;
var nodes = [];

View File

@@ -0,0 +1,278 @@
"use strict";
// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser)
// https://github.com/RReverser/jsx-transpiler
// jsx
var isString = require("lodash/lang/isString");
var esutils = require("esutils");
var react = require("./react");
var t = require("../../types");
module.exports = function (exports, opts) {
exports.check = function (node) {
if (t.isJSX(node)) return true;
if (react.isCreateClass(node)) return true;
return false;
};
exports.JSXIdentifier = function (node, parent) {
if (node.name === "this" && t.isReferenced(node, parent)) {
return t.thisExpression();
} else if (esutils.keyword.isIdentifierName(node.name)) {
node.type = "Identifier";
} else {
return t.literal(node.name);
}
};
exports.JSXNamespacedName = function (node, parent, scope, file) {
throw file.errorWithNode(node, "Namespace tags are not supported. ReactJSX is not XML.");
};
exports.JSXMemberExpression = {
exit: function (node) {
node.computed = t.isLiteral(node.property);
node.type = "MemberExpression";
}
};
exports.JSXExpressionContainer = function (node) {
return node.expression;
};
exports.JSXAttribute = {
exit: function (node) {
var value = node.value || t.literal(true);
return t.inherits(t.property("init", node.name, value), node);
}
};
exports.JSXOpeningElement = {
exit: function (node, parent, scope, file) {
var tagExpr = node.name;
var args = [];
var tagName;
if (t.isIdentifier(tagExpr)) {
tagName = tagExpr.name;
} else if (t.isLiteral(tagExpr)) {
tagName = tagExpr.value;
}
var state = {
tagExpr: tagExpr,
tagName: tagName,
args: args
};
if (opts.pre) {
opts.pre(state);
}
var attribs = node.attributes;
if (attribs.length) {
attribs = buildJSXOpeningElementAttributes(attribs, file);
} else {
attribs = t.literal(null);
}
args.push(attribs);
if (opts.post) {
opts.post(state);
}
return state.call || t.callExpression(state.callee, args);
}
};
/**
* The logic for this is quite terse. It's because we need to
* support spread elements. We loop over all attributes,
* breaking on spreads, we then push a new object containg
* all prior attributes to an array for later processing.
*/
var buildJSXOpeningElementAttributes = function (attribs, file) {
var _props = [];
var objs = [];
var pushProps = function () {
if (!_props.length) return;
objs.push(t.objectExpression(_props));
_props = [];
};
while (attribs.length) {
var prop = attribs.shift();
if (t.isJSXSpreadAttribute(prop)) {
pushProps();
objs.push(prop.argument);
} else {
_props.push(prop);
}
}
pushProps();
if (objs.length === 1) {
// only one object
attribs = objs[0];
} else {
// looks like we have multiple objects
if (!t.isObjectExpression(objs[0])) {
objs.unshift(t.objectExpression([]));
}
// spread it
attribs = t.callExpression(
file.addHelper("extends"),
objs
);
}
return attribs;
};
exports.JSXElement = {
exit: function (node) {
var callExpr = node.openingElement;
for (var i = 0; i < node.children.length; i++) {
var child = node.children[i];
if (t.isLiteral(child) && typeof child.value === "string") {
cleanJSXElementLiteralChild(child, callExpr.arguments);
continue;
} else if (t.isJSXEmptyExpression(child)) {
continue;
}
callExpr.arguments.push(child);
}
callExpr.arguments = flatten(callExpr.arguments);
if (callExpr.arguments.length >= 3) {
callExpr._prettyCall = true;
}
return t.inherits(callExpr, node);
}
};
var isStringLiteral = function (node) {
return t.isLiteral(node) && isString(node.value);
};
var flatten = function (args) {
var flattened = [];
var last;
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (isStringLiteral(arg) && isStringLiteral(last)) {
last.value += arg.value;
} else {
last = arg;
flattened.push(arg);
}
}
return flattened;
};
var cleanJSXElementLiteralChild = function (child, args) {
var lines = child.value.split(/\r\n|\n|\r/);
var lastNonEmptyLine = 0;
var i;
for (i = 0; i < lines.length; i++) {
if (lines[i].match(/[^ \t]/)) {
lastNonEmptyLine = i;
}
}
for (i = 0; i < lines.length; i++) {
var line = lines[i];
var isFirstLine = i === 0;
var isLastLine = i === lines.length - 1;
var isLastNonEmptyLine = i === lastNonEmptyLine;
// replace rendered whitespace tabs with spaces
var trimmedLine = line.replace(/\t/g, " ");
// trim whitespace touching a newline
if (!isFirstLine) {
trimmedLine = trimmedLine.replace(/^[ ]+/, "");
}
// trim whitespace touching an endline
if (!isLastLine) {
trimmedLine = trimmedLine.replace(/[ ]+$/, "");
}
if (trimmedLine) {
if (!isLastNonEmptyLine) {
trimmedLine += " ";
}
args.push(t.literal(trimmedLine));
}
}
};
// display names
var addDisplayName = function (id, call) {
var props = call.arguments[0].properties;
var safe = true;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
if (t.isIdentifier(prop.key, { name: "displayName" })) {
safe = false;
break;
}
}
if (safe) {
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
}
};
exports.ExportDeclaration = function (node, parent, scope, file) {
if (node.default && react.isCreateClass(node.declaration)) {
addDisplayName(file.opts.basename, node.declaration);
}
};
exports.AssignmentExpression =
exports.Property =
exports.VariableDeclarator = function (node) {
var left, right;
if (t.isAssignmentExpression(node)) {
left = node.left;
right = node.right;
} else if (t.isProperty(node)) {
left = node.key;
right = node.value;
} else if (t.isVariableDeclarator(node)) {
left = node.id;
right = node.init;
}
if (t.isMemberExpression(left)) {
left = left.property;
}
if (t.isIdentifier(left) && react.isCreateClass(right)) {
addDisplayName(left.name, right);
}
};
};

View File

@@ -0,0 +1,73 @@
var cloneDeep = require("lodash/lang/cloneDeep");
var traverse = require("../../traversal");
var clone = require("lodash/lang/clone");
var each = require("lodash/collection/each");
var has = require("lodash/object/has");
var t = require("../../types");
exports.push = function (mutatorMap, key, kind, computed, value) {
var alias;
if (t.isIdentifier(key)) {
alias = key.name;
if (computed) alias = "computed:" + alias;
} else if (t.isLiteral(key)) {
alias = String(key.value);
} else {
alias = JSON.stringify(traverse.removeProperties(cloneDeep(key)));
}
var map;
if (has(mutatorMap, alias)) {
map = mutatorMap[alias];
} else {
map = {};
}
mutatorMap[alias] = map;
map._key = key;
if (computed) {
map._computed = true;
}
map[kind] = value;
};
exports.build = function (mutatorMap) {
var objExpr = t.objectExpression([]);
each(mutatorMap, function (map) {
var mapNode = t.objectExpression([]);
var propNode = t.property("init", map._key, mapNode, map._computed);
if (!map.get && !map.set) {
map.writable = t.literal(true);
}
if (map.enumerable === false) {
delete map.enumerable;
} else {
map.enumerable = t.literal(true);
}
map.configurable = t.literal(true);
each(map, function (node, key) {
if (key[0] === "_") return;
node = clone(node);
var inheritNode = node;
if (t.isMethodDefinition(node)) node = node.value;
var prop = t.property("init", t.identifier(key), node);
t.inheritsComments(prop, inheritNode);
t.removeComments(inheritNode);
mapNode.properties.push(prop);
});
objExpr.properties.push(propNode);
});
return objExpr;
};

View File

@@ -5,7 +5,7 @@ var t = require("../../types");
var getObjRef = function (node, nodes, file, scope) {
var ref;
if (t.isIdentifier(node)) {
if (scope.has(node.name, true)) {
if (scope.hasBinding(node.name)) {
// this variable is declared in scope so we can be 100% sure
// that evaluating it multiple times wont trigger a getter
// or something else
@@ -18,7 +18,7 @@ var getObjRef = function (node, nodes, file, scope) {
} else if (t.isMemberExpression(node)) {
ref = node.object;
if (t.isIdentifier(ref) && scope.has(ref.name)) {
if (t.isIdentifier(ref) && scope.hasReference(ref.name)) {
// the object reference that we need to save is locally declared
// so as per the previous comment we can be 100% sure evaluating
// it multiple times will be safe

View File

@@ -1,11 +1,10 @@
"use strict";
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
var util = require("../../util");
var t = require("../../types");
var visitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
// check if this node is an identifier that matches the same as our function id
if (!t.isIdentifier(node, { name: state.id })) return;
@@ -14,11 +13,11 @@ var visitor = {
// check that we don't have a local variable declared as that removes the need
// for the wrapper
var localDeclar = scope.get(state.id, true);
var localDeclar = scope.getBinding(state.id);
if (localDeclar !== state.outerDeclar) return;
state.selfReference = true;
context.stop();
this.stop();
}
};
@@ -32,20 +31,23 @@ exports.property = function (node, file, scope) {
var state = {
id: id,
selfReference: false,
outerDeclar: scope.get(id, true),
outerDeclar: scope.getBinding(id),
};
traverse(node, visitor, scope, state);
scope.traverse(node, visitor, state);
var method = node.value;
if (state.selfReference) {
// todo: support generators
node.value = util.template("property-method-assignment-wrapper", {
FUNCTION: node.value,
var templateName = "property-method-assignment-wrapper";
if (method.generator) templateName += "-generator";
node.value = util.template(templateName, {
FUNCTION: method,
FUNCTION_ID: key,
FUNCTION_KEY: scope.generateUidIdentifier(id),
WRAPPER_KEY: scope.generateUidIdentifier(id + "Wrapper")
});
} else {
node.value.id = key;
method.id = key;
}
};

View File

@@ -20,3 +20,7 @@ exports.isCreateClass = function (node) {
};
exports.isReactComponent = t.buildMatchMemberExpression("React.Component");
exports.isCompatTag = function (tagName) {
return tagName && /^[a-z]|\-/.test(tagName);
};

View File

@@ -1,11 +1,10 @@
"use strict";
var traverse = require("../../traverse");
var t = require("../../types");
var t = require("../../types");
var visitor = {
enter: function (node, parent, scope, context) {
if (t.isFunction(node)) context.skip();
enter: function (node) {
if (t.isFunction(node)) this.skip();
if (t.isAwaitExpression(node)) {
node.type = "YieldExpression";
@@ -23,7 +22,7 @@ module.exports = function (node, callId, scope) {
node.async = false;
node.generator = true;
traverse(node, visitor, scope);
scope.traverse(node, visitor);
var call = t.callExpression(callId, [node]);
var id = node.id;

View File

@@ -2,20 +2,23 @@
module.exports = ReplaceSupers;
var traverse = require("../../traverse");
var t = require("../../types");
var t = require("../../types");
/**
* Description
*
* @param {Object} opts
* @param {Boolean} [inClass]
*/
function ReplaceSupers(opts) {
this.topLevelThisReference = null;
function ReplaceSupers(opts, inClass) {
this.topLevelThisReference = opts.topLevelThisReference;
this.methodNode = opts.methodNode;
this.className = opts.className;
this.superName = opts.superName;
this.isStatic = opts.isStatic;
this.hasSuper = false;
this.inClass = inClass;
this.isLoose = opts.isLoose;
this.scope = opts.scope;
this.file = opts.file;
@@ -29,19 +32,21 @@ function ReplaceSupers(opts) {
* _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this)
*
* @param {Node} property
* @param {boolean} isStatic
* @param {boolean} isComputed
* @param {Node} value
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic, isComputed, thisExpression) {
ReplaceSupers.prototype.setSuperProperty = function (property, value, isComputed, thisExpression) {
return t.callExpression(
this.file.addHelper("set"),
[
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
@@ -59,20 +64,20 @@ ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic,
* _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
*
* @param {Node} property
* @param {boolean} isStatic
* @param {boolean} isComputed
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed, thisExpression) {
ReplaceSupers.prototype.getSuperProperty = function (property, isComputed, thisExpression) {
return t.callExpression(
this.file.addHelper("get"),
[
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
@@ -81,6 +86,70 @@ ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed
);
};
/**
* Description
*/
ReplaceSupers.prototype.replace = function () {
this.traverseLevel(this.methodNode.value, true);
};
var visitor = {
enter: function (node, parent, scope, state) {
var topLevel = state.topLevel;
var self = state.self;
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
// we need to call traverseLevel again so we're context aware
self.traverseLevel(node, false);
return this.skip();
}
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
// break on object methods
return this.skip();
}
var getThisReference = topLevel ?
// top level so `this` is the instance
t.thisExpression :
// not in the top level so we need to create a reference
self.getThisReference.bind(self);
var callback = self.specHandle;
if (self.isLoose) callback = self.looseHandle;
return callback.call(self, getThisReference, node, parent);
}
};
/**
* Description
*
* @param {Object} node
* @param {Boolean} topLevel
*/
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
var state = { self: this, topLevel: topLevel };
this.scope.traverse(node, visitor, state);
};
/**
* Description
*/
ReplaceSupers.prototype.getThisReference = function () {
if (this.topLevelThisReference) {
return this.topLevelThisReference;
} else {
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
]));
return ref;
}
};
/**
* Description
*
@@ -90,7 +159,8 @@ ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed
* @returns {Object}
*/
ReplaceSupers.prototype.looseSuperProperty = function (methodNode, id, parent) {
ReplaceSupers.prototype.getLooseSuperProperty = function (id, parent) {
var methodNode = this.methodNode;
var methodName = methodNode.key;
var superName = this.superName || t.identifier("Function");
@@ -122,70 +192,6 @@ ReplaceSupers.prototype.looseSuperProperty = function (methodNode, id, parent) {
}
};
/**
* Description
*/
ReplaceSupers.prototype.replace = function () {
this.traverseLevel(this.methodNode.value, true);
};
var visitor = {
enter: function (node, parent, scope, context, state) {
var topLevel = state.topLevel;
var self = state.self;
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
// we need to call traverseLevel again so we're context aware
self.traverseLevel(node, false);
return context.skip();
}
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
// break on object methods
return context.skip();
}
var getThisReference = topLevel ?
// top level so `this` is the instance
t.thisExpression :
// not in the top level so we need to create a reference
self.getThisReference;
var callback = self.specHandle;
if (self.isLoose) callback = self.looseHandle;
return callback.call(self, getThisReference, node, parent);
}
};
/**
* Description
*
* @param {Object} node
* @param {Boolean} topLevel
*/
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
var state = { self: this, topLevel: topLevel };
traverse(node, visitor, this.scope, state);
};
/**
* Description
*/
ReplaceSupers.prototype.getThisReference = function () {
if (this.topLevelThisReference) {
return this.topLevelThisReference;
} else {
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
]));
return ref;
}
};
/**
* Description
*
@@ -196,13 +202,15 @@ ReplaceSupers.prototype.getThisReference = function () {
ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) {
if (t.isIdentifier(node, { name: "super" })) {
return this.looseSuperProperty(this.methodNode, node, parent);
this.hasSuper = true;
return this.getLooseSuperProperty(node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
// super.test(); -> ClassName.prototype.MethodName.call(this);
this.hasSuper = true;
t.appendToMemberExpression(callee, t.identifier("call"));
node.arguments.unshift(getThisReference());
}
@@ -223,13 +231,13 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
var args;
var thisReference;
if (t.isIdentifier(node, { name: "super" })) {
if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
throw this.file.errorWithNode(node, "illegal use of bare super");
}
} else if (t.isCallExpression(node)) {
if (isIllegalBareSuper(node, parent)) {
throw this.file.errorWithNode(node, "Illegal use of bare super");
}
if (t.isCallExpression(node)) {
var callee = node.callee;
if (t.isIdentifier(callee, { name: "super" })) {
if (isSuper(callee, node)) {
// super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
property = methodNode.key;
computed = methodNode.computed;
@@ -238,38 +246,32 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
// bare `super` call is illegal inside non-constructors
// - https://esdiscuss.org/topic/super-call-in-methods
// - https://twitter.com/wycats/status/544553184396836864
if (methodNode.key.name !== "constructor") {
if (methodNode.key.name !== "constructor" || !this.inClass) {
var methodName = methodNode.key.name || "METHOD_NAME";
throw this.file.errorWithNode(node, "Direct super call is illegal in non-constructor, use super." + methodName + "() instead");
}
} else {
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
} else if (t.isMemberExpression(callee) && isSuper(callee.object, callee)) {
// super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
property = callee.property;
computed = callee.computed;
args = node.arguments;
}
} else if (t.isMemberExpression(node)) {
if (!t.isIdentifier(node.object, { name: "super" })) return;
} else if (t.isMemberExpression(node) && isSuper(node.object, node)) {
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
property = node.property;
computed = node.computed;
} else if (t.isAssignmentExpression(node)) {
if (!t.isIdentifier(node.left.object, { name: "super" })) return;
if (methodNode.kind !== "set") return;
thisReference = getThisReference();
} else if (t.isAssignmentExpression(node) && isSuper(node.left.object, node.left) && methodNode.kind === "set") {
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
return this.setSuperProperty(node.left.property, node.right, methodNode.static, node.left.computed, thisReference);
this.hasSuper = true;
return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference());
}
if (!property) return;
this.hasSuper = true;
thisReference = getThisReference();
var superProperty = this.superProperty(property, methodNode.static, computed, thisReference);
var superProperty = this.getSuperProperty(property, computed, thisReference);
if (args) {
if (args.length === 1 && t.isSpreadElement(args[0])) {
// super(...arguments);
@@ -287,3 +289,14 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
return superProperty;
}
};
var isIllegalBareSuper = function (node, parent) {
if (!isSuper(node, parent)) return false;
if (t.isMemberExpression(parent, { computed: false })) return false;
if (t.isCallExpression(parent, { callee: node })) return false;
return true;
};
var isSuper = function (node, parent) {
return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent);
};

View File

@@ -2,11 +2,11 @@
module.exports = transform;
var Transformer = require("./transformer");
var object = require("../helpers/object");
var File = require("../file");
var util = require("../util");
var each = require("lodash/collection/each");
var normalizeAst = require("../helpers/normalize-ast");
var Transformer = require("./transformer");
var object = require("../helpers/object");
var File = require("./file");
var each = require("lodash/collection/each");
function transform(code, opts) {
var file = new File(opts);
@@ -14,7 +14,7 @@ function transform(code, opts) {
}
transform.fromAst = function (ast, code, opts) {
ast = util.normaliseAst(ast);
ast = normalizeAst(ast);
var file = new File(opts);
file.addCode(code);

View File

@@ -2,7 +2,6 @@
module.exports = DefaultFormatter;
var traverse = require("../../traverse");
var object = require("../../helpers/object");
var util = require("../../util");
var t = require("../../types");
@@ -28,7 +27,7 @@ function DefaultFormatter(file) {
}
DefaultFormatter.prototype.doDefaultExportInterop = function (node) {
return node.default && !this.noInteropRequire && !this.hasNonDefaultExports;
return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports;
};
DefaultFormatter.prototype.bumpImportOccurences = function (node) {
@@ -39,13 +38,13 @@ DefaultFormatter.prototype.bumpImportOccurences = function (node) {
};
var exportsVisitor = {
enter: function (node, parent, scope, context, formatter) {
enter: function (node, parent, scope, formatter) {
var declar = node && node.declaration;
if (t.isExportDeclaration(node)) {
formatter.hasLocalImports = true;
if (declar && t.isStatement(declar)) {
extend(formatter.localExports, t.getDeclarations(declar));
extend(formatter.localExports, t.getBindingIdentifiers(declar));
}
if (!node.default) {
@@ -60,27 +59,27 @@ var exportsVisitor = {
};
DefaultFormatter.prototype.getLocalExports = function () {
traverse(this.file.ast, exportsVisitor, this.file.scope, this);
this.file.scope.traverse(this.file.ast, exportsVisitor, this);
};
var importsVisitor = {
enter: function (node, parent, scope, context, formatter) {
enter: function (node, parent, scope, formatter) {
if (t.isImportDeclaration(node)) {
formatter.hasLocalImports = true;
extend(formatter.localImports, t.getDeclarations(node));
extend(formatter.localImports, t.getBindingIdentifiers(node));
formatter.bumpImportOccurences(node);
}
}
};
DefaultFormatter.prototype.getLocalImports = function () {
traverse(this.file.ast, importsVisitor, this.file.scope, this);
this.file.scope.traverse(this.file.ast, importsVisitor, this);
};
var remapVisitor = {
enter: function (node, parent, scope, context, formatter) {
enter: function (node, parent, scope, formatter) {
if (t.isUpdateExpression(node) && formatter.isLocalReference(node.argument, scope)) {
context.skip();
this.skip();
// expand to long file assignment expression
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
@@ -108,7 +107,7 @@ var remapVisitor = {
}
if (t.isAssignmentExpression(node) && formatter.isLocalReference(node.left, scope)) {
context.skip();
this.skip();
return formatter.remapExportAssignment(node);
}
}
@@ -116,7 +115,7 @@ var remapVisitor = {
DefaultFormatter.prototype.remapAssignments = function () {
if (this.hasLocalImports) {
traverse(this.file.ast, remapVisitor, this.file.scope, this);
this.file.scope.traverse(this.file.ast, remapVisitor, this);
}
};
@@ -147,7 +146,7 @@ DefaultFormatter.prototype.remapExportAssignment = function (node) {
DefaultFormatter.prototype.isLocalReference = function (node, scope) {
var localExports = this.localExports;
var name = node.name;
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.get(name, true);
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBinding(name);
};
DefaultFormatter.prototype.getModuleName = function () {
@@ -171,12 +170,12 @@ DefaultFormatter.prototype.getModuleName = function () {
if (!opts.keepModuleIdExtensions) {
// remove extension
filenameRelative = filenameRelative.replace(/\.(.*?)$/, "");
filenameRelative = filenameRelative.replace(/\.(\w*?)$/, "");
}
moduleName += filenameRelative;
// normalise path separators
// normalize path separators
moduleName = moduleName.replace(/\\/g, "/");
return moduleName;
@@ -212,6 +211,12 @@ DefaultFormatter.prototype.getExternalReference = function (node, nodes) {
}
};
DefaultFormatter.prototype.checkExportIdentifier = function (node) {
if (t.isIdentifier(node, { name: "__esModule" })) {
throw this.file.errorWithNode(node, "Illegal export __esModule - this is used internally for CommonJS interop");
}
};
DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
var inherits = false;
if (node.specifiers.length === 1) inherits = node;
@@ -223,8 +228,8 @@ DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
// export * from "foo";
nodes.push(this.buildExportsWildcard(ref, node));
} else {
if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
// importing a default so we need to normalise it
if (t.isSpecifierDefault(specifier) && !this.noInteropRequireExport) {
// importing a default so we need to normalize it
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {
ref = t.memberExpression(ref, t.getSpecifierId(specifier));
@@ -251,6 +256,7 @@ DefaultFormatter.prototype.buildExportsWildcard = function (objectIdentifier) {
};
DefaultFormatter.prototype.buildExportsAssignment = function (id, init) {
this.checkExportIdentifier(id);
return util.template("exports-assign", {
VALUE: init,
KEY: id

View File

@@ -4,7 +4,7 @@ var util = require("../../util");
module.exports = function (Parent) {
var Constructor = function () {
this.noInteropRequire = true;
this.noInteropRequireExport = true;
Parent.apply(this, arguments);
};

View File

@@ -29,9 +29,8 @@ AMDFormatter.prototype.buildDependencyLiterals = function () {
* Wrap the entire body in a `define` wrapper.
*/
AMDFormatter.prototype.transform = function (ast) {
var program = ast.program;
var body = program.body;
AMDFormatter.prototype.transform = function (program) {
var body = program.body;
// build an array of module names
@@ -87,7 +86,7 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
this.ids[node.source.value] = ref;
} else if (t.isImportBatchSpecifier(specifier)) {
// import * as bar from "foo";
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) {
// import foo from "foo";
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {

View File

@@ -0,0 +1,13 @@
"use strict";
module.exports = CommonStandardFormatter;
var CommonStrictFormatter = require("./common-strict");
var util = require("../../util");
function CommonStandardFormatter() {
this.noInteropRequireImport = true;
CommonStrictFormatter.apply(this, arguments);
}
util.inherits(CommonStandardFormatter, CommonStrictFormatter);

View File

@@ -14,7 +14,7 @@ function CommonJSFormatter() {
util.inherits(CommonJSFormatter, DefaultFormatter);
CommonJSFormatter.prototype.init = function () {
if (this.hasNonDefaultExports) {
if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
this.file.ast.program.body.push(util.template("exports-module-declaration", true));
}
};
@@ -27,19 +27,23 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
// import foo from "foo";
if (t.isSpecifierDefault(specifier)) {
if (!contains(this.file.dynamicImported, node)) {
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
if (this.noInteropRequireImport) {
ref = t.memberExpression(ref, t.identifier("default"));
} else {
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
}
}
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)]));
} else {
if (specifier.type === "ImportBatchSpecifier") {
if (!this.noInteropRequireImport) {
ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]);
}
// import * as bar from "foo";
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(
variableName,
t.callExpression(this.file.addHelper("interop-require-wildcard"), [
ref
])
)
t.variableDeclarator(variableName, ref)
]));
} else {
// import { foo } from "foo";

View File

@@ -1,10 +1,11 @@
module.exports = {
commonStrict: require("./common-strict"),
amdStrict: require("./amd-strict"),
umdStrict: require("./umd-strict"),
common: require("./common"),
system: require("./system"),
ignore: require("./ignore"),
amd: require("./amd"),
umd: require("./umd")
commonStandard: require("./common-standard"),
commonStrict: require("./common-strict"),
amdStrict: require("./amd-strict"),
umdStrict: require("./umd-strict"),
common: require("./common"),
system: require("./system"),
ignore: require("./ignore"),
amd: require("./amd"),
umd: require("./umd")
};

View File

@@ -5,7 +5,6 @@ module.exports = SystemFormatter;
var DefaultFormatter = require("./_default");
var AMDFormatter = require("./amd");
var useStrict = require("../helpers/use-strict");
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
var last = require("lodash/array/last");
@@ -14,7 +13,8 @@ var map = require("lodash/collection/map");
function SystemFormatter(file) {
this.exportIdentifier = file.generateUidIdentifier("export");
this.noInteropRequire = true;
this.noInteropRequireExport = true;
this.noInteropRequireImport = true;
DefaultFormatter.apply(this, arguments);
}
@@ -69,7 +69,7 @@ SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
};
var runnerSettersVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (node._importSource === state.source) {
if (t.isVariableDeclaration(node)) {
each(node.declarations, function (declar) {
@@ -82,7 +82,7 @@ var runnerSettersVisitor = {
state.nodes.push(node);
}
context.remove();
this.remove();
}
}
};
@@ -97,17 +97,17 @@ SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators
hoistDeclarators: hoistDeclarators
};
traverse(block, runnerSettersVisitor, scope, state);
scope.traverse(block, runnerSettersVisitor, state);
return t.functionExpression(null, [uid], t.blockStatement(state.nodes));
}));
};
var hoistVariablesVisitor = {
enter: function (node, parent, scope, context, hoistDeclarators) {
enter: function (node, parent, scope, hoistDeclarators) {
if (t.isFunction(node)) {
// nothing inside is accessible
return context.skip();
return this.skip();
}
if (t.isVariableDeclaration(node)) {
@@ -149,19 +149,17 @@ var hoistVariablesVisitor = {
};
var hoistFunctionsVisitor = {
enter: function (node, parent, scope, context, handlerBody) {
if (t.isFunction(node)) context.skip();
enter: function (node, parent, scope, handlerBody) {
if (t.isFunction(node)) this.skip();
if (t.isFunctionDeclaration(node) || node._blockHoist) {
handlerBody.push(node);
context.remove();
this.remove();
}
}
};
SystemFormatter.prototype.transform = function (ast) {
var program = ast.program;
SystemFormatter.prototype.transform = function (program) {
var hoistDeclarators = [];
var moduleName = this.getModuleName();
var moduleNameLiteral = t.literal(moduleName);
@@ -182,7 +180,7 @@ SystemFormatter.prototype.transform = function (ast) {
var returnStatement = handlerBody.pop();
// hoist up all variable declarations
traverse(block, hoistVariablesVisitor, this.file.scope, hoistDeclarators);
this.file.scope.traverse(block, hoistVariablesVisitor, hoistDeclarators);
if (hoistDeclarators.length) {
var hoistDeclar = t.variableDeclaration("var", hoistDeclarators);
@@ -191,7 +189,7 @@ SystemFormatter.prototype.transform = function (ast) {
}
// hoist up function declarations for circular references
traverse(block, hoistFunctionsVisitor, this.file.scope, handlerBody);
this.file.scope.traverse(block, hoistFunctionsVisitor, handlerBody);
handlerBody.push(returnStatement);

View File

@@ -13,9 +13,8 @@ function UMDFormatter() {
util.inherits(UMDFormatter, AMDFormatter);
UMDFormatter.prototype.transform = function (ast) {
var program = ast.program;
var body = program.body;
UMDFormatter.prototype.transform = function (program) {
var body = program.body;
// build an array of module names

View File

@@ -0,0 +1,5 @@
(function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
});

View File

@@ -1,3 +1,3 @@
if (Object.getPrototypeOf(CLASS_NAME) !== null) {
Object.getPrototypeOf(CLASS_NAME).apply(this, arguments);
if (SUPER_NAME != null) {
SUPER_NAME.apply(this, arguments);
}

View File

@@ -1 +1 @@
var VARIABLE_NAME = ARGUMENTS[ARGUMENT_KEY] === undefined ? DEFAULT_VALUE : ARGUMENTS[ARGUMENT_KEY];
let VARIABLE_NAME = ARGUMENTS[ARGUMENT_KEY] === undefined ? DEFAULT_VALUE : ARGUMENTS[ARGUMENT_KEY];

View File

@@ -1 +1,3 @@
exports.__esModule = true;
Object.defineProperty(exports, "__esModule", {
value: true
});

View File

@@ -0,0 +1,3 @@
(function (obj) {
if (obj == null) throw new TypeError("Cannot destructure undefined");
});

View File

@@ -0,0 +1,11 @@
(function (FUNCTION_KEY) {
var WRAPPER_KEY = function* FUNCTION_ID() {
return yield* FUNCTION_KEY.apply(this, arguments);
};
WRAPPER_KEY.toString = function () {
return FUNCTION_KEY.toString();
};
return WRAPPER_KEY;
})(FUNCTION)

View File

@@ -4,21 +4,16 @@
if (desc === undefined) {
var parent = Object.getPrototypeOf(object);
if (parent === null) {
return;
} else {
if (parent !== null) {
return set(parent, property, value, receiver);
}
} else if ("value" in desc && desc.writable) {
desc.value = value;
return;
return desc.value = value;
} else {
var setter = desc.set;
if (setter === undefined) {
return;
if (setter !== undefined) {
return setter.call(receiver, value);
}
return setter.call(receiver, value);
}
});

View File

@@ -0,0 +1,23 @@
(function () {
function Tail(func, args, context) {
this.func = func;
this.args = args;
this.context = context;
}
Tail.prototype._isTailDescriptor = true;
var isRunning = false;
return function (func, args, context) {
var result = new Tail(func, args, context);
if (!isRunning) {
isRunning = true;
do {
result = result.func.apply(result.context, result.args);
} while (result instanceof Tail || (result && result._isTailDescriptor));
isRunning = false;
}
return result;
};
})()

View File

@@ -0,0 +1,6 @@
(function (val, name, undef) {
if (val === undef) {
throw new ReferenceError(name + " is not defined - temporal dead zone");
}
return true;
})

View File

@@ -0,0 +1 @@
({})

View File

@@ -1,7 +1,5 @@
module.exports = TransformerPass;
var traverse = require("../traverse");
var util = require("../util");
var contains = require("lodash/collection/contains");
/**
@@ -11,64 +9,55 @@ var contains = require("lodash/collection/contains");
function TransformerPass(file, transformer) {
this.transformer = transformer;
this.shouldRun = !transformer.check;
this.handlers = transformer.handlers;
this.file = file;
}
TransformerPass.prototype.astRun = function (key) {
var handlers = this.handlers;
var file = this.file;
if (handlers.ast && handlers.ast[key]) {
handlers.ast[key](file.ast, file);
}
};
TransformerPass.prototype.canRun = function () {
var transformer = this.transformer;
var opts = this.file.opts;
var key = transformer.key;
// internal
if (key[0] === "_") return true;
// blacklist
var blacklist = opts.blacklist;
if (blacklist.length && contains(blacklist, key)) return false;
// whitelist
var whitelist = opts.whitelist;
if (whitelist.length && !contains(whitelist, key)) return false;
if (whitelist.length) return contains(whitelist, key);
// optional
if (transformer.optional && !contains(opts.optional, key)) return false;
// experimental
if (transformer.experimental && !opts.experimental) return false;
// playground
if (transformer.playground && !opts.playground) return false;
return true;
};
var transformVisitor = {
enter: function (node, parent, scope, context, state) {
var fns = state.handlers[node.type];
if (!fns) return;
return fns.enter(node, parent, scope, context, state.file, state.pass);
},
exit: function (node, parent, scope, context, state) {
var fns = state.handlers[node.type];
if (!fns) return;
return fns.exit(node, parent, scope, context, state.file, state.pass);
TransformerPass.prototype.checkNode = function (node) {
var check = this.transformer.check;
if (check) {
return this.shouldRun = check(node);
} else {
return true;
}
};
TransformerPass.prototype.transform = function () {
if (!this.shouldRun) return;
var file = this.file;
util.debug(file.opts.filename + ": Running transformer " + this.transformer.key);
file.debug("Running transformer " + this.transformer.key);
this.astRun("before");
var state = { file: file, handlers: this.handlers, pass: this };
traverse(file.ast, transformVisitor, file.scope, state);
this.astRun("after");
file.scope.traverse(file.ast, this.handlers, file);
};

View File

@@ -4,8 +4,9 @@ module.exports = Transformer;
var TransformerPass = require("./transformer-pass");
var isFunction = require("lodash/lang/isFunction");
var traverse = require("../traverse");
var traverse = require("../traversal");
var isObject = require("lodash/lang/isObject");
var clone = require("../helpers/clone");
var each = require("lodash/collection/each");
/**
@@ -15,17 +16,30 @@ var each = require("lodash/collection/each");
*/
function Transformer(key, transformer, opts) {
this.manipulateOptions = transformer.manipulateOptions;
this.experimental = !!transformer.experimental;
this.playground = !!transformer.playground;
this.secondPass = !!transformer.secondPass;
this.optional = !!transformer.optional;
this.handlers = this.normalise(transformer);
this.opts = opts || {};
this.key = key;
transformer = clone(transformer);
var take = function (key) {
var val = transformer[key];
delete transformer[key];
return val;
};
this.manipulateOptions = take("manipulateOptions");
this.check = take("check");
this.post = take("post");
this.pre = take("pre");
this.experimental = !!take("experimental");
this.playground = !!take("playground");
this.secondPass = !!take("secondPass");
this.optional = !!take("optional");
this.handlers = this.normalize(transformer);
this.opts = opts || {};
this.key = key;
}
Transformer.prototype.normalise = function (transformer) {
Transformer.prototype.normalize = function (transformer) {
var self = this;
if (isFunction(transformer)) {

View File

@@ -12,7 +12,8 @@
"generatorComprehension": "es7.comprehensions",
"arrowFunctions": "es6.arrowFunctions",
"classes": "es6.classes",
"objectSpread": "es7.objectSpread",
"objectSpread": "es7.objectRestSpread",
"es7.objectSpread": "es7.objectRestSpread",
"exponentiationOperator": "es7.exponentiationOperator",
"spread": "es6.spread",
"templateLiterals": "es6.templateLiterals",
@@ -33,6 +34,8 @@
"coreAliasing": "selfContained",
"undefinedToVoid": "spec.undefinedToVoid",
"undeclaredVariableCheck": "validation.undeclaredVariableCheck",
"specPropertyLiterals": "minification.propertyLiterals",
"specMemberExpressionLiterals": "minification.memberExpressionLiterals"
"specPropertyLiterals": "es3.propertyLiterals",
"specMemberExpressionLiterals": "es3.memberExpressionLiterals",
"minification.propertyLiterals": "es3.propertyLiterals",
"minification.memberExpressionLiterals": "es3.memberExpressionLiterals"
}

View File

@@ -1,7 +1,11 @@
"use strict";
var util = require("../../../util");
var t = require("../../../types");
var defineMap = require("../../helpers/define-map");
var t = require("../../../types");
exports.check = function (node) {
return t.isProperty(node) && (node.kind === "get" || node.kind === "set");
};
exports.ObjectExpression = function (node) {
var mutatorMap = {};
@@ -10,7 +14,7 @@ exports.ObjectExpression = function (node) {
node.properties = node.properties.filter(function (prop) {
if (prop.kind === "get" || prop.kind === "set") {
hasAny = true;
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.computed, prop.value);
defineMap.push(mutatorMap, prop.key, prop.kind, prop.computed, prop.value);
return false;
} else {
return true;
@@ -21,6 +25,6 @@ exports.ObjectExpression = function (node) {
return t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("defineProperties")),
[node, util.buildDefineProperties(mutatorMap)]
[node, defineMap.build(mutatorMap)]
);
};

View File

@@ -2,6 +2,8 @@
var t = require("../../../types");
exports.check = t.isArrowFunctionExpression;
exports.ArrowFunctionExpression = function (node) {
t.ensureBlock(node);

View File

@@ -1,34 +1,29 @@
"use strict";
var traverse = require("../../../traverse");
var t = require("../../../types");
var t = require("../../../types");
var visitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (!t.isReferencedIdentifier(node, parent)) return;
var declared = state.letRefs[node.name];
if (!declared) return;
// declared node is different in this scope
if (scope.get(node.name, true) !== declared) return;
if (scope.getBinding(node.name) !== declared) return;
var declaredLoc = declared.loc;
var referenceLoc = node.loc;
var assert = t.callExpression(
state.file.addHelper("temporal-assert-defined"),
[node, t.literal(node.name), state.file.addHelper("temporal-undefined")]
);
if (!declaredLoc || !referenceLoc) return;
this.skip();
// does this reference appear on a line before the declaration?
var before = referenceLoc.start.line < declaredLoc.start.line;
if (referenceLoc.start.line === declaredLoc.start.line) {
// this reference appears on the same line
// check it appears before the declaration
before = referenceLoc.start.col < declaredLoc.start.col;
}
if (before) {
throw state.file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
if (t.isAssignmentExpression(parent) || t.isUpdateExpression(parent)) {
if (parent._ignoreBlockScopingTDZ) return;
this.parentPath.replaceNode(t.sequenceExpression([assert, parent]));
} else {
return t.logicalExpression("&&", assert, node);
}
}
};
@@ -37,7 +32,7 @@ exports.optional = true;
exports.Loop =
exports.Program =
exports.BlockStatement = function (node, parent, scope, context, file) {
exports.BlockStatement = function (node, parent, scope, file) {
var letRefs = node._letReferences;
if (!letRefs) return;
@@ -46,5 +41,5 @@ exports.BlockStatement = function (node, parent, scope, context, file) {
file: file
};
traverse(node, visitor, scope, state);
scope.traverse(node, visitor, state);
};

View File

@@ -1,19 +1,23 @@
"use strict";
var traverse = require("../../../traverse");
var traverse = require("../../../traversal");
var object = require("../../../helpers/object");
var util = require("../../../util");
var t = require("../../../types");
var values = require("lodash/object/values");
var extend = require("lodash/object/extend");
exports.check = function (node) {
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
};
var isLet = function (node, parent) {
if (!t.isVariableDeclaration(node)) return false;
if (node._let) return true;
if (node.kind !== "let") return false;
// https://github.com/6to5/6to5/issues/255
if (!t.isFor(parent) || t.isFor(parent) && parent.left !== node) {
if (isLetInitable(node, parent)) {
for (var i = 0; i < node.declarations.length; i++) {
var declar = node.declarations[i];
declar.init = declar.init || t.identifier("undefined");
@@ -25,35 +29,57 @@ var isLet = function (node, parent) {
return true;
};
var isLetInitable = function (node, parent) {
return !t.isFor(parent) || t.isFor(parent) && parent.left !== node;
};
var isVar = function (node, parent) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
};
var standardiseLets = function (declars) {
var standardizeLets = function (declars) {
for (var i = 0; i < declars.length; i++) {
delete declars[i]._let;
}
};
exports.VariableDeclaration = function (node, parent) {
isLet(node, parent);
exports.VariableDeclaration = function (node, parent, scope, file) {
if (!isLet(node, parent)) return;
if (isLetInitable(node) && file.transformers["es6.blockScopingTDZ"].canRun()) {
var nodes = [node];
for (var i = 0; i < node.declarations.length; i++) {
var decl = node.declarations[i];
if (decl.init) {
var assign = t.assignmentExpression("=", decl.id, decl.init);
assign._ignoreBlockScopingTDZ = true;
nodes.push(t.expressionStatement(assign));
}
decl.init = file.addHelper("temporal-undefined");
}
node._blockHoist = 2;
return nodes;
}
};
exports.Loop = function (node, parent, scope, context, file) {
exports.Loop = function (node, parent, scope, file) {
var init = node.left || node.init;
if (isLet(init, node)) {
t.ensureBlock(node);
node.body._letDeclarators = [init];
}
var letScoping = new LetScoping(node, node.body, parent, scope, file);
letScoping.run();
var blockScoping = new BlockScoping(node, node.body, parent, scope, file);
blockScoping.run();
};
exports.Program =
exports.BlockStatement = function (block, parent, scope, context, file) {
exports.BlockStatement = function (block, parent, scope, file) {
if (!t.isLoop(parent)) {
var letScoping = new LetScoping(false, block, parent, scope, file);
letScoping.run();
var blockScoping = new BlockScoping(false, block, parent, scope, file);
blockScoping.run();
}
};
@@ -67,7 +93,7 @@ exports.BlockStatement = function (block, parent, scope, context, file) {
* @param {File} file
*/
function LetScoping(loopParent, block, parent, scope, file) {
function BlockScoping(loopParent, block, parent, scope, file) {
this.loopParent = loopParent;
this.parent = parent;
this.scope = scope;
@@ -84,7 +110,7 @@ function LetScoping(loopParent, block, parent, scope, file) {
* Start the ball rolling.
*/
LetScoping.prototype.run = function () {
BlockScoping.prototype.run = function () {
var block = this.block;
if (block._letDone) return;
block._letDone = true;
@@ -104,19 +130,19 @@ LetScoping.prototype.run = function () {
}
};
function replace(node, parent, scope, context, remaps) {
function replace(node, parent, scope, remaps) {
if (!t.isReferencedIdentifier(node, parent)) return;
var remap = remaps[node.name];
if (!remap) return;
var own = scope.get(node.name, true);
if (own === remap.node) {
var ownBinding = scope.getBinding(node.name);
if (ownBinding === remap.binding) {
node.name = remap.uid;
} else {
// scope already has it's own declaration that doesn't
// scope already has it's own binding that doesn't
// match the one we have a stored replacement for
if (context) context.skip();
if (this) this.skip();
}
}
@@ -125,15 +151,15 @@ var replaceVisitor = {
};
function traverseReplace(node, parent, scope, remaps) {
replace(node, parent, scope, null, remaps);
traverse(node, replaceVisitor, scope, remaps);
replace(node, parent, scope, remaps);
scope.traverse(node, replaceVisitor, remaps);
}
/**
* Description
*/
LetScoping.prototype.remap = function () {
BlockScoping.prototype.remap = function () {
var hasRemaps = false;
var letRefs = this.letReferences;
var scope = this.scope;
@@ -149,13 +175,13 @@ LetScoping.prototype.remap = function () {
// this is the defining identifier of a declaration
var ref = letRefs[key];
if (scope.parentHas(key)) {
if (scope.parentHasReference(key)) {
var uid = scope.generateUidIdentifier(ref.name).name;
ref.name = uid;
hasRemaps = true;
remaps[key] = remaps[uid] = {
node: ref,
binding: ref,
uid: uid
};
}
@@ -172,14 +198,14 @@ LetScoping.prototype.remap = function () {
traverseReplace(loopParent.update, loopParent, scope, remaps);
}
traverse(this.block, replaceVisitor, scope, remaps);
scope.traverse(this.block, replaceVisitor, remaps);
};
/**
* Description
*/
LetScoping.prototype.needsClosure = function () {
BlockScoping.prototype.needsClosure = function () {
var block = this.block;
// if we're inside of a for loop then we search to see if there are any
@@ -221,13 +247,13 @@ LetScoping.prototype.needsClosure = function () {
};
var letReferenceFunctionVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
// not a direct reference
if (!t.isReferencedIdentifier(node, parent)) return;
// this scope has a variable with the same name so it couldn't belong
// to our let scope
if (scope.hasOwn(node.name, true)) return;
if (scope.hasOwnBinding(node.name)) return;
// not a part of our scope
if (!state.letReferences[node.name]) return;
@@ -237,10 +263,10 @@ var letReferenceFunctionVisitor = {
};
var letReferenceBlockVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isFunction(node)) {
traverse(node, letReferenceFunctionVisitor, scope, state);
return context.skip();
scope.traverse(node, letReferenceFunctionVisitor, state);
return this.skip();
}
}
};
@@ -249,7 +275,7 @@ var letReferenceBlockVisitor = {
* Description
*/
LetScoping.prototype.getLetReferences = function () {
BlockScoping.prototype.getLetReferences = function () {
var block = this.block;
var declarators = block._letDeclarators || [];
@@ -258,7 +284,7 @@ LetScoping.prototype.getLetReferences = function () {
//
for (var i = 0; i < declarators.length; i++) {
declar = declarators[i];
extend(this.outsideLetReferences, t.getDeclarations(declar));
extend(this.outsideLetReferences, t.getBindingIdentifiers(declar));
}
//
@@ -274,7 +300,7 @@ LetScoping.prototype.getLetReferences = function () {
//
for (i = 0; i < declarators.length; i++) {
declar = declarators[i];
var keys = t.getDeclarations(declar);
var keys = t.getBindingIdentifiers(declar);
extend(this.letReferences, keys);
this.hasLetReferences = true;
}
@@ -283,7 +309,7 @@ LetScoping.prototype.getLetReferences = function () {
if (!this.hasLetReferences) return;
// set let references to plain var references
standardiseLets(declarators);
standardizeLets(declarators);
var state = {
letReferences: this.letReferences,
@@ -292,7 +318,7 @@ LetScoping.prototype.getLetReferences = function () {
// traverse through this block, stopping on functions and checking if they
// contain any local let references
traverse(this.block, letReferenceBlockVisitor, this.scope, state);
this.scope.traverse(this.block, letReferenceBlockVisitor, state);
return state.closurify;
};
@@ -306,17 +332,17 @@ var loopNodeTo = function (node) {
};
var loopVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
var replace;
if (t.isLoop(node)) {
state.ignoreLabeless = true;
traverse(node, loopVisitor, scope, state);
scope.traverse(node, loopVisitor, state);
state.ignoreLabeless = false;
}
if (t.isFunction(node) || t.isLoop(node)) {
return context.skip();
return this.skip();
}
var loopText = loopNodeTo(node);
@@ -358,7 +384,7 @@ var loopVisitor = {
};
var loopLabelVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isLabeledStatement(node)) {
state.innerLabels.push(node.label.name);
}
@@ -374,7 +400,7 @@ var loopLabelVisitor = {
* @returns {Object}
*/
LetScoping.prototype.checkLoop = function () {
BlockScoping.prototype.checkLoop = function () {
var state = {
hasBreakContinue: false,
ignoreLabeless: false,
@@ -384,14 +410,14 @@ LetScoping.prototype.checkLoop = function () {
map: {}
};
traverse(this.block, loopLabelVisitor, this.scope, state);
traverse(this.block, loopVisitor, this.scope, state);
this.scope.traverse(this.block, loopLabelVisitor, state);
this.scope.traverse(this.block, loopVisitor, state);
return state;
};
var hoistVarDeclarationsVisitor = {
enter: function (node, parent, scope, context, self) {
enter: function (node, parent, scope, self) {
if (t.isForStatement(node)) {
if (isVar(node.init, node)) {
node.init = t.sequenceExpression(self.pushDeclar(node.init));
@@ -403,7 +429,7 @@ var hoistVarDeclarationsVisitor = {
} else if (isVar(node, parent)) {
return self.pushDeclar(node).map(t.expressionStatement);
} else if (t.isFunction(node)) {
return context.skip();
return this.skip();
}
}
};
@@ -413,7 +439,7 @@ var hoistVarDeclarationsVisitor = {
* once we wrap everything in a closure.
*/
LetScoping.prototype.hoistVarDeclarations = function () {
BlockScoping.prototype.hoistVarDeclarations = function () {
traverse(this.block, hoistVarDeclarationsVisitor, this.scope, this);
};
@@ -425,7 +451,7 @@ LetScoping.prototype.hoistVarDeclarations = function () {
* @returns {Array}
*/
LetScoping.prototype.pushDeclar = function (node) {
BlockScoping.prototype.pushDeclar = function (node) {
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
@@ -450,7 +476,7 @@ LetScoping.prototype.pushDeclar = function (node) {
* @param {Node} call CallExpression
*/
LetScoping.prototype.build = function (ret, call) {
BlockScoping.prototype.build = function (ret, call) {
var has = this.has;
if (has.hasReturn || has.hasBreakContinue) {
this.buildHas(ret, call);
@@ -466,7 +492,7 @@ LetScoping.prototype.build = function (ret, call) {
* @param {Node} call CallExpression
*/
LetScoping.prototype.buildHas = function (ret, call) {
BlockScoping.prototype.buildHas = function (ret, call) {
var body = this.body;
body.push(t.variableDeclaration("var", [

View File

@@ -2,14 +2,17 @@
var ReplaceSupers = require("../../helpers/replace-supers");
var nameMethod = require("../../helpers/name-method");
var defineMap = require("../../helpers/define-map");
var util = require("../../../util");
var t = require("../../../types");
exports.ClassDeclaration = function (node, parent, scope, context, file) {
exports.check = t.isClass;
exports.ClassDeclaration = function (node, parent, scope, file) {
return new Class(node, file, scope, true).run();
};
exports.ClassExpression = function (node, parent, scope, context, file) {
exports.ClassExpression = function (node, parent, scope, file) {
if (!node.id) {
if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) {
// var o = { foo: class {} };
@@ -47,7 +50,8 @@ function Class(node, file, scope, isStatement) {
this.staticMutatorMap = {};
this.hasConstructor = false;
this.className = node.id || scope.generateUidIdentifier("class");
this.superName = node.superClass;
this.superName = node.superClass || t.identifier("Function");
this.hasSuper = !!node.superClass;
this.isLoose = file.isLoose("es6.classes");
}
@@ -66,12 +70,19 @@ Class.prototype.run = function () {
var body = this.body = [];
var constructorBody = t.blockStatement([
t.expressionStatement(t.callExpression(file.addHelper("class-call-check"), [
t.thisExpression(),
className
]))
]);
var constructor;
if (this.node.id) {
constructor = t.functionDeclaration(className, [], t.blockStatement([]));
constructor = t.functionDeclaration(className, [], constructorBody);
body.push(constructor);
} else {
constructor = t.functionExpression(null, [], t.blockStatement([]));
constructor = t.functionExpression(null, [], constructorBody);
body.push(t.variableDeclaration("var", [
t.variableDeclarator(className, constructor)
]));
@@ -83,7 +94,7 @@ Class.prototype.run = function () {
//
if (superName) {
if (this.hasSuper) {
closureArgs.push(superName);
if (!t.isIdentifier(superName)) {
@@ -141,10 +152,11 @@ Class.prototype.buildBody = function () {
methodNode: node,
className: this.className,
superName: this.superName,
isStatic: node.static,
isLoose: this.isLoose,
scope: this.scope,
file: this.file
});
}, true);
replaceSupers.replace();
if (node.key.name === "constructor") {
@@ -159,11 +171,10 @@ Class.prototype.buildBody = function () {
}
// we have no constructor, we have a super, and the super doesn't appear to be falsy
if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) {
var defaultConstructorTemplate = "class-super-constructor-call";
if (this.isLoose) defaultConstructorTemplate += "-loose";
constructor.body.body.push(util.template(defaultConstructorTemplate, {
if (!this.hasConstructor && this.hasSuper && !t.isFalsyExpression(superName)) {
var helperName = "class-super-constructor-call";
if (this.isLoose) helperName += "-loose";
constructor.body.body.push(util.template(helperName, {
CLASS_NAME: className,
SUPER_NAME: this.superName
}, true));
@@ -173,11 +184,11 @@ Class.prototype.buildBody = function () {
var staticProps;
if (this.hasInstanceMutators) {
instanceProps = util.buildDefineProperties(this.instanceMutatorMap);
instanceProps = defineMap.build(this.instanceMutatorMap);
}
if (this.hasStaticMutators) {
staticProps = util.buildDefineProperties(this.staticMutatorMap);
staticProps = defineMap.build(this.staticMutatorMap);
}
if (instanceProps || staticProps) {
@@ -230,8 +241,8 @@ Class.prototype.pushMethod = function (node) {
this.hasInstanceMutators = true;
}
util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
util.pushMutatorMap(mutatorMap, methodName, "enumerable", node.computed, false);
defineMap.push(mutatorMap, methodName, kind, node.computed, node);
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
};
/**
@@ -255,5 +266,5 @@ Class.prototype.pushConstructor = function (method) {
construct._ignoreUserWhitespace = true;
construct.params = fn.params;
construct.body = fn.body;
construct.body.body = construct.body.body.concat(fn.body.body);
};

View File

@@ -1,12 +1,15 @@
"use strict";
var traverse = require("../../../traverse");
var t = require("../../../types");
var t = require("../../../types");
exports.check = function (node) {
return t.isVariableDeclaration(node, { kind: "const" });
};
var visitor = {
enter: function (node, parent, scope, context, state) {
if (t.isDeclaration(node) || t.isAssignmentExpression(node)) {
var ids = t.getDeclarations(node);
enter: function (node, parent, scope, state) {
if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
var ids = t.getBindingIdentifiers(node);
for (var key in ids) {
var id = ids[key];
@@ -21,16 +24,19 @@ var visitor = {
// constant so we can just ignore it
if (id === constant) continue;
// check if there's been a local binding that shadows this constant
if (!scope.bindingEquals(key, constant)) continue;
throw state.file.errorWithNode(id, key + " is read-only");
}
} else if (t.isScope(node)) {
context.skip();
this.skip();
}
}
};
exports.Scope = function (node, parent, scope, context, file) {
traverse(node, visitor, scope, {
exports.Scope = function (node, parent, scope, file) {
scope.traverse(node, visitor, {
constants: scope.getAllDeclarationsOfKind("const"),
file: file
});

View File

@@ -1,11 +1,20 @@
"use strict";
// TODO: Clean up
var t = require("../../../types");
var buildVariableAssign = function (opts, id, init) {
var op = opts.operator;
exports.check = t.isPattern;
function Destructuring(opts) {
this.blockHoist = opts.blockHoist;
this.operator = opts.operator;
this.nodes = opts.nodes;
this.scope = opts.scope;
this.file = opts.file;
this.kind = opts.kind;
}
Destructuring.prototype.buildVariableAssignment = function (id, init) {
var op = this.operator;
if (t.isMemberExpression(id)) op = "=";
var node;
@@ -13,47 +22,46 @@ var buildVariableAssign = function (opts, id, init) {
if (op) {
node = t.expressionStatement(t.assignmentExpression(op, id, init));
} else {
node = t.variableDeclaration(opts.kind, [
node = t.variableDeclaration(this.kind, [
t.variableDeclarator(id, init)
]);
}
node._blockHoist = opts.blockHoist;
node._blockHoist = this.blockHoist;
return node;
};
var buildVariableDeclar = function (opts, id, init) {
Destructuring.prototype.buildVariableDeclaration = function (id, init) {
var declar = t.variableDeclaration("var", [
t.variableDeclarator(id, init)
]);
declar._blockHoist = opts.blockHoist;
declar._blockHoist = this.blockHoist;
return declar;
};
var push = function (opts, nodes, elem, parentId) {
Destructuring.prototype.push = function (elem, parentId) {
if (t.isObjectPattern(elem)) {
pushObjectPattern(opts, nodes, elem, parentId);
this.pushObjectPattern(elem, parentId);
} else if (t.isArrayPattern(elem)) {
pushArrayPattern(opts, nodes, elem, parentId);
this.pushArrayPattern(elem, parentId);
} else if (t.isAssignmentPattern(elem)) {
pushAssignmentPattern(opts, nodes, elem, parentId);
this.pushAssignmentPattern(elem, parentId);
} else {
nodes.push(buildVariableAssign(opts, elem, parentId));
this.nodes.push(this.buildVariableAssignment(elem, parentId));
}
};
var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
var tempParentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
var tempParentId = this.scope.generateUidBasedOnNode(parentId);
var declar = t.variableDeclaration("var", [
t.variableDeclarator(tempParentId, parentId)
]);
declar._blockHoist = opts.blockHoist;
nodes.push(declar);
declar._blockHoist = this.blockHoist;
this.nodes.push(declar);
nodes.push(buildVariableAssign(
opts,
this.nodes.push(this.buildVariableAssignment(
pattern.left,
t.conditionalExpression(
t.binaryExpression("===", tempParentId, t.identifier("undefined")),
@@ -63,72 +71,94 @@ var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
));
};
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
var prop2 = pattern.properties[i2];
if (i2 >= i) break;
if (t.isSpreadProperty(prop2)) continue;
var key = prop2.key;
if (t.isIdentifier(key)) {
key = t.literal(prop2.key.name);
}
keys.push(key);
}
keys = t.arrayExpression(keys);
var value = t.callExpression(this.file.addHelper("object-without-properties"), [parentId, keys]);
this.nodes.push(this.buildVariableAssignment(prop.argument, value));
};
Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
if (t.isPattern(pattern2)) {
this.push(pattern2, patternId2);
} else {
this.nodes.push(this.buildVariableAssignment(pattern2, patternId2));
}
};
Destructuring.prototype.pushObjectPattern = function (pattern, parentId) {
if (!pattern.properties.length) {
this.nodes.push(t.expressionStatement(
t.callExpression(this.file.addHelper("object-destructuring-empty"), [parentId])
));
}
if (pattern.properties.length > 1 && t.isMemberExpression(parentId)) {
var temp = this.scope.generateUidBasedOnNode(parentId, this.file);
this.nodes.push(this.buildVariableDeclaration(temp, parentId));
parentId = temp;
}
for (var i = 0; i < pattern.properties.length; i++) {
var prop = pattern.properties[i];
if (t.isSpreadProperty(prop)) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
var prop2 = pattern.properties[i2];
if (i2 >= i) break;
if (t.isSpreadProperty(prop2)) continue;
var key = prop2.key;
if (t.isIdentifier(key)) {
key = t.literal(prop2.key.name);
}
keys.push(key);
}
keys = t.arrayExpression(keys);
var value = t.callExpression(opts.file.addHelper("object-without-properties"), [parentId, keys]);
nodes.push(buildVariableAssign(opts, prop.argument, value));
this.pushObjectSpread(pattern, parentId, prop, i);
} else {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
if (t.isPattern(pattern2)) {
push(opts, nodes, pattern2, patternId2);
} else {
nodes.push(buildVariableAssign(opts, pattern2, patternId2));
}
this.pushObjectProperty(prop, parentId);
}
}
};
var pushArrayPattern = function (opts, nodes, pattern, parentId) {
if (!pattern.elements) return;
var i;
var hasRest = false;
for (i = 0; i < pattern.elements.length; i++) {
var hasRest = function (pattern) {
for (var i = 0; i < pattern.elements.length; i++) {
if (t.isRestElement(pattern.elements[i])) {
hasRest = true;
break;
return true;
}
}
return false;
};
var toArray = opts.file.toArray(parentId, !hasRest && pattern.elements.length);
Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
if (!pattern.elements) return;
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
nodes.push(buildVariableDeclar(opts, _parentId, toArray));
// if we have a rest then we need all the elements
var count = !hasRest(pattern) && pattern.elements.length;
var toArray = this.file.toArray(parentId, count);
var _parentId = this.scope.generateUidBasedOnNode(parentId, this.file);
this.nodes.push(this.buildVariableDeclaration(_parentId, toArray));
parentId = _parentId;
for (i = 0; i < pattern.elements.length; i++) {
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
if (!elem) continue;
i = +i;
// hole
if (!elem) continue;
var newPatternId;
if (t.isRestElement(elem)) {
newPatternId = opts.file.toArray(parentId);
newPatternId = this.file.toArray(parentId);
if (i > 0) {
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
@@ -139,45 +169,62 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
newPatternId = t.memberExpression(parentId, t.literal(i), true);
}
push(opts, nodes, elem, newPatternId);
this.push(elem, newPatternId);
}
};
var pushPattern = function (opts) {
var nodes = opts.nodes;
var pattern = opts.pattern;
var parentId = opts.id;
var scope = opts.scope;
Destructuring.prototype.init = function (pattern, parentId) {
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
var key = scope.generateUidBasedOnNode(parentId);
nodes.push(buildVariableDeclar(opts, key, parentId));
var key = this.scope.generateUidBasedOnNode(parentId);
this.nodes.push(this.buildVariableDeclaration(key, parentId));
parentId = key;
}
push(opts, nodes, pattern, parentId);
this.push(pattern, parentId);
};
exports.ForInStatement =
exports.ForOfStatement = function (node, parent, scope, context, file) {
var declar = node.left;
if (!t.isVariableDeclaration(declar)) return;
exports.ForOfStatement = function (node, parent, scope, file) {
var left = node.left;
var pattern = declar.declarations[0].id;
if (t.isPattern(left)) {
// for ({ length: k } in { abc: 3 });
var temp = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration("var", [
t.variableDeclarator(temp)
]);
t.ensureBlock(node);
node.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(left, temp)
]));
return;
}
if (!t.isVariableDeclaration(left)) return;
var pattern = left.declarations[0].id;
if (!t.isPattern(pattern)) return;
var key = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration(declar.kind, [
node.left = t.variableDeclaration(left.kind, [
t.variableDeclarator(key, null)
]);
var nodes = [];
push({
kind: declar.kind,
var destructuring = new Destructuring({
kind: left.kind,
file: file,
scope: scope
}, nodes, pattern, key);
scope: scope,
nodes: nodes
});
destructuring.init(pattern, key);
t.ensureBlock(node);
@@ -185,7 +232,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
block.body = nodes.concat(block.body);
};
exports.Function = function (node, parent, scope, context, file) {
exports.Function = function (node, parent, scope, file) {
var nodes = [];
var hasDestructuring = false;
@@ -196,15 +243,14 @@ exports.Function = function (node, parent, scope, context, file) {
hasDestructuring = true;
var parentId = scope.generateUidIdentifier("ref");
pushPattern({
var destructuring = new Destructuring({
blockHoist: node.params.length - i,
pattern: pattern,
nodes: nodes,
scope: scope,
file: file,
kind: "var",
id: parentId
});
destructuring.init(pattern, parentId);
return parentId;
});
@@ -217,7 +263,7 @@ exports.Function = function (node, parent, scope, context, file) {
block.body = nodes.concat(block.body);
};
exports.CatchClause = function (node, parent, scope, context, file) {
exports.CatchClause = function (node, parent, scope, file) {
var pattern = node.param;
if (!t.isPattern(pattern)) return;
@@ -226,16 +272,20 @@ exports.CatchClause = function (node, parent, scope, context, file) {
var nodes = [];
push({
kind: "var",
var destructuring = new Destructuring({
kind: "let",
file: file,
scope: scope
}, nodes, pattern, ref);
scope: scope,
nodes: nodes
});
destructuring.init(pattern, ref);
node.body.body = nodes.concat(node.body.body);
return node;
};
exports.ExpressionStatement = function (node, parent, scope, context, file) {
exports.ExpressionStatement = function (node, parent, scope, file) {
var expr = node.expression;
if (expr.type !== "AssignmentExpression") return;
if (!t.isPattern(expr.left)) return;
@@ -248,16 +298,18 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
t.variableDeclarator(ref, expr.right)
]));
push({
var destructuring = new Destructuring({
operator: expr.operator,
file: file,
scope: scope
}, nodes, expr.left, ref);
scope: scope,
nodes: nodes
});
destructuring.init(expr.left, ref);
return nodes;
};
exports.AssignmentExpression = function (node, parent, scope, context, file) {
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!t.isPattern(node.left)) return;
var ref = scope.generateUidIdentifier("temp");
@@ -269,50 +321,50 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
var nodes = [];
nodes.push(t.assignmentExpression("=", ref, node.right));
push({
var destructuring = new Destructuring({
operator: node.operator,
file: file,
scope: scope
}, nodes, node.left, ref);
scope: scope,
nodes: nodes
});
destructuring.init(node.left, ref);
nodes.push(ref);
return t.toSequenceExpression(nodes, scope);
};
exports.VariableDeclaration = function (node, parent, scope, context, file) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
var nodes = [];
var i;
var declar;
var hasPattern = false;
for (i = 0; i < node.declarations.length; i++) {
declar = node.declarations[i];
if (t.isPattern(declar.id)) {
hasPattern = true;
break;
var variableDeclarationhasPattern = function (node) {
for (var i = 0; i < node.declarations.length; i++) {
if (t.isPattern(node.declarations[i].id)) {
return true;
}
}
if (!hasPattern) return;
return false;
};
for (i = 0; i < node.declarations.length; i++) {
exports.VariableDeclaration = function (node, parent, scope, file) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
if (!variableDeclarationhasPattern(node)) return;
var nodes = [];
var declar;
for (var i = 0; i < node.declarations.length; i++) {
declar = node.declarations[i];
var patternId = declar.init;
var pattern = declar.id;
var opts = {
pattern: pattern,
nodes: nodes,
scope: scope,
kind: node.kind,
file: file,
id: patternId,
};
var destructuring = new Destructuring({
nodes: nodes,
scope: scope,
kind: node.kind,
file: file
});
if (t.isPattern(pattern) && patternId) {
pushPattern(opts);
destructuring.init(pattern, patternId);
if (+i !== node.declarations.length - 1) {
// we aren't the last declarator so let's just make the
@@ -320,11 +372,14 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
t.inherits(nodes[nodes.length - 1], declar);
}
} else {
nodes.push(t.inherits(buildVariableAssign(opts, declar.id, declar.init), declar));
nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar));
}
}
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
// https://github.com/6to5/6to5/issues/113
// for (let [x] = [0]; false;) {}
declar = null;
for (i = 0; i < nodes.length; i++) {

View File

@@ -3,11 +3,13 @@
var util = require("../../../util");
var t = require("../../../types");
exports.ForOfStatement = function (node, parent, scope, context, file) {
exports.check = t.isForOfStatement;
exports.ForOfStatement = function (node, parent, scope, file) {
var callback = spec;
if (file.isLoose("es6.forOf")) callback = loose;
var build = callback(node, parent, scope, context, file);
var build = callback(node, parent, scope, file);
var declar = build.declar;
var loop = build.loop;
var block = loop.body;
@@ -26,13 +28,15 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
// push the rest of the original loop body onto our new body
block.body = block.body.concat(node.body.body);
t.inherits(loop, node);
// todo: find out why this is necessary? #538
loop._scopeInfo = node._scopeInfo;
return loop;
};
var loose = function (node, parent, scope, context, file) {
var loose = function (node, parent, scope, file) {
var left = node.left;
var declar, id;
@@ -69,7 +73,7 @@ var loose = function (node, parent, scope, context, file) {
};
};
var spec = function (node, parent, scope, context, file) {
var spec = function (node, parent, scope, file) {
var left = node.left;
var declar;

View File

@@ -2,7 +2,9 @@
var t = require("../../../types");
exports.ImportDeclaration = function (node, parent, scope, context, file) {
exports.check = require("../internal/modules").check;
exports.ImportDeclaration = function (node, parent, scope, file) {
var nodes = [];
if (node.specifiers.length) {
@@ -21,12 +23,12 @@ exports.ImportDeclaration = function (node, parent, scope, context, file) {
return nodes;
};
exports.ExportDeclaration = function (node, parent, scope, context, file) {
exports.ExportDeclaration = function (node, parent, scope, file) {
var nodes = [];
var i;
if (node.declaration) {
// make sure variable exports have an initialiser
// make sure variable exports have an initializer
// this is done here to avoid duplicating it in the module formatters
if (t.isVariableDeclaration(node.declaration)) {
var declar = node.declaration.declarations[0];

View File

@@ -0,0 +1,34 @@
"use strict";
var ReplaceSupers = require("../../helpers/replace-supers");
var t = require("../../../types");
exports.check = function (node) {
return t.isIdentifier(node, { name: "super" });
};
exports.Property = function (node, parent, scope, file) {
if (!node.method) return;
var value = node.value;
var thisExpr = scope.generateUidIdentifier("this");
var replaceSupers = new ReplaceSupers({
topLevelThisReference: thisExpr,
methodNode: node,
className: thisExpr,
isStatic: true,
scope: scope,
file: file
});
replaceSupers.replace();
if (replaceSupers.hasSuper) {
value.body.body.unshift(
t.variableDeclaration("var", [
t.variableDeclarator(thisExpr, t.thisExpression())
])
);
}
};

View File

@@ -1,26 +1,31 @@
"use strict";
var traverse = require("../../../traverse");
var util = require("../../../util");
var t = require("../../../types");
var util = require("../../../util");
var t = require("../../../types");
exports.check = function (node) {
return t.isFunction(node) && hasDefaults(node);
};
var hasDefaults = function (node) {
for (var i = 0; i < node.params.length; i++) {
if (t.isAssignmentPattern(node.params[i])) return true;
if (!t.isIdentifier(node.params[i])) return true;
}
return false;
};
var iifeVisitor = {
enter: function (node, parent, scope, context, state) {
if (t.isReferencedIdentifier(node, parent) && state.scope.hasOwn(node.name)) {
state.iife = true;
context.stop();
}
enter: function (node, parent, scope, state) {
if (!t.isReferencedIdentifier(node, parent)) return;
if (!state.scope.hasOwnBinding(node.name)) return;
if (state.scope.bindingEquals(node.name, node)) return;
state.iife = true;
this.stop();
}
};
exports.Function = function (node, parent, scope) {
exports.Function = function (node, parent, scope, file) {
if (!hasDefaults(node)) return;
t.ensureBlock(node);
@@ -34,11 +39,32 @@ exports.Function = function (node, parent, scope) {
var state = { iife: false, scope: scope };
var pushDefNode = function (left, right, i) {
var defNode = util.template("default-parameter", {
VARIABLE_NAME: left,
DEFAULT_VALUE: right,
ARGUMENT_KEY: t.literal(i),
ARGUMENTS: argsIdentifier
}, true);
file.checkNode(defNode);
defNode._blockHoist = node.params.length - i;
body.push(defNode);
};
for (var i = 0; i < node.params.length; i++) {
var param = node.params[i];
if (!t.isAssignmentPattern(param)) {
lastNonDefaultParam = +i + 1;
lastNonDefaultParam = i + 1;
if (!t.isIdentifier(param)) {
scope.traverse(param, iifeVisitor, state);
}
if (file.transformers["es6.blockScopingTDZ"].canRun()) {
pushDefNode(param, t.identifier("undefined"), i);
}
continue;
}
@@ -48,21 +74,14 @@ exports.Function = function (node, parent, scope) {
node.params[i] = scope.generateUidIdentifier("x");
if (!state.iife) {
if (t.isIdentifier(right) && scope.hasOwn(right.name)) {
if (t.isIdentifier(right) && scope.hasOwnReference(right.name)) {
state.iife = true;
} else {
traverse(right, iifeVisitor, scope, state);
scope.traverse(right, iifeVisitor, state);
}
}
var defNode = util.template("default-parameter", {
VARIABLE_NAME: left,
DEFAULT_VALUE: right,
ARGUMENT_KEY: t.literal(+i),
ARGUMENTS: argsIdentifier
}, true);
defNode._blockHoist = node.params.length - i;
body.push(defNode);
pushDefNode(left, right, i);
}
// we need to cut off all trailing default parameters

View File

@@ -3,6 +3,8 @@
var util = require("../../../util");
var t = require("../../../types");
exports.check = t.isRestElement;
var hasRest = function (node) {
return t.isRestElement(node.params[node.params.length - 1]);
};

View File

@@ -2,7 +2,11 @@
var t = require("../../../types");
exports.ObjectExpression = function (node, parent, scope, context, file) {
exports.check = function (node) {
return t.isProperty(node) && node.computed;
};
exports.ObjectExpression = function (node, parent, scope, file) {
var hasComputed = false;
for (var i = 0; i < node.properties.length; i++) {
@@ -58,7 +62,7 @@ var spec = function (node, body, objId, initProps, file) {
var props = node.properties;
var prop, key;
// normalise key
// normalize key
for (var i = 0; i < props.length; i++) {
prop = props[i];

View File

@@ -4,7 +4,11 @@ var nameMethod = require("../../helpers/name-method");
var t = require("../../../types");
var clone = require("lodash/lang/clone");
exports.Property = function (node, parent, scope, context, file) {
exports.check = function (node) {
return t.isProperty(node) && (node.method || node.shorthand);
};
exports.Property = function (node, parent, scope, file) {
if (node.method) {
node.method = false;
nameMethod.property(node, file, scope);

View File

@@ -1,7 +1,9 @@
"use strict";
var t = require("../../../types");
var contains = require("lodash/collection/contains");
var t = require("../../../types");
exports.check = t.isSpreadElement;
var getSpreadLiteral = function (spread, file) {
return file.toArray(spread.argument);
@@ -42,7 +44,7 @@ var build = function (props, file) {
return nodes;
};
exports.ArrayExpression = function (node, parent, scope, context, file) {
exports.ArrayExpression = function (node, parent, scope, file) {
var elements = node.elements;
if (!hasSpread(elements)) return;
@@ -57,7 +59,7 @@ exports.ArrayExpression = function (node, parent, scope, context, file) {
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
};
exports.CallExpression = function (node, parent, scope, context, file) {
exports.CallExpression = function (node, parent, scope, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
@@ -71,8 +73,8 @@ exports.CallExpression = function (node, parent, scope, context, file) {
} else {
nodes = build(args, file);
}
var first = nodes.shift();
var first = nodes.shift();
if (nodes.length) {
node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
} else {
@@ -97,7 +99,7 @@ exports.CallExpression = function (node, parent, scope, context, file) {
node.arguments.unshift(contextLiteral);
};
exports.NewExpression = function (node, parent, scope, context, file) {
exports.NewExpression = function (node, parent, scope, file) {
var args = node.arguments;
if (!hasSpread(args)) return;

View File

@@ -0,0 +1,116 @@
"use strict";
var t = require("../../../types");
function transformExpression(node, scope, state) {
if (!node) return;
return (function subTransform(node) {
switch (node.type) {
case "ConditionalExpression":
// any value of ternary operator can be final one
subTransform(node.consequent);
subTransform(node.alternate);
break;
case "LogicalExpression":
// only right expression can be final and so optimized
subTransform(node.right);
break;
case "SequenceExpression":
// only last element of sequence can be optimized
var seq = node.expressions;
subTransform(seq[seq.length - 1]);
break;
case "CallExpression":
var callee = node.callee, thisBinding;
var args = [callee];
// bind `this` to object in member expressions
if (t.isMemberExpression(callee)) {
var object = state.wrapSideEffect(callee.object);
callee.object = object.expr;
thisBinding = object.ref;
}
if (node.arguments.length > 0 || thisBinding) {
args.push(t.arrayExpression(node.arguments));
}
if (thisBinding) {
args.push(thisBinding);
}
node.callee = state.getHelperRef();
node.arguments = args;
break;
}
})(node);
}
var functionChildrenVisitor = {
enter: function (node, parent, scope, state) {
if (t.isReturnStatement(node)) {
// prevent entrance by current visitor
this.skip();
// transform return argument into statement if
// it contains tail recursion
transformExpression(node.argument, scope, state);
} else if (t.isFunction(node)) {
// inner function's bodies are irrelevant
this.skip();
} else if (t.isTryStatement(parent)) {
if (node === parent.block) {
// `try`-blocks can't be optimized
this.skip();
} else if (parent.finalizer && node !== parent.finalizer) {
// `catch` clause followed by `finally` can't be optimized
this.skip();
}
}
}
};
var functionVisitor = {
enter: function (node, parent, scope, state) {
// traverse all child nodes of this function and find `arguments` and `this`
scope.traverse(node, functionChildrenVisitor, state);
return this.skip();
}
};
exports.FunctionDeclaration =
exports.FunctionExpression = function (node, parent, scope, file) {
var tempId, helperRef;
var state = {
ownerId: node.id,
getHelperRef: function () {
return helperRef = helperRef || file.addHelper("tail-call");
},
wrapSideEffect: function (node) {
if (t.isIdentifier(node) || t.isLiteral(node)) {
return {expr: node, ref: node};
}
tempId = tempId || scope.generateUidIdentifier("temp");
return {
expr: t.assignmentExpression("=", tempId, node),
ref: tempId
};
}
};
// traverse the function and look for tail recursion
scope.traverse(node, functionVisitor, state);
if (tempId) {
t.ensureBlock(node).body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(tempId)
]));
}
};

View File

@@ -6,7 +6,11 @@ var buildBinaryExpression = function (left, right) {
return t.binaryExpression("+", left, right);
};
exports.TaggedTemplateExpression = function (node, parent, scope, context, file) {
exports.check = function (node) {
return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node);
};
exports.TaggedTemplateExpression = function (node, parent, scope, file) {
var args = [];
var quasi = node.quasi;

View File

@@ -2,6 +2,11 @@
var rewritePattern = require("regexpu/rewrite-pattern");
var pull = require("lodash/array/pull");
var t = require("../../../types");
exports.check = function (node) {
return t.isLiteral(node) && node.regex && node.regex.flags.indexOf("u") >= 0;
};
exports.Literal = function (node) {
var regex = node.regex;

View File

@@ -23,7 +23,7 @@ var container = function (parent, call, ret, file) {
}
};
exports.AssignmentExpression = function (node, parent, scope, context, file) {
exports.AssignmentExpression = function (node, parent, scope, file) {
var left = node.left;
if (!t.isVirtualPropertyExpression(left)) return;
@@ -63,7 +63,7 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
return container(parent, call, value, file);
};
exports.UnaryExpression = function (node, parent, scope, context, file) {
exports.UnaryExpression = function (node, parent, scope, file) {
var arg = node.argument;
if (!t.isVirtualPropertyExpression(arg)) return;
if (node.operator !== "delete") return;

View File

@@ -1,13 +1,13 @@
"use strict";
var buildComprehension = require("../../helpers/build-comprehension");
var traverse = require("../../../traverse");
var traverse = require("../../../traversal");
var util = require("../../../util");
var t = require("../../../types");
exports.experimental = true;
exports.ComprehensionExpression = function (node, parent, scope, context, file) {
exports.ComprehensionExpression = function (node, parent, scope, file) {
var callback = array;
if (node.generator) callback = generator;
return callback(node, parent, scope, file);

View File

@@ -6,18 +6,21 @@ var t = require("../../../types");
exports.experimental = true;
exports.ObjectExpression = function (node, parent, scope, context, file) {
var hasSpread = false;
var i;
var prop;
for (i = 0; i < node.properties.length; i++) {
prop = node.properties[i];
if (t.isSpreadProperty(prop)) {
hasSpread = true;
break;
exports.manipulateOptions = function (opts) {
if (opts.whitelist.length) opts.whitelist.push("es6.destructuring");
};
var hasSpread = function (node) {
for (var i = 0; i < node.properties.length; i++) {
if (t.isSpreadProperty(node.properties[i])) {
return true;
}
}
if (!hasSpread) return;
return false;
};
exports.ObjectExpression = function (node, parent, scope, file) {
if (!hasSpread(node)) return;
var args = [];
var props = [];
@@ -28,8 +31,8 @@ exports.ObjectExpression = function (node, parent, scope, context, file) {
props = [];
};
for (i = 0; i < node.properties.length; i++) {
prop = node.properties[i];
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i];
if (t.isSpreadProperty(prop)) {
push();
args.push(prop.argument);

View File

@@ -11,8 +11,8 @@ module.exports = {
"playground.memoizationOperator": require("./playground/memoization-operator"),
"playground.objectGetterMemoization": require("./playground/object-getter-memoization"),
reactCompat: require("./other/react-compat"),
react: require("./other/react"),
"optimisation.react": require("./optimisation/react"),
_modules: require("./internal/modules"),
@@ -28,7 +28,8 @@ module.exports = {
asyncToGenerator: require("./other/async-to-generator"),
bluebirdCoroutines: require("./other/bluebird-coroutines"),
"es7.objectSpread": require("./es7/object-spread"),
"es6.objectSuper": require("./es6/object-super"),
"es7.objectRestSpread": require("./es7/object-rest-spread"),
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
"es6.spread": require("./es6/spread"),
"es6.templateLiterals": require("./es6/template-literals"),
@@ -46,6 +47,14 @@ module.exports = {
"es6.constants": require("./es6/constants"),
// needs to be before `es6.blockScoping` as default parameters have a TDZ
"es6.parameters.default": require("./es6/parameters.default"),
"es6.parameters.rest": require("./es6/parameters.rest"),
// needs to be before `es6.blockScoping` as let variables may be produced
"es6.destructuring": require("./es6/destructuring"),
// needs to be before `_aliasFunction` due to block scopes sometimes being wrapped in a
// closure
"es6.blockScoping": require("./es6/block-scoping"),
@@ -53,10 +62,7 @@ module.exports = {
// needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks
"es6.blockScopingTDZ": require("./es6/block-scoping-tdz"),
"es6.parameters.default": require("./es6/parameters.default"),
"es6.parameters.rest": require("./es6/parameters.rest"),
"es6.destructuring": require("./es6/destructuring"),
"es6.tailCall": require("./es6/tail-call"),
regenerator: require("./other/regenerator"),
@@ -80,6 +86,13 @@ module.exports = {
"spec.typeofSymbol": require("./spec/typeof-symbol"),
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
"minification.propertyLiterals": require("./minification/property-literals"),
"minification.memberExpressionLiterals": require("./minification/member-expression-literals")
"es3.propertyLiterals": require("./es3/property-literals"),
"es3.memberExpressionLiterals": require("./es3/member-expression-literals"),
"minification.removeDebugger": require("./minification/remove-debugger"),
"minification.removeConsoleCalls": require("./minification/remove-console-calls"),
"minification.deadCodeElimination": require("./minification/dead-code-elimination"),
"minification.renameLocalVariables": require("./minification/rename-local-variables"),
_cleanUp: require("./internal/cleanup")
};

View File

@@ -1,15 +1,14 @@
"use strict";
var traverse = require("../../../traverse");
var t = require("../../../types");
var t = require("../../../types");
var functionChildrenVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isFunction(node) && !node._aliasFunction) {
return context.skip();
return this.skip();
}
if (node._ignoreAliasFunctions) return context.skip();
if (node._ignoreAliasFunctions) return this.skip();
var getId;
@@ -26,20 +25,20 @@ var functionChildrenVisitor = {
};
var functionVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (!node._aliasFunction) {
if (t.isFunction(node)) {
// stop traversal of this node as it'll be hit again by this transformer
return context.skip();
return this.skip();
} else {
return;
}
}
// traverse all child nodes of this function and find `arguments` and `this`
traverse(node, functionChildrenVisitor, scope, state);
scope.traverse(node, functionChildrenVisitor, state);
return context.skip();
return this.skip();
}
};
@@ -58,7 +57,7 @@ var go = function (getBody, node, scope) {
// traverse the function and find all alias functions so we can alias
// `arguments` and `this` if necessary
traverse(node, functionVisitor, scope, state);
scope.traverse(node, functionVisitor, state);
var body;

View File

@@ -0,0 +1,5 @@
exports.SequenceExpression = function (node) {
if (node.expressions.length === 1) {
return node.expressions[0];
}
};

View File

@@ -2,16 +2,16 @@
var useStrict = require("../../helpers/use-strict");
exports.ast = {
exit: function (ast, file) {
if (!file.transformers["es6.modules"].canRun()) return;
exports.post = function (file) {
if (!file.transformers["es6.modules"].canRun()) return;
useStrict.wrap(ast.program, function () {
ast.program.body = file.dynamicImports.concat(ast.program.body);
});
var program = file.ast.program;
if (file.moduleFormatter.transform) {
file.moduleFormatter.transform(ast);
}
useStrict.wrap(program, function () {
program.body = file.dynamicImports.concat(program.body);
});
if (file.moduleFormatter.transform) {
file.moduleFormatter.transform(program);
}
};

View File

@@ -8,13 +8,17 @@
var t = require("../../../types");
var resolveModuleSource = function (node, parent, scope, context, file) {
var resolveModuleSource = function (node, parent, scope, file) {
var resolveModuleSource = file.opts.resolveModuleSource;
if (node.source && resolveModuleSource) {
node.source.value = resolveModuleSource(node.source.value);
}
};
exports.check = function (node) {
return t.isImportDeclaration(node) || t.isExportDeclaration(node);
};
exports.ImportDeclaration = resolveModuleSource;
exports.ExportDeclaration = function (node, parent, scope) {

View File

@@ -0,0 +1,76 @@
var t = require("../../../types");
exports.optional = true;
exports.ExpressionStatement = function (node) {
// remove consequenceless expressions such as local variables and literals
//
// var foo = true; foo; -> var foo = true;
// "foo"; ->
//
var expr = node.expression;
if (t.isLiteral(expr) || (t.isIdentifier(node) && t.hasBinding(node.name))) {
this.remove();
}
};
exports.IfStatement = {
exit: function (node) {
// todo: in scenarios where we can just return the consequent or
// alternate we should drop the block statement if it contains no
// block scoped variables
var consequent = node.consequent;
var alternate = node.alternate;
var test = node.test;
// we can check if a test will be truthy 100% and if so then we can inline
// the consequent and completely ignore the alternate
//
// if (true) { foo; } -> { foo; }
// if ("foo") { foo; } -> { foo; }
//
if (t.isLiteral(test) && test.value) {
return alternate;
}
// we can check if a test will be falsy 100% and if so we can inline the
// alternate if there is one and completely remove the consequent
//
// if ("") { bar; } else { foo; } -> { foo; }
// if ("") { bar; } ->
//
if (t.isFalsyExpression(test)) {
if (alternate) {
return alternate;
} else {
return this.remove();
}
}
// remove alternate blocks that are empty
//
// if (foo) { foo; } else {} -> if (foo) { foo; }
//
if (t.isBlockStatement(alternate) && !alternate.body.length) {
alternate = node.alternate = null;
}
// if the consequent block is empty turn alternate blocks into a consequent
// and flip the test
//
// if (foo) {} else { bar; } -> if (!foo) { bar; }
//
if (t.blockStatement(consequent) && !consequent.body.length &&
t.isBlockStatement(alternate) && alternate.body.length) {
node.consequent = node.alternate;
node.alternate = null;
node.test = t.unaryExpression("!", test, true);
}
}
};

View File

@@ -0,0 +1,13 @@
"use strict";
var t = require("../../../types");
var isConsole = t.buildMatchMemberExpression("console", true);
exports.optional = true;
exports.CallExpression = function (node) {
if (isConsole(node.callee)) {
this.remove();
}
};

View File

@@ -0,0 +1,9 @@
var t = require("../../../types");
exports.optional = true;
exports.ExpressionStatement = function (node) {
if (t.isIdentifier(node.expression, { name: "debugger" })) {
this.remove();
}
};

View File

@@ -0,0 +1,11 @@
//var t = require("../../../types");
exports.optional = true;
exports.Scope = function () {
// todo: get all binding identifiers, generate compact names
// that wont collide and then call the remap identifier helper
// this transformer **has** to be ran last as it will absolutley
// destroy the scope tree
};

View File

@@ -1,55 +0,0 @@
module.exports = BaseOptimiser;
var object = require("../../../../helpers/object");
/**
* Description
*
* @param {Node} node
*/
function BaseOptimiser(node) {
this.methods = object();
this.types = object();
this.node = node;
}
/**
* Description
*/
BaseOptimiser.prototype.run = function () {
this.getMethods();
this.getTypes();
};
/**
* Add an `ObjectExpression` `node` that contains `propTypes`.
*
* Search it and match it against the types that we can optimise
* and register it for consumption later.
*
* @param {Node} node
*/
BaseOptimiser.prototype.addPropTypes = function (node) {
var props = node.properties;
for (var i = 0; i < props.length; i++) {
this.addPropType(props[i]);
}
};
/**
* Register a `Property` node as a prop type.
*
* We'll try and resolve it to a known type if we can and normalise
* it for consumption later.
*
* @param {Node} prop
*/
BaseOptimiser.prototype.addPropType = function () {
};

View File

@@ -1,51 +0,0 @@
module.exports = CreateClassOptimiser;
var BaseOptimiser = require("./base");
var util = require("../../../../util");
var t = require("../../../../types");
function CreateClassOptimiser() {
BaseOptimiser.apply(this, arguments);
}
util.inherits(CreateClassOptimiser, BaseOptimiser);
/**
* Get all function expressions.
*/
CreateClassOptimiser.prototype.getMethods = function () {
var props = this.node.properties;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
// irrelevant
if (!t.isFunctionExpression(prop.value)) continue;
// deopt
if (prop.computed) continue;
this.methods[prop.key.name] = prop;
}
};
/**
* Find a `propTypes` property.
*/
CreateClassOptimiser.prototype.getTypes = function () {
var props = this.node.properties;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
var key = t.toComputedKey(prop, prop.key);
if (t.isLiteral(key, { value: "propTypes" }) && t.isObjectExpression(prop.value)) {
this.addPropTypes(prop.value);
return;
}
}
// not found
};

View File

@@ -1,17 +0,0 @@
var CreateClassOptimiser = require("./create-class");
var NativeClassOptimiser = require("./native-class");
var react = require("../../../helpers/react");
exports.optional = true;
exports.CallExpression = function (node) {
if (react.isCreateClass(node)) {
new CreateClassOptimiser(node.arguments[0]).run();
}
};
exports.CallExpression = function (node) {
if (react.isReactComponent(node.superClass)) {
new NativeClassOptimiser(node).run();
}
};

View File

@@ -1,42 +0,0 @@
module.exports = NativeClassOptimiser;
var BaseOptimiser = require("./base");
var util = require("../../../../util");
var t = require("../../../../types");
function NativeClassOptimiser() {
BaseOptimiser.apply(this, arguments);
}
util.inherits(NativeClassOptimiser, BaseOptimiser);
/**
* Get all instance methods.
*/
NativeClassOptimiser.prototype.getMethods = function () {
var body = this.node.body;
for (var i = 0; i < body.length; i++) {
var node = body[i];
// PrivateDeclaration etc
if (!t.isMethodDefinition(node)) continue;
// deopt
if (node.computed) continue;
// irrelevant
if (node.static) continue;
this.methods[node.key.name] = node;
}
};
/**
* Description
*/
NativeClassOptimiser.prototype.getTypes = function () {
};

View File

@@ -7,7 +7,7 @@ exports.optional = true;
exports.manipulateOptions = bluebirdCoroutines.manipulateOptions;
exports.Function = function (node, parent, scope, context, file) {
exports.Function = function (node, parent, scope, file) {
if (!node.async || node.generator) return;
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"), scope);

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