Compare commits

...

207 Commits

Author SHA1 Message Date
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
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
Sebastian McKenzie
4763b95a0d v3.3.2 2015-02-02 01:43:47 +11:00
Sebastian McKenzie
9fe1e37ca7 fix t.buildMatchMemberExpression 2015-02-02 01:41:39 +11:00
Sebastian McKenzie
8a9aac3e68 fix linting errors 2015-02-02 01:37:27 +11:00
Sebastian McKenzie
27138abd29 simplify member expression checking, flesh out react component optimiser #653 2015-02-02 01:30:06 +11:00
Sebastian McKenzie
dcf91db475 add react component optimisation base #653 2015-02-02 00:50:25 +11:00
Sebastian McKenzie
ab63345764 3.3.1 2015-02-01 18:44:46 +11:00
Sebastian McKenzie
a35e63fb29 v3.3.1 2015-02-01 18:44:07 +11:00
Sebastian McKenzie
3fe7df9a48 fix regenerator destructuring test 2015-02-01 18:42:15 +11:00
Sebastian McKenzie
5288f3afda add 3.3.1 changelog 2015-02-01 18:33:54 +11:00
Sebastian McKenzie
25566a24f6 block hoist assignment pattern destructuring - fixes #652 2015-02-01 18:33:36 +11:00
Sebastian McKenzie
2ff6dee0ec 3.3.0 2015-02-01 16:52:23 +11:00
Sebastian McKenzie
491d1238c2 fix buildHelpers function name 2015-02-01 16:51:57 +11:00
Sebastian McKenzie
234414c2f2 v3.3.0 2015-02-01 16:49:18 +11:00
Sebastian McKenzie
3ff544bbab fix indentation detection 2015-02-01 16:47:28 +11:00
Sebastian McKenzie
416c4cbb84 fix linting errors 2015-02-01 16:44:47 +11:00
Sebastian McKenzie
db5bf1749b fix linting errors 2015-02-01 16:43:42 +11:00
Sebastian McKenzie
41349afea3 add 3.3.0 changelog 2015-02-01 16:43:05 +11:00
Sebastian McKenzie
27da6de723 add back runtime - fixes #651 2015-02-01 16:38:13 +11:00
Sebastian McKenzie
2cdb4e3343 fix linting errors 2015-02-01 16:21:13 +11:00
Sebastian McKenzie
981d3e40f8 add canRun check for playground transformers 2015-02-01 16:20:32 +11:00
Sebastian McKenzie
c7a616730c add levenshtein suggestions to undeclared variable transformer 2015-02-01 16:20:18 +11:00
Sebastian McKenzie
5aa8ece242 don't run playground transformers at all if playground isn't enabled 2015-02-01 16:19:49 +11:00
Sebastian McKenzie
8c7ba20f86 fix regenerator transformer order - fixes #617 2015-02-01 16:19:35 +11:00
Sebastian McKenzie
1cc9027fcf 3.2.1 2015-02-01 16:19:09 +11:00
Sebastian McKenzie
e63dbaa646 v3.2.1 2015-01-31 21:33:26 +11:00
Sebastian McKenzie
4a720625d9 fix linting errors 2015-01-31 21:29:44 +11:00
Sebastian McKenzie
ad428b107a add 3.2.1 changelog 2015-01-31 21:28:14 +11:00
Sebastian McKenzie
c0299320f0 avoid transforming of inner labels and propagation of maps in block scoping transformer - #644 2015-01-31 21:27:20 +11:00
Sebastian McKenzie
efaee3d5d9 remove pending tests 2015-01-31 18:11:54 +11:00
Sebastian McKenzie
12bee73070 restructure internal indexes a bit 2015-01-31 18:04:57 +11:00
Sebastian McKenzie
82c18a837d add detection skeleton #631 2015-01-31 17:59:30 +11:00
Sebastian McKenzie
fed51e8246 3.2.0 2015-01-31 17:59:08 +11:00
Sebastian McKenzie
71f17e464f update 3.2.0 changelog 2015-01-31 17:59:02 +11:00
Sebastian McKenzie
026fd7eddb v3.2.0 2015-01-31 10:15:22 +11:00
Sebastian McKenzie
456b2d3910 remove unused keys declaration in types 2015-01-31 10:12:32 +11:00
Sebastian McKenzie
4208bf3f4b add accept to valid options 6to5/gobble-6to5#2 2015-01-31 10:11:40 +11:00
Sebastian McKenzie
a81678d327 add 3.2.0 changelog 2015-01-31 10:11:19 +11:00
Sebastian McKenzie
be55f42f80 simplify Scope::has 2015-01-31 10:06:22 +11:00
Sebastian McKenzie
b1b326cf9c better self contained module tests - fixes #634 2015-01-30 22:32:21 +11:00
Sebastian McKenzie
a9ff73b4f6 use double quotes instead of single 2015-01-30 21:50:31 +11:00
Sebastian McKenzie
f5ccb9c0ba clean up types, add missing jsdoc parameters, add some descriptions 2015-01-30 21:48:32 +11:00
Sebastian McKenzie
1cbbe00b7a Merge pull request #582 from kruppel/kurt/setter-super
Support use of super inside instance setter.
2015-01-30 21:47:24 +11:00
Sebastian McKenzie
055dd5d2c3 simplify t.getDeclarations keys 2015-01-30 21:42:24 +11:00
Sebastian McKenzie
0fea437536 rename t.getIds to t.getDeclarations and remove dead code 2015-01-30 21:36:51 +11:00
Sebastian McKenzie
f325d3b065 add pattern rest parameters test 2015-01-30 21:26:45 +11:00
Sebastian McKenzie
e514660fbd we no longer have to handle labels on loops in block scoping 2015-01-30 21:26:35 +11:00
Sebastian McKenzie
a5d8144cce don't lazily check kangax compat-table exec comment 2015-01-30 21:17:35 +11:00
Sebastian McKenzie
8145840264 add istanbul config 2015-01-30 21:17:16 +11:00
Sebastian McKenzie
a02eafedfd add additional let scoping nested label tests 2015-01-30 21:07:40 +11:00
Sebastian McKenzie
3f3cd2bb3a add better support for labels in the block scoping transformer and add more let scoping tests - fixes #644 and closes #608 2015-01-30 20:51:20 +11:00
Sebastian McKenzie
503a3f2e3a ignore compat-table tests that have no code 2015-01-30 19:43:47 +11:00
Sebastian McKenzie
48a8723fdb add compat-table to make bootstrap 2015-01-30 19:39:58 +11:00
Sebastian McKenzie
92c297b1be add assertVendor test helper 2015-01-30 19:39:51 +11:00
Sebastian McKenzie
56e26378ff delay running 6to5/register in tests 2015-01-30 19:39:38 +11:00
Sebastian McKenzie
f3f69ab4fa fix scope tracking for default parameters iife 2015-01-30 19:39:20 +11:00
Sebastian McKenzie
2a488b951d remove unused variable in commonjs module formatter 2015-01-30 19:39:09 +11:00
Sebastian McKenzie
ac01caacd3 rename useStrict test to something more specific 2015-01-30 19:39:00 +11:00
Sebastian McKenzie
cbdf746474 fix block scoped functions 2015-01-30 19:38:50 +11:00
Sebastian McKenzie
ad0a1ae66d add kangax compat-table tests - fixes #606 2015-01-30 19:38:44 +11:00
Sebastian McKenzie
3b783979d8 add resolveModuleSource option - closes #471 2015-01-30 18:04:54 +11:00
Sebastian McKenzie
b2ec15accc allow test options to be plain javascript files 2015-01-30 18:04:28 +11:00
Sebastian McKenzie
3b7cfc908e use globals module instead of maintaining our own list 2015-01-30 17:17:42 +11:00
Sebastian McKenzie
010ca83d0d improved relative resolution handling for bin/6to5 - closes #643 2015-01-30 16:59:04 +11:00
Sebastian McKenzie
161c895a90 move esvalid to devDependencies 2015-01-30 16:58:38 +11:00
Sebastian McKenzie
47a45f3731 add additional react ThisExpression conversion test 2015-01-30 11:05:16 +11:00
Sebastian McKenzie
7bb3cfd932 3.1.1 2015-01-30 11:04:46 +11:00
Kurt Ruppel
d87b70b57e Use right side verbatim for ES6 class setter. 2015-01-26 15:55:27 -08:00
Kurt Ruppel
bbfb297d73 Support use of super inside instance setter. 2015-01-26 15:55:27 -08:00
Kurt Ruppel
9b68d08604 Add test for failing assignment to super setter. 2015-01-26 15:55:27 -08:00
280 changed files with 4137 additions and 2313 deletions

