Compare commits

...

222 Commits

Author SHA1 Message Date
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
Sebastian McKenzie
16a94a769a v3.1.1 2015-01-30 11:02:28 +11:00
Sebastian McKenzie
f7c7918efe add 3.1.1 changelog 2015-01-30 11:00:43 +11:00
Sebastian McKenzie
bf393c025f properly transform XJSIdentifier nodes referencing this into a ThisExpression - facebook/react#2927 2015-01-30 11:00:37 +11:00
Sebastian McKenzie
bbbc9c0c5e remove redundant enumerable: true property on class methods 2015-01-30 10:44:33 +11:00
Sebastian McKenzie
579db9107f fix link in 3.1.0 changelog - thanks @AluisioASG - closes #641 2015-01-30 10:42:52 +11:00
Sebastian McKenzie
d1d30e9ec9 3.1.0 2015-01-30 10:15:09 +11:00
Sebastian McKenzie
ee782f93c4 v3.1.0 2015-01-30 10:13:50 +11:00
Sebastian McKenzie
9ed6aa48a0 add esdiscuss link to class enumerability change - @thejameskyle 2015-01-30 10:11:26 +11:00
Sebastian McKenzie
ecebedd5a2 update esnext class tests 2015-01-30 10:11:11 +11:00
Sebastian McKenzie
31df576d26 make class methods nonenumerable - fixes #639 2015-01-30 10:05:17 +11:00
Sebastian McKenzie
63d6335d99 3.0.16 2015-01-30 00:18:32 +11:00
Sebastian McKenzie
9e21994c01 v3.0.16 2015-01-30 00:18:01 +11:00
Sebastian McKenzie
b8ee654ac2 update 3.0.16 changelog 2015-01-30 00:14:08 +11:00
Sebastian McKenzie
00b22b1231 don't ignore dynamic import specifiers - fixes #633 2015-01-30 00:13:37 +11:00
Sebastian McKenzie
2e589904c7 comment out detection file 2015-01-30 00:05:38 +11:00
Sebastian McKenzie
1cd475d118 add 3.0.16 changelog 2015-01-30 00:05:01 +11:00
Sebastian McKenzie
fbdea41399 comment out strictMode option until acorn-6to5 works properly 2015-01-30 00:02:25 +11:00
Sebastian McKenzie
5d720dbc43 upgrade regenerator 2015-01-30 00:01:40 +11:00
Sebastian McKenzie
3940149517 add whitespace to functions in logical expressions 2015-01-29 22:50:17 +11:00
Sebastian McKenzie
e963798067 update tests to reflect _extends helper modifications 2015-01-29 22:38:07 +11:00
Sebastian McKenzie
36acfd16ea better line break delimeter - thanks @RReverser! 2015-01-29 22:23:43 +11:00
Sebastian McKenzie
dda372f93e use either Object.assign or the extends helper 2015-01-29 21:07:51 +11:00
Sebastian McKenzie
62bc815f81 only set strictMode to true when the useStrict transformer is enabled 2015-01-29 21:07:34 +11:00
Sebastian McKenzie
4e68f94023 start adding detection base 2015-01-29 21:03:16 +11:00
Sebastian McKenzie
2687b435e0 Merge pull request #629 from stefanpenner/lodash-cleanup
cleanup: require explicit lodash modules needed
2015-01-29 16:04:47 +11:00
Stefan Penner
9ddf411f2c cleanup: require explicit lodash modules needed 2015-01-28 23:52:17 -05:00
Sebastian McKenzie
c2fc89af6c 3.0.15 2015-01-29 15:18:18 +11:00
Sebastian McKenzie
a5eda35ff4 v3.0.15 2015-01-29 15:17:08 +11:00
Sebastian McKenzie
b5e1221c54 uUse debug/node instead of debug to avoid browserify using the browser version that references window - fixes #628 2015-01-29 15:11:33 +11:00
Sebastian McKenzie
03942da57a add in support for AwaitExpression "delegation" 2015-01-29 15:11:17 +11:00
Sebastian McKenzie
e469c864bc 3.0.14 2015-01-29 12:02:05 +11:00
Sebastian McKenzie
9d50cae9fd v3.0.14 2015-01-29 12:01:11 +11:00
Sebastian McKenzie
249d749580 update asyncToGenerator tests 2015-01-29 11:58:58 +11:00
Sebastian McKenzie
ea860ac5a5 add 3.0.14 changelog 2015-01-29 11:54:42 +11:00
Sebastian McKenzie
30259f3a99 don't use a generator iterator function as this in the asyncToGenerator helper - fixes #625 2015-01-29 11:53:30 +11:00
Sebastian McKenzie
a3d7a29961 add support for using optional in 6to5-node 2015-01-29 11:52:44 +11:00
Sebastian McKenzie
8ce762846e fix 3.0.0 changelog indentation 2015-01-29 11:08:19 +11:00
Sebastian McKenzie
8092716b79 3.0.13 2015-01-29 10:44:35 +11:00
Sebastian McKenzie
b7ba54724c v3.0.13 2015-01-29 10:44:11 +11:00
Sebastian McKenzie
7f7ee41315 fix modules loose mode using modules instead of es6.modules 2015-01-29 10:42:03 +11:00
Sebastian McKenzie
b33f05bd3d 3.0.12 2015-01-29 10:41:56 +11:00
Sebastian McKenzie
1ae6eabedd v3.0.12 2015-01-29 10:15:35 +11:00
Sebastian McKenzie
973be9ad96 add noScope option to traverse.clearProperties - fixes #624 2015-01-29 10:13:29 +11:00
Sebastian McKenzie
979ce93499 add 3.0.12 changelog 2015-01-29 10:13:17 +11:00
Sebastian McKenzie
642e36c259 remove old es6.destructuring position comment - thanks @appden! 2015-01-29 09:04:01 +11:00
Sebastian McKenzie
efaf56c6de add debug messages 2015-01-29 09:03:30 +11:00
Sebastian McKenzie
a0c7950d8a 3.0.11 2015-01-29 07:43:09 +11:00
Sebastian McKenzie
f7be1b74d7 v3.0.11 2015-01-29 07:42:43 +11:00
Sebastian McKenzie
e264ac03b3 put destructuring transformer back 2015-01-29 07:40:50 +11:00
Sebastian McKenzie
425f0c5fdf add 3.0.11 changelog 2015-01-29 07:38:15 +11:00
Sebastian McKenzie
960a70287d add improved for-of loose behaviour that supports destructuring - fixes #615 2015-01-29 00:50:22 +11:00
Sebastian McKenzie
c25c33e3ee remove unnecessary ensureBlock in es6 rest parameters transformer 2015-01-29 00:06:42 +11:00
Sebastian McKenzie
d72081f82c fix codeFrame call in transformation helper 2015-01-29 00:06:24 +11:00
Sebastian McKenzie
d4debc3c85 fix regenerator tests 2015-01-29 00:06:12 +11:00
Sebastian McKenzie
7894f1a079 add regenerator parameter tests 2015-01-28 23:45:11 +11:00
Sebastian McKenzie
5ffaeb5e9f 3.0.10 2015-01-28 23:41:55 +11:00
Sebastian McKenzie
e50a7406ad move destructuring transformer to before regenerator 2015-01-28 23:41:51 +11:00
Sebastian McKenzie
962eeed252 clean up t.getIds 2015-01-28 23:41:42 +11:00
Sebastian McKenzie
2d8944fbd5 fix RestElement ast-types definition 2015-01-28 23:41:31 +11:00
Sebastian McKenzie
ddfb492ed9 v3.0.10 2015-01-28 23:14:43 +11:00
Sebastian McKenzie
3d98364adb in types.getIds make sure the declaration inside of ExportDeclaration is actually a Declaration, clean up types.isReferenced - fixes #614 2015-01-28 23:12:53 +11:00
Sebastian McKenzie
3affa543ef add yes/no comments to describe what we're actually testing for in types.isReferenced 2015-01-28 20:21:25 +11:00
Sebastian McKenzie
2a47afebde more accurate types.isReferenced comment 2015-01-28 20:09:37 +11:00
Sebastian McKenzie
f2fc6d8852 3.0.9 2015-01-28 20:09:20 +11:00
Sebastian McKenzie
28c4c18ee2 v3.0.9 2015-01-28 20:08:49 +11:00
Sebastian McKenzie
968db67d0a add in pattern support to t.isReferenced 2015-01-28 20:06:49 +11:00
Sebastian McKenzie
b22ef22e36 add missing semicolon 2015-01-28 20:03:29 +11:00
Sebastian McKenzie
044ce45d98 add 3.0.9 changelog 2015-01-28 20:02:49 +11:00
Sebastian McKenzie
69f2a0d3f1 better t.toIdentifier behaviour that doesn't camelcase on underscores - fixes #610 2015-01-28 20:01:55 +11:00
Sebastian McKenzie
4b66dcb738 more reliable t.isReferenced - fixes #610 2015-01-28 19:58:20 +11:00
Sebastian McKenzie
dfc6f1d1cf add comment explaining what the modules-split transformer does 2015-01-28 18:40:33 +11:00
Sebastian McKenzie
a64e040ac7 3.0.8 2015-01-28 18:36:45 +11:00
Sebastian McKenzie
4f9414dbb0 v3.0.8 2015-01-28 18:36:22 +11:00
Sebastian McKenzie
bc6b31efbc split up function declarations from their exports - fixes #609 2015-01-28 18:34:43 +11:00
Sebastian McKenzie
244aed1ae9 3.0.7 2015-01-28 18:20:04 +11:00
Sebastian McKenzie
4fdb2ce939 v3.0.7 2015-01-28 18:18:23 +11:00
Sebastian McKenzie
fe57eb554c add 3.0.7 changelog 2015-01-28 18:16:44 +11:00
Sebastian McKenzie
3b798943e3 upgrade core-js and use a caret, make all other dependency versions static 2015-01-28 18:15:14 +11:00
Sebastian McKenzie
4ff66a5cfc add id to a function expression scope 2015-01-28 18:14:52 +11:00
Sebastian McKenzie
5477a990bc construct null object for types.getIds 2015-01-28 18:09:38 +11:00
Sebastian McKenzie
656ca422a5 3.0.6 2015-01-28 17:52:09 +11:00
Sebastian McKenzie
7a3071a094 v3.0.6 2015-01-28 17:51:02 +11:00
Sebastian McKenzie
77361582f4 don't stop block scoped variable traversal on any scope, just skip it and fix block statement for parent delegation - fixes #605 2015-01-28 17:48:37 +11:00
Sebastian McKenzie
f585039430 3.0.5 2015-01-28 15:23:11 +11:00
Sebastian McKenzie
21dcb6037a v3.0.5 2015-01-28 15:21:38 +11:00
Sebastian McKenzie
d10d96d19a fix unused iife declaration 2015-01-28 15:19:50 +11:00
Sebastian McKenzie
64766eea44 add more reliable iife detection for default parameter independent scope 2015-01-28 15:18:50 +11:00
Sebastian McKenzie
a9e682836b 3.0.4 2015-01-28 14:52:05 +11:00
Sebastian McKenzie
f504b8d529 v3.0.4 2015-01-28 14:49:55 +11:00
Sebastian McKenzie
30b2b55c86 remove badges from readme because noone cares 2015-01-28 14:48:13 +11:00
Sebastian McKenzie
836bc3a9a4 only check for duplicates for let variables 2015-01-28 14:47:09 +11:00
Sebastian McKenzie
630bfcc6cd add 3.0.x changelogs 2015-01-28 14:44:07 +11:00
Sebastian McKenzie
117203010a don't stop block variable scope finding on first hit 2015-01-28 14:39:46 +11:00
Sebastian McKenzie
f0986fe9c7 3.0.3 2015-01-28 14:39:01 +11:00
Sebastian McKenzie
4379441277 v3.0.3 2015-01-28 14:17:26 +11:00
Sebastian McKenzie
a955af06e0 remove opts from transform output 2015-01-28 14:14:55 +11:00
Sebastian McKenzie
8f69e59f29 ignore underscored options - fixes #29 2015-01-28 14:14:33 +11:00
Sebastian McKenzie
efda5ca897 3.0.2 2015-01-28 13:59:29 +11:00
Sebastian McKenzie
8a99fd3c8d v3.0.2 2015-01-28 13:53:19 +11:00
Sebastian McKenzie
614ce4de0a add common plugin options to validOptions just to be safe 2015-01-28 13:48:45 +11:00
Sebastian McKenzie
06b2cffbfc 3.0.1 2015-01-28 13:17:54 +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
246 changed files with 2617 additions and 1106 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