3
.gitmodules vendored
View File

@@ -7,3 +7,6 @@
[submodule "vendor/test262"]
path = vendor/test262
url = https://github.com/tc39/test262
[submodule "vendor/compat-table"]
path = vendor/compat-table
url = https://github.com/kangax/compat-table

2
.istanbul.yml Normal file
View File

@@ -0,0 +1,2 @@
instrumentation:
root: lib

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,113 @@
_Note: Gaps between patch versions are faulty/broken releases._
## 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**
* Block hoist assignment pattern destructuring.
## 3.3.0
* **Bug Fix**
* Do all transforms before the regenerator transform is ran.
* **New Feature**
* Added back the 2.x optional runtime.
## 3.2.1
* **Bug Fix**
* Fix block scoping transformer rewriting breaks and continues to inner labels.
## 3.2.0
* **Bug Fix**
* Fixed scope tracking for default parameters IIFE.
* Fixed block scoped functions.
* Improved `bin/6to5` path resolution.
* **New Feature**
* You can now trigger super setters in classes. Thanks [@kruppel](https://github.com/kruppel)!
* Add `resolveSourceMap` option.
* Better support and output for block scoping loops with labels.
## 3.1.1
* **Polish**
@@ -290,8 +397,8 @@ _Note: Gaps between patch versions are faulty/broken releases._
* **Polish**
* Rest parameters now allocate the array before populating.
* **Internal**
* `for...in` loops have been changed to optimised `for` loops - better performance and no enumeration of protoype keys.
* Parts of the code generator have now been optimised thanks to [gaearon](https://github.com/gaearon).
* `for...in` loops have been changed to optimized `for` loops - better performance and no enumeration of protoype keys.
* Parts of the code generator have now been optimized thanks to [gaearon](https://github.com/gaearon).
## 2.12.3
@@ -314,7 +421,7 @@ _Note: Gaps between patch versions are faulty/broken releases._
* **Bug Fix**
* Support non-string JSX literals.
* **New Feature**
* Loose mode for some transformers that enables non-spec behaviour.
* Loose mode for some transformers that enables non-spec behavior.
* **Internal**
* Uglify `--mangle sort` has been added to the build script, cutting minified scripts in half.
@@ -752,7 +859,7 @@ _Note: Gaps between patch versions are faulty/broken releases._
## 1.13.2
* Optimise `Array.from` usage by adding a helper method.
* Optimize `Array.from` usage by adding a helper method.
* Upgrade `acorn-6to5`.
## 1.13.1

View File

@@ -18,9 +18,12 @@ 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
node $(UGLIFY_CMD) dist/runtime.js >dist/runtime.min.js
rm -rf templates.json
clean:
@@ -77,6 +80,7 @@ publish:
make build
cp dist/6to5.min.js browser.js
cp dist/polyfill.min.js browser-polyfill.js
cp dist/runtime.min.js runtime.js
node tools/cache-templates
test -f templates.json
@@ -88,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; \
@@ -110,3 +114,4 @@ bootstrap:
npm install
git submodule update --init
cd vendor/regenerator; npm install
cd vendor/compat-table; npm install object-assign

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;

4
bin/6to5-runtime Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env node
var runtime = require("../lib/6to5/build-runtime");
console.log(runtime());

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 });
@@ -53,10 +56,7 @@ module.exports = function (commander, filenames, opts) {
_.each(["add", "change"], function (type) {
watcher.on(type, function (filename) {
// chop off the dirname plus the path separator
var relative = filename.slice(dirname.length + 1);
console.log(type, filename);
var relative = path.relative(dirname, filename) || filename;
write(filename, relative);
});
});

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env node
var commander = require("commander");
var transform = require("../../lib/6to5/transformation/transform");
var transform = require("../../lib/6to5/transformation");
var util = require("../../lib/6to5/util");
var fs = require("fs");
var each = require("lodash/collection/each");
@@ -11,6 +11,7 @@ commander.option("-t, --source-maps-inline", "Append sourceMappingURL comment to
commander.option("-s, --source-maps", "Save source map alongside the compiled code");
commander.option("-f, --filename [filename]", "Filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]", "stdin");
commander.option("-w, --watch", "Recompile files on changes");
commander.option("-r, --runtime", "Replace 6to5 declarations with references to a runtime");
commander.option("-e, --experimental", "Enable experimental support for proposed ES7 features");
commander.option("-p, --playground", "Enable playground support");
@@ -22,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);
@@ -108,16 +109,22 @@ exports.opts = {
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
optional: commander.optional,
comments: !commander.removeComments,
runtime: commander.runtime,
modules: commander.modules,
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/transform");
var transform = module.exports = require("../transformation");
transform.version = require("../../package").version;
transform.version = require("../../../package").version;
transform.transform = transform;

View File

@@ -1,22 +1,24 @@
"use strict";
var transform = require("./transformation/transform");
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.types = require("./types");
exports.runtime = require("../build-runtime");
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);
};

13
lib/6to5/build-helpers.js Normal file
View File

@@ -0,0 +1,13 @@
var File = require("./transformation/file");
var util = require("./util");
var each = require("lodash/collection/each");
var t = require("./types");
module.exports = function (body, namespace) {
each(File.helpers, function (name) {
var key = t.identifier(t.toIdentifier(name));
body.push(t.expressionStatement(
t.assignmentExpression("=", t.memberExpression(namespace, key), util.template(name))
));
});
};

25
lib/6to5/build-runtime.js Normal file
View File

@@ -0,0 +1,25 @@
"use strict";
var buildHelpers = require("./build-helpers");
var generator = require("./generation");
var util = require("./util");
var t = require("./types");
module.exports = function () {
var namespace = t.identifier("to5Runtime");
var body = [];
var container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
var tree = t.program([t.expressionStatement(t.callExpression(container, [util.template("self-global")]))]);
body.push(t.variableDeclaration("var", [
t.variableDeclarator(
namespace,
t.assignmentExpression("=", t.memberExpression(t.identifier("global"), namespace), t.objectExpression([]))
)
]));
buildHelpers(body, namespace);
return generator(tree).code;
};

View File

@@ -1,7 +1,29 @@
//exports.canRun = function (ast, userAgent) {
module.exports = detect;
//};
var SYNTAX_KEYS = require("./syntax-keys");
var traverse = require("../traversal");
var visitors = traverse.explode(require("./visitors"));
//exports.whoCanRun = function (ast, userAgent) {
function detect(ast) {
var stats = {
syntax: {},
builtins: {}
};
//};
var detectedSyntax = function (name) {
stats.syntax[name] = true;
};
traverse(ast, {
enter: function (node, parent) {
if (SYNTAX_KEYS[node.type]) {
detectedSyntax(SYNTAX_KEYS[node.type]);
}
var visitor = visitors[node.type];
if (visitor) visitor(node, parent, detectedSyntax);
}
});
return stats;
}

View File

@@ -0,0 +1,84 @@
{
"ArrowFunctionExpression": "es6.arrowFunctions",
"AwaitExpression": "es7.asyncFunctions",
"ClassBody": "es6.classes",
"ClassDeclaration": "es6.classes",
"ClassExpression": "es6.classes",
"MethodDefinition": "es6.classes",
"ComprehensionBlock": "es7.comprehensions",
"ComprehensionExpression": "es7.comprehensions",
"ForOfStatement": "es6.forOf",
"ExportBatchSpecifier": "es6.modules",
"ExportDeclaration": "es6.modules",
"ExportSpecifier": "es6.modules",
"ImportBatchSpecifier": "es6.modules",
"ImportDeclaration": "es6.modules",
"ImportSpecifier": "es6.modules",
"ArrayPattern": "es6.destructuring",
"AssignmentPattern": "es6.destructuring",
"ObjectPattern": "es6.destructuring",
"RestElement": "es6.parameters.rest",
"SpreadElement": "es6.spread",
"SpreadProperty": "es7.objectSpread",
"TaggedTemplateExpression": "es6.templateLiterals",
"TemplateElement": "es6.templateLiterals",
"TemplateLiteral": "es6.templateLiterals",
"VirtualPropertyExpression": "es7.abstractReferences",
"PrivateDeclaration": "es7.abstractReferences",
"YieldExpression": "es6.generators",
"AnyTypeAnnotation": "flow",
"ArrayTypeAnnotation": "flow",
"BooleanTypeAnnotation": "flow",
"ClassProperty": "flow",
"DeclareClass": "flow",
"DeclareFunction": "flow",
"DeclareModule": "flow",
"DeclareVariable": "flow",
"FunctionTypeAnnotation": "flow",
"FunctionTypeParam": "flow",
"GenericTypeAnnotation": "flow",
"InterfaceExtends": "flow",
"InterfaceDeclaration": "flow",
"IntersectionTypeAnnotation": "flow",
"NullableTypeAnnotation": "flow",
"NumberTypeAnnotation": "flow",
"StringLiteralTypeAnnotation": "flow",
"StringTypeAnnotation": "flow",
"TupleTypeAnnotation": "flow",
"TypeofTypeAnnotation": "flow",
"TypeAlias": "flow",
"TypeAnnotation": "flow",
"TypeParameterDeclaration": "flow",
"TypeParameterInstantiation": "flow",
"ObjectTypeAnnotation": "flow",
"ObjectTypeCallProperty": "flow",
"ObjectTypeIndexer": "flow",
"ObjectTypeProperty": "flow",
"QualifiedTypeIdentifier": "flow",
"UnionTypeAnnotation": "flow",
"VoidTypeAnnotation": "flow",
"JSXAttribute": "jsx",
"JSXClosingElement": "jsx",
"JSXElement": "jsx",
"JSXEmptyExpression": "jsx",
"JSXExpressionContainer": "jsx",
"JSXIdentifier": "jsx",
"JSXMemberExpression": "jsx",
"JSXNamespacedName": "jsx",
"JSXOpeningElement": "jsx",
"JSXSpreadAttribute": "jsx"
}

View File

@@ -0,0 +1,54 @@
var t = require("../types");
var _ = require("lodash");
exports.AssignmentExpression = function (node, parent, detected) {
if (node.operator === "**=") {
detected("es6.exponentation");
}
};
exports.BinaryExpression = function (node, parent, detected) {
if (node.operator === "**") {
detected("es6.exponentation");
}
};
exports.VariableDeclaration = function (node, parent, detected) {
if (node.kind === "let" || node.kind === "const") {
detected("es6.blockScoping");
}
if (node.kind === "const") {
detected("es6.constants");
}
};
exports.Property = function (node, parent, detected) {
if (node.shorthand || node.method) {
detected("es6.properties.shorthand");
}
if (node.kind === "set" || node.kind === "get") {
detected("es5.properties.mutators");
}
if (node.computed) {
detected("es6.properties.computed");
}
};
exports.AssignmentPattern = function (node, parent, detected) {
if (t.isFunction(parent) && _.contains(parent.params, node)) {
detected("es6.parameters.default");
}
};
exports.Function = function (node, parent, detected) {
if (node.generator) {
detected("es6.generators");
}
if (node.async) {
detected("es7.asyncFunctions");
}
};

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,15 +40,18 @@ each(Buffer.prototype, function (fn, key) {
};
});
CodeGenerator.normaliseOptions = function (code, opts) {
var indent = detectIndent(code);
var style = indent.indent;
if (!style || style === " ") style = " ";
CodeGenerator.normalizeOptions = function (code, opts) {
var style = " ";
if (code) {
var indent = detectIndent(code).indent;
if (indent && indent !== " ") style = indent;
}
return merge({
parentheses: true,
comments: opts.comments == null || opts.comments,
compact: false,
concise: false,
indent: {
adjustMultilineComment: true,
style: style,
@@ -109,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);
};
@@ -127,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;
@@ -197,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,38 @@
// taken from stackoverflow, it's crap i know.
module.exports = function (a, b) {
if (a.length === 0) return b.length;
if (b.length === 0) return a.length;
var matrix = [];
// increment along the first column of each row
var i;
for (i = 0; i <= b.length; i++) {
matrix[i] = [i];
}
// increment each column in the first row
var j;
for (j = 0; j <= a.length; j++) {
matrix[0][j] = j;
}
// Fill in the rest of the matrix
for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
if (b.charAt(i - 1) == a.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1];
} else {
matrix[i][j] = Math.min(
matrix[i - 1][j - 1] + 1, // substitution
Math.min(
matrix[i][j - 1] + 1, // insertion
matrix[i - 1][j] + 1) // deletion
);
}
}
}
return matrix[b.length][a.length];
};

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/transform");
var generate = require("./generation/generator");
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 = File.normaliseOptions(opts);
this.opts = this.normalizeOptions(opts);
this.ast = {};
this.buildTransformers();
@@ -49,7 +51,10 @@ File.helpers = [
"interop-require-wildcard",
"typeof",
"extends",
"get"
"get",
"set",
"class-call-check",
"object-destructuring-empty"
];
File.validOptions = [
@@ -74,14 +79,17 @@ File.validOptions = [
"format",
"playground",
"experimental",
"resolveModuleSource",
"runtime",
// these are used by plugins
"ignore",
"only",
"extensions"
"extensions",
"accept"
];
File.normaliseOptions = function (opts) {
File.prototype.normalizeOptions = function (opts) {
opts = clone(opts);
for (var key in opts) {
@@ -92,6 +100,7 @@ File.normaliseOptions = function (opts) {
defaults(opts, {
keepModuleIdExtensions: false,
resolveModuleSource: null,
experimental: false,
reactCompat: false,
playground: false,
@@ -104,14 +113,17 @@ File.normaliseOptions = function (opts) {
comments: true,
filename: "unknown",
modules: "common",
runtime: false,
loose: [],
code: true,
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);
@@ -142,10 +154,20 @@ File.normaliseOptions = function (opts) {
opts.experimental = true;
}
if (opts.runtime) {
this.set("runtimeIdentifier", t.identifier("to5Runtime"));
}
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;
};
@@ -167,6 +189,7 @@ File.prototype.buildTransformers = function () {
if (pass.canRun(file)) {
stack.push(pass);
if (transformer.secondPass) {
secondaryStack.push(pass);
}
@@ -181,6 +204,12 @@ File.prototype.buildTransformers = function () {
this.transformers = transformers;
};
File.prototype.debug = function (msg) {
var parts = this.opts.filename;
if (msg) parts += ": " + msg;
util.debug(parts);
};
File.prototype.toArray = function (node, i) {
if (t.isArrayExpression(node)) {
return node;
@@ -318,35 +347,67 @@ 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);
this.scope = new Scope(ast.program, ast, null, this);
this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
var astRun = function (key) {
each(self.transformerStack, function (pass) {
pass.astRun(key);
});
};
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
if (modFormatter.init && this.transformers["es6.modules"].canRun()) {
modFormatter.init();
}
astRun("enter");
this.checkNode(ast);
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 () {
@@ -373,6 +434,7 @@ File.prototype.generate = function () {
if (opts.sourceMap === "inline") {
result.code += "\n" + util.sourceMapToComment(result.map);
result.map = null;
}
return result;
@@ -388,14 +450,14 @@ File.prototype.generateUid = function (name, scope) {
do {
uid = this._generateUid(name, i);
i++;
} while (scope.has(uid));
} while (scope.hasReference(uid));
return uid;
};
File.prototype.generateUidIdentifier = function (name, scope) {
scope = scope || this.scope;
var id = t.identifier(this.generateUid(name, scope));
scope.add(id);
scope.addDeclarationToFunctionScope("var", id);
return id;
};

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,10 +31,10 @@ exports.property = function (node, file, scope) {
var state = {
id: id,
selfReference: false,
outerDeclar: scope.get(id, true),
outerDeclar: scope.getBinding(id),
};
traverse(node, visitor, scope, state);
scope.traverse(node, visitor, state);
if (state.selfReference) {
// todo: support generators

View File

@@ -0,0 +1,26 @@
var t = require("../../types");
var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass");
exports.isCreateClass = function (node) {
if (!node || !t.isCallExpression(node)) return false;
// not React.createClass call member object
if (!isCreateClassCallExpression(node.callee)) return false;
// no call arguments
var args = node.arguments;
if (args.length !== 1) return false;
// first node arg is not an object
var first = args[0];
if (!t.isObjectExpression(first)) return false;
return true;
};
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,8 +2,7 @@
module.exports = ReplaceSupers;
var traverse = require("../../traverse");
var t = require("../../types");
var t = require("../../types");
/**
* Description
@@ -21,6 +20,36 @@ function ReplaceSupers(opts) {
this.file = opts.file;
}
/**
* Sets a super class value of the named property.
*
* @example
*
* _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this)
*
* @param {Node} property
* @param {boolean} isStatic
* @param {boolean} isComputed
*
* @returns {Node}
*/
ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic, 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"))
]
),
isComputed ? property : t.literal(property.name),
value,
thisExpression
]
);
};
/**
* Gets a node representing the super class value of the named property.
*
@@ -35,7 +64,7 @@ function ReplaceSupers(opts) {
* @returns {Node}
*/
ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed, thisExpression) {
ReplaceSupers.prototype.getSuperProperty = function (property, isStatic, isComputed, thisExpression) {
return t.callExpression(
this.file.addHelper("get"),
[
@@ -51,6 +80,70 @@ ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed
);
};
/**
* Description
*/
ReplaceSupers.prototype.replace = function () {
this.traverseLevel(this.methodNode.value, true);
};
var visitor = {
enter: function (node, parent, scope, state) {
var topLevel = state.topLevel;
var self = state.self;
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
// we need to call traverseLevel again so we're context aware
self.traverseLevel(node, false);
return this.skip();
}
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
// break on object methods
return this.skip();
}
var getThisReference = topLevel ?
// top level so `this` is the instance
t.thisExpression :
// not in the top level so we need to create a reference
self.getThisReference.bind(self);
var callback = self.specHandle;
if (self.isLoose) callback = self.looseHandle;
return callback.call(self, getThisReference, node, parent);
}
};
/**
* Description
*
* @param {Object} node
* @param {Boolean} topLevel
*/
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
var state = { self: this, topLevel: topLevel };
this.scope.traverse(node, visitor, state);
};
/**
* Description
*/
ReplaceSupers.prototype.getThisReference = function () {
if (this.topLevelThisReference) {
return this.topLevelThisReference;
} else {
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
]));
return ref;
}
};
/**
* Description
*
@@ -60,7 +153,7 @@ ReplaceSupers.prototype.superProperty = function (property, isStatic, isComputed
* @returns {Object}
*/
ReplaceSupers.prototype.looseSuperProperty = function (methodNode, id, parent) {
ReplaceSupers.prototype.getLooseSuperProperty = function (methodNode, id, parent) {
var methodName = methodNode.key;
var superName = this.superName || t.identifier("Function");
@@ -92,70 +185,6 @@ ReplaceSupers.prototype.looseSuperProperty = function (methodNode, id, parent) {
}
};
/**
* Description
*/
ReplaceSupers.prototype.replace = function () {
this.traverseLevel(this.methodNode.value, true);
};
var visitor = {
enter: function (node, parent, scope, context, state) {
var topLevel = state.topLevel;
var self = state.self;
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
// we need to call traverseLevel again so we're context aware
self.traverseLevel(node, false);
return context.skip();
}
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
// break on object methods
return context.skip();
}
var getThisReference = topLevel ?
// top level so `this` is the instance
t.thisExpression :
// not in the top level so we need to create a reference
self.getThisReference;
var callback = self.specHandle;
if (self.isLoose) callback = self.looseHandle;
return callback.call(self, getThisReference, node, parent);
}
};
/**
* Description
*
* @param {Object} node
* @param {Boolean} topLevel
*/
ReplaceSupers.prototype.traverseLevel = function (node, topLevel) {
var state = { self: this, topLevel: topLevel };
traverse(node, visitor, this.scope, state);
};
/**
* Description
*/
ReplaceSupers.prototype.getThisReference = function () {
if (this.topLevelThisReference) {
return this.topLevelThisReference;
} else {
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
]));
return ref;
}
};
/**
* Description
*
@@ -166,7 +195,7 @@ ReplaceSupers.prototype.getThisReference = function () {
ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) {
if (t.isIdentifier(node, { name: "super" })) {
return this.looseSuperProperty(this.methodNode, node, parent);
return this.getLooseSuperProperty(this.methodNode, node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
@@ -191,14 +220,15 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
var property;
var computed;
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;
@@ -211,27 +241,25 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
var methodName = methodNode.key.name || "METHOD_NAME";
throw this.file.errorWithNode(node, "Direct super call is illegal in non-constructor, use super." + methodName + "() instead");
}
} else {
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
} else if (t.isMemberExpression(callee) && isSuper(callee.object, callee)) {
// super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
property = callee.property;
computed = callee.computed;
args = node.arguments;
}
} else if (t.isMemberExpression(node)) {
if (!t.isIdentifier(node.object, { name: "super" })) return;
} else if (t.isMemberExpression(node) && isSuper(node.object, node)) {
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
property = node.property;
computed = node.computed;
} else if (t.isAssignmentExpression(node) && 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, getThisReference());
}
if (!property) return;
var thisReference = getThisReference();
var superProperty = this.superProperty(property, methodNode.static, computed, thisReference);
thisReference = getThisReference();
var superProperty = this.getSuperProperty(property, methodNode.static, computed, thisReference);
if (args) {
if (args.length === 1 && t.isSpreadElement(args[0])) {
// super(...arguments);
@@ -249,3 +277,14 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
return superProperty;
}
};
var isIllegalBareSuper = function (node, parent) {
if (!isSuper(node, parent)) return false;
if (t.isMemberExpression(parent, { computed: false })) return false;
if (t.isCallExpression(parent, { callee: node })) return false;
return true;
};
var isSuper = function (node, parent) {
return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent);
};

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.getIds(declar, true));
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.getIds(node, true));
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

@@ -15,6 +15,8 @@ function AMDFormatter() {
util.inherits(AMDFormatter, DefaultFormatter);
AMDFormatter.prototype.init = CommonFormatter.prototype.init;
AMDFormatter.prototype.buildDependencyLiterals = function () {
var names = [];
for (var name in this.ids) {
@@ -27,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
@@ -85,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

@@ -3,20 +3,22 @@
module.exports = CommonJSFormatter;
var DefaultFormatter = require("./_default");
var contains = require("lodash/collection/contains");
var util = require("../../util");
var t = require("../../types");
var contains = require("lodash/collection/contains");
function CommonJSFormatter(file) {
function CommonJSFormatter() {
DefaultFormatter.apply(this, arguments);
if (this.hasNonDefaultExports) {
file.ast.program.body.push(util.template("exports-module-declaration", true));
}
}
util.inherits(CommonJSFormatter, DefaultFormatter);
CommonJSFormatter.prototype.init = function () {
if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
this.file.ast.program.body.push(util.template("exports-module-declaration", true));
}
};
CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var variableName = t.getSpecifierName(specifier);
@@ -25,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,13 +13,16 @@ 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);
}
util.inherits(SystemFormatter, AMDFormatter);
SystemFormatter.prototype.init = function () {};
SystemFormatter.prototype._addImportSource = function (node, exportNode) {
node._importSource = exportNode.source && exportNode.source.value;
return node;
@@ -67,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) {
@@ -80,7 +82,7 @@ var runnerSettersVisitor = {
state.nodes.push(node);
}
context.remove();
this.remove();
}
}
};
@@ -95,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)) {
@@ -147,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);
@@ -180,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);
@@ -189,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

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

View File

@@ -0,0 +1,24 @@
(function set(object, property, value, receiver) {
var desc = Object.getOwnPropertyDescriptor(object, property);
if (desc === undefined) {
var parent = Object.getPrototypeOf(object);
if (parent === null) {
return;
} else {
return set(parent, property, value, receiver);
}
} else if ("value" in desc && desc.writable) {
desc.value = value;
return;
} else {
var setter = desc.set;
if (setter === undefined) {
return;
}
return setter.call(receiver, value);
}
});

View File

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

View File

@@ -3,9 +3,10 @@
module.exports = Transformer;
var TransformerPass = require("./transformer-pass");
var t = require("../types");
var isFunction = require("lodash/lang/isFunction");
var traverse = require("../traversal");
var isObject = require("lodash/lang/isObject");
var clone = require("../helpers/clone");
var each = require("lodash/collection/each");
/**
@@ -15,22 +16,38 @@ var each = require("lodash/collection/each");
*/
function Transformer(key, transformer, opts) {
this.manipulateOptions = transformer.manipulateOptions;
this.experimental = !!transformer.experimental;
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)) {
transformer = { ast: transformer };
}
traverse.explode(transformer);
each(transformer, function (fns, type) {
// hidden property
if (type[0] === "_") {
@@ -46,13 +63,6 @@ Transformer.prototype.normalise = function (transformer) {
if (!fns.exit) fns.exit = function () { };
transformer[type] = fns;
var aliases = t.FLIPPED_ALIAS_KEYS[type];
if (aliases) {
each(aliases, function (alias) {
transformer[alias] = fns;
});
}
});
return 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,17 +1,16 @@
"use strict";
var traverse = require("../../../traverse");
var t = require("../../../types");
var t = require("../../../types");
var visitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (!t.isReferencedIdentifier(node, parent)) return;
var declared = state.letRefs[node.name];
if (!declared) return;
// declared node is different in this scope
if (scope.get(node.name, true) !== declared) return;
if (scope.getBinding(node.name) !== declared) return;
var declaredLoc = declared.loc;
var referenceLoc = node.loc;
@@ -37,7 +36,7 @@ exports.optional = true;
exports.Loop =
exports.Program =
exports.BlockStatement = function (node, parent, scope, context, file) {
exports.BlockStatement = function (node, parent, scope, file) {
var letRefs = node._letReferences;
if (!letRefs) return;
@@ -46,5 +45,5 @@ exports.BlockStatement = function (node, parent, scope, context, file) {
file: file
};
traverse(node, visitor, scope, state);
scope.traverse(node, visitor, state);
};

View File

@@ -1,12 +1,16 @@
"use strict";
var traverse = require("../../../traverse");
var traverse = require("../../../traversal");
var object = require("../../../helpers/object");
var util = require("../../../util");
var t = require("../../../types");
var values = require("lodash/object/values");
var extend = require("lodash/object/extend");
exports.check = function (node) {
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
};
var isLet = function (node, parent) {
if (!t.isVariableDeclaration(node)) return false;
if (node._let) return true;
@@ -29,7 +33,7 @@ var isVar = function (node, parent) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
};
var standardiseLets = function (declars) {
var standardizeLets = function (declars) {
for (var i = 0; i < declars.length; i++) {
delete declars[i]._let;
}
@@ -39,32 +43,21 @@ exports.VariableDeclaration = function (node, parent) {
isLet(node, parent);
};
exports.Loop = function (node, parent, scope, context, file) {
exports.Loop = function (node, parent, scope, file) {
var init = node.left || node.init;
if (isLet(init, node)) {
t.ensureBlock(node);
node.body._letDeclarators = [init];
}
if (t.isLabeledStatement(parent)) {
// set label so `run` has access to it
node.label = parent.label;
}
var letScoping = new LetScoping(node, node.body, parent, scope, file);
letScoping.run();
if (node.label && !t.isLabeledStatement(parent)) {
// we've been given a label so let's wrap ourselves
return t.labeledStatement(node.label, node);
}
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();
}
};
@@ -78,7 +71,7 @@ exports.BlockStatement = function (block, parent, scope, context, file) {
* @param {File} file
*/
function LetScoping(loopParent, block, parent, scope, file) {
function BlockScoping(loopParent, block, parent, scope, file) {
this.loopParent = loopParent;
this.parent = parent;
this.scope = scope;
@@ -95,7 +88,7 @@ function LetScoping(loopParent, block, parent, scope, file) {
* Start the ball rolling.
*/
LetScoping.prototype.run = function () {
BlockScoping.prototype.run = function () {
var block = this.block;
if (block._letDone) return;
block._letDone = true;
@@ -115,19 +108,19 @@ LetScoping.prototype.run = function () {
}
};
function replace(node, parent, scope, context, remaps) {
function replace(node, parent, scope, remaps) {
if (!t.isReferencedIdentifier(node, parent)) return;
var remap = remaps[node.name];
if (!remap) return;
var own = scope.get(node.name, true);
if (own === remap.node) {
var ownBinding = scope.getBinding(node.name);
if (ownBinding === remap.binding) {
node.name = remap.uid;
} else {
// scope already has it's own declaration that doesn't
// scope already has it's own binding that doesn't
// match the one we have a stored replacement for
if (context) context.skip();
if (this) this.skip();
}
}
@@ -136,15 +129,15 @@ var replaceVisitor = {
};
function traverseReplace(node, parent, scope, remaps) {
replace(node, parent, scope, null, remaps);
traverse(node, replaceVisitor, scope, remaps);
replace(node, parent, scope, remaps);
scope.traverse(node, replaceVisitor, remaps);
}
/**
* Description
*/
LetScoping.prototype.remap = function () {
BlockScoping.prototype.remap = function () {
var hasRemaps = false;
var letRefs = this.letReferences;
var scope = this.scope;
@@ -160,13 +153,13 @@ LetScoping.prototype.remap = function () {
// this is the defining identifier of a declaration
var ref = letRefs[key];
if (scope.parentHas(key)) {
if (scope.parentHasReference(key)) {
var uid = scope.generateUidIdentifier(ref.name).name;
ref.name = uid;
hasRemaps = true;
remaps[key] = remaps[uid] = {
node: ref,
binding: ref,
uid: uid
};
}
@@ -183,14 +176,14 @@ LetScoping.prototype.remap = function () {
traverseReplace(loopParent.update, loopParent, scope, remaps);
}
traverse(this.block, replaceVisitor, scope, remaps);
scope.traverse(this.block, replaceVisitor, remaps);
};
/**
* Description
*/
LetScoping.prototype.needsClosure = function () {
BlockScoping.prototype.needsClosure = function () {
var block = this.block;
// if we're inside of a for loop then we search to see if there are any
@@ -232,13 +225,13 @@ LetScoping.prototype.needsClosure = function () {
};
var letReferenceFunctionVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
// not a direct reference
if (!t.isReferencedIdentifier(node, parent)) return;
// this scope has a variable with the same name so it couldn't belong
// to our let scope
if (scope.hasOwn(node.name, true)) return;
if (scope.hasOwnBinding(node.name)) return;
// not a part of our scope
if (!state.letReferences[node.name]) return;
@@ -248,10 +241,10 @@ var letReferenceFunctionVisitor = {
};
var letReferenceBlockVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isFunction(node)) {
traverse(node, letReferenceFunctionVisitor, scope, state);
return context.skip();
scope.traverse(node, letReferenceFunctionVisitor, state);
return this.skip();
}
}
};
@@ -260,7 +253,7 @@ var letReferenceBlockVisitor = {
* Description
*/
LetScoping.prototype.getLetReferences = function () {
BlockScoping.prototype.getLetReferences = function () {
var block = this.block;
var declarators = block._letDeclarators || [];
@@ -269,7 +262,7 @@ LetScoping.prototype.getLetReferences = function () {
//
for (var i = 0; i < declarators.length; i++) {
declar = declarators[i];
extend(this.outsideLetReferences, t.getIds(declar, true));
extend(this.outsideLetReferences, t.getBindingIdentifiers(declar));
}
//
@@ -285,7 +278,7 @@ LetScoping.prototype.getLetReferences = function () {
//
for (i = 0; i < declarators.length; i++) {
declar = declarators[i];
var keys = t.getIds(declar, true);
var keys = t.getBindingIdentifiers(declar);
extend(this.letReferences, keys);
this.hasLetReferences = true;
}
@@ -294,7 +287,7 @@ LetScoping.prototype.getLetReferences = function () {
if (!this.hasLetReferences) return;
// set let references to plain var references
standardiseLets(declarators);
standardizeLets(declarators);
var state = {
letReferences: this.letReferences,
@@ -303,39 +296,76 @@ 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;
};
var loopNodeTo = function (node) {
if (t.isBreakStatement(node)) {
return "break";
} else if (t.isContinueStatement(node)) {
return "continue";
}
};
var loopVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
var replace;
if (t.isFunction(node) || t.isLoop(node)) {
return context.skip();
if (t.isLoop(node)) {
state.ignoreLabeless = true;
scope.traverse(node, loopVisitor, state);
state.ignoreLabeless = false;
}
if (node && !node.label && state.isLoop) {
if (t.isBreakStatement(node)) {
if (t.isSwitchCase(parent)) return;
if (t.isFunction(node) || t.isLoop(node)) {
return this.skip();
}
state.hasBreak = true;
replace = t.returnStatement(t.literal("break"));
} else if (t.isContinueStatement(node)) {
state.hasContinue = true;
replace = t.returnStatement(t.literal("continue"));
var loopText = loopNodeTo(node);
if (loopText) {
if (node.label) {
// we shouldn't be transforming this because it exists somewhere inside
if (state.innerLabels.indexOf(node.label.name) >= 0) {
return;
}
loopText = loopText + "|" + node.label.name;
} else {
// we shouldn't be transforming these statements because
// they don't refer to the actual loop we're scopifying
if (state.ignoreLabeless) return;
// break statements mean something different in this context
if (t.isBreakStatement(node) && t.isSwitchCase(parent)) return;
}
state.hasBreakContinue = true;
state.map[loopText] = node;
replace = t.literal(loopText);
}
if (t.isReturnStatement(node)) {
state.hasReturn = true;
replace = t.returnStatement(t.objectExpression([
replace = t.objectExpression([
t.property("init", t.identifier("v"), node.argument || t.identifier("undefined"))
]));
]);
}
if (replace) return t.inherits(replace, node);
if (replace) {
replace = t.returnStatement(replace);
return t.inherits(replace, node);
}
}
};
var loopLabelVisitor = {
enter: function (node, parent, scope, state) {
if (t.isLabeledStatement(node)) {
state.innerLabels.push(node.label.name);
}
}
};
@@ -348,20 +378,24 @@ var loopVisitor = {
* @returns {Object}
*/
LetScoping.prototype.checkLoop = function () {
BlockScoping.prototype.checkLoop = function () {
var state = {
hasContinue: false,
hasReturn: false,
hasBreak: false,
isLoop: !!this.loopParent
hasBreakContinue: false,
ignoreLabeless: false,
innerLabels: [],
hasReturn: false,
isLoop: !!this.loopParent,
map: {}
};
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));
@@ -373,7 +407,7 @@ var hoistVarDeclarationsVisitor = {
} else if (isVar(node, parent)) {
return self.pushDeclar(node).map(t.expressionStatement);
} else if (t.isFunction(node)) {
return context.skip();
return this.skip();
}
}
};
@@ -383,7 +417,7 @@ var hoistVarDeclarationsVisitor = {
* once we wrap everything in a closure.
*/
LetScoping.prototype.hoistVarDeclarations = function () {
BlockScoping.prototype.hoistVarDeclarations = function () {
traverse(this.block, hoistVarDeclarationsVisitor, this.scope, this);
};
@@ -395,7 +429,7 @@ LetScoping.prototype.hoistVarDeclarations = function () {
* @returns {Array}
*/
LetScoping.prototype.pushDeclar = function (node) {
BlockScoping.prototype.pushDeclar = function (node) {
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
@@ -420,9 +454,9 @@ 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.hasBreak || has.hasContinue) {
if (has.hasReturn || has.hasBreakContinue) {
this.buildHas(ret, call);
} else {
this.body.push(t.expressionStatement(call));
@@ -436,7 +470,7 @@ LetScoping.prototype.build = function (ret, call) {
* @param {Node} call CallExpression
*/
LetScoping.prototype.buildHas = function (ret, call) {
BlockScoping.prototype.buildHas = function (ret, call) {
var body = this.body;
body.push(t.variableDeclaration("var", [
@@ -455,22 +489,14 @@ LetScoping.prototype.buildHas = function (ret, call) {
});
}
if (has.hasBreak || has.hasContinue) {
if (has.hasBreakContinue) {
if (!loopParent) {
throw new Error("Has no loop parent but we're trying to reassign breaks " +
"and continues, something is going wrong here.");
}
// ensure that the parent has a label as we're building a switch and we
// need to be able to access it
var label = loopParent.label = loopParent.label || this.scope.generateUidIdentifier("loop");
if (has.hasBreak) {
cases.push(t.switchCase(t.literal("break"), [t.breakStatement(label)]));
}
if (has.hasContinue) {
cases.push(t.switchCase(t.literal("continue"), [t.continueStatement(label)]));
for (var key in has.map) {
cases.push(t.switchCase(t.literal(key), [has.map[key]]));
}
if (has.hasReturn) {

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)) {
@@ -159,11 +170,10 @@ Class.prototype.buildBody = function () {
}
// we have no constructor, we have a super, and the super doesn't appear to be falsy
if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) {
var defaultConstructorTemplate = "class-super-constructor-call";
if (this.isLoose) defaultConstructorTemplate += "-loose";
constructor.body.body.push(util.template(defaultConstructorTemplate, {
if (!this.hasConstructor && this.hasSuper && !t.isFalsyExpression(superName)) {
var helperName = "class-super-constructor-call";
if (this.isLoose) helperName += "-loose";
constructor.body.body.push(util.template(helperName, {
CLASS_NAME: className,
SUPER_NAME: this.superName
}, true));
@@ -173,11 +183,11 @@ Class.prototype.buildBody = function () {
var staticProps;
if (this.hasInstanceMutators) {
instanceProps = util.buildDefineProperties(this.instanceMutatorMap);
instanceProps = defineMap.build(this.instanceMutatorMap);
}
if (this.hasStaticMutators) {
staticProps = util.buildDefineProperties(this.staticMutatorMap);
staticProps = defineMap.build(this.staticMutatorMap);
}
if (instanceProps || staticProps) {
@@ -230,8 +240,8 @@ Class.prototype.pushMethod = function (node) {
this.hasInstanceMutators = true;
}
util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
util.pushMutatorMap(mutatorMap, methodName, "enumerable", node.computed, false);
defineMap.push(mutatorMap, methodName, kind, node.computed, node);
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
};
/**
@@ -255,5 +265,5 @@ Class.prototype.pushConstructor = function (method) {
construct._ignoreUserWhitespace = true;
construct.params = fn.params;
construct.body = fn.body;
construct.body.body = construct.body.body.concat(fn.body.body);
};

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.getIds(node, true);
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,17 +24,20 @@ 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, {
constants: scope.getAllOfKind("const"),
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,45 +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);
nodes.push(t.variableDeclaration("var", [
var declar = t.variableDeclaration("var", [
t.variableDeclarator(tempParentId, parentId)
]));
]);
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")),
@@ -61,72 +71,88 @@ var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
));
};
var pushObjectPattern = function (opts, nodes, pattern, parentId) {
Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
var prop2 = pattern.properties[i2];
if (i2 >= i) break;
if (t.isSpreadProperty(prop2)) continue;
var key = prop2.key;
if (t.isIdentifier(key)) {
key = t.literal(prop2.key.name);
}
keys.push(key);
}
keys = t.arrayExpression(keys);
var value = t.callExpression(this.file.addHelper("object-without-properties"), [parentId, keys]);
this.nodes.push(this.buildVariableAssignment(prop.argument, value));
};
Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
if (t.isPattern(pattern2)) {
this.push(pattern2, patternId2);
} else {
this.nodes.push(this.buildVariableAssignment(pattern2, patternId2));
}
};
Destructuring.prototype.pushObjectPattern = function (pattern, parentId) {
if (!pattern.properties.length) {
this.nodes.push(t.expressionStatement(
t.callExpression(this.file.addHelper("object-destructuring-empty"), [parentId])
));
}
for (var i = 0; i < pattern.properties.length; i++) {
var prop = pattern.properties[i];
if (t.isSpreadProperty(prop)) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
var prop2 = pattern.properties[i2];
if (i2 >= i) break;
if (t.isSpreadProperty(prop2)) continue;
var key = prop2.key;
if (t.isIdentifier(key)) {
key = t.literal(prop2.key.name);
}
keys.push(key);
}
keys = t.arrayExpression(keys);
var value = t.callExpression(opts.file.addHelper("object-without-properties"), [parentId, keys]);
nodes.push(buildVariableAssign(opts, prop.argument, value));
this.pushObjectSpread(pattern, parentId, prop, i);
} else {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
if (t.isPattern(pattern2)) {
push(opts, nodes, pattern2, patternId2);
} else {
nodes.push(buildVariableAssign(opts, pattern2, patternId2));
}
this.pushObjectProperty(prop, parentId);
}
}
};
var pushArrayPattern = function (opts, nodes, pattern, parentId) {
if (!pattern.elements) return;
var i;
var hasRest = false;
for (i = 0; i < pattern.elements.length; i++) {
var hasRest = function (pattern) {
for (var i = 0; i < pattern.elements.length; i++) {
if (t.isRestElement(pattern.elements[i])) {
hasRest = true;
break;
return true;
}
}
return false;
};
var toArray = opts.file.toArray(parentId, !hasRest && pattern.elements.length);
Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
if (!pattern.elements) return;
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
nodes.push(buildVariableDeclar(opts, _parentId, toArray));
// if we have a rest then we need all the elements
var count = !hasRest(pattern) && pattern.elements.length;
var toArray = this.file.toArray(parentId, count);
var _parentId = this.scope.generateUidBasedOnNode(parentId, this.file);
this.nodes.push(this.buildVariableDeclaration(_parentId, toArray));
parentId = _parentId;
for (i = 0; i < pattern.elements.length; i++) {
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
if (!elem) continue;
i = +i;
// hole
if (!elem) continue;
var newPatternId;
if (t.isRestElement(elem)) {
newPatternId = opts.file.toArray(parentId);
newPatternId = this.file.toArray(parentId);
if (i > 0) {
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
@@ -137,27 +163,22 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
newPatternId = t.memberExpression(parentId, t.literal(i), true);
}
push(opts, nodes, elem, newPatternId);
this.push(elem, newPatternId);
}
};
var pushPattern = function (opts) {
var nodes = opts.nodes;
var pattern = opts.pattern;
var parentId = opts.id;
var scope = opts.scope;
Destructuring.prototype.init = function (pattern, parentId) {
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
var key = scope.generateUidBasedOnNode(parentId);
nodes.push(buildVariableDeclar(opts, key, parentId));
var key = this.scope.generateUidBasedOnNode(parentId);
this.nodes.push(this.buildVariableDeclaration(key, parentId));
parentId = key;
}
push(opts, nodes, pattern, parentId);
this.push(pattern, parentId);
};
exports.ForInStatement =
exports.ForOfStatement = function (node, parent, scope, context, file) {
exports.ForOfStatement = function (node, parent, scope, file) {
var declar = node.left;
if (!t.isVariableDeclaration(declar)) return;
@@ -171,11 +192,14 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
var nodes = [];
push({
var destructuring = new Destructuring({
kind: declar.kind,
file: file,
scope: scope
}, nodes, pattern, key);
scope: scope,
nodes: nodes
});
destructuring.init(pattern, key);
t.ensureBlock(node);
@@ -183,7 +207,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
block.body = nodes.concat(block.body);
};
exports.Function = function (node, parent, scope, context, file) {
exports.Function = function (node, parent, scope, file) {
var nodes = [];
var hasDestructuring = false;
@@ -194,15 +218,14 @@ exports.Function = function (node, parent, scope, context, file) {
hasDestructuring = true;
var parentId = scope.generateUidIdentifier("ref");
pushPattern({
var destructuring = new Destructuring({
blockHoist: node.params.length - i,
pattern: pattern,
nodes: nodes,
scope: scope,
file: file,
kind: "var",
id: parentId
});
destructuring.init(pattern, parentId);
return parentId;
});
@@ -215,7 +238,7 @@ exports.Function = function (node, parent, scope, context, file) {
block.body = nodes.concat(block.body);
};
exports.CatchClause = function (node, parent, scope, context, file) {
exports.CatchClause = function (node, parent, scope, file) {
var pattern = node.param;
if (!t.isPattern(pattern)) return;
@@ -224,16 +247,18 @@ exports.CatchClause = function (node, parent, scope, context, file) {
var nodes = [];
push({
var destructuring = new Destructuring({
kind: "var",
file: file,
scope: scope
}, nodes, pattern, ref);
scope: scope,
nodes: nodes
});
destructuring.init(pattern, ref);
node.body.body = nodes.concat(node.body.body);
};
exports.ExpressionStatement = function (node, parent, scope, context, file) {
exports.ExpressionStatement = function (node, parent, scope, file) {
var expr = node.expression;
if (expr.type !== "AssignmentExpression") return;
if (!t.isPattern(expr.left)) return;
@@ -246,16 +271,18 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
t.variableDeclarator(ref, expr.right)
]));
push({
var destructuring = new Destructuring({
operator: expr.operator,
file: file,
scope: scope
}, nodes, expr.left, ref);
scope: scope,
nodes: nodes
});
destructuring.init(expr.left, ref);
return nodes;
};
exports.AssignmentExpression = function (node, parent, scope, context, file) {
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!t.isPattern(node.left)) return;
var ref = scope.generateUidIdentifier("temp");
@@ -267,50 +294,50 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
var nodes = [];
nodes.push(t.assignmentExpression("=", ref, node.right));
push({
var destructuring = new Destructuring({
operator: node.operator,
file: file,
scope: scope
}, nodes, node.left, ref);
scope: scope,
nodes: nodes
});
destructuring.init(node.left, ref);
nodes.push(ref);
return t.toSequenceExpression(nodes, scope);
};
exports.VariableDeclaration = function (node, parent, scope, context, file) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
var nodes = [];
var i;
var declar;
var hasPattern = false;
for (i = 0; i < node.declarations.length; i++) {
declar = node.declarations[i];
if (t.isPattern(declar.id)) {
hasPattern = true;
break;
var variableDeclarationhasPattern = function (node) {
for (var i = 0; i < node.declarations.length; i++) {
if (t.isPattern(node.declarations[i].id)) {
return true;
}
}
if (!hasPattern) return;
return false;
};
for (i = 0; i < node.declarations.length; i++) {
exports.VariableDeclaration = function (node, parent, scope, file) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
if (!variableDeclarationhasPattern(node)) return;
var nodes = [];
var declar;
for (var i = 0; i < node.declarations.length; i++) {
declar = node.declarations[i];
var patternId = declar.init;
var pattern = declar.id;
var opts = {
pattern: pattern,
nodes: nodes,
scope: scope,
kind: node.kind,
file: file,
id: patternId,
};
var destructuring = new Destructuring({
nodes: nodes,
scope: scope,
kind: node.kind,
file: file
});
if (t.isPattern(pattern) && patternId) {
pushPattern(opts);
destructuring.init(pattern, patternId);
if (+i !== node.declarations.length - 1) {
// we aren't the last declarator so let's just make the
@@ -318,11 +345,14 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
t.inherits(nodes[nodes.length - 1], declar);
}
} else {
nodes.push(t.inherits(buildVariableAssign(opts, declar.id, declar.init), declar));
nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar));
}
}
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
// https://github.com/6to5/6to5/issues/113
// for (let [x] = [0]; false;) {}
declar = null;
for (i = 0; i < nodes.length; i++) {

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;
@@ -32,7 +34,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
return loop;
};
var loose = function (node, parent, scope, context, file) {
var loose = function (node, parent, scope, file) {
var left = node.left;
var declar, id;
@@ -69,7 +71,7 @@ var loose = function (node, parent, scope, context, file) {
};
};
var spec = function (node, parent, scope, context, file) {
var spec = function (node, parent, scope, file) {
var left = node.left;
var declar;

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

@@ -1,8 +1,11 @@
"use strict";
var traverse = require("../../../traverse");
var util = require("../../../util");
var t = require("../../../types");
var util = require("../../../util");
var t = require("../../../types");
exports.check = function (node) {
return t.isFunction(node) && hasDefaults(node);
};
var hasDefaults = function (node) {
for (var i = 0; i < node.params.length; i++) {
@@ -12,10 +15,10 @@ var hasDefaults = function (node) {
};
var iifeVisitor = {
enter: function (node, parent, scope, context, state) {
if (t.isReferencedIdentifier(node, parent) && scope.hasOwn(node.name)) {
enter: function (node, parent, scope, state) {
if (t.isReferencedIdentifier(node, parent) && state.scope.hasOwnReference(node.name)) {
state.iife = true;
context.stop();
this.stop();
}
}
};
@@ -48,10 +51,10 @@ exports.Function = function (node, parent, scope) {
node.params[i] = scope.generateUidIdentifier("x");
if (!state.iife) {
if (t.isIdentifier(right) && scope.hasOwn(right.name)) {
if (t.isIdentifier(right) && scope.hasOwnReference(right.name)) {
state.iife = true;
} else {
traverse(right, iifeVisitor, scope, state);
scope.traverse(right, iifeVisitor, state);
}
}

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]);
};
@@ -58,15 +60,15 @@ exports.Function = function (node, parent, scope) {
node.body.body.unshift(restDeclar);
}
node.body.body.unshift(
util.template("rest", {
ARGUMENTS: argsId,
ARRAY_KEY: arrKey,
ARRAY_LEN: arrLen,
START: start,
ARRAY: rest,
KEY: key,
LEN: len,
})
);
var loop = util.template("rest", {
ARGUMENTS: argsId,
ARRAY_KEY: arrKey,
ARRAY_LEN: arrLen,
START: start,
ARRAY: rest,
KEY: key,
LEN: len,
});
loop._blockHoist = node.params.length + 1;
node.body.body.unshift(loop);
};

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;
@@ -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

@@ -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,9 +11,10 @@ module.exports = {
"playground.memoizationOperator": require("./playground/memoization-operator"),
"playground.objectGetterMemoization": require("./playground/object-getter-memoization"),
reactCompat: require("./other/react-compat"),
react: require("./other/react"),
_modulesSplit: require("./internal/modules-split"),
_modules: require("./internal/modules"),
// needs to be before `regenerator` due to generator comprehensions
// needs to be before `_aliasFunction`
@@ -27,7 +28,7 @@ module.exports = {
asyncToGenerator: require("./other/async-to-generator"),
bluebirdCoroutines: require("./other/bluebird-coroutines"),
"es7.objectSpread": require("./es7/object-spread"),
"es7.objectRestSpread": require("./es7/object-rest-spread"),
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
"es6.spread": require("./es6/spread"),
"es6.templateLiterals": require("./es6/template-literals"),
@@ -52,14 +53,13 @@ module.exports = {
// needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks
"es6.blockScopingTDZ": require("./es6/block-scoping-tdz"),
// needs to be after block scoping since regenerator doesn't support it
regenerator: require("./other/regenerator"),
"es6.parameters.default": require("./es6/parameters.default"),
"es6.parameters.rest": require("./es6/parameters.rest"),
"es6.destructuring": require("./es6/destructuring"),
regenerator: require("./other/regenerator"),
// needs to be after `regenerator` due to needing `regeneratorRuntime` references
// needs to be after `es6.forOf` due to needing `Symbol.iterator` references
// needs to be before `es6.modules` due to dynamic imports
@@ -80,6 +80,11 @@ module.exports = {
"spec.typeofSymbol": require("./spec/typeof-symbol"),
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
"minification.propertyLiterals": require("./minification/property-literals"),
"minification.memberExpressionLiterals": require("./minification/member-expression-literals")
"es3.propertyLiterals": require("./es3/property-literals"),
"es3.memberExpressionLiterals": require("./es3/member-expression-literals"),
"minification.removeDebugger": require("./minification/remove-debugger"),
"minification.removeConsoleCalls": require("./minification/remove-console-calls"),
"minification.deadCodeElimination": require("./minification/dead-code-elimination"),
"minification.renameLocalVariables": require("./minification/rename-local-variables")
};

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

@@ -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,7 +8,22 @@
var t = require("../../../types");
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) {
resolveModuleSource.apply(null, arguments);
var declar = node.declaration;
if (node.default) {

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

@@ -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);

View File

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

View File

@@ -0,0 +1,29 @@
"use strict";
var react = require("../../helpers/react");
var t = require("../../../types");
exports.manipulateOptions = function (opts) {
opts.blacklist.push("react");
};
exports.optional = true;
require("../../helpers/build-react-transformer")(exports, {
pre: function (state) {
state.callee = state.tagExpr;
},
post: function (state) {
if (react.isCompatTag(state.tagName)) {
state.call = t.callExpression(
t.memberExpression(
t.memberExpression(t.identifier("React"), t.identifier("DOM")),
state.tagExpr,
t.isLiteral(state.tagExpr)
),
state.args
);
}
}
});

View File

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

View File

@@ -1,11 +1,15 @@
"use strict";
var regenerator = require("regenerator-6to5");
var t = require("../../../types");
exports.ast = {
before: function (ast, file) {
regenerator.transform(ast, {
includeRuntime: file.opts.includeRegenerator && "if used"
});
exports.check = function (node) {
return t.isFunction(node) && (node.async || node.generator);
};
exports.Program = {
enter: function (ast) {
regenerator.transform(ast);
this.stop();
}
};

View File

@@ -1,6 +1,5 @@
"use strict";
var traverse = require("../../../traverse");
var util = require("../../../util");
var core = require("core-js/library");
var t = require("../../../types");
@@ -21,7 +20,7 @@ var ALIASABLE_CONSTRUCTORS = [
];
var astVisitor = {
enter: function (node, parent, scope, context, file) {
enter: function (node, parent, scope, file) {
var prop;
if (t.isMemberExpression(node) && t.isReferenced(node, parent)) {
@@ -31,11 +30,11 @@ var astVisitor = {
if (!t.isReferenced(obj, node)) return;
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name)) {
context.skip();
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name) && !scope.getBinding(obj.name)) {
this.skip();
return t.prependToMemberExpression(node, file.get("coreIdentifier"));
}
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && contains(ALIASABLE_CONSTRUCTORS, node.name) && !scope.get(node.name, true)) {
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && contains(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBinding(node.name)) {
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
return t.memberExpression(file.get("coreIdentifier"), node);
} else if (t.isCallExpression(node)) {
@@ -61,27 +60,29 @@ var astVisitor = {
exports.optional = true;
exports.ast = {
enter: function (ast, file) {
file.setDynamic("runtimeIdentifier", function () {
return file.addImport("6to5-runtime/helpers", "to5Helpers");
});
file.setDynamic("coreIdentifier", function () {
return file.addImport("6to5-runtime/core-js", "core");
});
file.setDynamic("regeneratorIdentifier", function () {
return file.addImport("6to5-runtime/regenerator", "regeneratorRuntime");
});
},
after: function (ast, file) {
traverse(ast, astVisitor, null, file);
}
exports.manipulateOptions = function (opts) {
if (opts.whitelist.length) opts.whitelist.push("es6.modules");
};
exports.Identifier = function (node, parent, scope, context, file) {
exports.post = function (file) {
file.scope.traverse(file.ast, astVisitor, file);
};
exports.pre = function (file) {
file.setDynamic("runtimeIdentifier", function () {
return file.addImport("6to5-runtime/helpers", "to5Helpers");
});
file.setDynamic("coreIdentifier", function () {
return file.addImport("6to5-runtime/core-js", "core");
});
file.setDynamic("regeneratorIdentifier", function () {
return file.addImport("6to5-runtime/regenerator", "regeneratorRuntime");
});
};
exports.Identifier = function (node, parent, scope, file) {
if (node.name === "regeneratorRuntime" && t.isReferenced(node, parent)) {
return file.get("regeneratorIdentifier");
}

View File

@@ -3,19 +3,18 @@
var useStrict = require("../../helpers/use-strict");
var t = require("../../../types");
exports.ast = {
exit: function (ast) {
if (!useStrict.has(ast.program)) {
ast.program.body.unshift(t.expressionStatement(t.literal("use strict")));
}
exports.post = function (file) {
var program = file.ast.program;
if (!useStrict.has(program)) {
program.body.unshift(t.expressionStatement(t.literal("use strict")));
}
};
exports.FunctionDeclaration =
exports.FunctionExpression = function (node, parent, scope, context) {
context.skip();
exports.FunctionExpression = function () {
this.skip();
};
exports.ThisExpression = function (node, parent, scope, context, file) {
throw file.errorWithNode(node, "Top level `this` is not allowed", ReferenceError);
exports.ThisExpression = function () {
return t.identifier("undefined");
};

View File

@@ -1,7 +1,9 @@
"use strict";
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
var t = require("../../../types");
var t = require("../../../types");
exports.playground = true;
build(exports, {
is: function (node, file) {

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