@@ -11,6 +11,173 @@
_Note: Gaps between patch versions are faulty/broken releases._
## 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**
* Drop `enumerable: false` clause from class method definitions as `enumerable` already defaults to `false`.
* **Bug Fix**
* Properly transform `XJSIdentifier` nodes referencing `this` into a `ThisExpression`.
## 3.1.0
* **Breaking Change**
* [Make class methods unenumerable](https://esdiscuss.org/topic/classes-and-enumerability#content-61).
## 3.0.16
* **Bug Fix**
* Don't ignore dynamic import specifiers.
* **Internal**
* Upgrade `regenerator-6to5`.
* **Polish**
* Use `Object.assign` in place of extends helper if it exists.
* Require individual `lodash` methods. Thanks [@stefanpenner](https://github.com/stefanpenner)!
## 3.0.15
* **Bug Fix**
* Use `debug/node` instead of `debug` to avoid browserify using the browser version that references `window`.
## 3.0.14
* **New Feature**
* Add `--optional` argument to `6to5-node`.
* **Bug Fix**
* Fix bug in `asyncToGenerator` helper where it was incorrectly calling generator iterator functions.
## 3.0.13
* **Bug Fix**
* Fix modules loose mode using `modules` instead of `es6.modules`.
## 3.0.12
* **Internal**
* Add internal debug messages.
* **Bug Fix**
* Add `noScope` option to `traverse.clearProperties`.
## 3.0.11
* **Bug Fix**
* Fix `ast-types` `RestElement` definition.
* Make `es6.forOf` loose mode more versatile and support destructuring.
## 3.0.10
* **Bug Fix**
* In `types.getIds` make sure the `declaration` inside of `ExportDeclaration` is actually a `Declaration`.
## 3.0.9
* **Bug Fix**
* Make `t.isReferenced` more powerful, actually take into consideration all contexts were identifier nodes aren't actually references.
* Don't camelcase underscores when converting a string to a valid identifier.
## 3.0.8
* **Bug Fix**
* Split up default function declaration exports due to regenerator destroying the parent export declaration.
## 3.0.7
* **Internal**
* Upgrade `core-js` to `0.4.9`.
* **Bug Fix**
* Add id to function express scope tracking.
## 3.0.6
* **Bug Fix**
* Fix block scope variable tracking stopping whenever it hits a new scope.
* Fix block scope variable tracking breaking on all block statement scopes that have a for loop parent.
## 3.0.5
* **Internal**
* More reliable default parameter scope.
## 3.0.4
* **Bug Fix**
* Remove traversal stops from block scope tracking.
## 3.0.3
* **Internal**
* Ignore options starting with `_`.
## 3.0.2
* **Internal**
* Add common plugin options to valid options list.
## 3.0.1
* **Internal**
* Downgrade `kexec` as `1.1.0` throws compilation errors.
## 3.0.0
* **Polish**
@@ -45,13 +212,13 @@ _Note: Gaps between patch versions are faulty/broken releases._
* This shorthand has been removed from the playground.
* `6to5/polyfill` can now only be required **once**.
* **CLI**
* `--indent` option has been removed.
* `--include-regenerator` option has been removed.
* `--amd-modules-id` option has been removed, use `--module-ids` instead.
* `--indent` option has been removed.
* `--include-regenerator` option has been removed.
* `--amd-modules-id` option has been removed, use `--module-ids` instead.
* **Options**
* `amdModuleIds` option has been removed, use `moduleIds` instead.
* `includeRegenerator` has been removed.
* `ignoreRegex` fallback has now been dropped from the require hook. `register(/foo/);`, `register({ ignoreRegex: /foo/ })` -> `register({ ignore: /foo/ })`.
* `amdModuleIds` option has been removed, use `moduleIds` instead.
* `includeRegenerator` has been removed.
* `ignoreRegex` fallback has now been dropped from the require hook. `register(/foo/);`, `register({ ignoreRegex: /foo/ })` -> `register({ ignore: /foo/ })`.
* **Modules**
* Module interop now only collapses to `module.exports` when there's a **single** export that's default.
* Imports and exports are now illegal anywhere except the root level by default. Set `modules` to [loose mode](http://6to5.org/docs/usage/loose) to allow them everywhere.
@@ -184,8 +351,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
@@ -208,7 +375,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.
@@ -646,7 +813,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

@@ -21,6 +21,9 @@ build:
node $(BROWSERIFY_CMD) lib/6to5/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
@@ -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).

View File

@@ -2,28 +2,6 @@
<img alt="6to5" src="https://raw.githubusercontent.com/6to5/logo/master/logo.png" width="546">
</p>
<p align="center">
<a href="https://gratipay.com/sebmck">
<img alt="Gratipay" src="https://img.shields.io/gratipay/sebmck.svg?style=flat">
</a>
<a href="https://travis-ci.org/6to5/6to5">
<img alt="Travis Status" src="http://img.shields.io/travis/6to5/6to5/master.svg?style=flat&amp;label=travis">
</a>
<a href="https://codeclimate.com/github/6to5/6to5">
<img alt="Code Climate Score" src="http://img.shields.io/codeclimate/github/6to5/6to5.svg?style=flat">
</a>
<a href="https://codeclimate.com/github/6to5/6to5">
<img alt="Coverage" src="http://img.shields.io/codeclimate/coverage/github/6to5/6to5.svg?style=flat">
</a>
<a href="https://david-dm.org/6to5/6to5">
<img alt="Dependency Status" src="http://img.shields.io/david/6to5/6to5.svg?style=flat">
</a>
</p>
<p align="center">
<strong>6to5</strong> turns ES6+ code into vanilla ES5, so you can use next generation features <strong>today.</strong>
</p>

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,15 +1,17 @@
#!/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 _ = require("lodash");
var each = require("lodash/collection/each");
var keys = require("lodash/object/keys");
commander.option("-t, --source-maps-inline", "Append sourceMappingURL comment to bottom of code");
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");
@@ -30,7 +32,7 @@ commander.on("--help", function () {
console.log(" " + title + ":");
console.log();
_.each(_.keys(obj).sort(), function (key) {
each(keys(obj).sort(), function (key) {
if (key[0] === "_") return;
if (obj[key].optional) {
@@ -58,7 +60,7 @@ var errors = [];
var filenames = commander.args;
_.each(filenames, function (filename) {
each(filenames, function (filename) {
if (!fs.existsSync(filename)) {
errors.push(filename + " doesn't exist");
}
@@ -107,6 +109,7 @@ exports.opts = {
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
optional: commander.optional,
comments: !commander.removeComments,
runtime: commander.runtime,
modules: commander.modules,
loose: commander.loose
};

View File

@@ -19,6 +19,7 @@ program.option("-r, --experimental", "Enable experimental support for proposed E
program.option("-g, --playground", "Enable playground support");
program.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
program.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list);
program.option("-o, --optional [optional]", "List of optional transformers to enable", util.list);
var pkg = require("../package.json");
program.version(pkg.version);
@@ -33,6 +34,7 @@ to5.register({
playground: program.playground,
blacklist: program.blacklist,
whitelist: program.whitelist,
optional: program.optional,
ignore: program.ignore
});
@@ -43,6 +45,7 @@ var _eval = function (code, filename) {
filename: filename,
blacklist: ["useStrict"].concat(program.blacklist || []),
whitelist: program.whitelist,
optional: program.optional,
experimental: program.experimental,
playground: program.playground
}).code;
@@ -61,8 +64,19 @@ if (program.eval || program.print) {
var args = process.argv.slice(2);
var i = 0;
var ignoreNext = false;
_.each(args, function (arg, i2) {
if (arg[0] !== "-") {
if (ignoreNext) {
ignoreNext = false;
return;
}
if (arg[0] === "-") {
var parsedArg = program[arg.slice(2)];
if (parsedArg && parsedArg !== true) {
ignoreNext = true;
}
} else {
i = i2;
return false;
}

View File

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

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

@@ -0,0 +1,13 @@
var File = require("./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

@@ -0,0 +1,29 @@
module.exports = detect;
var SYNTAX_KEYS = require("./syntax-keys");
var traverse = require("../traverse");
var visitors = traverse.explode(require("./visitors"));
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

@@ -4,13 +4,17 @@ 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 _ = require("lodash");
var isFunction = require("lodash/lang/isFunction");
var transform = require("./transformation");
var generate = require("./generation");
var defaults = require("lodash/object/defaults");
var contains = require("lodash/collection/contains");
var clone = require("./helpers/clone");
var Scope = require("./traverse/scope");
var util = require("./util");
var path = require("path");
var each = require("lodash/collection/each");
var t = require("./types");
function File(opts) {
this.dynamicImportIds = {};
@@ -21,7 +25,7 @@ function File(opts) {
this.data = {};
this.lastStatements = [];
this.opts = File.normaliseOptions(opts);
this.opts = this.normalizeOptions(opts);
this.ast = {};
this.buildTransformers();
@@ -46,7 +50,10 @@ File.helpers = [
"interop-require-wildcard",
"typeof",
"extends",
"get"
"get",
"set",
"class-call-check",
"class-super-constructor-call"
];
File.validOptions = [
@@ -70,20 +77,29 @@ File.validOptions = [
"ast",
"format",
"playground",
"experimental"
"experimental",
"resolveModuleSource",
"runtime",
// these are used by plugins
"ignore",
"only",
"extensions",
"accept"
];
File.normaliseOptions = function (opts) {
File.prototype.normalizeOptions = function (opts) {
opts = clone(opts);
for (var key in opts) {
if (File.validOptions.indexOf(key) < 0) {
if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) {
throw new ReferenceError("Unknown option: " + key);
}
}
_.defaults(opts, {
defaults(opts, {
keepModuleIdExtensions: false,
resolveModuleSource: null,
experimental: false,
reactCompat: false,
playground: false,
@@ -96,36 +112,39 @@ 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);
opts.loose = util.arrayify(opts.loose);
if (_.contains(opts.loose, "all")) {
if (contains(opts.loose, "all")) {
opts.loose = Object.keys(transform.transformers);
}
_.defaults(opts, {
defaults(opts, {
moduleRoot: opts.sourceRoot
});
_.defaults(opts, {
defaults(opts, {
sourceRoot: opts.moduleRoot
});
_.defaults(opts, {
defaults(opts, {
filenameRelative: opts.filename
});
_.defaults(opts, {
defaults(opts, {
sourceFileName: opts.filenameRelative,
sourceMapName: opts.filenameRelative
});
@@ -134,6 +153,10 @@ 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);
@@ -143,7 +166,7 @@ File.normaliseOptions = function (opts) {
};
File.prototype.isLoose = function (key) {
return _.contains(this.opts.loose, key);
return contains(this.opts.loose, key);
};
File.prototype.buildTransformers = function () {
@@ -154,7 +177,7 @@ File.prototype.buildTransformers = function () {
var secondaryStack = [];
var stack = [];
_.each(transform.transformers, function (transformer, key) {
each(transform.transformers, function (transformer, key) {
var pass = transformers[key] = transformer.buildPass(file);
if (pass.canRun(file)) {
@@ -190,7 +213,7 @@ File.prototype.toArray = function (node, i) {
};
File.prototype.getModuleFormatter = function (type) {
var ModuleFormatter = _.isFunction(type) ? type : transform.moduleFormatters[type];
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
if (!ModuleFormatter) {
var loc = util.resolve(type);
@@ -259,7 +282,7 @@ File.prototype.isConsequenceExpressionStatement = function (node) {
};
File.prototype.addHelper = function (name) {
if (!_.contains(File.helpers, name)) {
if (!contains(File.helpers, name)) {
throw new ReferenceError("unknown declaration " + name);
}
@@ -307,7 +330,8 @@ File.prototype.parse = function (code) {
var opts = this.opts;
opts.allowImportExportEverywhere = this.isLoose("modules");
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
//opts.strictMode = this.transformers.useStrict.canRun();
return util.parse(opts, code, function (tree) {
self.transform(tree);
@@ -318,20 +342,26 @@ File.prototype.parse = function (code) {
File.prototype.transform = function (ast) {
var self = this;
util.debug(this.opts.filename);
this.ast = ast;
this.lastStatements = t.getLastStatements(ast.program);
this.scope = new Scope(ast.program, null, this);
this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
this.scope = new Scope(ast.program, ast, null, this);
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
if (modFormatter.init && this.transformers["es6.modules"].canRun()) {
modFormatter.init();
}
var astRun = function (key) {
_.each(self.transformerStack, function (pass) {
each(self.transformerStack, function (pass) {
pass.astRun(key);
});
};
astRun("enter");
_.each(this.transformerStack, function (pass) {
each(this.transformerStack, function (pass) {
pass.transform();
});
@@ -344,7 +374,6 @@ File.prototype.generate = function () {
var result = {
code: "",
opts: opts,
map: null,
ast: null
};
@@ -378,14 +407,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

@@ -2,8 +2,10 @@
module.exports = Buffer;
var util = require("../util");
var _ = require("lodash");
var util = require("../util");
var isNumber = require("lodash/lang/isNumber");
var isBoolean = require("lodash/lang/isBoolean");
var contains = require("lodash/collection/contains");
function Buffer(position, format) {
this.position = position;
@@ -75,7 +77,7 @@ Buffer.prototype.newline = function (i, removeLast) {
removeLast = removeLast || false;
if (_.isNumber(i)) {
if (isNumber(i)) {
if (this.endsWith("{\n")) i--;
if (this.endsWith(util.repeat(i, "\n"))) return;
@@ -85,7 +87,7 @@ Buffer.prototype.newline = function (i, removeLast) {
return;
}
if (_.isBoolean(i)) {
if (isBoolean(i)) {
removeLast = i;
}
@@ -155,7 +157,7 @@ Buffer.prototype.isLast = function (cha, trimRight) {
var last = buf[buf.length - 1];
if (Array.isArray(cha)) {
return _.contains(cha, last);
return contains(cha, last);
} else {
return cha === last;
}

View File

@@ -1,8 +1,8 @@
"use strict";
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var util = require("../../util");
var t = require("../../types");
var isNumber = require("lodash/lang/isNumber");
exports.UnaryExpression = function (node, print) {
var hasSpace = /[a-z]$/.test(node.operator);
@@ -87,7 +87,11 @@ exports.CallExpression = function (node, print) {
var buildYieldAwait = function (keyword) {
return function (node, print) {
this.push(keyword);
if (node.delegate) this.push("*");
if (node.delegate || node.all) {
this.push("*");
}
if (node.argument) {
this.space();
print(node.argument);
@@ -129,7 +133,7 @@ exports.MemberExpression = function (node, print) {
}
var computed = node.computed;
if (t.isLiteral(node.property) && _.isNumber(node.property.value)) {
if (t.isLiteral(node.property) && isNumber(node.property.value)) {
computed = true;
}

View File

@@ -1,7 +1,7 @@
"use strict";
var t = require("../../types");
var _ = require("lodash");
var t = require("../../types");
var each = require("lodash/collection/each");
exports.JSXAttribute = function (node, print) {
print(node.name);
@@ -47,7 +47,7 @@ exports.JSXElement = function (node, print) {
if (open.selfClosing) return;
this.indent();
_.each(node.children, function (child) {
each(node.children, function (child) {
if (t.isLiteral(child)) {
self.push(child.value);
} else {

View File

@@ -1,7 +1,7 @@
"use strict";
var t = require("../../types");
var _ = require("lodash");
var t = require("../../types");
var each = require("lodash/collection/each");
exports.ImportSpecifier = function (node, print) {
if (t.isSpecifierDefault(node)) {
@@ -66,7 +66,7 @@ exports.ImportDeclaration = function (node, print) {
if (specfiers && specfiers.length) {
var foundImportSpecifier = false;
_.each(node.specifiers, function (spec, i) {
each(node.specifiers, function (spec, i) {
if (+i > 0) {
self.push(", ");
}

View File

@@ -1,8 +1,8 @@
"use strict";
var _ = require("lodash");
var each = require("lodash/collection/each");
_.each(["BindMemberExpression", "BindFunctionExpression"], function (type) {
each(["BindMemberExpression", "BindFunctionExpression"], function (type) {
exports[type] = function () {
throw new ReferenceError("Trying to render non-standard playground node " + JSON.stringify(type));
};

View File

@@ -1,6 +1,6 @@
"use strict";
var _ = require("lodash");
var each = require("lodash/collection/each");
exports.TaggedTemplateExpression = function (node, print) {
print(node.tag);
@@ -18,7 +18,7 @@ exports.TemplateLiteral = function (node, print) {
var self = this;
var len = quasis.length;
_.each(quasis, function (quasi, i) {
each(quasis, function (quasi, i) {
print(quasi);
if (i + 1 < len) {

View File

@@ -1,6 +1,6 @@
"use strict";
var _ = require("lodash");
var each = require("lodash/collection/each");
exports.Identifier = function (node) {
this.push(node.name);
@@ -62,7 +62,7 @@ exports.ArrayPattern = function (node, print) {
this.push("[");
_.each(elems, function (elem, i) {
each(elems, function (elem, i) {
if (!elem) {
// If the array expression ends with a hole, that hole
// will be ignored by the interpreter, but if it ends with

View File

@@ -15,14 +15,16 @@ var Buffer = require("./buffer");
var util = require("../util");
var n = require("./node");
var t = require("../types");
var _ = require("lodash");
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.ast = ast;
this.whitespace = new Whitespace(this.tokens, this.comments);
@@ -31,18 +33,20 @@ function CodeGenerator(ast, opts, code) {
this.buffer = new Buffer(this.position, this.format);
}
_.each(Buffer.prototype, function (fn, key) {
each(Buffer.prototype, function (fn, key) {
CodeGenerator.prototype[key] = function () {
return fn.apply(this.buffer, arguments);
};
});
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({
return merge({
parentheses: true,
comments: opts.comments == null || opts.comments,
compact: false,
@@ -69,8 +73,8 @@ CodeGenerator.generators = {
jsx: require("./generators/jsx")
};
_.each(CodeGenerator.generators, function (generator) {
_.extend(CodeGenerator.prototype, generator);
each(CodeGenerator.generators, function (generator) {
extend(CodeGenerator.prototype, generator);
});
CodeGenerator.prototype.generate = function () {
@@ -79,7 +83,7 @@ CodeGenerator.prototype.generate = function () {
this.print(ast);
var comments = [];
_.each(ast.comments, function (comment) {
each(ast.comments, function (comment) {
if (!comment._displayed) comments.push(comment);
});
this._printComments(comments);
@@ -175,7 +179,7 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
newline(true);
if (opts.before) opts.before();
this.map.mark(node, "start");
this.map.mark(node);
this[node.type](node, this.buildPrint(node), parent);
@@ -185,7 +189,6 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
}
if (needsParens) this.push(")");
this.map.mark(node, "end");
if (opts.after) opts.after();
newline(false);
@@ -208,7 +211,7 @@ CodeGenerator.prototype.printJoin = function (print, nodes, opts) {
if (opts.indent) self.indent();
_.each(nodes, function (node, i) {
each(nodes, function (node, i) {
print(node, {
statement: opts.statement,
after: function () {
@@ -273,7 +276,7 @@ CodeGenerator.prototype.getComments = function (key, node, parent) {
nodes.push(node.argument);
}
_.each(nodes, function (node) {
each(nodes, function (node) {
comments = comments.concat(self._getComments(key, node));
});
@@ -291,11 +294,11 @@ CodeGenerator.prototype._printComments = function (comments) {
var self = this;
_.each(comments, function (comment) {
each(comments, function (comment) {
var skip = false;
// find the original comment in the ast and set it as displayed
_.each(self.ast.comments, function (origComment) {
each(self.ast.comments, function (origComment) {
if (origComment.start === comment.start) {
// comment has already been output
if (origComment._displayed) skip = true;

View File

@@ -5,7 +5,8 @@ module.exports = Node;
var whitespace = require("./whitespace");
var parens = require("./parentheses");
var t = require("../../types");
var _ = require("lodash");
var each = require("lodash/collection/each");
var some = require("lodash/collection/some");
var find = function (obj, node, parent) {
if (!obj) return;
@@ -44,7 +45,7 @@ Node.needsWhitespace = function (node, parent, type) {
var lines = find(whitespace[type].nodes, node, parent);
if (lines) return lines;
_.each(find(whitespace[type].list, node, parent), function (expr) {
each(find(whitespace[type].list, node, parent), function (expr) {
lines = Node.needsWhitespace(expr, node, type);
if (lines) return false;
});
@@ -65,7 +66,7 @@ Node.needsParens = function (node, parent) {
if (t.isNewExpression(parent) && parent.callee === node) {
if (t.isCallExpression(node)) return true;
var hasCall = _.some(node, function (val) {
var hasCall = some(node, function (val) {
return t.isCallExpression(val);
});
if (hasCall) return true;
@@ -94,7 +95,7 @@ Node.needsParensNoLineTerminator = function (node, parent) {
return false;
};
_.each(Node, function (fn, key) {
each(Node, function (fn, key) {
Node.prototype[key] = function () {
// Avoid leaking arguments to prevent deoptimization
var args = new Array(arguments.length + 2);

View File

@@ -1,11 +1,11 @@
"use strict";
var t = require("../../types");
var _ = require("lodash");
var t = require("../../types");
var each = require("lodash/collection/each");
var PRECEDENCE = {};
_.each([
each([
["||"],
["&&"],
["|"],
@@ -18,7 +18,7 @@ _.each([
["*", "/", "%"],
["**"]
], function (tier, i) {
_.each(tier, function (op) {
each(tier, function (op) {
PRECEDENCE[op] = i;
});
});

View File

@@ -1,7 +1,9 @@
"use strict";
var _ = require("lodash");
var t = require("../../types");
var t = require("../../types");
var each = require("lodash/collection/each");
var map = require("lodash/collection/map");
var isNumber = require("lodash/lang/isNumber");
exports.before = {
nodes: {
@@ -31,6 +33,10 @@ exports.before = {
exports.after = {
nodes: {
LogicalExpression: function (node) {
return t.isFunction(node.left) || t.isFunction(node.right);
},
AssignmentExpression: function (node) {
if (t.isFunction(node.right)) {
return 1;
@@ -40,7 +46,7 @@ exports.after = {
list: {
VariableDeclaration: function (node) {
return _.map(node.declarations, "init");
return map(node.declarations, "init");
},
ArrayExpression: function (node) {
@@ -53,7 +59,7 @@ exports.after = {
}
};
_.each({
each({
Function: 1,
Class: 1,
For: 1,
@@ -64,12 +70,12 @@ _.each({
CallExpression: { after: 1 },
Literal: { after: 1 }
}, function (amounts, type) {
if (_.isNumber(amounts)) {
if (isNumber(amounts)) {
amounts = { after: amounts, before: amounts };
}
_.each([type].concat(t.FLIPPED_ALIAS_KEYS[type] || []), function (type) {
_.each(amounts, function (amount, key) {
each([type].concat(t.FLIPPED_ALIAS_KEYS[type] || []), function (type) {
each(amounts, function (amount, key) {
exports[key].nodes[type] = function () {
return amount;
};

View File

@@ -30,7 +30,7 @@ SourceMap.prototype.get = function () {
}
};
SourceMap.prototype.mark = function (node, type) {
SourceMap.prototype.mark = function (node) {
var loc = node.loc;
if (!loc) return; // no location info
@@ -46,9 +46,7 @@ SourceMap.prototype.mark = function (node, type) {
column: position.column
};
var original = loc[type];
if (generated.line === original.line && generated.column === original.column) return; // nothing to map
var original = loc.start;
map.addMapping({
source: this.opts.sourceFileName,

View File

@@ -2,7 +2,7 @@
module.exports = Whitespace;
var _ = require("lodash");
var sortBy = require("lodash/collection/sortBy");
/**
* Returns `i`th number from `base`, continuing from 0 when `max` is reached.
@@ -23,7 +23,7 @@ function getLookupIndex(i, base, max) {
}
function Whitespace(tokens, comments) {
this.tokens = _.sortBy(tokens.concat(comments), "start");
this.tokens = sortBy(tokens.concat(comments), "start");
this.used = {};
// Profiling this code shows that while generator passes over it, indexes

View File

@@ -47,7 +47,7 @@ module.exports = function (lines, lineNumber, colNumber) {
lines = highlight(lines);
}
lines = lines.split("\n");
lines = lines.split(/\r\n|[\n\r\u2028\u2029]/);
var start = Math.max(lineNumber - 3, 0);
var end = Math.min(lines.length, lineNumber + 3);

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

@@ -1,12 +1,14 @@
"use strict";
var transform = require("./transformation/transform");
var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
var transform = require("./transformation");
var util = require("./util");
var fs = require("fs");
var isFunction = require("lodash/lang/isFunction");
exports.version = require("../../package").version;
exports.runtime = require("./build-runtime");
exports.types = require("./types");
exports.register = function (opts) {
@@ -27,7 +29,7 @@ exports._util = util;
exports.transform = transform;
exports.transformFile = function (filename, opts, callback) {
if (_.isFunction(opts)) {
if (isFunction(opts)) {
callback = opts;
opts = {};
}

View File

View File

@@ -1,14 +1,14 @@
"use strict";
var t = require("./types");
var _ = require("lodash");
var t = require("./types");
var extend = require("lodash/object/extend");
require("./types/node");
// estraverse
var estraverse = require("estraverse");
_.extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
// regenerator-6to5/ast-types
@@ -34,9 +34,9 @@ def("ImportBatchSpecifier")
.field("name", def("Identifier"));
def("RestElement")
.bases("Node")
.bases("Pattern")
.build("argument")
.field("argument", def("Pattern"));
.field("argument", def("expression"));
// Abstract references
def("VirtualPropertyExpression")

View File

@@ -7,7 +7,8 @@ var registerCache = require("./register-cache");
var util = require("./util");
var to5 = require("./index");
var fs = require("fs");
var _ = require("lodash");
var extend = require("lodash/object/extend");
var each = require("lodash/collection/each");
sourceMapSupport.install({
retrieveSourceMap: function (source) {
@@ -33,20 +34,14 @@ 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 compile = function (filename) {
var result;
if (cache) {
@@ -56,11 +51,12 @@ var loader = function (m, filename) {
}
}
result = result || to5.transformFileSync(filename, _.extend({
whitelist: whitelist,
sourceMap: true,
ast: false
}, transformOpts));
if (!result) {
result = to5.transformFileSync(filename, extend({
sourceMap: true,
ast: false
}, transformOpts));
}
if (cache) {
result.mtime = mtime(filename);
@@ -69,26 +65,73 @@ var loader = function (m, filename) {
maps[filename] = result.map;
m._compile(result.code, filename);
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) {
each(exts, function (old, ext) {
require.extensions[ext] = old;
});
exts = {};
_.each(_exts, function (ext) {
each(_exts, function (ext) {
exts[ext] = require.extensions[ext];
require.extensions[ext] = loader;
registerExtension(ext);
});
};
hookExtensions(util.canCompile.EXTENSIONS);
module.exports = function (opts) {
// normalise options
// normalize options
opts = opts || {};
if (opts.only != null) onlyRegex = util.regexify(opts.only);
@@ -103,5 +146,5 @@ module.exports = function (opts) {
delete opts.cache;
delete opts.only;
_.extend(transformOpts, opts);
extend(transformOpts, opts);
};

View File

@@ -0,0 +1,73 @@
var cloneDeep = require("lodash/lang/cloneDeep");
var traverse = require("../../traverse");
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

@@ -14,7 +14,7 @@ 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;
@@ -32,7 +32,7 @@ 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);

View File

@@ -0,0 +1,22 @@
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");

View File

@@ -9,6 +9,12 @@ var visitor = {
if (t.isAwaitExpression(node)) {
node.type = "YieldExpression";
if (node.all) {
// await* foo; -> yield Promise.all(foo);
node.all = false;
node.argument = t.callExpression(t.memberExpression(t.identifier("Promise"), t.identifier("all")), [node.argument]);
}
}
}
};

View File

@@ -21,6 +21,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.
*
@@ -191,6 +221,7 @@ 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)) {
@@ -226,11 +257,18 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
property = node.property;
computed = node.computed;
} else if (t.isAssignmentExpression(node)) {
if (!t.isIdentifier(node.left.object, { name: "super" })) return;
if (methodNode.kind !== "set") return;
thisReference = getThisReference();
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
return this.setSuperProperty(node.left.property, node.right, methodNode.static, node.left.computed, thisReference);
}
if (!property) return;
var thisReference = getThisReference();
thisReference = getThisReference();
var superProperty = this.superProperty(property, methodNode.static, computed, thisReference);
if (args) {
if (args.length === 1 && t.isSpreadElement(args[0])) {

View File

@@ -6,7 +6,7 @@ var Transformer = require("./transformer");
var object = require("../helpers/object");
var File = require("../file");
var util = require("../util");
var _ = require("lodash");
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 = util.normalizeAst(ast);
var file = new File(opts);
file.addCode(code);
@@ -64,7 +64,7 @@ transform.moduleFormatters = require("./modules");
var rawTransformers = require("./transformers");
_.each(rawTransformers, function (transformer, key) {
each(rawTransformers, function (transformer, key) {
var namespace = key.split(".")[0];
transform.namespaces[namespace] = transform.namespaces[namespace] || [];
transform.namespaces[namespace].push(key);

View File

@@ -6,7 +6,7 @@ var traverse = require("../../traverse");
var object = require("../../helpers/object");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var extend = require("lodash/object/extend");
function DefaultFormatter(file) {
this.file = file;
@@ -45,7 +45,7 @@ var exportsVisitor = {
formatter.hasLocalImports = true;
if (declar && t.isStatement(declar)) {
_.extend(formatter.localExports, t.getIds(declar, true));
extend(formatter.localExports, t.getBindingIdentifiers(declar));
}
if (!node.default) {
@@ -67,7 +67,7 @@ var importsVisitor = {
enter: function (node, parent, scope, context, formatter) {
if (t.isImportDeclaration(node)) {
formatter.hasLocalImports = true;
_.extend(formatter.localImports, t.getIds(node, true));
extend(formatter.localImports, t.getBindingIdentifiers(node));
formatter.bumpImportOccurences(node);
}
}
@@ -147,7 +147,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 +171,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 +212,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;
@@ -224,7 +230,7 @@ DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
nodes.push(this.buildExportsWildcard(ref, node));
} else {
if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
// importing a default so we need to normalise it
// 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 +257,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

@@ -6,7 +6,8 @@ var DefaultFormatter = require("./_default");
var CommonFormatter = require("./common");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var contains = require("lodash/collection/contains");
var values = require("lodash/object/values");
function AMDFormatter() {
CommonFormatter.apply(this, arguments);
@@ -14,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) {
@@ -39,7 +42,7 @@ AMDFormatter.prototype.transform = function (ast) {
// build up define container
var params = _.values(this.ids);
var params = values(this.ids);
if (this.passModuleArg) params.unshift(t.identifier("module"));
params.unshift(t.identifier("exports"));
@@ -79,10 +82,9 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var key = t.getSpecifierName(specifier);
var ref = this.getExternalReference(node);
if (_.contains(this.file.dynamicImported, node)) {
if (contains(this.file.dynamicImported, node)) {
// Prevent unnecessary renaming of dynamic imports.
this.ids[node.source.value] = key;
return;
this.ids[node.source.value] = ref;
} else if (t.isImportBatchSpecifier(specifier)) {
// import * as bar from "foo";
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {

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 _ = require("lodash");
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.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);
@@ -24,7 +26,7 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
// import foo from "foo";
if (t.isSpecifierDefault(specifier)) {
if (!_.contains(this.file.dynamicImported, node)) {
if (!contains(this.file.dynamicImported, node)) {
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
}
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)]));

View File

@@ -8,7 +8,9 @@ var useStrict = require("../helpers/use-strict");
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var last = require("lodash/array/last");
var each = require("lodash/collection/each");
var map = require("lodash/collection/map");
function SystemFormatter(file) {
this.exportIdentifier = file.generateUidIdentifier("export");
@@ -19,6 +21,8 @@ function SystemFormatter(file) {
util.inherits(SystemFormatter, AMDFormatter);
SystemFormatter.prototype.init = function () {};
SystemFormatter.prototype._addImportSource = function (node, exportNode) {
node._importSource = exportNode.source && exportNode.source.value;
return node;
@@ -61,14 +65,14 @@ SystemFormatter.prototype.buildExportCall = function (id, init, isStatement) {
SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
AMDFormatter.prototype.importSpecifier.apply(this, arguments);
this._addImportSource(_.last(nodes), node);
this._addImportSource(last(nodes), node);
};
var runnerSettersVisitor = {
enter: function (node, parent, scope, context, state) {
if (node._importSource === state.source) {
if (t.isVariableDeclaration(node)) {
_.each(node.declarations, function (declar) {
each(node.declarations, function (declar) {
state.hoistDeclarators.push(t.variableDeclarator(declar.id));
state.nodes.push(t.expressionStatement(
t.assignmentExpression("=", declar.id, declar.init)
@@ -86,7 +90,7 @@ var runnerSettersVisitor = {
SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators) {
var scope = this.file.scope;
return t.arrayExpression(_.map(this.ids, function (uid, source) {
return t.arrayExpression(map(this.ids, function (uid, source) {
var state = {
source: source,
nodes: [],

View File

@@ -5,7 +5,7 @@ module.exports = UMDFormatter;
var AMDFormatter = require("./amd");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var values = require("lodash/object/values");
function UMDFormatter() {
AMDFormatter.apply(this, arguments);
@@ -26,7 +26,7 @@ UMDFormatter.prototype.transform = function (ast) {
// factory
var ids = _.values(this.ids);
var ids = values(this.ids);
var args = [t.identifier("exports")];
if (this.passModuleArg) args.push(t.identifier("module"));
args = args.concat(ids);

View File

@@ -3,12 +3,12 @@
var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) {
var callNext = step.bind(gen.next);
var callThrow = step.bind(gen.throw);
var callNext = step.bind(null, "next");
var callThrow = step.bind(null, "throw");
function step(arg) {
function step(key, arg) {
try {
var info = this(arg);
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);

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,5 @@
if (Object.getPrototypeOf(CLASS_NAME) !== null) {
Object.getPrototypeOf(CLASS_NAME).apply(this, arguments);
}
(function (instance, Constructor) {
if (Object.getPrototypeOf(Constructor) !== null) {
Object.getPrototypeOf(Constructor).apply(instance, arguments);
}
});

View File

@@ -1,4 +1,4 @@
(function (target) {
Object.assign || (function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {

View File

@@ -2,6 +2,7 @@ for (var LOOP_OBJECT = OBJECT,
IS_ARRAY = Array.isArray(LOOP_OBJECT),
INDEX = 0,
LOOP_OBJECT = IS_ARRAY ? LOOP_OBJECT : LOOP_OBJECT[Symbol.iterator]();;) {
var ID;
if (IS_ARRAY) {
if (INDEX >= LOOP_OBJECT.length) break;
ID = LOOP_OBJECT[INDEX++];

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,8 @@
module.exports = TransformerPass;
var traverse = require("../traverse");
var _ = require("lodash");
var util = require("../util");
var contains = require("lodash/collection/contains");
/**
* This class is responsible for traversing over the provided `File`s
@@ -31,15 +32,17 @@ TransformerPass.prototype.canRun = function () {
if (key[0] === "_") return true;
var blacklist = opts.blacklist;
if (blacklist.length && _.contains(blacklist, key)) return false;
if (blacklist.length && contains(blacklist, key)) return false;
var whitelist = opts.whitelist;
if (whitelist.length && !_.contains(whitelist, key)) return false;
if (whitelist.length && !contains(whitelist, key)) return false;
if (transformer.optional && !_.contains(opts.optional, key)) return false;
if (transformer.optional && !contains(opts.optional, key)) return false;
if (transformer.experimental && !opts.experimental) return false;
if (transformer.playground && !opts.playground) return false;
return true;
};
@@ -60,6 +63,8 @@ var transformVisitor = {
TransformerPass.prototype.transform = function () {
var file = this.file;
util.debug(file.opts.filename + ": Running transformer " + this.transformer.key);
this.astRun("before");
var state = { file: file, handlers: this.handlers, pass: this };

View File

@@ -3,8 +3,10 @@
module.exports = Transformer;
var TransformerPass = require("./transformer-pass");
var t = require("../types");
var _ = require("lodash");
var isFunction = require("lodash/lang/isFunction");
var traverse = require("../traverse");
var isObject = require("lodash/lang/isObject");
var each = require("lodash/collection/each");
/**
* This is the class responsible for normalising a transformers handlers
@@ -15,42 +17,38 @@ var _ = require("lodash");
function Transformer(key, transformer, opts) {
this.manipulateOptions = transformer.manipulateOptions;
this.experimental = !!transformer.experimental;
this.playground = !!transformer.playground;
this.secondPass = !!transformer.secondPass;
this.optional = !!transformer.optional;
this.handlers = this.normalise(transformer);
this.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)) {
if (isFunction(transformer)) {
transformer = { ast: transformer };
}
_.each(transformer, function (fns, type) {
traverse.explode(transformer);
each(transformer, function (fns, type) {
// hidden property
if (type[0] === "_") {
self[type] = fns;
return;
}
if (_.isFunction(fns)) fns = { enter: fns };
if (isFunction(fns)) fns = { enter: fns };
if (!_.isObject(fns)) return;
if (!isObject(fns)) return;
if (!fns.enter) fns.enter = _.noop;
if (!fns.exit) fns.exit = _.noop;
if (!fns.enter) fns.enter = function () { };
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

@@ -1,7 +1,7 @@
"use strict";
var util = require("../../../util");
var t = require("../../../types");
var defineMap = require("../../helpers/define-map");
var t = require("../../../types");
exports.ObjectExpression = function (node) {
var mutatorMap = {};
@@ -10,7 +10,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 +21,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

@@ -11,7 +11,7 @@ var visitor = {
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;

View File

@@ -4,7 +4,8 @@ var traverse = require("../../../traverse");
var object = require("../../../helpers/object");
var util = require("../../../util");
var t = require("../../../types");
var _ = require("lodash");
var values = require("lodash/object/values");
var extend = require("lodash/object/extend");
var isLet = function (node, parent) {
if (!t.isVariableDeclaration(node)) return false;
@@ -28,7 +29,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;
}
@@ -44,26 +45,15 @@ exports.Loop = function (node, parent, scope, context, file) {
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) {
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();
}
};
@@ -77,7 +67,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;
@@ -94,7 +84,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;
@@ -120,11 +110,11 @@ function replace(node, parent, scope, context, remaps) {
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();
}
@@ -143,7 +133,7 @@ function traverseReplace(node, parent, scope, remaps) {
* Description
*/
LetScoping.prototype.remap = function () {
BlockScoping.prototype.remap = function () {
var hasRemaps = false;
var letRefs = this.letReferences;
var scope = this.scope;
@@ -159,13 +149,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
};
}
@@ -189,7 +179,7 @@ LetScoping.prototype.remap = function () {
* 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
@@ -200,7 +190,7 @@ LetScoping.prototype.needsClosure = function () {
this.hoistVarDeclarations();
// turn outsideLetReferences into an array
var params = _.values(this.outsideLetReferences);
var params = values(this.outsideLetReferences);
// build the closure that we're going to wrap the block with
var fn = t.functionExpression(null, params, t.blockStatement(block.body));
@@ -237,7 +227,7 @@ var letReferenceFunctionVisitor = {
// 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;
@@ -259,7 +249,7 @@ var letReferenceBlockVisitor = {
* Description
*/
LetScoping.prototype.getLetReferences = function () {
BlockScoping.prototype.getLetReferences = function () {
var block = this.block;
var declarators = block._letDeclarators || [];
@@ -268,7 +258,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));
}
//
@@ -284,8 +274,8 @@ LetScoping.prototype.getLetReferences = function () {
//
for (i = 0; i < declarators.length; i++) {
declar = declarators[i];
var keys = t.getIds(declar, true);
_.extend(this.letReferences, keys);
var keys = t.getBindingIdentifiers(declar);
extend(this.letReferences, keys);
this.hasLetReferences = true;
}
@@ -293,7 +283,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,
@@ -307,34 +297,71 @@ LetScoping.prototype.getLetReferences = function () {
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) {
var replace;
if (t.isLoop(node)) {
state.ignoreLabeless = true;
traverse(node, loopVisitor, scope, state);
state.ignoreLabeless = false;
}
if (t.isFunction(node) || t.isLoop(node)) {
return context.skip();
}
if (node && !node.label && state.isLoop) {
if (t.isBreakStatement(node)) {
if (t.isSwitchCase(parent)) return;
var loopText = loopNodeTo(node);
state.hasBreak = true;
replace = t.returnStatement(t.literal("break"));
} else if (t.isContinueStatement(node)) {
state.hasContinue = true;
replace = t.returnStatement(t.literal("continue"));
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, context, state) {
if (t.isLabeledStatement(node)) {
state.innerLabels.push(node.label.name);
}
}
};
@@ -347,15 +374,19 @@ 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, loopLabelVisitor, this.scope, state);
traverse(this.block, loopVisitor, this.scope, state);
return state;
};
@@ -382,7 +413,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);
};
@@ -394,7 +425,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);
})));
@@ -419,9 +450,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));
@@ -435,7 +466,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", [
@@ -454,22 +485,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,6 +2,7 @@
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");
@@ -66,12 +67,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)
]));
@@ -160,24 +168,31 @@ 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";
var helperName = "class-super-constructor-call";
constructor.body.body.push(util.template(defaultConstructorTemplate, {
CLASS_NAME: className,
SUPER_NAME: this.superName
}, true));
if (this.isLoose) {
constructor.body.body.push(util.template(helperName + "-loose", {
CLASS_NAME: className,
SUPER_NAME: this.superName
}, true));
} else {
constructor.body.body.push(
t.expressionStatement(
t.callExpression(this.file.addHelper(helperName), [t.thisExpression(), className])
)
);
}
}
var instanceProps;
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,7 +245,8 @@ Class.prototype.pushMethod = function (node) {
this.hasInstanceMutators = true;
}
util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
defineMap.push(mutatorMap, methodName, kind, node.computed, node);
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
};
/**
@@ -254,5 +270,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

@@ -5,8 +5,8 @@ var t = require("../../../types");
var visitor = {
enter: function (node, parent, scope, context, state) {
if (t.isDeclaration(node) || t.isAssignmentExpression(node)) {
var ids = t.getIds(node, true);
if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
var ids = t.getBindingIdentifiers(node);
for (var key in ids) {
var id = ids[key];
@@ -21,6 +21,9 @@ var visitor = {
// constant so we can just ignore it
if (id === constant) continue;
var localBinding = scope.getBinding(key);
if (localBinding !== constant) continue;
throw state.file.errorWithNode(id, key + " is read-only");
}
} else if (t.isScope(node)) {
@@ -31,7 +34,7 @@ var visitor = {
exports.Scope = function (node, parent, scope, context, file) {
traverse(node, visitor, scope, {
constants: scope.getAllOfKind("const"),
constants: scope.getAllDeclarationsOfKind("const"),
file: file
});
};

View File

@@ -46,9 +46,11 @@ var push = function (opts, nodes, elem, parentId) {
var pushAssignmentPattern = function (opts, nodes, pattern, parentId) {
var tempParentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
nodes.push(t.variableDeclaration("var", [
var declar = t.variableDeclaration("var", [
t.variableDeclarator(tempParentId, parentId)
]));
]);
declar._blockHoist = opts.blockHoist;
nodes.push(declar);
nodes.push(buildVariableAssign(
opts,

View File

@@ -20,11 +20,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
// add the value declaration to the new loop body
if (declar) {
if (build.shouldUnshift) {
block.body.unshift(declar);
} else {
block.body.push(declar);
}
block.body.push(declar);
}
// push the rest of the original loop body onto our new body
@@ -45,9 +41,9 @@ var loose = function (node, parent, scope, context, file) {
id = left;
} else if (t.isVariableDeclaration(left)) {
// for (var i of test)
id = left.declarations[0].id;
id = scope.generateUidIdentifier("ref");
declar = t.variableDeclaration(left.kind, [
t.variableDeclarator(id)
t.variableDeclarator(left.declarations[0].id, id)
]);
} else {
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
@@ -61,10 +57,15 @@ var loose = function (node, parent, scope, context, file) {
ID: id
});
if (!declar) {
// no declaration so we need to remove the variable declaration at the top of
// the for-of-loose template
loop.body.body.shift();
}
return {
shouldUnshift: true,
declar: declar,
loop: loop
declar: declar,
loop: loop
};
};

View File

@@ -26,7 +26,7 @@ exports.ExportDeclaration = function (node, parent, scope, context, file) {
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,7 +1,8 @@
"use strict";
var util = require("../../../util");
var t = require("../../../types");
var traverse = require("../../../traverse");
var util = require("../../../util");
var t = require("../../../types");
var hasDefaults = function (node) {
for (var i = 0; i < node.params.length; i++) {
@@ -10,12 +11,20 @@ var hasDefaults = function (node) {
return false;
};
var iifeVisitor = {
enter: function (node, parent, scope, context, state) {
if (t.isReferencedIdentifier(node, parent) && state.scope.hasOwnReference(node.name)) {
state.iife = true;
context.stop();
}
}
};
exports.Function = function (node, parent, scope) {
if (!hasDefaults(node)) return;
t.ensureBlock(node);
var iife = false;
var body = [];
var argsIdentifier = t.identifier("arguments");
@@ -23,6 +32,8 @@ exports.Function = function (node, parent, scope) {
var lastNonDefaultParam = 0;
var state = { iife: false, scope: scope };
for (var i = 0; i < node.params.length; i++) {
var param = node.params[i];
@@ -36,10 +47,12 @@ exports.Function = function (node, parent, scope) {
node.params[i] = scope.generateUidIdentifier("x");
// we're accessing a variable that's already defined within this function
var localDeclar = scope.get(left.name, true);
if (localDeclar !== left) {
iife = true;
if (!state.iife) {
if (t.isIdentifier(right) && scope.hasOwnReference(right.name)) {
state.iife = true;
} else {
traverse(right, iifeVisitor, scope, state);
}
}
var defNode = util.template("default-parameter", {
@@ -55,7 +68,7 @@ exports.Function = function (node, parent, scope) {
// we need to cut off all trailing default parameters
node.params = node.params.slice(0, lastNonDefaultParam);
if (iife) {
if (state.iife) {
var container = t.functionExpression(null, [], node.body, node.generator);
container._aliasFunction = true;

View File

@@ -12,8 +12,6 @@ exports.Function = function (node, parent, scope) {
var rest = node.params.pop().argument;
t.ensureBlock(node);
var argsId = t.identifier("arguments");
// otherwise `arguments` will be remapped in arrow functions
@@ -60,15 +58,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

@@ -58,7 +58,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

@@ -2,7 +2,7 @@
var nameMethod = require("../../helpers/name-method");
var t = require("../../../types");
var _ = require("lodash");
var clone = require("lodash/lang/clone");
exports.Property = function (node, parent, scope, context, file) {
if (node.method) {
@@ -12,6 +12,6 @@ exports.Property = function (node, parent, scope, context, file) {
if (node.shorthand) {
node.shorthand = false;
node.key = t.removeComments(_.clone(node.key));
node.key = t.removeComments(clone(node.key));
}
};

View File

@@ -1,7 +1,7 @@
"use strict";
var t = require("../../../types");
var _ = require("lodash");
var contains = require("lodash/collection/contains");
var getSpreadLiteral = function (spread, file) {
return file.toArray(spread.argument);
@@ -101,7 +101,7 @@ exports.NewExpression = function (node, parent, scope, context, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
var nativeType = t.isIdentifier(node.callee) && _.contains(t.NATIVE_TYPE_NAMES, node.callee.name);
var nativeType = t.isIdentifier(node.callee) && contains(t.NATIVE_TYPE_NAMES, node.callee.name);
var nodes = build(args, file);

View File

@@ -1,7 +1,7 @@
"use strict";
var rewritePattern = require("regexpu/rewrite-pattern");
var _ = require("lodash");
var pull = require("lodash/array/pull");
exports.Literal = function (node) {
var regex = node.regex;
@@ -9,7 +9,7 @@ exports.Literal = function (node) {
var flags = regex.flags.split("");
if (regex.flags.indexOf("u") < 0) return;
_.pull(flags, "u");
pull(flags, "u");
regex.pattern = rewritePattern(regex.pattern, regex.flags);
regex.flags = flags.join("");

View File

@@ -13,7 +13,7 @@ module.exports = {
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`
@@ -52,14 +52,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

View File

@@ -1,7 +1,9 @@
"use strict";
var useStrict = require("../../helpers/use-strict");
var _ = require("lodash");
var groupBy = require("lodash/collection/groupBy");
var flatten = require("lodash/array/flatten");
var values = require("lodash/object/values");
// Priority:
//
@@ -21,14 +23,14 @@ exports.Program = {
if (!hasChange) return;
useStrict.wrap(node, function () {
var nodePriorities = _.groupBy(node.body, function (bodyNode) {
var nodePriorities = groupBy(node.body, function (bodyNode) {
var priority = bodyNode._blockHoist;
if (priority == null) priority = 1;
if (priority === true) priority = 2;
return priority;
});
node.body = _.flatten(_.values(nodePriorities).reverse());
node.body = flatten(values(nodePriorities).reverse());
});
}
};

View File

@@ -1,28 +0,0 @@
"use strict";
var t = require("../../../types");
exports.ExportDeclaration = function (node, parent, scope) {
var declar = node.declaration;
if (node.default) {
if (t.isClassDeclaration(declar)) {
node.declaration = declar.id;
return [declar, node];
} else if (t.isClassExpression(declar)) {
var temp = scope.generateUidIdentifier("default");
declar = t.variableDeclaration("var", [
t.variableDeclarator(temp, declar)
]);
node.declaration = temp;
return [declar, node];
}
} else {
if (t.isFunctionDeclaration(declar)) {
node.specifiers = [t.importSpecifier(declar.id, declar.id)];
node.declaration = null;
node._blockHoist = 2;
return [declar, node];
}
}
};

View File

@@ -0,0 +1,49 @@
"use strict";
// in this transformer we have to split up classes and function declarations
// from their exports. why? because sometimes we need to replace classes with
// nodes that aren't allowed in the same contexts. also, if you're exporting
// a generator function as a default then regenerator will destroy the export
// declaration and leave a variable declaration in it's place... yeah, handy.
var t = require("../../../types");
var resolveModuleSource = function (node, parent, scope, context, file) {
var resolveModuleSource = file.opts.resolveModuleSource;
if (node.source && resolveModuleSource) {
node.source.value = resolveModuleSource(node.source.value);
}
};
exports.ImportDeclaration = resolveModuleSource;
exports.ExportDeclaration = function (node, parent, scope) {
resolveModuleSource.apply(null, arguments);
var declar = node.declaration;
if (node.default) {
if (t.isClassDeclaration(declar)) {
node.declaration = declar.id;
return [declar, node];
} else if (t.isClassExpression(declar)) {
var temp = scope.generateUidIdentifier("default");
declar = t.variableDeclaration("var", [
t.variableDeclarator(temp, declar)
]);
node.declaration = temp;
return [declar, node];
} else if (t.isFunctionDeclaration(declar)) {
node._blockHoist = 2;
node.declaration = declar.id;
return [declar, node];
}
} else {
if (t.isFunctionDeclaration(declar)) {
node.specifiers = [t.importSpecifier(declar.id, declar.id)];
node.declaration = null;
node._blockHoist = 2;
return [declar, node];
}
}
};

View File

@@ -6,10 +6,13 @@
// jsx
var esutils = require("esutils");
var react = require("../../helpers/react");
var t = require("../../../types");
exports.JSXIdentifier = function (node) {
if (esutils.keyword.isIdentifierName(node.name)) {
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);
@@ -168,11 +171,21 @@ exports.JSXElement = {
var cleanJSXElementLiteralChild = function (child, args) {
var lines = child.value.split(/\r\n|\n|\r/);
for (var i = 0; i < lines.length; i++) {
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, " ");
@@ -188,6 +201,10 @@ var cleanJSXElementLiteralChild = function (child, args) {
}
if (trimmedLine) {
if (!isLastNonEmptyLine) {
trimmedLine += " ";
}
args.push(t.literal(trimmedLine));
}
}
@@ -195,34 +212,7 @@ var cleanJSXElementLiteralChild = function (child, args) {
// 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;
@@ -239,6 +229,12 @@ var addDisplayName = function (id, call) {
}
};
exports.ExportDeclaration = function (node, parent, scope, context, file) {
if (node.default && react.isCreateClass(node.declaration)) {
addDisplayName(file.opts.basename, node.declaration);
}
};
exports.AssignmentExpression =
exports.Property =
exports.VariableDeclarator = function (node) {
@@ -259,7 +255,7 @@ exports.VariableDeclarator = function (node) {
left = left.property;
}
if (t.isIdentifier(left)) {
if (t.isIdentifier(left) && react.isCreateClass(right)) {
addDisplayName(left.name, right);
}
};

View File

@@ -4,10 +4,11 @@ var traverse = require("../../../traverse");
var util = require("../../../util");
var core = require("core-js/library");
var t = require("../../../types");
var _ = require("lodash");
var has = require("lodash/object/has");
var contains = require("lodash/collection/contains");
var coreHas = function (node) {
return node.name !== "_" && _.has(core, node.name);
return node.name !== "_" && has(core, node.name);
};
var ALIASABLE_CONSTRUCTORS = [
@@ -30,11 +31,11 @@ var astVisitor = {
if (!t.isReferenced(obj, node)) return;
if (!node.computed && coreHas(obj) && _.has(core[obj.name], prop.name)) {
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name)) {
context.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)) {

View File

@@ -16,6 +16,6 @@ exports.FunctionExpression = function (node, parent, scope, context) {
context.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) {

View File

@@ -3,6 +3,8 @@
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
var t = require("../../../types");
exports.playground = true;
build(exports, {
is: function (node) {
var is = t.isAssignmentExpression(node) && node.operator === "?=";

View File

@@ -2,6 +2,8 @@
var t = require("../../../types");
exports.playground = true;
exports.BindMemberExpression = function (node, parent, scope) {
var object = node.object;
var prop = node.property;

View File

@@ -3,6 +3,8 @@
var traverse = require("../../../traverse");
var t = require("../../../types");
exports.playground = true;
var visitor = {
enter: function (node, parent, scope, context, state) {
if (t.isFunction(node)) return;

View File

@@ -3,13 +3,13 @@
var t = require("../../../types");
exports.BlockStatement = function (node, parent) {
if (t.isFunction(parent) || t.isExportDeclaration(parent)) {
if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) {
return;
}
for (var i = 0; i < node.body.length; i++) {
var func = node.body[i];
if (!t.isFunctionDeclaration(i)) continue;
if (!t.isFunctionDeclaration(func)) continue;
var declar = t.variableDeclaration("let", [
t.variableDeclarator(func.id, t.toExpression(func))
@@ -21,6 +21,6 @@ exports.BlockStatement = function (node, parent) {
// todo: name this
func.id = null;
func.body[i] = declar;
node.body[i] = declar;
}
};

View File

@@ -1,7 +1,7 @@
"use strict";
var t = require("../../../types");
var _ = require("lodash");
var t = require("../../../types");
var pull = require("lodash/array/pull");
var isProtoKey = function (node) {
return t.isLiteral(t.toComputedKey(node, node.key), { value: "__proto__" });
@@ -50,7 +50,7 @@ exports.ObjectExpression = function (node, parent, scope, context, file) {
if (isProtoKey(prop)) {
proto = prop.value;
_.pull(node.properties, prop);
pull(node.properties, prop);
}
}

View File

@@ -1,9 +1,38 @@
"use strict";
var levenshtein = require("../../../helpers/levenshtein");
var t = require("../../../types");
exports.optional = true;
exports.Identifier = function (node, parent, scope, context, file) {
if (!scope.has(node.name, true)) {
throw file.errorWithNode(node, "Reference to undeclared variable", ReferenceError);
if (!t.isReferenced(node, parent)) return;
if (scope.hasBinding(node.name)) return;
var msg = "Reference to undeclared variable";
// get the closest declaration to offer as a suggestion
// the variable name may have just been mistyped
var bindings = scope.getAllBindings();
var closest;
var shortest = -1;
for (var name in bindings) {
var distance = levenshtein(node.name, name);
if (distance <= 0 || distance > 3) continue;
if (distance <= shortest) continue;
closest = name;
shortest = distance;
}
if (closest) {
msg += " - Did you mean " + closest + "?";
}
//
throw file.errorWithNode(node, msg, ReferenceError);
};

View File

@@ -1,64 +0,0 @@
[
"Set",
"Map",
"WeakMap",
"WeakSet",
"Proxy",
"Promise",
"Reflect",
"Symbol",
"System",
"__filename",
"__dirname",
"GLOBAL",
"global",
"module",
"require",
"Buffer",
"console",
"exports",
"process",
"setTimeout",
"clearTimeout",
"setInterval",
"clearInterval",
"setImmediate",
"clearImmediate",
"Array",
"Boolean",
"Date",
"decodeURI",
"decodeURIComponent",
"encodeURI",
"encodeURIComponent",
"Error",
"eval",
"EvalError",
"Function",
"hasOwnProperty",
"isFinite",
"isNaN",
"JSON",
"Map",
"Math",
"Number",
"Object",
"Proxy",
"Promise",
"parseInt",
"parseFloat",
"RangeError",
"ReferenceError",
"RegExp",
"Set",
"String",
"SyntaxError",
"TypeError",
"URIError",
"WeakMap",
"WeakSet",
"arguments",
"NaN",
"window",
"self"
]

View File

@@ -4,9 +4,11 @@ module.exports = traverse;
/* jshint maxparams:7 */
var Scope = require("./scope");
var t = require("../types");
var _ = require("lodash");
var Scope = require("./scope");
var t = require("../types");
var contains = require("lodash/collection/contains");
var flatten = require("lodash/array/flatten");
var compact = require("lodash/array/compact");
function TraversalContext() {
this.shouldFlatten = false;
@@ -52,7 +54,7 @@ function replaceNode(obj, key, node, result) {
// we're replacing a statement or block node with an array of statements so we better
// ensure that it's a block
if (isArray && _.contains(t.STATEMENT_OR_BLOCK_KEYS, key) && !t.isBlockStatement(obj)) {
if (isArray && contains(t.STATEMENT_OR_BLOCK_KEYS, key) && !t.isBlockStatement(obj)) {
t.ensureBlock(obj, key);
}
@@ -110,8 +112,8 @@ TraversalContext.prototype.visitNode = function (obj, key, opts, scope, parent,
var ourScope = scope;
// we're entering a new scope so let's construct it!
if (t.isScope(node)) {
ourScope = new Scope(node, scope);
if (!opts.noScope && t.isScope(node)) {
ourScope = new Scope(node, parent, scope);
}
node = this.enterNode(obj, key, node, opts.enter, parent, ourScope, state);
@@ -153,11 +155,11 @@ TraversalContext.prototype.visit = function (node, key, opts, scope, state) {
}
if (this.shouldFlatten) {
node[key] = _.flatten(node[key]);
node[key] = flatten(node[key]);
if (key === "body") {
// we can safely compact this
node[key] = _.compact(node[key]);
node[key] = compact(node[key]);
}
}
};
@@ -177,15 +179,15 @@ function traverseNode(node, opts, scope, state) {
function traverse(parent, opts, scope, state) {
if (!parent) return;
if (!scope) {
if (!opts.noScope && !scope) {
if (parent.type !== "Program" && parent.type !== "File") {
throw new Error("Must pass a scope unless traversing a Program/File got a " + parent.type + " node");
}
}
if (!opts) opts = {};
if (!opts.enter) opts.enter = _.noop;
if (!opts.exit) opts.exit = _.noop;
if (!opts.enter) opts.enter = function () { };
if (!opts.exit) opts.exit = function () { };
// array of nodes
if (Array.isArray(parent)) {
@@ -217,7 +219,10 @@ function clearNode(node) {
}
}
var clearVisitor = { enter: clearNode };
var clearVisitor = {
noScope: true,
enter: clearNode
};
function clearComments(comments) {
for (var i = 0; i < comments.length; i++) {
@@ -232,6 +237,20 @@ traverse.removeProperties = function (tree) {
return tree;
};
traverse.explode = function (obj) {
for (var type in obj) {
var fns = obj[type];
var aliases = t.FLIPPED_ALIAS_KEYS[type];
if (aliases) {
for (var i = 0; i < aliases.length; i++) {
obj[aliases[i]] = fns;
}
}
}
return obj;
};
function hasBlacklistedType(node, parent, scope, context, state) {
if (node.type === state.type) {
state.has = true;
@@ -241,7 +260,7 @@ function hasBlacklistedType(node, parent, scope, context, state) {
traverse.hasType = function (tree, scope, type, blacklistTypes) {
// the node we're searching in is blacklisted
if (_.contains(blacklistTypes, tree.type)) return false;
if (contains(blacklistTypes, tree.type)) return false;
// the type we're looking for is the same as the passed node
if (tree.type === type) return true;

View File

@@ -2,50 +2,38 @@
module.exports = Scope;
var contains = require("lodash/collection/contains");
var traverse = require("./index");
var defaults = require("lodash/object/defaults");
var globals = require("globals");
var flatten = require("lodash/array/flatten");
var extend = require("lodash/object/extend");
var object = require("../helpers/object");
var each = require("lodash/collection/each");
var has = require("lodash/object/has");
var t = require("../types");
var _ = require("lodash");
var FOR_KEYS = ["left", "init"];
/**
* This searches the current "scope" and collects all references/declarations
* This searches the current "scope" and collects all references/bindings
* within.
*
* @param {Node} block
* @param {Node} parentBlock
* @param {Scope} [parent]
* @param {File} [file]
*/
function Scope(block, parent, file) {
function Scope(block, parentBlock, parent, file) {
this.parent = parent;
this.block = block;
this.file = parent ? parent.file : file;
var info = this.getInfo();
this.references = info.references;
this.declarations = info.declarations;
this.declarationKinds = info.declarationKinds;
this.parentBlock = parentBlock;
this.block = block;
this.crawl();
}
Scope.defaultDeclarations = require("./global-keys");
Scope.prototype._add = function (node, references, throwOnDuplicate) {
if (!node) return;
var ids = t.getIds(node, true);
for (var key in ids) {
var id = ids[key];
if (throwOnDuplicate && references[key]) {
throw this.file.errorWithNode(id, "Duplicate declaration", TypeError);
}
references[key] = id;
}
};
Scope.defaultDeclarations = flatten([globals.builtin, globals.browser, globals.node].map(Object.keys));
/**
* Description
@@ -122,7 +110,7 @@ Scope.prototype.generateUidBasedOnNode = function (parent) {
*/
Scope.prototype.generateTempBasedOnNode = function (node) {
if (t.isIdentifier(node) && this.has(node.name, true)) {
if (t.isIdentifier(node) && this.hasBinding(node.name)) {
return null;
}
@@ -134,12 +122,91 @@ Scope.prototype.generateTempBasedOnNode = function (node) {
return id;
};
Scope.prototype.checkBlockScopedCollisions = function (key, id) {
if (this.declarationKinds["let"][key] || this.declarationKinds["const"][key]) {
throw this.file.errorWithNode(id, "Duplicate declaration " + key, TypeError);
}
};
Scope.prototype.inferType = function (node) {
var target;
if (t.isVariableDeclarator(node)) {
target = node.init;
}
if (t.isArrayExpression(target) || t.isObjectExpression(target)) {
// todo: possibly call some helper that will resolve these to a type annotation
}
if (t.isCallExpression(target)) {
target = target.callee;
}
if (t.isMemberExpression(target)) {
// todo: crawl this and find the correct type, bail on anything that we cannot
// possibly be 100% confident on
}
if (t.isIdentifier(target)) {
return this.getType(target.name);
}
};
Scope.prototype.registerType = function (key, id, node) {
var type;
if (id.typeAnnotation) {
type = id.typeAnnotation;
}
if (!type) {
type = this.inferType(node);
}
if (type) {
if (t.isTypeAnnotation(type)) type = type.typeAnnotation;
this.types[key] = type;
}
};
Scope.prototype.register = function (node, reference, kind) {
if (t.isVariableDeclaration(node)) {
return this.registerVariableDeclaration(node);
}
var ids = t.getBindingIdentifiers(node);
extend(this.references, ids);
if (reference) return;
for (var key in ids) {
var id = ids[key];
this.checkBlockScopedCollisions(key, id);
this.registerType(key, id, node);
this.bindings[key] = id;
}
var kinds = this.declarationKinds[kind];
if (kinds) extend(kinds, ids);
};
Scope.prototype.registerVariableDeclaration = function (declar) {
var declars = declar.declarations;
for (var i = 0; i < declars.length; i++) {
this.register(declars[i], false, declar.kind);
}
};
var functionVariableVisitor = {
enter: function (node, parent, scope, context, state) {
if (t.isFor(node)) {
_.each(FOR_KEYS, function (key) {
each(t.FOR_INIT_KEYS, function (key) {
var declar = node[key];
if (t.isVar(declar)) state.add(declar);
if (t.isVar(declar)) state.scope.register(declar);
});
}
@@ -150,64 +217,76 @@ var functionVariableVisitor = {
// function identifier doesn't belong to this scope
if (state.blockId && node === state.blockId) return;
// delegate block scope handling to the `blockVariableVisitor`
if (t.isBlockScoped(node)) return;
// this will be hit again once we traverse into it after this iteration
if (t.isExportDeclaration(node) && t.isDeclaration(node.declaration)) return;
// we've ran into a declaration!
// we'll let the BlockStatement scope deal with `let` declarations unless
if (t.isDeclaration(node) && !t.isBlockScoped(node)) {
state.add(node);
}
if (t.isDeclaration(node)) state.scope.register(node);
}
};
var programReferenceVisitor = {
enter: function (node, parent, scope, context, add) {
if (t.isReferencedIdentifier(node, parent) && !scope.has(node.name)) {
add(node, true);
enter: function (node, parent, scope, context, state) {
if (t.isReferencedIdentifier(node, parent) && !scope.hasReference(node.name)) {
state.register(node, true);
}
}
};
var blockVariableVisitor = {
enter: function (node, parent, scope, context, add) {
enter: function (node, parent, scope, context, state) {
if (t.isBlockScoped(node)) {
add(node, false, true);
context.stop();
state.register(node);
} else if (t.isScope(node)) {
context.skip();
}
}
};
Scope.prototype.getInfo = function () {
Scope.prototype.crawl = function () {
var parent = this.parent;
var block = this.block;
var self = this;
if (block._scopeInfo) return block._scopeInfo;
var i;
var info = block._scopeInfo = {};
var references = info.references = object();
var declarations = info.declarations = object();
var declarationKinds = info.declarationKinds = {};
//
var add = function (node, reference, throwOnDuplicate) {
self._add(node, references);
var info = block._scopeInfo;
if (info) {
extend(this, info);
return;
}
if (!reference) {
self._add(node, declarations, throwOnDuplicate);
self._add(node, declarationKinds[node.kind] = declarationKinds[node.kind] || object());
}
info = block._scopeInfo = {
declarationKinds: {
"const": object(),
"var": object(),
"let": object()
},
references: object(),
bindings: object(),
types: object(),
};
if (parent && t.isBlockStatement(block) && t.isFor(parent.block)) {
return info;
extend(this, info);
//
if (parent && t.isBlockStatement(block) && t.isLoop(parent.block, { body: block })) {
// delegate let bindings to the parent loop
return;
}
// ForStatement - left, init
if (t.isFor(block)) {
_.each(FOR_KEYS, function (key) {
var node = block[key];
if (t.isBlockScoped(node)) add(node, false, true);
});
if (t.isLoop(block)) {
for (i = 0; i < t.FOR_INIT_KEYS.length; i++) {
var node = block[t.FOR_INIT_KEYS[i]];
if (t.isBlockScoped(node)) this.register(node, false, true);
}
if (t.isBlockStatement(block.body)) {
block = block.body;
@@ -217,19 +296,27 @@ Scope.prototype.getInfo = function () {
// Program, BlockStatement - let variables
if (t.isBlockStatement(block) || t.isProgram(block)) {
traverse(block, blockVariableVisitor, this, add);
traverse(block, blockVariableVisitor, this, this);
}
// CatchClause - param
if (t.isCatchClause(block)) {
add(block.param);
this.register(block.param);
}
// ComprehensionExpression - blocks
if (t.isComprehensionExpression(block)) {
add(block);
this.register(block);
}
// Function - params, rest
if (t.isFunction(block)) {
for (i = 0; i < block.params.length; i++) {
this.register(block.params[i]);
}
}
// Program, Function - var variables
@@ -237,25 +324,23 @@ Scope.prototype.getInfo = function () {
if (t.isProgram(block) || t.isFunction(block)) {
traverse(block, functionVariableVisitor, this, {
blockId: block.id,
add: add
scope: this
});
}
if (t.isFunctionExpression(block) && block.id) {
if (!t.isProperty(this.parentBlock, { method: true })) {
// SpiderMonkey AST doesn't use MethodDefinition here when it probably
// should since they should be semantically the same?
this.register(block.id);
}
}
// Program
if (t.isProgram(block)) {
traverse(block, programReferenceVisitor, this, add);
traverse(block, programReferenceVisitor, this, this);
}
// Function - params, rest
if (t.isFunction(block)) {
_.each(block.params, function (param) {
add(param);
});
}
return info;
};
/**
@@ -288,12 +373,20 @@ Scope.prototype.push = function (opts) {
* Walk up the scope tree until we hit a `Function` and then
* push our `node` to it's references.
*
* @param {String} kind
* @param {Object} node
*/
Scope.prototype.add = function (node) {
Scope.prototype.addDeclarationToFunctionScope = function (kind, node) {
var scope = this.getFunctionParent();
scope._add(node, scope.references);
var ids = t.getBindingIdentifiers(node);
extend(scope.bindings, ids);
extend(scope.references, ids);
// this ignores the duplicate declaration logic specified in `getInfo`
// but it doesn't really matter
extend(scope.declarationKinds[kind], ids);
};
/**
@@ -310,17 +403,17 @@ Scope.prototype.getFunctionParent = function () {
};
/**
* Walks the scope tree and gathers all declarations of `kind`.
* Walks the scope tree and gathers **all** bindings.
*
* @returns {Object}
*/
Scope.prototype.getAllOfKind = function (kind) {
Scope.prototype.getAllBindings = function () {
var ids = object();
var scope = this;
do {
_.defaults(ids, scope.declarationKinds[kind]);
defaults(ids, scope.bindings);
scope = scope.parent;
} while (scope);
@@ -328,73 +421,74 @@ Scope.prototype.getAllOfKind = function (kind) {
};
/**
* Description
* Walks the scope tree and gathers all declarations of `kind`.
*
* @param {String} [id]
* @param {Boolean} [decl]
* @param {String} kind
* @returns {Object}
*/
Scope.prototype.get = function (id, decl) {
return id && (this.getOwn(id, decl) || this.parentGet(id, decl));
Scope.prototype.getAllDeclarationsOfKind = function (kind) {
var ids = object();
var scope = this;
do {
defaults(ids, scope.declarationKinds[kind]);
scope = scope.parent;
} while (scope);
return ids;
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
*/
//
Scope.prototype.getOwn = function (id, decl) {
var refs = this.references;
if (decl) refs = this.declarations;
return _.has(refs, id) && refs[id];
Scope.prototype.get = function (id, type) {
return id && (this.getOwn(id, type) || this.parentGet(id, type));
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
*/
Scope.prototype.parentGet = function (id, decl) {
return this.parent && this.parent.get(id, decl);
Scope.prototype.getOwn = function (id, type) {
var refs = {
reference: this.references,
binding: this.bindings,
type: this.types
}[type];
return refs && has(refs, id) && refs[id];
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
* @returns {Boolean}
*/
Scope.prototype.has = function (id, decl) {
return (id && (this.hasOwn(id, decl) || this.parentHas(id, decl))) ||
_.contains(Scope.defaultDeclarations, id);
Scope.prototype.parentGet = function (id, type) {
return this.parent && this.parent.get(id, type);
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
* @returns {Boolean}
*/
Scope.prototype.hasOwn = function (id, decl) {
return !!this.getOwn(id, decl);
Scope.prototype.has = function (id, type) {
if (!id) return false;
if (this.hasOwn(id, type)) return true;
if (this.parentHas(id, type)) return true;
if (contains(Scope.defaultDeclarations, id)) return true;
return false;
};
/**
* Description
*
* @param {String} [id]
* @param {Boolean} [decl]
* @returns {Boolean}
*/
Scope.prototype.parentHas = function (id, decl) {
return this.parent && this.parent.has(id, decl);
Scope.prototype.hasOwn = function (id, type) {
return !!this.getOwn(id, type);
};
Scope.prototype.parentHas = function (id, type) {
return this.parent && this.parent.has(id, type);
};
each({
reference: "Reference",
binding: "Binding",
type: "Type"
}, function (title, type) {
each([
"get",
"has",
"getOwn",
"hasOwn",
"parentGet",
"parentHas",
], function (methodName) {
Scope.prototype[methodName + title] = function (id) {
return this[methodName](id, type);
};
});
});

View File

@@ -3,13 +3,13 @@
"BreakStatement": ["Statement"],
"ContinueStatement": ["Statement"],
"DebuggerStatement": ["Statement"],
"DoWhileStatement": ["Statement", "Loop", "While"],
"DoWhileStatement": ["Statement", "Loop", "While", "Scope"],
"IfStatement": ["Statement"],
"ReturnStatement": ["Statement"],
"SwitchStatement": ["Statement"],
"ThrowStatement": ["Statement"],
"TryStatement": ["Statement"],
"WhileStatement": ["Statement", "Loop", "While"],
"WhileStatement": ["Statement", "Loop", "While", "Scope"],
"WithStatement": ["Statement"],
"EmptyStatement": ["Statement"],
"LabeledStatement": ["Statement"],

View File

@@ -2,15 +2,16 @@
var toFastProperties = require("../helpers/to-fast-properties");
var esutils = require("esutils");
var object = require("../helpers/object");
var Node = require("./node");
var _ = require("lodash");
var each = require("lodash/collection/each");
var uniq = require("lodash/array/uniq");
var compact = require("lodash/array/compact");
var defaults = require("lodash/object/defaults");
var isString = require("lodash/lang/isString");
var t = exports;
t.NATIVE_TYPE_NAMES = ["Array", "Object", "Number", "Boolean", "Date", "Array", "String"];
//
/**
* Registers `is[Type]` and `assert[Type]` generated functions for a given `type`.
* Pass `skipAliasCheck` to force it to directly compare `node.type` with `type`.
@@ -33,33 +34,33 @@ function registerType(type, skipAliasCheck) {
}
t.STATEMENT_OR_BLOCK_KEYS = ["consequent", "body"];
//
t.NATIVE_TYPE_NAMES = ["Array", "Object", "Number", "Boolean", "Date", "Array", "String"];
t.FOR_INIT_KEYS = ["left", "init"];
t.VISITOR_KEYS = require("./visitor-keys");
t.ALIAS_KEYS = require("./alias-keys");
t.ALIAS_KEYS = require("./alias-keys");
t.FLIPPED_ALIAS_KEYS = {};
_.each(t.VISITOR_KEYS, function (keys, type) {
each(t.VISITOR_KEYS, function (keys, type) {
registerType(type, true);
});
_.each(t.ALIAS_KEYS, function (aliases, type) {
_.each(aliases, function (alias) {
each(t.ALIAS_KEYS, function (aliases, type) {
each(aliases, function (alias) {
var types = t.FLIPPED_ALIAS_KEYS[alias] = t.FLIPPED_ALIAS_KEYS[alias] || [];
types.push(type);
});
});
_.each(t.FLIPPED_ALIAS_KEYS, function (types, type) {
each(t.FLIPPED_ALIAS_KEYS, function (types, type) {
t[type.toUpperCase() + "_TYPES"] = types;
registerType(type, false);
});
/**
* Returns whether `node` is of given `type`.
*
* For better performance, use this instead of `is[Type]` when `type` is unknown.
* Optionally, pass `skipAliasCheck` to directly compare `node.type` with `type`.
*
@@ -96,15 +97,15 @@ t.is = function (type, node, opts, skipAliasCheck) {
//
t.BUILDER_KEYS = _.defaults(require("./builder-keys"), t.VISITOR_KEYS);
t.BUILDER_KEYS = defaults(require("./builder-keys"), t.VISITOR_KEYS);
_.each(t.BUILDER_KEYS, function (keys, type) {
each(t.BUILDER_KEYS, function (keys, type) {
t[type[0].toLowerCase() + type.slice(1)] = function () {
var args = arguments;
var node = new Node;
node.start = null;
node.type = type;
_.each(keys, function (key, i) {
each(keys, function (key, i) {
node[key] = args[i];
});
return node;
@@ -150,18 +151,21 @@ t.isFalsyExpression = function (node) {
* declarations hoisted to the top of the current scope.
*
* Expression statements are just resolved to their standard expression.
*
* @param {Array} nodes
* @param {Scope} scope
*/
t.toSequenceExpression = function (nodes, scope) {
var exprs = [];
_.each(nodes, function (node) {
each(nodes, function (node) {
if (t.isExpression(node)) {
exprs.push(node);
} if (t.isExpressionStatement(node)) {
exprs.push(node.expression);
} else if (t.isVariableDeclaration(node)) {
_.each(node.declarations, function (declar) {
each(node.declarations, function (declar) {
scope.push({
kind: node.kind,
key: declar.id.name,
@@ -179,17 +183,23 @@ t.toSequenceExpression = function (nodes, scope) {
}
};
//
/*
* Description
*
* @param {Object} actual
* @param {Object} expected
* @returns {Boolean}
*/
t.shallowEqual = function (actual, expected) {
var keys = Object.keys(expected);
var key;
for (var i = 0; i < keys.length; i++) {
key = keys[i];
var key = keys[i];
if (actual[key] !== expected[key])
if (actual[key] !== expected[key]) {
return false;
}
}
return true;
@@ -225,7 +235,7 @@ t.prependToMemberExpression = function (member, append) {
};
/**
* Description
* Check if the input `node` is a reference to a bound variable.
*
* @param {Object} node
* @param {Object} parent
@@ -233,49 +243,99 @@ t.prependToMemberExpression = function (member, append) {
*/
t.isReferenced = function (node, parent) {
// we're a property key and we aren't computed so we aren't referenced
if (t.isProperty(parent) && parent.key === node && !parent.computed) return false;
if (t.isFunction(parent)) {
// we're a function param
if (_.contains(parent.params, node)) return false;
for (var i = 0; i < parent.params.length; i++) {
var param = parent.params[i];
if (param === node) {
return false;
} else if (t.isRestElement(param) && param.argument === node) {
return false;
}
// yes: PARENT[NODE]
// yes: NODE.child
// no: parent.CHILD
if (t.isMemberExpression(parent)) {
if (parent.property === node && parent.computed) {
return true;
} else if (parent.object === node) {
return true;
} else {
return false;
}
}
if (t.isMethodDefinition(parent) && parent.key === node && !parent.computed) {
// yes: { [NODE]: "" }
// no: { NODE: "" }
if (t.isProperty(parent) && parent.key === node) {
return parent.computed;
}
// no: var NODE = init;
// yes: var id = NODE;
if (t.isVariableDeclarator(parent)) {
return parent.id !== node;
}
// no: function NODE() {}
// no: function foo(NODE) {}
if (t.isFunction(parent)) {
for (var i = 0; i < parent.params.length; i++) {
var param = parent.params[i];
if (param === node) return false;
}
return parent.id !== node;
}
// no: class NODE {}
if (t.isClass(parent)) {
return parent.id !== node;
}
// yes: class { [NODE](){} }
if (t.isMethodDefinition(parent)) {
return parent.key === node && parent.computed;
}
// no: NODE: for (;;) {}
if (t.isLabeledStatement(parent)) {
return false;
}
// we're a catch clause param
if (t.isCatchClause(parent) && parent.param === node) return false;
// no: try {} catch (NODE) {}
if (t.isCatchClause(parent)) {
return parent.param !== node;
}
// we're a variable declarator id so we aren't referenced
if (t.isVariableDeclarator(parent) && parent.id === node) return false;
// no: function foo(...NODE) {}
if (t.isRestElement(parent)) {
return false;
}
var isMemberExpression = t.isMemberExpression(parent);
// no: [NODE = foo] = [];
// yes: [foo = NODE] = [];
if (t.isAssignmentPattern(parent)) {
return parent.right !== node;
}
// we're in a member expression and we're the computed property so we're referenced
var isComputedProperty = isMemberExpression && parent.property === node && parent.computed;
// no: [NODE] = [];
// no: ({ NODE }) = [];
if (t.isPattern(parent)) {
return false;
}
// we're in a member expression and we're the object so we're referenced
var isObject = isMemberExpression && parent.object === node;
// no: import NODE from "bar";
if (t.isImportSpecifier(parent)) {
return false;
}
// we are referenced
if (!isMemberExpression || isComputedProperty || isObject) return true;
// no: import * as NODE from "foo";
if (t.isImportBatchSpecifier(parent)) {
return false;
}
return false;
// no: class Foo { private NODE; }
if (t.isPrivateDeclaration(parent)) {
return false;
}
return true;
};
/**
* Description
* Check if the input `node` is an `Identifier` and `isReferenced`.
*
* @param {Object} node
* @param {Object} parent
@@ -287,14 +347,15 @@ t.isReferencedIdentifier = function (node, parent) {
};
/**
* Description
* Check if the input `name` is a valid identifier name
* and isn't a reserved word.
*
* @param {String} name
* @returns {Boolean}
*/
t.isValidIdentifier = function (name) {
return _.isString(name) && esutils.keyword.isIdentifierName(name) && !esutils.keyword.isReservedWordES6(name, true);
return isString(name) && esutils.keyword.isIdentifierName(name) && !esutils.keyword.isReservedWordES6(name, true);
};
/*
@@ -316,13 +377,10 @@ t.toIdentifier = function (name) {
name = name.replace(/^[-0-9]+/, "");
// camel case
name = name.replace(/[-_\s]+(.)?/g, function (match, c) {
name = name.replace(/[-\s]+(.)?/g, function (match, c) {
return c ? c.toUpperCase() : "";
});
// remove underscores from start of name
name = name.replace(/^\_/, "");
if (!t.isValidIdentifier(name)) {
name = "_" + name;
}
@@ -342,6 +400,65 @@ t.ensureBlock = function (node, key) {
node[key] = t.toBlock(node[key], node);
};
/**
* Build a function that when called will return whether or not the
* input `node` `MemberExpression` matches the input `match`.
*
* For example, given the match `React.createClass` it would match the
* parsed nodes of `React.createClass` and `React["createClass"]`.
*
* @param {String} match Dot delimetered string
* @param {Boolean} [allowPartial] Allow a partial match
* @returns {Function}
*/
t.buildMatchMemberExpression = function (match, allowPartial) {
var parts = match.split(".");
return function (member) {
// not a member expression
if (!t.isMemberExpression(member)) return false;
var search = [member];
var i = 0;
while (search.length) {
var node = search.shift();
if (t.isIdentifier(node)) {
// this part doesn't match
if (parts[i] !== node.name) return false;
} else if (t.isLiteral(node)) {
// this part doesn't match
if (parts[i] !== node.value) return false;
} else if (t.isMemberExpression(node)) {
if (node.computed && !t.isLiteral(node.property)) {
// we can't deal with this
return false;
} else {
search.push(node.object);
search.push(node.property);
continue;
}
} else {
// we can't deal with this
return false;
}
// too many parts
if (++i > parts.length) {
if (allowPartial) {
return true;
} else {
return false;
}
}
}
return true;
};
};
/**
* Description
*
@@ -443,53 +560,41 @@ t.toBlock = function (node, parent) {
};
/**
* Description
* Return a list of binding identifiers associated with
* the input `node`.
*
* @param {Object} node
* @param {Boolean} [map]
* @param {Array} [ignoreTypes]
* @returns {Array|Object}
*/
t.getIds = function (node, map, ignoreTypes) {
ignoreTypes = ignoreTypes || [];
t.getBindingIdentifiers = function (node) {
var search = [].concat(node);
var ids = {};
var ids = object();
while (search.length) {
var id = search.shift();
if (!id) continue;
if (_.contains(ignoreTypes, id.type)) continue;
var nodeKeys = t.getIds.nodes[id.type];
var arrKeys = t.getIds.arrays[id.type];
var i, key;
var keys = t.getBindingIdentifiers.keys[id.type];
if (t.isIdentifier(id)) {
ids[id.name] = id;
} else if (nodeKeys) {
for (i = 0; i < nodeKeys.length; i++) {
key = nodeKeys[i];
if (id[key]) {
search.push(id[key]);
break;
}
} else if (t.isExportDeclaration(id)) {
if (t.isDeclaration(node.declaration)) {
search.push(node.declaration);
}
} else if (arrKeys) {
for (i = 0; i < arrKeys.length; i++) {
key = arrKeys[i];
} else if (keys) {
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
search = search.concat(id[key] || []);
}
}
}
if (!map) ids = _.keys(ids);
return ids;
};
t.getIds.nodes = {
t.getBindingIdentifiers.keys = {
AssignmentExpression: ["left"],
ImportBatchSpecifier: ["name"],
ImportSpecifier: ["name", "id"],
@@ -500,15 +605,12 @@ t.getIds.nodes = {
MemeberExpression: ["object"],
SpreadElement: ["argument"],
RestElement: ["argument"],
UpdateExpression: ["argument"],
Property: ["value"],
ComprehensionBlock: ["left"],
AssignmentPattern: ["left"]
};
t.getIds.arrays = {
AssignmentPattern: ["left"],
PrivateDeclaration: ["declarations"],
ComprehensionExpression: ["blocks"],
ExportDeclaration: ["specifiers", "declaration"],
ImportDeclaration: ["specifiers"],
VariableDeclaration: ["declarations"],
ArrayPattern: ["elements"],
@@ -534,7 +636,7 @@ t.isLet = function (node) {
*/
t.isBlockScoped = function (node) {
return t.isFunctionDeclaration(node) || t.isLet(node);
return t.isFunctionDeclaration(node) || t.isClassDeclaration(node) || t.isLet(node);
};
/**
@@ -560,7 +662,7 @@ t.COMMENT_KEYS = ["leadingComments", "trailingComments"];
*/
t.removeComments = function (child) {
_.each(t.COMMENT_KEYS, function (key) {
each(t.COMMENT_KEYS, function (key) {
delete child[key];
});
return child;
@@ -575,8 +677,8 @@ t.removeComments = function (child) {
*/
t.inheritsComments = function (child, parent) {
_.each(t.COMMENT_KEYS, function (key) {
child[key] = _.uniq(_.compact([].concat(child[key], parent[key])));
each(t.COMMENT_KEYS, function (key) {
child[key] = uniq(compact([].concat(child[key], parent[key])));
});
return child;
};

View File

@@ -5,25 +5,35 @@ require("./patch");
var estraverse = require("estraverse");
var codeFrame = require("./helpers/code-frame");
var traverse = require("./traverse");
var debug = require("debug/node");
var acorn = require("acorn-6to5");
var path = require("path");
var util = require("util");
var fs = require("fs");
var t = require("./types");
var _ = require("lodash");
var each = require("lodash/collection/each");
var isNumber = require("lodash/lang/isNumber");
var isString = require("lodash/lang/isString");
var isRegExp = require("lodash/lang/isRegExp");
var isEmpty = require("lodash/lang/isEmpty");
var cloneDeep = require("lodash/lang/cloneDeep");
var has = require("lodash/object/has");
var contains = require("lodash/collection/contains");
exports.inherits = util.inherits;
exports.debug = debug("6to5");
exports.canCompile = function (filename, altExts) {
var exts = altExts || exports.canCompile.EXTENSIONS;
var ext = path.extname(filename);
return _.contains(exts, ext);
return contains(exts, ext);
};
exports.canCompile.EXTENSIONS = [".js", ".jsx", ".es6", ".es"];
exports.isInteger = function (i) {
return _.isNumber(i) && i % 1 === 0;
return isNumber(i) && i % 1 === 0;
};
exports.resolve = function (loc) {
@@ -45,14 +55,14 @@ exports.list = function (val) {
exports.regexify = function (val) {
if (!val) return new RegExp(/.^/);
if (Array.isArray(val)) val = val.join("|");
if (_.isString(val)) return new RegExp(val);
if (_.isRegExp(val)) return val;
if (isString(val)) return new RegExp(val);
if (isRegExp(val)) return val;
throw new TypeError("illegal type for regexify");
};
exports.arrayify = function (val) {
if (!val) return [];
if (_.isString(val)) return exports.list(val);
if (isString(val)) return exports.list(val);
if (Array.isArray(val)) return val;
throw new TypeError("illegal type for arrayify");
};
@@ -70,71 +80,9 @@ exports.sourceMapToComment = function (map) {
return "//# sourceMappingURL=data:application/json;base64," + base64;
};
exports.pushMutatorMap = function (mutatorMap, key, kind, computed, method) {
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] = method;
};
exports.buildDefineProperties = 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);
}
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;
};
var templateVisitor = {
enter: function (node, parent, scope, context, nodes) {
if (t.isIdentifier(node) && _.has(nodes, node.name)) {
if (t.isIdentifier(node) && has(nodes, node.name)) {
return nodes[node.name];
}
}
@@ -149,9 +97,9 @@ exports.template = function (name, nodes, keepExpression) {
nodes = null;
}
template = _.cloneDeep(template);
template = cloneDeep(template);
if (!_.isEmpty(nodes)) {
if (!isEmpty(nodes)) {
traverse(template, templateVisitor, null, nodes);
}
@@ -175,7 +123,7 @@ exports.repeat = function (width, cha) {
return result;
};
exports.normaliseAst = function (ast, comments, tokens) {
exports.normalizeAst = function (ast, comments, tokens) {
if (ast && ast.type === "Program") {
return t.file(ast, comments || [], tokens || []);
} else {
@@ -193,7 +141,7 @@ exports.parse = function (opts, code, callback) {
allowReturnOutsideFunction: true,
ecmaVersion: opts.experimental ? 7 : 6,
playground: opts.playground,
strictMode: true,
strictMode: opts.strictMode,
onComment: comments,
locations: true,
onToken: tokens,
@@ -202,7 +150,7 @@ exports.parse = function (opts, code, callback) {
estraverse.attachComments(ast, comments, tokens);
ast = exports.normaliseAst(ast, comments, tokens);
ast = exports.normalizeAst(ast, comments, tokens);
if (callback) {
return callback(ast);
@@ -243,7 +191,7 @@ var loadTemplates = function () {
"https://github.com/6to5/6to5/issues");
}
_.each(fs.readdirSync(templatesLoc), function (name) {
each(fs.readdirSync(templatesLoc), function (name) {
if (name[0] === ".") return;
var key = path.basename(name, path.extname(name));

View File

@@ -1,7 +1,7 @@
{
"name": "6to5",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "3.0.1",
"version": "3.3.7",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://6to5.org/",
"repository": "6to5/6to5",
@@ -9,7 +9,8 @@
"main": "lib/6to5/index.js",
"bin": {
"6to5": "./bin/6to5/index.js",
"6to5-node": "./bin/6to5-node"
"6to5-node": "./bin/6to5-node",
"6to5-runtime": "./bin/6to5-runtime"
},
"browser": {
"./lib/6to5/index.js": "./lib/6to5/browser.js",
@@ -37,28 +38,31 @@
"chalk": "^0.5.1",
"chokidar": "0.12.6",
"commander": "2.6.0",
"core-js": "0.4.6",
"detect-indent": "^3.0.0",
"core-js": "^0.4.9",
"debug": "^2.1.1",
"detect-indent": "3.0.0",
"estraverse": "1.9.1",
"esutils": "1.1.6",
"esvalid": "1.1.0",
"fs-readdir-recursive": "0.1.0",
"js-tokenizer": "^1.3.3",
"globals": "^5.1.0",
"js-tokenizer": "1.3.3",
"lodash": "3.0.0",
"output-file-sync": "^1.1.0",
"output-file-sync": "1.1.0",
"private": "0.1.6",
"regenerator-6to5": "0.8.9-6",
"regenerator-6to5": "0.8.9-8",
"regexpu": "1.1.0",
"roadrunner": "1.0.4",
"source-map": "0.1.43",
"source-map-support": "0.2.9",
"supports-color": "^1.2.0"
"supports-color": "1.2.0",
"useragent": "^2.1.5"
},
"devDependencies": {
"browserify": "8.1.1",
"chai": "1.10.0",
"esvalid": "1.1.0",
"istanbul": "0.3.5",
"jscs": "^1.10.0",
"jscs": "1.10.0",
"jshint": "2.6.0",
"jshint-stylish": "1.0.0",
"matcha": "0.6.0",

View File

@@ -1,6 +1,7 @@
{
"name": "6to5-runtime",
"description": "6to5 selfContained runtime",
"version": "3.0.0",
"version": "3.3.5",
"repository": "6to5/6to5",
"author": "Sebastian McKenzie <sebmck@gmail.com>"
}

View File

@@ -1,11 +1,10 @@
"use strict";
var transform = require("../lib/6to5/transformation/transform");
var File = require("../lib/6to5/file");
var util = require("../lib/6to5/util");
var fs = require("fs");
var t = require("../lib/6to5/types");
var _ = require("lodash");
var buildHelpers = require("../lib/6to5/build-helpers");
var transform = require("../lib/6to5/transformation");
var fs = require("fs");
var t = require("../lib/6to5/types");
var _ = require("lodash");
var relative = function (filename) {
return __dirname + "/6to5-runtime/" + filename;
@@ -31,24 +30,25 @@ var updatePackage = function () {
writeFile("package.json", JSON.stringify(pkg, null, 2));
};
var buildHelpers = function () {
var selfContainify = function (code) {
return transform(code, {
optional: ["selfContained"]
}).code;
};
var buildHelpers2 = function () {
var body = [];
var tree = t.program(body);
_.each(File.helpers, function (name) {
var key = t.identifier(t.toIdentifier(name));
body.push(t.expressionStatement(
t.assignmentExpression("=", t.memberExpression(t.identifier("exports"), key), util.template(name))
));
});
buildHelpers(body, t.identifier("exports"));
return transform.fromAst(tree, null, {
optional: ["selfContained"]
}).code;
};
writeFile("helpers.js", buildHelpers());
writeFile("helpers.js", buildHelpers2());
writeFile("core-js.js", readFile("core-js/library"));
writeFile("regenerator/index.js", readFile("regenerator-6to5/runtime-module"));
writeFile("regenerator/runtime.js", readFile("regenerator-6to5/runtime"));
writeFile("regenerator/runtime.js", selfContainify(readFile("regenerator-6to5/runtime")));
updatePackage();

View File

@@ -1,8 +1,9 @@
var util = require("../lib/6to5/util");
var path = require("path");
var fs = require("fs");
var _ = require("lodash");
var humanise = function (val, noext) {
var humanize = function (val, noext) {
if (noext) val = path.basename(val, path.extname(val));
return val.replace(/-/g, " ");
};
@@ -17,6 +18,13 @@ var readFile = exports.readFile = function (filename) {
}
};
exports.assertVendor = function (name) {
if (!fs.existsSync(__dirname + "/../vendor/" + name)) {
console.error("No vendor/" + name + " - run `make bootstrap`");
process.exit(1);
}
};
exports.get = function (entryName, entryLoc) {
if (exports.cache[entryName]) return exports.cache[entryName];
@@ -29,13 +37,13 @@ exports.get = function (entryName, entryLoc) {
var suite = {
options: {},
tests: [],
title: humanise(suiteName),
title: humanize(suiteName),
filename: entryLoc + "/" + suiteName
};
suites.push(suite);
var suiteOptsLoc = suite.filename + "/options.json";
if (fs.existsSync(suiteOptsLoc)) suite.options = require(suiteOptsLoc);
var suiteOptsLoc = util.resolve(suite.filename + "/options");
if (suiteOptsLoc) suite.options = require(suiteOptsLoc);
if (fs.statSync(suite.filename).isFile()) {
push(suiteName, suite.filename);
@@ -71,11 +79,11 @@ exports.get = function (entryName, entryLoc) {
sourceMapName: expectLocAlias
}, _.cloneDeep(suite.options));
var taskOptsLoc = taskDir + "/options.json";
if (fs.existsSync(taskOptsLoc)) _.merge(taskOpts, require(taskOptsLoc));
var taskOptsLoc = util.resolve(taskDir + "/options");
if (taskOptsLoc) _.merge(taskOpts, require(taskOptsLoc));
var test = {
title: humanise(taskName, true),
title: humanize(taskName, true),
disabled: taskName[0] === ".",
options: taskOpts,
exec: {

View File

@@ -1,6 +1,7 @@
var genHelpers = require("./_generator-helpers");
var transform = require("../lib/6to5/transformation/transform");
var transform = require("../lib/6to5/transformation");
var sourceMap = require("source-map");
var codeFrame = require("../lib/6to5/helpers/code-frame");
var esvalid = require("esvalid");
var Module = require("module");
var helper = require("./_helper");
@@ -85,7 +86,7 @@ var run = function (task, done) {
fn.call(global, fakeRequire, chai.assert, done);
} catch (err) {
err.message = exec.loc + ": " + err.message;
err.message += util.codeFrame(execCode);
err.message += codeFrame(execCode);
throw err;
}
}
@@ -113,10 +114,10 @@ var run = function (task, done) {
var consumer = new sourceMap.SourceMapConsumer(result.map);
_.each(task.sourceMappings, function (mapping, i) {
var expect = mapping.original;
var actual = mapping.original;
var actual = consumer.originalPositionFor(mapping.generated);
chai.expect({ line: actual.line, column: actual.column }).to.deep.equal(expect);
var expect = consumer.originalPositionFor(mapping.generated);
chai.expect({ line: expect.line, column: expect.column }).to.deep.equal(actual);
});
}
};
@@ -124,12 +125,14 @@ var run = function (task, done) {
module.exports = function (suiteOpts, taskOpts, dynamicOpts) {
taskOpts = taskOpts || {};
require("../register")(taskOpts);
_.each(helper.get(suiteOpts.name, suiteOpts.loc), function (testSuite) {
if (_.contains(suiteOpts.ignoreSuites, testSuite.title)) return;
suite(suiteOpts.name + "/" + testSuite.title, function () {
setup(function () {
require("../register")(taskOpts);
});
_.each(testSuite.tests, function (task) {
if (_.contains(suiteOpts.ignoreTasks, task.title) || _.contains(suiteOpts.ignoreTasks, testSuite.title + "/" + task.title)) return;

View File

@@ -1,4 +1,4 @@
var transform = require("../lib/6to5/transformation/transform");
var transform = require("../lib/6to5/transformation");
var assert = require("assert");
var File = require("../lib/6to5/file");

140
test/detection.js Normal file
View File

@@ -0,0 +1,140 @@
var detect = require("../lib/6to5/detection");
var assert = require("assert");
var util = require("../lib/6to5/util");
suite("detection", function () {
var checkSyntax = function (code, name) {
var ast = util.parse({
experimental: true
}, code);
assert.ok(detect(ast).syntax[name]);
};
test("es5.properties.mutators", function () {
checkSyntax("var obj = { get foo() {} };", "es5.properties.mutators");
checkSyntax("var obj = { set foo() {} };", "es5.properties.mutators");
});
test("es6.exponentation", function () {
checkSyntax("x ** 2;", "es6.exponentation");
checkSyntax("x **= 2;", "es6.exponentation");
});
test("es6.blockScoping", function () {
checkSyntax("let foo;", "es6.blockScoping");
checkSyntax("let foo = bar;", "es6.blockScoping");
checkSyntax("const foo = bar;", "es6.blockScoping");
});
test("es6.constants", function () {
checkSyntax("const foo = bar;", "es6.constants");
});
test("es6.properties.shorthand", function () {
checkSyntax("var obj = { foo };", "es6.properties.shorthand");
checkSyntax("var obj = { foo };", "es6.properties.shorthand");
});
test("es6.properties.computed", function () {
checkSyntax("var obj = { [foo]: bar };", "es6.properties.computed");
checkSyntax("var obj = { ['foo']: bar };", "es6.properties.computed");
});
test("es6.parameters.default", function () {
checkSyntax("var obj = (foo = bar) => {};", "es6.parameters.default");
checkSyntax("var obj = function (foo = bar) {};", "es6.parameters.default");
checkSyntax("function foo(foo = bar) {}", "es6.parameters.default");
});
test("es6.arrowFunctions", function () {
checkSyntax("var foo = x => x;", "es6.arrowFunctions");
checkSyntax("var foo = x => { return x * x };", "es6.arrowFunctions");
checkSyntax("var foo = (x) => x;", "es6.arrowFunctions");
checkSyntax("var foo = (a, b) => { return a * b };", "es6.arrowFunctions");
});
test("es6.classes", function () {
checkSyntax("class Foo {}", "es6.classes");
checkSyntax("var Foo = class {};", "es6.classes");
});
test("es6.forOf", function () {
checkSyntax("for (var val of foo);", "es6.forOf");
checkSyntax("for (val of foo);", "es6.forOf");
});
test("es6.modules", function () {
checkSyntax("import 'foo';", "es6.modules");
checkSyntax("import foo from 'foo';", "es6.modules");
checkSyntax("import * as foo from 'foo';", "es6.modules");
checkSyntax("import { foo } from 'foo';", "es6.modules");
checkSyntax("export { foo } from 'foo';", "es6.modules");
checkSyntax("export var foo = 5;", "es6.modules");
checkSyntax("export class Foo {}", "es6.modules");
checkSyntax("export function foo() {}", "es6.modules");
checkSyntax("export default class Foo {}", "es6.modules");
checkSyntax("export default function foo() {}", "es6.modules");
});
test("es6.destructuring", function () {
checkSyntax("[a, b] = [];", "es6.destructuring");
checkSyntax("var [a, b] = [];", "es6.destructuring");
checkSyntax("({ a, b }) = {};", "es6.destructuring");
checkSyntax("var { a, b } = {};", "es6.destructuring");
checkSyntax("function foo(foo = bar) {}", "es6.destructuring");
});
test("es6.parameters.rest", function () {
checkSyntax("function foo(...items) {}", "es6.parameters.rest");
checkSyntax("var foo = (...items) => {}", "es6.parameters.rest");
});
test("es6.spread", function () {
checkSyntax("new Foo(...items);", "es6.spread");
checkSyntax("foo(...items);", "es6.spread");
checkSyntax("[...items];", "es6.spread");
});
test("es6.templateLiterals", function () {
checkSyntax("`foobar`;", "es6.templateLiterals");
checkSyntax("foobar`foobar`;", "es6.templateLiterals");
});
test("es6.generators", function () {
checkSyntax("function* foo() {}", "es6.generators");
checkSyntax("var foo = function* () {};", "es6.generators");
});
test("es7.asyncFunctions", function () {
checkSyntax("async function foo() {}", "es7.asyncFunctions");
checkSyntax("var foo = async function() {};", "es7.asyncFunctions");
checkSyntax("var foo = async () => {};", "es7.asyncFunctions");
});
test("es7.comprehensions", function () {
checkSyntax("[for (i of test) i]", "es7.comprehensions");
checkSyntax("(for (i of test) i)", "es7.comprehensions");
});
test("es7.objectSpread", function () {
checkSyntax("var foo = { ...bar };", "es7.objectSpread");
});
test("es7.abstractReferences", function () {
checkSyntax("class Foo { private A; }", "es7.abstractReferences");
checkSyntax("foo::bar();", "es7.abstractReferences");
checkSyntax("delete foo::bar;", "es7.abstractReferences");
checkSyntax("foo::bar;", "es7.abstractReferences");
checkSyntax("foo::bar = baz;", "es7.abstractReferences");
});
test("flow", function () {
});
test("jsx", function () {
checkSyntax("<div />", "jsx");
checkSyntax("<Element />", "jsx");
});
});

View File

@@ -1,4 +1,8 @@
"use strict";
var Test = function Test() {};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9iYXIvYmFyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0lBQU0sSUFBSSxZQUFKLElBQUkiLCJmaWxlIjoic3JjL2Jhci9iYXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJjbGFzcyBUZXN0IHtcblxufSJdfQ==
var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
var Test = function Test() {
_classCallCheck(this, Test);
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9iYXIvYmFyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7SUFBTSxnQkFBQTt3QkFBQSIsImZpbGUiOiJzcmMvYmFyL2Jhci5qcyIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIFRlc3Qge1xuXG59Il19

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