Compare commits

..

455 Commits

Author SHA1 Message Date
Sebastian McKenzie
751ea7a12c v1.12.7 2014-11-13 13:19:45 +11:00
Sebastian McKenzie
b30cd227cc update acorn-6to5 - fixes #153 2014-11-13 13:18:59 +11:00
Sebastian McKenzie
18dc7b8143 v1.12.6 2014-11-13 12:55:39 +11:00
Sebastian McKenzie
1c628bbec1 disable generation/comments/comment-only test 2014-11-13 12:53:38 +11:00
Sebastian McKenzie
d4c3dde02a update to latest acorn-6to5 2014-11-13 12:49:29 +11:00
Sebastian McKenzie
a587106a6b v1.12.5 2014-11-13 12:26:16 +11:00
Sebastian McKenzie
9c1b60e451 fix excessive whitespace trimming resulting in innaccurate sourcemap line - fixes #151 2014-11-13 12:25:11 +11:00
Sebastian McKenzie
0c7e0b65b9 add browser support, array comprehension, async functions and generator comprehension to differences table 2014-11-13 03:24:45 +11:00
Sebastian McKenzie
5c17091db4 replace documentation link 2014-11-13 01:17:14 +11:00
Sebastian McKenzie
7fa5ba88df v1.12.4 2014-11-13 01:16:45 +11:00
Sebastian McKenzie
2fae245cd5 add 1.12.4 changelog 2014-11-13 01:15:41 +11:00
Sebastian McKenzie
297f103ddb move docs to folder 2014-11-13 01:13:48 +11:00
Sebastian McKenzie
fd63650d6a add .hound.yml 2014-11-12 19:25:35 +11:00
Sebastian McKenzie
e13ed39567 v1.12.3 2014-11-12 18:43:39 +11:00
Sebastian McKenzie
bb00f641b7 remove unused variables in spread transformer 2014-11-12 18:42:24 +11:00
Sebastian McKenzie
25b466a627 remove unused variables 2014-11-12 18:39:50 +11:00
Sebastian McKenzie
ac231f2987 add 1.12.3 changelog 2014-11-12 18:38:39 +11:00
Sebastian McKenzie
458e3d48f6 use Array.from instead of Array.prototype.slice in spread transformer and support NewExpression spreads - fixes #148 2014-11-12 18:38:30 +11:00
Sebastian McKenzie
c235780611 move down 6to5-node util declaration 2014-11-12 18:37:32 +11:00
Sebastian McKenzie
56b858ccb1 add generator comprehension transformer 2014-11-12 18:29:41 +11:00
Sebastian McKenzie
d42351bb02 add default parameters existence change to well... the defaultParameters transformer 2014-11-12 18:29:27 +11:00
Sebastian McKenzie
ed7378cc2d add apply-constructor declaration and add support for not returning generated code in opts.code 2014-11-12 18:29:03 +11:00
Sebastian McKenzie
a47a7dc347 rename util.parseNoProperties to util.parseTemplate 2014-11-12 18:28:11 +11:00
Sebastian McKenzie
2c82b5a4b0 add generator option to FunctionExpression builder keys 2014-11-12 18:27:56 +11:00
Sebastian McKenzie
3578135b90 add spread caveat and add generator comprehension and react/jsx to features 2014-11-12 18:27:05 +11:00
Sebastian McKenzie
5f3408b2a2 upgrade regenerator-6to5 2014-11-12 18:26:29 +11:00
Sebastian McKenzie
9e3f9fda6b add support for generator comprehensions - fixes #149 2014-11-12 18:26:22 +11:00
Sebastian McKenzie
7f425d2c6e v1.12.2 2014-11-12 12:22:03 +11:00
Sebastian McKenzie
311a8e042b add missing semicolon 2014-11-12 12:19:25 +11:00
Sebastian McKenzie
27d30329fd add more react spread tests 2014-11-12 12:18:16 +11:00
Sebastian McKenzie
12c5a3e73b add 1.12.2 changelog 2014-11-12 12:17:59 +11:00
Sebastian McKenzie
2a166a6ed1 support jsx spread attributes that aren't the first - fixes #146 2014-11-12 12:17:45 +11:00
Sebastian McKenzie
896929378e add util.trimRight method - fixes #147 2014-11-12 12:17:26 +11:00
Sebastian McKenzie
ae439d27b9 update mocha and browserify 2014-11-12 12:08:33 +11:00
Sebastian McKenzie
e22798261a change useless self references to this 2014-11-12 02:03:46 +11:00
Sebastian McKenzie
d0af8b8d0a remove numeric literals transformer 2014-11-12 02:03:25 +11:00
Sebastian McKenzie
beaa2fa540 add async functions to features 2014-11-12 02:03:11 +11:00
Sebastian McKenzie
b8cac9787e produce new MemberExpression in a CallExpression super identifier instead of mutating the property 2014-11-12 01:51:57 +11:00
Sebastian McKenzie
64f6e4a0c5 clean up classes transformer and add comments 2014-11-12 01:48:55 +11:00
Sebastian McKenzie
c4a7ac5a8b turn classes transformer into a class like let scoping 2014-11-12 01:39:35 +11:00
Sebastian McKenzie
1ed682fa76 fix up jsdoc in let-scoping transformer 2014-11-12 01:39:02 +11:00
Sebastian McKenzie
9987e7fe0e add 1.12.1 changelog 2014-11-12 01:38:50 +11:00
Sebastian McKenzie
e74c7cb0b7 turn the let scoping transformer into a class because it's quite complicated and the logic needs to be WAY more organised 2014-11-12 01:20:51 +11:00
Sebastian McKenzie
2f01e5c3af v1.12.1 2014-11-12 00:47:53 +11:00
Sebastian McKenzie
6847211971 fix up aliasFunctions transformer 2014-11-12 00:46:36 +11:00
Sebastian McKenzie
965e246259 add back opts defaults 2014-11-12 00:46:20 +11:00
Sebastian McKenzie
af59eb7d6a fix linting errors 2014-11-12 00:33:39 +11:00
Sebastian McKenzie
def4319058 stop _alias-functions transformer when hitting a function that's not an arrow function - fixes #145 2014-11-12 00:32:30 +11:00
Sebastian McKenzie
d90383b1ba generator: add Buffer class that deals with the actual code output 2014-11-12 00:27:59 +11:00
Sebastian McKenzie
1ac40ee834 remove static whitespace properties in favor of pushing to the dynamic ones 2014-11-12 00:15:31 +11:00
Sebastian McKenzie
3d5d170eff move whitespace and parentheses generation logic into separate files 2014-11-12 00:11:34 +11:00
Sebastian McKenzie
b5bdba46f1 change test-appveyor to test-spec and add test-clean method to clean up after tests 2014-11-11 23:27:01 +11:00
Sebastian McKenzie
c4e162b8e5 add rails to plugins 2014-11-11 22:27:52 +11:00
Sebastian McKenzie
98bc750b05 add mocha to plugins 2014-11-11 22:25:27 +11:00
Sebastian McKenzie
84002ed1ce add jest to plugins 2014-11-11 22:12:26 +11:00
Sebastian McKenzie
aaab2db0ec add react/jsx to readme 2014-11-11 20:06:02 +11:00
Sebastian McKenzie
7f3959444c v1.12.0 2014-11-11 19:14:52 +11:00
Sebastian McKenzie
0ba9216d6f remove unused variables in react transformer 2014-11-11 19:14:00 +11:00
Sebastian McKenzie
6dfe66bce3 add v1.12.0 to changelog 2014-11-11 19:12:44 +11:00
Sebastian McKenzie
9e08a6f084 combine jsx and react transformer so we can make the jsx output correct - #143 2014-11-11 19:11:30 +11:00
Sebastian McKenzie
b9f3f1e2a9 add comment inheriting to types.inherits 2014-11-11 19:10:41 +11:00
Sebastian McKenzie
4f18ed406c v1.11.15 2014-11-11 17:17:08 +11:00
Sebastian McKenzie
4d8e5f728a 1.11.15 2014-11-11 17:16:11 +11:00
Sebastian McKenzie
54857ceac7 fix jsx literal generator - closes #143 2014-11-11 17:15:37 +11:00
Sebastian McKenzie
5b961ea3e7 v1.11.14 2014-11-11 15:35:18 +11:00
Sebastian McKenzie
35b28cf722 more reliable jsx literal whitespace 2014-11-11 15:34:29 +11:00
Sebastian McKenzie
c5bfbf37f0 add 1.11.14 changelog 2014-11-11 15:27:23 +11:00
Sebastian McKenzie
cfee68aa67 jsx: replace all newlines and excess whitespace with spaces - fixes #142 2014-11-11 15:26:25 +11:00
Sebastian McKenzie
7d0dae129c nicer let-scoping switch 2014-11-11 15:25:37 +11:00
Sebastian McKenzie
f9d14fa2ed add runtime, property-literals and shebang tests 2014-11-11 15:25:27 +11:00
Sebastian McKenzie
11d55e661e rename let-scoping tests to traceur-let-scoping and add additional let-scoping tests 2014-11-11 15:25:13 +11:00
Sebastian McKenzie
0544e98fb1 add switch case generated node whitespace 2014-11-11 15:24:40 +11:00
Sebastian McKenzie
59d918ea67 remove unused isArray traverse.hasType 2014-11-11 15:23:52 +11:00
Sebastian McKenzie
b4232699d2 add newline after shebang 2014-11-11 15:23:31 +11:00
Sebastian McKenzie
6bd67ca660 v1.11.13 2014-11-11 14:31:06 +11:00
Sebastian McKenzie
4722c0ce56 add support for escodegen-style format options 2014-11-11 14:30:06 +11:00
Sebastian McKenzie
25a5caa0fc update regenerator-6to5 2014-11-11 14:29:32 +11:00
Sebastian McKenzie
6f05466cf5 normalise windows path separators to unix 2014-11-11 13:36:59 +11:00
Sebastian McKenzie
1ad9edb57c tests/bin: normalise stdout path separators 2014-11-11 13:33:50 +11:00
Sebastian McKenzie
c6ae33c5a2 tests: change all windows line endings to unix ones 2014-11-11 13:30:19 +11:00
Sebastian McKenzie
e0d620b1d5 remove browser-polyfill.js instead of polyfill.js 2014-11-11 13:29:50 +11:00
Sebastian McKenzie
5588bf56eb add CHANGELOG 2014-11-11 13:29:37 +11:00
Sebastian McKenzie
a0e500de6c v1.11.12 2014-11-11 13:14:31 +11:00
Sebastian McKenzie
bf8d9801ce rename browserified polyfill to browser-polyfill - fixes #140 2014-11-11 13:13:10 +11:00
Sebastian McKenzie
68b99a7004 v1.11.11 2014-11-11 13:06:06 +11:00
Sebastian McKenzie
5ae4f8eec7 add AwaitExpression generator 2014-11-11 13:05:07 +11:00
Sebastian McKenzie
d9a3eadad7 move generators transformer to bottom 2014-11-11 13:03:06 +11:00
Sebastian McKenzie
b1cc5419a4 add AwaitExpression visitor keys - fixes #141 2014-11-11 13:02:55 +11:00
Sebastian McKenzie
c6a7a9c401 v1.11.10 2014-11-11 09:48:28 +11:00
Sebastian McKenzie
608df54b02 bump acorn-6to5 version to one that supports async/await - closes #134 2014-11-11 09:47:29 +11:00
Sebastian McKenzie
2ac83ec95b v1.11.9 2014-11-11 08:07:29 +11:00
Sebastian McKenzie
e4596f638d only check string literals in property-literals transformer 2014-11-11 08:06:31 +11:00
Sebastian McKenzie
1425af9b2a v1.11.8 2014-11-11 07:51:43 +11:00
Sebastian McKenzie
9351c6470f bump regenerator version 2014-11-11 07:50:07 +11:00
Sebastian McKenzie
7b8a50509a v1.11.7 2014-11-11 01:07:20 +11:00
Sebastian McKenzie
1400dee0c1 delegate code and opts assurance to File 2014-11-11 01:06:29 +11:00
Sebastian McKenzie
9e2fc6db9c clone options - sindresorhus/grunt-6to5#7 2014-11-11 01:04:39 +11:00
Sebastian McKenzie
aef5b89492 fix appveyor badge 2014-11-10 21:12:30 +11:00
Sebastian McKenzie
e0bf6f698e add appveyor badge to readme 2014-11-10 21:09:09 +11:00
Sebastian McKenzie
1ac459a05d better appveyor make test 2014-11-10 21:09:04 +11:00
Sebastian McKenzie
1b49835b27 v1.11.6 2014-11-10 16:46:40 +11:00
Sebastian McKenzie
db7b6a4972 fix canCompile in readdirFilter in bin/6to5 util 2014-11-10 16:45:30 +11:00
Sebastian McKenzie
79045e15c5 remove second canCompile declaration 2014-11-10 16:42:04 +11:00
Sebastian McKenzie
b7e6d8f998 add appveyor.yml 2014-11-10 16:31:32 +11:00
Sebastian McKenzie
88c6ce4e48 v1.11.5 2014-11-10 13:10:39 +11:00
Sebastian McKenzie
8c97f1d92e allow constant properties to be modified - fixes #131 2014-11-10 13:09:45 +11:00
Sebastian McKenzie
833e8b091b v1.11.4 2014-11-10 13:02:04 +11:00
Sebastian McKenzie
23ebb23944 add missing util declaration to let scoping transformer 2014-11-10 13:00:52 +11:00
Sebastian McKenzie
778cab33d5 move canCompile method to util 2014-11-10 12:59:24 +11:00
Sebastian McKenzie
5849c6af17 add canCompile method to node api 2014-11-10 12:58:44 +11:00
Sebastian McKenzie
bb0655d8f6 move transformer assignment to new Transformer 2014-11-10 08:21:35 +11:00
Sebastian McKenzie
9977a5f614 change gitter travis hook to always 2014-11-10 08:20:18 +11:00
Sebastian McKenzie
9318d63b5c add let-scoping-return template to let scoping transformer 2014-11-10 08:16:47 +11:00
Sebastian McKenzie
b2ab0dbedc add self-global template to runtime generation 2014-11-10 08:16:38 +11:00
Sebastian McKenzie
e0d3e18865 add allowReturnOutsideFunction to util.parse and make nodes optional in util.template 2014-11-10 08:16:22 +11:00
Sebastian McKenzie
3a3ad4775b add gitter webhook to travis 2014-11-10 08:16:00 +11:00
Sebastian McKenzie
40fdd2a828 dry up types.getIds 2014-11-10 00:51:46 +11:00
Sebastian McKenzie
12f66e852a v1.11.3 2014-11-10 00:22:09 +11:00
Sebastian McKenzie
c61c9aab56 remove invalid ObjectPattern assignment 2014-11-10 00:19:37 +11:00
Sebastian McKenzie
7adc919bb6 remove invalid ObjectPattern destructuring assignment 2014-11-10 00:18:01 +11:00
Sebastian McKenzie
9989b89b92 v1.11.2 2014-11-09 22:27:52 +11:00
Sebastian McKenzie
361ef02a88 support ParenthesizedExpression in types.getIds 2014-11-09 22:26:48 +11:00
Sebastian McKenzie
72369c90a2 update dependencies 2014-11-09 22:11:06 +11:00
Sebastian McKenzie
fa26174d3f better isParenthesizedExpression support for destructuring 2014-11-09 22:10:59 +11:00
Sebastian McKenzie
227d51a556 add AssignmentExpression ObjectPattern test 2014-11-09 22:10:43 +11:00
Sebastian McKenzie
a5f00aa3f6 v1.11.1 2014-11-09 21:39:19 +11:00
Sebastian McKenzie
a47723c66c fix destructuring to support ParanthesizedExpression 2014-11-09 21:37:59 +11:00
Sebastian McKenzie
ab2f652bdf break up let scoping transformer some more 2014-11-09 21:25:14 +11:00
Sebastian McKenzie
5aff7709f7 add back _property-literals transformer that somehow disappeared? 2014-11-09 21:25:05 +11:00
Sebastian McKenzie
06ba731452 traverse: pass opts.scope instead of opts 2014-11-09 21:24:48 +11:00
Sebastian McKenzie
f4c81531ad break up let scoping 2014-11-09 20:31:46 +11:00
Sebastian McKenzie
19b115c76b generator: dry up ForXStatements and *Statements 2014-11-09 20:31:36 +11:00
Sebastian McKenzie
96b08bf7df remove codeclimate from travis 2014-11-09 20:20:21 +11:00
Sebastian McKenzie
8f435d59da change sebmck to new 6to5 org 2014-11-09 20:08:36 +11:00
Sebastian McKenzie
6df03c00a8 Merge pull request #130 from thejameskyle/patch-1
Update logo on README
2014-11-09 20:05:11 +11:00
James Kyle
4ec134814e Update logo on README 2014-11-09 01:04:32 -08:00
Sebastian McKenzie
4fb50cfe20 v1.11.0 2014-11-09 18:45:50 +11:00
Sebastian McKenzie
bac952e036 move runtime to dist/runtime 2014-11-09 18:42:42 +11:00
Sebastian McKenzie
9844540bb0 add npm release-only files to gitignore 2014-11-09 18:38:09 +11:00
Sebastian McKenzie
1a9a60e010 fix polyfill require path 2014-11-09 18:37:57 +11:00
Sebastian McKenzie
e26812e622 remove v8-argv 2014-11-09 18:33:07 +11:00
Sebastian McKenzie
7f306388e4 remove polyfill from root 2014-11-09 18:32:19 +11:00
Sebastian McKenzie
b217453d49 clean up runtime generation declarations 2014-11-09 18:22:26 +11:00
Sebastian McKenzie
463165e0c8 remove unneccesary declaration 2014-11-09 18:22:12 +11:00
Sebastian McKenzie
85d7da9a7c fix comment space column bug 2014-11-09 18:22:04 +11:00
Sebastian McKenzie
48f6c5c649 remove i from mocha globals 2014-11-09 18:21:50 +11:00
Sebastian McKenzie
d1187dde82 fix up tests to work with the new code generator 2014-11-09 18:21:42 +11:00
Sebastian McKenzie
f21a6b36ac peg regenerator-6to5 and acorn-6to5 to a commit 2014-11-09 18:21:29 +11:00
Sebastian McKenzie
407bb9278f uglify polyfill.js and use minified versions in npm release 2014-11-09 16:41:45 +11:00
Sebastian McKenzie
70b3d88455 fix browser polyfill copytext 2014-11-09 16:40:46 +11:00
Sebastian McKenzie
98df094e60 fix cached templates exporting 2014-11-09 16:40:37 +11:00
Sebastian McKenzie
4bae820a5a remove Error.captureStackTrace monkey patch as it's no longer necessary with the latest ast-types 2014-11-09 16:37:47 +11:00
Sebastian McKenzie
4e8afa18da move Polyfill from caveats 2014-11-09 16:34:21 +11:00
Sebastian McKenzie
fbf0c25bbe include polyfill 2014-11-09 16:33:26 +11:00
Sebastian McKenzie
a90da9908c only prepend whitespace to properties if we're the first 2014-11-09 16:28:56 +11:00
Sebastian McKenzie
bd51215316 change Runtime to Optional runtime in README 2014-11-09 16:28:21 +11:00
Sebastian McKenzie
e3c6ee5c88 only use needsParens if the node has changed parent 2014-11-09 16:28:05 +11:00
Sebastian McKenzie
8c40db5658 use Program builder 2014-11-09 16:27:39 +11:00
Sebastian McKenzie
4d59976d82 remove _parent from nodes in traverse.removeProperties 2014-11-09 16:27:31 +11:00
Sebastian McKenzie
83286cccd2 use file node builder and save parents to ast tree 2014-11-09 16:26:52 +11:00
Sebastian McKenzie
de7edcaeb0 finalize ast-types 2014-11-09 16:26:32 +11:00
Sebastian McKenzie
6c8db61b23 switch to regenerator-6to5 2014-11-09 16:26:27 +11:00
Sebastian McKenzie
e3d2748970 fix up react display-name test whitespace 2014-11-09 16:26:12 +11:00
Sebastian McKenzie
fa8c570e77 add File and Program to builder keys 2014-11-09 16:25:55 +11:00
Sebastian McKenzie
677f9805c6 update ast-types and add regenerator-6to5 2014-11-09 16:25:45 +11:00
Sebastian McKenzie
eff5efaf10 fix up patching 2014-11-09 13:42:11 +11:00
Sebastian McKenzie
a909a6febd add CatchClause scope 2014-11-09 13:42:00 +11:00
Sebastian McKenzie
61ee0ef6f6 fix generation comments return-no-argument test whitespace 2014-11-09 12:14:15 +11:00
Sebastian McKenzie
07c15f02e6 update generation test to new api 2014-11-09 12:13:55 +11:00
Sebastian McKenzie
3f4068ae00 fix runtime declaration inclusion copytext 2014-11-09 12:12:23 +11:00
Sebastian McKenzie
dce41bb989 fix up tests 2014-11-09 12:09:59 +11:00
Sebastian McKenzie
896663056d add ParenthesizedExpression builder 2014-11-09 12:09:42 +11:00
Sebastian McKenzie
dfe4ce86e0 fix up templateLiterals blacklist check 2014-11-09 12:09:32 +11:00
Sebastian McKenzie
24f0120e01 add patch so we can patch estraverse and ast-types 2014-11-09 12:09:07 +11:00
Sebastian McKenzie
0108562e88 remove unused key variable 2014-11-09 12:07:57 +11:00
Sebastian McKenzie
e4e4ae5b1d fix up node inheritance 2014-11-09 12:07:46 +11:00
Sebastian McKenzie
ba04377ed8 add types.toIdentifier 2014-11-09 12:07:25 +11:00
Sebastian McKenzie
cd9e289dee traverse: clean up scope getIds building 2014-11-09 12:07:14 +11:00
Sebastian McKenzie
0b86a2fef8 use acorns preserveParens 2014-11-09 12:06:56 +11:00
Sebastian McKenzie
b84cb1828b generator: avoid redundant source map mappings 2014-11-09 12:03:47 +11:00
Sebastian McKenzie
aedc013ab8 generator: rename Whitespace methods 2014-11-09 12:03:31 +11:00
Sebastian McKenzie
ab9cd4e630 add support for an optional runtime - closes #129 2014-11-09 12:02:06 +11:00
Sebastian McKenzie
8ef5148870 fix up modules tests 2014-11-08 12:00:49 +11:00
Sebastian McKenzie
4cb90cb1e0 add precedence to generated node generation 2014-11-08 12:00:26 +11:00
Sebastian McKenzie
d0a33ab933 add inherits option to util.template 2014-11-08 12:00:12 +11:00
Sebastian McKenzie
9ea4431ba3 add alternate shallow equals option to types.is* 2014-11-08 11:59:54 +11:00
Sebastian McKenzie
08580edda8 fix up some tests 2014-11-08 09:17:21 +11:00
Sebastian McKenzie
5c6d57c51b add transformation and generation folders 2014-11-08 09:17:12 +11:00
Sebastian McKenzie
744d1af485 move down propertyLiterals transformer in case classes produces any 2014-11-07 21:10:28 +11:00
Sebastian McKenzie
591b78b159 move property literal check to a separate transformer 2014-11-07 21:01:39 +11:00
Sebastian McKenzie
49ea641314 ignore computed property literals that are valid identifiers 2014-11-07 20:51:01 +11:00
Sebastian McKenzie
37a7c92500 remove duplicate mutator map test 2014-11-07 20:47:15 +11:00
Sebastian McKenzie
35b7b140da fix pointless newlines after left braces 2014-11-07 20:47:09 +11:00
Sebastian McKenzie
159f5217e3 simplify ast transformer code 2014-11-07 20:46:54 +11:00
Sebastian McKenzie
795e38e4f4 add Statement node type 2014-11-07 20:46:43 +11:00
Sebastian McKenzie
2a9af21e93 add modules ignore tests 2014-11-07 20:46:20 +11:00
Sebastian McKenzie
e327e041ab add basic generation tests 2014-11-07 20:46:11 +11:00
Sebastian McKenzie
f8e8cd3979 support SpreadElement in destructuring - fixes #128 2014-11-07 20:46:02 +11:00
Sebastian McKenzie
b3206d94a6 Merge branch 'master' into experimental
Conflicts:
	README.md
	lib/6to5/register.js
2014-11-07 13:54:59 +11:00
Sebastian McKenzie
fcbd315bc1 v1.10.12 2014-11-07 13:53:15 +11:00
Sebastian McKenzie
71646f4ade register: fix ignoreRegex compatibility check 2014-11-07 13:52:13 +11:00
Sebastian McKenzie
56ac964e54 remove newline assurance and add optional Error constructor to File::errorWithNode 2014-11-07 13:51:31 +11:00
Sebastian McKenzie
e5f1eb64b6 clarify default ignore in 6to5/register 2014-11-07 13:41:24 +11:00
Sebastian McKenzie
6145f0a03b v1.10.11 2014-11-07 13:17:41 +11:00
Sebastian McKenzie
54f901f131 require: add missing blacklistTests, implement opts.whitelist and opts.only - closes #125
Conflicts:
	lib/6to5/register.js
2014-11-07 13:16:26 +11:00
Sebastian McKenzie
df70be4ebb clean up and fix tests 2014-11-07 12:33:35 +11:00
Sebastian McKenzie
99ba77bb0b nicer removeProperties for comments 2014-11-07 12:33:22 +11:00
Sebastian McKenzie
346f72be05 ensure files end with a newline 2014-11-07 12:32:48 +11:00
Sebastian McKenzie
c0e6cda071 add UserWhitespacable alias to Property 2014-11-07 12:32:31 +11:00
Sebastian McKenzie
c054ff7bbb better whitespace detection in generator 2014-11-07 12:32:15 +11:00
Sebastian McKenzie
771d3dc8a0 don't inherit from XJSAttribute in jsx transformer because it causes some weird whitespace issues 2014-11-07 12:31:54 +11:00
Sebastian McKenzie
e8d4806b45 combine export declaration assignments into variable declarations 2014-11-07 12:31:31 +11:00
Sebastian McKenzie
469a522300 better whitespace for code generation 2014-11-07 12:31:09 +11:00
Sebastian McKenzie
4068a8bf68 remove exposure to generator from browser build 2014-11-07 12:30:29 +11:00
Sebastian McKenzie
a04513a3c7 faster util.pushMutatorMap aliases 2014-11-07 12:28:52 +11:00
Sebastian McKenzie
6f0ca947a7 remove exposure to generate and util 2014-11-07 12:28:28 +11:00
Sebastian McKenzie
dd62244e10 use v8-argv to make sure node is ran with --harmony for 6to5-node 2014-11-07 12:28:17 +11:00
Sebastian McKenzie
12f68b05c3 better Symbol polyfill existence check because the one es6-symbol uses isn't reliable 2014-11-07 12:27:57 +11:00
Sebastian McKenzie
62fe128132 more support to t.getIds and add t.needsWhitespaceBefore method 2014-11-07 12:26:48 +11:00
Sebastian McKenzie
bf632ca20b more efficient constants collision checking 2014-11-07 12:26:19 +11:00
Sebastian McKenzie
26428cde41 require: add missing blacklistTests, implement opts.whitelist and opts.only - closes #125 2014-11-07 12:25:42 +11:00
Sebastian McKenzie
9bb8a16d93 change polyfill to monkey patch in browser comment 2014-11-05 15:22:17 +11:00
Sebastian McKenzie
44cd044586 add duo and karma plugins to readme - thanks @shuhei and @bd-labs! 2014-11-05 15:22:07 +11:00
Sebastian McKenzie
765899a521 use push instead of _push for first backtick in template literals 2014-11-04 18:37:00 +11:00
Sebastian McKenzie
1d40cac52f let ExpressionStatements handle child comments 2014-11-04 18:34:21 +11:00
Sebastian McKenzie
fb0325a4d8 add support for SpreadElement to types.getIds 2014-11-04 18:33:48 +11:00
Sebastian McKenzie
1df25a633c fix code reference on generate 2014-11-04 18:33:33 +11:00
Sebastian McKenzie
cfbaae456b use _push instead of push on template literals end 2014-11-04 18:32:51 +11:00
Sebastian McKenzie
95ace3220d fix indentation on generation comments tests 2014-11-04 18:32:30 +11:00
Sebastian McKenzie
2e0f3de72c add missing util require 2014-11-04 18:07:28 +11:00
Sebastian McKenzie
732c21d42a clean up some tests 2014-11-04 18:07:19 +11:00
Sebastian McKenzie
a535007a35 clean up let scoping transformer and add lots of comments 2014-11-04 18:06:54 +11:00
Sebastian McKenzie
5ff6f445b2 fix class computed methods 2014-11-04 15:53:36 +11:00
Sebastian McKenzie
d7ae3b506a fix linting errors 2014-11-04 15:53:11 +11:00
Sebastian McKenzie
287cbbb6a1 implement new and improved let scoping - fixes #91, fixes #102, fixes #124 2014-11-04 14:59:44 +11:00
Sebastian McKenzie
d1088583ba default generateUid scope to Program 2014-11-04 12:57:06 +11:00
Sebastian McKenzie
c967cded78 make id optional in t.getIds 2014-11-04 12:56:53 +11:00
Sebastian McKenzie
71d87f5b97 cache scope ids and limit id variable declarations to kind 2014-11-04 12:56:37 +11:00
Sebastian McKenzie
56271efada pass scope to transformers 2014-11-04 12:48:08 +11:00
Sebastian McKenzie
89fbb06658 simplify VariableDeclaration ForStatement check 2014-11-04 12:47:56 +11:00
Sebastian McKenzie
43ee3b77f3 add SequenceExpression and UnaryExpression builders 2014-11-04 12:47:39 +11:00
Sebastian McKenzie
9ef826b53e move visitor-keys from traverse to types 2014-11-04 12:47:27 +11:00
Sebastian McKenzie
6519ceaa63 move util.getIds to types.getIds 2014-11-04 12:47:03 +11:00
Sebastian McKenzie
d28496006e implement Scope so we can keep track of references to avoid collisions when generating ids 2014-11-04 12:46:47 +11:00
Sebastian McKenzie
5f9710e61f add explanation for gross Error.captureStackTrace polyfill 2014-11-04 12:45:17 +11:00
Sebastian McKenzie
c4cadd8a64 add text/6to5 to browser compilation script types 2014-11-04 09:13:50 +11:00
Sebastian McKenzie
d3c5b8ef0b automatic browser <script type="text/ecmascript-6"> compilation - closes #97 2014-11-04 08:56:48 +11:00
Sebastian McKenzie
120df2c611 make browser api backwards compatible 2014-11-04 08:22:44 +11:00
Sebastian McKenzie
719d23eb3b add Error.captureStackTrace polyfill so browser build will work in non-v8 environments - fixes #107 2014-11-04 08:19:13 +11:00
Sebastian McKenzie
364abf60ea fix generation test whitespace 2014-11-04 08:05:09 +11:00
Sebastian McKenzie
0f5a141c91 change acorn-ast-types to ast-types 2014-11-04 08:04:41 +11:00
Sebastian McKenzie
fca3a0c56f generator: add ensureSemicolon and printBlock methods 2014-11-04 08:04:32 +11:00
Sebastian McKenzie
e88505aba6 better ExportDeclaration generation 2014-11-04 08:04:22 +11:00
Sebastian McKenzie
500a0bdfb6 better whitespace for blocks and methods 2014-11-04 08:04:11 +11:00
Sebastian McKenzie
2a0efceef5 change behaviour of tests and browser testing/build 2014-11-04 08:03:52 +11:00
Sebastian McKenzie
225754ae12 Merge branch 'master' into experimental 2014-11-03 21:18:50 +11:00
Sebastian McKenzie
6f230de01c fix maybeReplace wrong node callback bug 2014-11-03 21:17:56 +11:00
Sebastian McKenzie
3c3746b21f fix transformer alias types key 2014-11-03 21:17:42 +11:00
Sebastian McKenzie
f49f057b33 generator: add trim option to isLast 2014-11-03 21:17:17 +11:00
Sebastian McKenzie
e3b9a0dd38 update alias-functions transformer to use types 2014-11-03 21:16:15 +11:00
Sebastian McKenzie
f540c3f4b7 fix test newlines 2014-11-03 21:15:58 +11:00
Sebastian McKenzie
6e5917e537 make array comprehensions use for-of unless using an array literal - fixes #98 2014-11-03 21:15:49 +11:00
Sebastian McKenzie
816c1d304b remove builders and move them to automatially generated types 2014-11-03 21:13:35 +11:00
Sebastian McKenzie
5deeae1aa2 travis: ignore experimental branch 2014-11-03 18:26:50 +11:00
Sebastian McKenzie
718e342e86 fix classes supername transformer inference 2014-11-03 18:22:57 +11:00
Sebastian McKenzie
cb98605520 add example usage for custom module formatters 2014-11-03 18:20:01 +11:00
Sebastian McKenzie
600513bcab add ignore module formatter - closes #119 2014-11-03 18:18:51 +11:00
Sebastian McKenzie
620e5791af use t.is* methods to nicen up code 2014-11-03 18:10:52 +11:00
Sebastian McKenzie
47ee2cc99f simplify err.loc references 2014-11-03 17:53:08 +11:00
Sebastian McKenzie
6cc70f7465 compare code instead of ast for transformation tests 2014-11-03 17:52:59 +11:00
Sebastian McKenzie
20484c66c5 add types.inherits method that inherits loc, range, start, end etc 2014-11-03 17:52:50 +11:00
Sebastian McKenzie
171bcad870 make transformation tests compare output instead of ast 2014-11-03 17:52:15 +11:00
Sebastian McKenzie
c963c30107 fix errorWithNode line mapping 2014-11-03 17:50:25 +11:00
Sebastian McKenzie
795183569d fix export default assignment bug 2014-11-03 14:40:47 +11:00
Sebastian McKenzie
9a3c973280 add removeLastNewline to generator and add newlines to generated nodes 2014-11-03 14:40:33 +11:00
Sebastian McKenzie
95f3ca6348 Merge branch 'master' into code-generator
Conflicts:
	lib/6to5/transformers/classes.js
	test/fixtures/transformation/source-maps/class/expected.js
	test/fixtures/transformation/source-maps/class/source-mappings.json
2014-11-03 13:38:44 +11:00
Sebastian McKenzie
c17878913b add classProps declaration to simplify/nicen up class property defining - closes #88 2014-11-03 13:36:23 +11:00
Sebastian McKenzie
c8139317ee add static property inherit warning for IE <= 9 to README - closes #116 2014-11-03 13:09:36 +11:00
Sebastian McKenzie
6d6039aeb6 Merge branch 'master' into code-generator 2014-11-03 12:36:11 +11:00
Sebastian McKenzie
74f11dfddf add chai to devDependencies 2014-11-03 12:35:59 +11:00
Sebastian McKenzie
4c63b4ea1e Merge branch 'master' into code-generator 2014-11-03 12:34:15 +11:00
Sebastian McKenzie
6332e725fe update bin tests to match updated use strict behaviour 2014-11-03 12:34:00 +11:00
Sebastian McKenzie
f3d371869d Merge branch 'master' into code-generator
Conflicts:
	lib/6to5/register.js
2014-11-03 12:22:07 +11:00
Sebastian McKenzie
89ecd46b77 move _moduleFormatter transformer before useStrict transformer and remove duplicate use strict removing - fixes #114 2014-11-03 12:20:47 +11:00
Sebastian McKenzie
9f8e8d96a8 simplify hasParans for NewExpression 2014-11-03 12:15:57 +11:00
Sebastian McKenzie
a7bbd1dd3e generator: fix comments in harmony-edgecase tests 2014-11-03 12:15:44 +11:00
Sebastian McKenzie
6d961c1857 faster traverse.hasType with array of nodes 2014-11-03 12:15:27 +11:00
Sebastian McKenzie
e13a650d05 remove IfStatement making consequent and alternate blocks 2014-11-03 11:17:36 +11:00
Sebastian McKenzie
3cd7ed69a3 remove useless blank template 2014-11-03 11:16:48 +11:00
Sebastian McKenzie
93c6d69e21 make transformation tests ignore whitespace 2014-11-03 11:15:06 +11:00
Sebastian McKenzie
57d3c836bd register: add additional blacklistTests 2014-11-03 11:14:52 +11:00
Sebastian McKenzie
115282d57b generator: add _push method to simplify buffer pushing and location tracking 2014-11-03 11:13:37 +11:00
Sebastian McKenzie
72d924d85b generator: fix NewExpression arguments 2014-11-03 11:12:30 +11:00
Sebastian McKenzie
6838062279 move util.errorWithNode to File 2014-11-03 11:11:37 +11:00
Sebastian McKenzie
bc79cec15a add NewExpression support to needsParans 2014-11-03 11:11:07 +11:00
Sebastian McKenzie
85f0f6fb14 add whitespace option and move util.errorWithNode to File 2014-11-03 11:09:58 +11:00
Sebastian McKenzie
bf61c1e85d remove recast and add ast-types 2014-11-03 11:09:24 +11:00
Sebastian McKenzie
bd2e3d784f fix source-map transformation tests 2014-11-03 11:09:14 +11:00
Sebastian McKenzie
7e8c5cd20f Merge pull request #118 from amsul/patch-1
Added ability to register 6to5 with a blacklist
2014-11-02 10:39:13 +11:00
amsul
ddbb522392 Updated blacklist option to replace reference 2014-11-01 19:36:10 -04:00
amsul
288cfd1f00 Added ability to register 6to5 with a blacklist
Currently, to achieve this, I have to use this workaround:

```js
var to5 = require('6to5')
delete to5.transform.transformers.generators
require('6to5/register')
```

After this simple change, I can make it much nicer:

```js
require('6to5/register')({
    blacklist: ['generators']
})
```

Cheers!
2014-11-01 14:15:52 -04:00
Sebastian McKenzie
435b9434ea don't mess with the indentation of TemplateElements 2014-11-01 23:26:48 +11:00
Sebastian McKenzie
2409b017db generator: remove parans around ConditionalExpression 2014-11-01 23:08:50 +11:00
Sebastian McKenzie
99f2864048 generator: remove redundant print call 2014-11-01 23:08:33 +11:00
Sebastian McKenzie
5351057557 generator: move BlockStatement to base generator 2014-11-01 23:08:16 +11:00
Sebastian McKenzie
1a5ee7d5da change acorn-jsx to acorn-6to5 2014-11-01 23:07:53 +11:00
Sebastian McKenzie
ebea86c527 split up types.ensureBlock into types.toBlock 2014-11-01 23:07:34 +11:00
Sebastian McKenzie
bf58004947 generator: add intelligent whitespace based on tokens on nodes in a sequence 2014-11-01 23:07:17 +11:00
Sebastian McKenzie
f0c78102ca move template literal generators into separate file 2014-11-01 19:37:21 +11:00
Sebastian McKenzie
da1512eeb0 rename generation test names to be more descriptive 2014-11-01 19:34:16 +11:00
Sebastian McKenzie
43ea593677 traverse.removeProperties: remove raw property 2014-11-01 19:29:17 +11:00
Sebastian McKenzie
629cea497f move keyword method and restyle variable declarations 2014-11-01 19:29:02 +11:00
Sebastian McKenzie
9475dc681f finish jsx generator 2014-11-01 19:28:42 +11:00
Sebastian McKenzie
6e41309ede add err.stack test to code frame error capture 2014-11-01 19:28:35 +11:00
Sebastian McKenzie
42322e1ce7 add examples to types.needsParans tests 2014-11-01 19:27:42 +11:00
Sebastian McKenzie
400fa8ed97 remove unused ParenthesizedExpression 2014-11-01 19:27:23 +11:00
Sebastian McKenzie
07e2842226 implement array comprehension generator 2014-11-01 19:27:09 +11:00
Sebastian McKenzie
7d46b7c465 expose generator 2014-11-01 17:56:07 +11:00
Sebastian McKenzie
fcf6c9e066 generator: add isLast helper method 2014-11-01 17:53:01 +11:00
Sebastian McKenzie
a5523664fc generator: add alternate support to IfStatement 2014-11-01 17:52:48 +11:00
Sebastian McKenzie
1841f5c8a0 v1.10.10 2014-11-01 16:08:11 +11:00
Sebastian McKenzie
33f8988313 support for numeric literals with recast - fixes #117 2014-11-01 16:06:46 +11:00
Sebastian McKenzie
1d3544eadc fix function generation spacing 2014-11-01 16:00:17 +11:00
Sebastian McKenzie
646bdfd04c types.needsParans: add parent ExpressionStatement check for FunctionExpression 2014-11-01 15:58:44 +11:00
Sebastian McKenzie
aba9bba7db generator: use new keyword method for keywords 2014-11-01 15:56:27 +11:00
Sebastian McKenzie
e77382582f generator: add keyword method, remove __ident method and implement better position tracking 2014-11-01 15:56:10 +11:00
Sebastian McKenzie
af997b9945 Merge pull request #115 from djindjic/patch-1
Just a little info added
2014-11-01 08:39:33 +11:00
Aleksandar Djindjic
a2332f08bc Just a little info added
I needed this and it maybe help to someone else
2014-10-31 14:58:46 +01:00
Sebastian McKenzie
bbffde374e Merge branch 'master' into code-generator 2014-10-31 21:39:47 +11:00
Sebastian McKenzie
115dca56b6 v1.10.9 2014-10-31 21:39:17 +11:00
Sebastian McKenzie
251e4d01c8 join together declarations in destructuring to return a single node if possible - fixes #113 2014-10-31 21:38:22 +11:00
Sebastian McKenzie
0fbf0e2a77 generator: add semicolon helper method, add optional printJoin iterator 2014-10-31 21:24:54 +11:00
Sebastian McKenzie
e8628ea1a7 add chai 2014-10-31 21:24:36 +11:00
Sebastian McKenzie
a5a8f08bb8 generator: implement missing node types 2014-10-31 21:23:45 +11:00
Sebastian McKenzie
d376bd3c0e generator: remove redundant async tests 2014-10-31 21:23:31 +11:00
Sebastian McKenzie
20818b086c generator: add support for modules 2014-10-31 21:22:56 +11:00
Sebastian McKenzie
f9ef1723a6 generator: add support for ForOfStatement 2014-10-31 21:22:43 +11:00
Sebastian McKenzie
6e7b8a14fe remove comments in traverse.removeProperties 2014-10-31 21:22:28 +11:00
Sebastian McKenzie
622bb2e962 types: add more tests for optional paranthesis 2014-10-31 21:22:03 +11:00
Sebastian McKenzie
5c5348537d generator: add support for method properties and computed keys and shorthand 2014-10-31 21:21:50 +11:00
Sebastian McKenzie
0def62b918 replace single quotes with double quotes in generaton tests 2014-10-31 21:21:26 +11:00
Sebastian McKenzie
530ad78428 fix & html entity in travis badge branch url - thanks @davidchambers 2014-10-31 11:51:49 +11:00
Sebastian McKenzie
daced12baa add base for TemplateLiteral generator 2014-10-31 11:51:00 +11:00
Sebastian McKenzie
51f18a152e fix test generation actual ast 2014-10-31 11:50:52 +11:00
Sebastian McKenzie
51f72ace57 Merge pull request #112 from thejameskyle/travis-badge
Add ?branch=master to Travis CI badge
2014-10-31 11:47:50 +11:00
James Kyle
2fa36b30d5 Add ?branch=master to Travis CI badge 2014-10-30 17:46:08 -07:00
Sebastian McKenzie
11270e0803 Merge branch 'master' into code-generator
Conflicts:
	lib/6to5/transformers/rest-parameters.js
2014-10-31 11:44:48 +11:00
Sebastian McKenzie
6f8cbf0ad1 v1.10.8 2014-10-31 11:43:36 +11:00
Sebastian McKenzie
6696d5fcf4 fix rest parameters in arrow functions containing wrong arguments reference - fixes #11 2014-10-31 11:42:09 +11:00
Sebastian McKenzie
591f123670 update tests to work with new syntax 2014-10-31 11:38:52 +11:00
Sebastian McKenzie
1f7270720f add more type methods 2014-10-31 11:38:37 +11:00
Sebastian McKenzie
ec3a3cbbc9 more descriptive test helper method names 2014-10-31 11:38:18 +11:00
Sebastian McKenzie
8a1ea82e97 remove legacy generator options 2014-10-31 11:38:04 +11:00
Sebastian McKenzie
6953b6e8b6 remove start and end props from nodes in traverse.removeProperties 2014-10-31 11:37:49 +11:00
Sebastian McKenzie
378832d31b add comments with estraverse 2014-10-31 11:37:17 +11:00
Sebastian McKenzie
85703eb5b8 run internal transformers when using a whitelist 2014-10-31 11:37:04 +11:00
Sebastian McKenzie
d0fdd3bf41 remove comments transformer 2014-10-31 11:36:44 +11:00
Sebastian McKenzie
a7385bdf1b make CodeGenerators use static method calls instead of recursive string methods 2014-10-31 11:36:28 +11:00
Sebastian McKenzie
9c7c385ee8 add generation tests from escodegen 2014-10-31 11:35:57 +11:00
Sebastian McKenzie
7c84af2ba8 remove optional computed property in b.memberExpression 2014-10-30 17:38:05 +11:00
Sebastian McKenzie
009d063790 just return constructor if only a constructor exists in classes 2014-10-30 17:37:51 +11:00
Sebastian McKenzie
5483c4ef6f split up code generators 2014-10-30 17:30:05 +11:00
Sebastian McKenzie
5558f61518 add more feature detection to 6to5/register 2014-10-30 17:16:33 +11:00
Sebastian McKenzie
96bc95d6d9 add blacklist syntax feature checking to 6to5/register 2014-10-30 17:11:54 +11:00
Sebastian McKenzie
11dd13b7e0 remove invalid node types from generator and add todo ones 2014-10-30 17:11:31 +11:00
Sebastian McKenzie
976e6782a2 expose traverse.VISITOR_KEYS 2014-10-30 17:11:13 +11:00
Sebastian McKenzie
febc3062cc update traverse visitor keys to acorn ones 2014-10-30 17:11:05 +11:00
Sebastian McKenzie
efff5e5aab add generation completeness test 2014-10-30 17:10:54 +11:00
Sebastian McKenzie
eefab7f80f remove unused variables 2014-10-30 13:31:45 +11:00
Sebastian McKenzie
1a3d306949 Merge branch 'master' into code-generator
Conflicts:
	package.json
2014-10-30 13:29:05 +11:00
Sebastian McKenzie
e5ae2f8eaf fix linting errors 2014-10-30 13:26:13 +11:00
Sebastian McKenzie
e797be518f move some util and traverse methods into types 2014-10-30 13:26:06 +11:00
Sebastian McKenzie
45cb755845 better eval contexts in bin/6to5-node 2014-10-30 13:09:37 +11:00
Sebastian McKenzie
3b9a339c79 remove useless traverse.Delete 2014-10-30 13:09:23 +11:00
Sebastian McKenzie
ea7ac4cd2d change acorn-ast-types to internal builders 2014-10-30 13:09:12 +11:00
Sebastian McKenzie
e141a8b875 run 6to5-node repl in a context 2014-10-30 12:15:37 +11:00
Sebastian McKenzie
6768fc3800 add back regex.flags in unicode regex transformer 2014-10-30 12:15:12 +11:00
Sebastian McKenzie
0af5e00b5f update jsx empty test to new dom tags behaviour 2014-10-30 12:14:41 +11:00
Sebastian McKenzie
ecedc23892 v1.10.7 2014-10-29 20:59:35 +11:00
Sebastian McKenzie
163c68dd6a fix lint errors 2014-10-29 20:57:43 +11:00
Sebastian McKenzie
4dc6147348 update acorn-recast 2014-10-29 20:53:25 +11:00
Sebastian McKenzie
4b3ebc62b1 fix indentation 2014-10-29 20:52:31 +11:00
Sebastian McKenzie
cc094efe1b modify regex object instead of creating a new literal 2014-10-29 20:52:25 +11:00
Sebastian McKenzie
8f4a3f77a0 remove jsx known-tags and use the latest jsx known tag definition 2014-10-29 20:52:12 +11:00
Sebastian McKenzie
b31f3666c8 yank out acorn-recast and replace it with our own code generator 2014-10-29 20:51:52 +11:00
Sebastian McKenzie
b1495832d7 remove acorn-recast 2014-10-29 20:51:03 +11:00
Sebastian McKenzie
fa6e50ea28 Merge pull request #103 from eventualbuddha/remove-unused-vars
Remove unused vars & fix typo
2014-10-28 14:31:24 +11:00
Sebastian McKenzie
a72c839a73 add bin and benchmark directories to jshint test #103 2014-10-28 14:31:09 +11:00
Brian Donovan
32b5edb711 Remove unused requires. 2014-10-27 20:28:31 -07:00
Brian Donovan
8cbb121e3f Fix typo. 2014-10-27 20:28:08 -07:00
Sebastian McKenzie
75ece96475 v1.10.6 2014-10-28 13:18:47 +11:00
Sebastian McKenzie
b016fda8af add browser.js to .gitignore 2014-10-28 13:18:00 +11:00
Sebastian McKenzie
2cffad61fa more reliable destructuring building 2014-10-28 13:16:31 +11:00
Sebastian McKenzie
4e248c0a16 add member expression destructuring test 2014-10-28 13:16:21 +11:00
Sebastian McKenzie
4f5026101b fix cache-templates build script position - fixes #101 2014-10-28 13:16:08 +11:00
Sebastian McKenzie
4ce38eab37 v1.10.5 2014-10-28 10:59:28 +11:00
Sebastian McKenzie
0a7ce115ff remove browser.js in make publish 2014-10-28 10:58:29 +11:00
Sebastian McKenzie
21ed438fd8 alias functions in scope call wrapping - fixes #99 2014-10-28 10:58:20 +11:00
Sebastian McKenzie
5f9e954d21 v1.10.4 2014-10-28 10:54:18 +11:00
Sebastian McKenzie
a03fd0f43a fix formatting 2014-10-28 10:52:48 +11:00
Sebastian McKenzie
dcc5eaa95e support MemberExpressions in destructuring - fixes #100 2014-10-28 10:52:24 +11:00
Sebastian McKenzie
3b7ce5aaa1 add browser file so we can have a custom browser environment 2014-10-28 10:52:07 +11:00
Sebastian McKenzie
6811f071a9 v1.10.3 2014-10-25 17:24:43 +11:00
Sebastian McKenzie
9abda34e59 simplify transform call chain 2014-10-25 17:23:27 +11:00
Sebastian McKenzie
417ba2bd92 disable uglify benchmark 2014-10-25 17:23:14 +11:00
Sebastian McKenzie
e23f8e92ba remove internal transformer check from ensureTransformerNames #94 2014-10-25 17:23:03 +11:00
Sebastian McKenzie
ef2638eb89 v1.10.2 2014-10-25 13:04:49 +11:00
Sebastian McKenzie
a7d860aab4 fix error stack not getting updated 2014-10-25 13:03:44 +11:00
Sebastian McKenzie
0e3498d785 v1.10.1 2014-10-25 12:57:38 +11:00
Sebastian McKenzie
45fe1d0d47 use my acorn-jsx fork with unicode regex support 2014-10-25 12:56:12 +11:00
Sebastian McKenzie
d5c2647701 add ability to blacklist internal transformers #94 2014-10-25 10:20:11 +11:00
Sebastian McKenzie
af4d8a27aa add --inline-diffs flag to mocha 2014-10-25 09:10:14 +11:00
Sebastian McKenzie
8136b4c40b rename syntax tests to transformation 2014-10-25 09:09:55 +11:00
Sebastian McKenzie
65ba4d35e7 fix jshint errors 2014-10-25 09:09:31 +11:00
Sebastian McKenzie
e09312f127 Merge pull request #92 from jupl/master
Load regenerator runtime only for polyfill
2014-10-25 09:07:13 +11:00
jupl
1b0e42ad03 Load regenerator runtime only for polyfill 2014-10-24 13:02:06 -05:00
Sebastian McKenzie
e21a0d0a8b peg acorn-recast and acorn-ast-types versions 2014-10-23 09:14:04 +11:00
Sebastian McKenzie
ce170f7646 add more custom module formatter documentation 2014-10-23 09:01:29 +11:00
Sebastian McKenzie
5f8420f23e move from ast-types and recast to acorn-ast-types and acorn-recast 2014-10-23 09:00:27 +11:00
Sebastian McKenzie
ce4220644d abstract subclassing into declaration #88 2014-10-23 08:59:52 +11:00
Sebastian McKenzie
aa50a450bd peg esutil version and update to official acorn-jsx release 2014-10-22 22:11:52 +11:00
Sebastian McKenzie
1e6b8d80bb push to arguments instead of an array literal for jsx children 2014-10-22 21:44:08 +11:00
Sebastian McKenzie
035829e726 add custom module formatters 2014-10-22 21:43:43 +11:00
Sebastian McKenzie
2b70df4141 add util.resolve 2014-10-22 21:43:35 +11:00
Sebastian McKenzie
1e7b7b3e0c use acorn-jsx fork 2014-10-22 21:43:24 +11:00
Sebastian McKenzie
b8b670e607 fix regenerator resolution bug, don't depend on 6to5 being linked - closes #85 2014-10-22 07:23:29 +11:00
Sebastian McKenzie
3467d509f7 save old extension handlers so we can put them back if the extensions are hooked again 2014-10-22 07:22:36 +11:00
Sebastian McKenzie
66cc6bea08 add back esutils to dependencies 2014-10-22 07:22:11 +11:00
Sebastian McKenzie
dba935c63d dry up amd and common module formatter export specifiers 2014-10-22 07:21:56 +11:00
Sebastian McKenzie
73f65ae634 fix jshint spacing issues 2014-10-20 08:35:02 +11:00
Sebastian McKenzie
e263757509 simplify amd module formatter 2014-10-20 01:40:23 +11:00
Sebastian McKenzie
b8a80364df Revert "remove jsx and react transformers"
This reverts commit 4241227dbe.
2014-10-19 19:46:18 +11:00
Sebastian McKenzie
19ba55410b downgrade acorn since 0.9.1 isn't in npm 2014-10-19 19:23:13 +11:00
Sebastian McKenzie
c65197f006 better modules summary wording 2014-10-19 19:23:13 +11:00
Sebastian McKenzie
98a04a070f remove esutils and upgrade acorn 2014-10-19 19:23:13 +11:00
Sebastian McKenzie
2bda223001 update unexpected character in bin/6to5 stdin --filename test 2014-10-19 19:23:13 +11:00
Sebastian McKenzie
ddefc09510 fix linting errors 2014-10-19 19:23:13 +11:00
Sebastian McKenzie
489547b77b Merge pull request #84 from thejameskyle/module-docs
Update commonjs modules docs to be consistent
2014-10-19 19:22:53 +11:00
James Kyle
a16685d36d Update commonjs modules docs to be consistent 2014-10-19 01:21:38 -07:00
Sebastian McKenzie
891bbba375 fix Modules - Common link in readme 2014-10-19 17:53:50 +11:00
Sebastian McKenzie
7f2335974b bump dependency versions and remove benchmark transpilers 2014-10-19 17:53:08 +11:00
Sebastian McKenzie
ca597a2306 paragraph module documentation in readme 2014-10-19 17:52:52 +11:00
Sebastian McKenzie
45bab5709f change require("recast").types to require("ast-types") 2014-10-19 17:52:41 +11:00
Sebastian McKenzie
0683591c6c add new module formatters documentation 2014-10-19 17:49:09 +11:00
Sebastian McKenzie
44966849f9 remove useless root variable in umd module formatter 2014-10-19 17:48:59 +11:00
Sebastian McKenzie
e76462303e add umd module formatter - closes #82 2014-10-19 17:39:41 +11:00
Sebastian McKenzie
fceff4b52f add amd module formatter #82 2014-10-19 17:05:24 +11:00
Sebastian McKenzie
209093a3f0 move ImportbatchSpecifier definition to modules transformer 2014-10-19 15:23:37 +11:00
Sebastian McKenzie
7013e970d8 fix acorn to esprima module ast/syntax changes 2014-10-19 14:58:14 +11:00
Sebastian McKenzie
42a7973a9d add support for spreads anywhere in list - fixes #73 2014-10-19 14:52:37 +11:00
Sebastian McKenzie
a75248d2d2 remove jsx from valid extensions since we're now using acorn 2014-10-19 14:21:27 +11:00
Sebastian McKenzie
1f274a3b95 monkeypatch in acorn instead of esprima - immediately fixes #38, fixes #67 @thejameskyle 2014-10-19 13:21:56 +11:00
Sebastian McKenzie
5bc4dfc14c add base umd and amd module formatter tests 2014-10-19 13:17:21 +11:00
Sebastian McKenzie
4241227dbe remove jsx and react transformers 2014-10-19 13:17:02 +11:00
Sebastian McKenzie
a1adca6b65 add support for custom module formatters - #82 2014-10-19 12:11:12 +11:00
784 changed files with 8658 additions and 3260 deletions

4
.gitignore vendored
View File

@@ -4,5 +4,9 @@ test/tmp
*.log
*.cache
/templates.json
/tests.json
/browser.js
/browser-polyfill.js
/runtime.js
coverage
dist

3
.hound.yml Normal file
View File

@@ -0,0 +1,3 @@
java_script:
enabled: true
config_file: .jshintrc

View File

@@ -17,5 +17,13 @@
"loopfunc": true,
"white": true,
"maxparams": 5,
"maxdepth": 4
"maxdepth": 4,
"globals": {
"window": true,
"suite": true,
"set": true,
"before": true,
"bench": true
}
}

View File

@@ -7,4 +7,5 @@ benchmark
Makefile
.*
dist
!README.md
tests.json
CHANGELOG.md

View File

@@ -3,10 +3,17 @@ node_js:
- "0.10"
- "0.11"
branches:
except:
- experimental
before_script: "npm install -g codeclimate-test-reporter"
script: "make test-travis"
addons:
code_climate:
repo_token:
secure: "PfP9sDUJzSznDb+ZEPO2cignXabSTXJxEVm5ESRPgEcFr+/4b0pt3hI8R9b+9mLtBEwtw3DLUq48MOeqEKnq29csQmpjPVcN6gT4uR2DdNa1JpVgDuwxT05NB3fBea9U2reM73iV8ylCgPHExr2uGR9/87JzR2beY/56EUL5NjY="
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/acf1870e9d223c65e8d5
on_success: always
on_failure: always
on_start: false

50
CHANGELOG.md Normal file
View File

@@ -0,0 +1,50 @@
# 1.12.7
* Update to latest `acorn-6to5`.
# 1.12.6
* Update to latest `acorn-6to5`.
# 1.12.5
* Fix excessive whitespace trimming resulting in innaccurate sourcemap line.
# 1.12.4
* Add `doc` folder for documentation.
# 1.12.3
* Support generator comprehensions.
* Use `Array.from` instead of `Array.prototype.slice` in spread transformer.
* Support spread in `NewExpression`s.
# 1.12.2
* Upgrade `matcha` to `0.6.0` and `browserify` to `6.3.2`.
* Add own `trimRight` helper instead of relying on the string instance method.
* Support JSX spreads that aren't the first.
# 1.12.1
* Fix `this` and `arguments` mapping in the `_aliasFunctions` transformer.
# 1.12.0
* Combine `jsx` and `react` transformers to `react`.
* Update `react` syntax output to React v0.12.
# 1.11.15
* Fix JSX literal whitespace generation.
# 1.11.14
* Avoid using a switch for let-scoping continue and break statements and use an if statement instead.
* Remove excess whitespace and newlines from JSX literals.
# 1.11.13
* Update regenerator-6to5
* Add support for most escodegen formatting options

View File

@@ -1,32 +1,50 @@
BROWSERIFY_CMD = node_modules/browserify/bin/cmd.js
ISTANBUL_CMD = node_modules/istanbul/lib/cli.js cover
UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
JSHINT_CMD = node_modules/jshint/bin/jshint
MOCHA_CMD = node_modules/mocha/bin/_mocha
export NODE_ENV = test
.PHONY: clean test test-cov test-travis test-browser publish bench build
.PHONY: clean test test-cov test-clean lint test-travis test-spec test-browser publish bench build
clean:
rm -rf coverage templates.json test/tmp dist
bench:
npm install es6-transpiler traceur esnext es6now jstransform
node node_modules/matcha/bin/_matcha
lint:
$(JSHINT_CMD) lib bin benchmark/index.js
test-clean:
rm -rf test/tmp
test:
$(JSHINT_CMD) lib
make lint
$(MOCHA_CMD)
make test-clean
test-cov:
rm -rf coverage
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
test-travis:
test-spec:
node $(ISTANBUL_CMD) $(MOCHA_CMD) -- --reporter spec
test-travis:
make test-spec
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi
test-browser:
make build
node bin/generate-browser-test >dist/6to5-test.js
mkdir -p dist
node bin/cache-templates
node bin/cache-tests
node $(BROWSERIFY_CMD) -e test/_browser.js >dist/6to5-test.js
rm -rf templates.json tests.json
test -n "`which open`" && open test/browser.html
build:
@@ -34,8 +52,14 @@ build:
node bin/cache-templates
browserify lib/6to5/transform.js -s to5 >dist/6to5.js
uglifyjs dist/6to5.js >dist/6to5.min.js
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
node $(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
@@ -44,6 +68,11 @@ publish:
make test
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 bin/cache-templates
test -f templates.json
@@ -53,4 +82,4 @@ publish:
git push --follow-tags
rm -rf templates.json
rm -rf templates.json browser.js runtime.js browser-polyfill.js

399
README.md
View File

@@ -1,400 +1,29 @@
<p align="center">
<img alt="6to5" src="http://i.imgur.com/hVl9KRw.png">
<img alt="6to5" src="https://raw.githubusercontent.com/6to5/logo/master/logo.png" width="546">
</p>
<p align="center">
<a href="https://travis-ci.org/sebmck/6to5">
<img alt="Travis Status" src="http://img.shields.io/travis/sebmck/6to5.svg?style=flat&amp;label=travis">
<a href="https://travis-ci.org/6to5/6to5">
<img alt="Travis Status" src="http://img.shields.io/travis/6to5/6to5.svg?branch=master&amp;style=flat&amp;label=travis">
</a>
<a href="https://codeclimate.com/github/sebmck/6to5">
<img alt="Code Climate Score" src="http://img.shields.io/codeclimate/github/sebmck/6to5.svg?style=flat">
<a href="https://ci.appveyor.com/project/sebmck/6to5">
<img alt="Appveyor Status" src="http://img.shields.io/appveyor/ci/sebmck/6to5.svg?style=flat&amp;label=appveyor">
</a>
<a href="https://codeclimate.com/github/sebmck/6to5">
<img alt="Coverage" src="http://img.shields.io/codeclimate/coverage/github/sebmck/6to5.svg?style=flat">
<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://david-dm.org/sebmck/6to5">
<img alt="Dependency Status" src="http://img.shields.io/david/sebmck/6to5.svg?style=flat">
<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>
**6to5** turns ES6 code into vanilla ES5, so you can use ES6 features **today.**
- **Readable** - formatting is retained if possible so your generated code is as similar as possible.
- **Extensible** - with a large range of [plugins](#plugins) and **browser support**.
- **Lossless** - **source map support** so you can debug your compiled code with ease.
- **Compact** - maps directly to the equivalent ES5 with **no runtime**[\*](#generators).
## Installation
It's as easy as:
$ npm install -g 6to5
## Table of Contents
- [Features](#features)
- [Usage](#usage)
- [Plugins](#plugins)
- [CLI](#cli)
- [Node](#node-1)
- [Browser](#browser)
- [Modules](#modules)
- [Caveats](#caveats)
- [Differences](#differences)
## [Features](FEATURES.md)
- [Array comprehension](FEATURES.md#array-comprehension)
- [Arrow functions](FEATURES.md#arrow-functions)
- [Classes](FEATURES.md#classes)
- [Computed property names](FEATURES.md#computed-property-names)
- [Constants](FEATURES.md#constants)
- [Default parameters](FEATURES.md#default-parameters)
- [Destructuring](FEATURES.md#destructuring)
- [For-of](FEATURES.md#for-of)
- [Generators](FEATURES.md#generators) via [regenerator](https://github.com/facebook/regenerator)
- [Let scoping](FEATURES.md#let-scoping)
- [Modules](FEATURES.md#modules)
- [Numeric literals](FEATURES.md#numeric-literals)
- [Property method assignment](FEATURES.md#property-method-assignment)
- [Property name shorthand](FEATURES.md#property-name-shorthand)
- [Rest parameters](FEATURES.md#rest-parameters)
- [Spread](FEATURES.md#spread)
- [Template literals](FEATURES.md#template-literals)
- [Unicode regex](FEATURES.md#unicode-regex)
## Usage
### Plugins
- [Broccoli](https://github.com/very-geek/broccoli-6to5-transpiler)
- [Browserify](https://github.com/sebmck/6to5-browserify)
- [Brunch](https://github.com/es128/6to5-brunch)
- [Connect](https://github.com/sebmck/6to5-connect)
- [Gulp](https://github.com/sindresorhus/gulp-6to5)
- [Grunt](https://github.com/sindresorhus/grunt-6to5)
- [Jade](https://github.com/Apoxx/jade-6to5)
- [webpack](https://github.com/Couto/6to5-loader)
### CLI
Compile the file `script.js` and output it to stdout.
$ 6to5 script.js
Compile the file `script.js` and output it to `script-compiled.js`.
$ 6to5 script.js --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` and save a
source map to `script-compiled.js.map`.
$ 6to5 script.js --source-maps --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` with a source
map embedded in a comment at the bottom.
$ 6to5 script.js --source-maps-inline --out-file script-compiled.js
Compile the entire `src` directory and output it to the `lib` directory.
$ 6to5 src --out-dir lib
Pipe a file in via stdin and output it to `script-compiled.js`
$ 6to5 --out-file script-compiled.js < script.js
#### Node
Launch a repl.
$ 6to5-node
Evaluate code.
$ 6to5-node -e "class Test { }"
Compile and run `test.js`.
$ 6to5-node test
### Node
```javascript
var to5 = require("6to5");
var result = to5.transform("code();", options);
result.code;
result.map;
result.ast;
to5.transformFileSync("filename.js", options).code;
to5.transformFile("filename.js", options, function (err, result) {
});
```
##### Options
```javascript
{
// Filename for use in errors etc.
// Default: "unknown"
filename: "filename",
// List of transformers to EXCLUDE.
// Run `6to5 --help` to see a full list of transformers.
blacklist: [],
// List of transformers to ONLY use.
// Run `6to5 --help` to see a full list of transformers.
whitelist: [],
// If truthy, adds a `map` property to returned output.
// If set to "inline", a comment with a sourceMappingURL directive is added to
// the bottom of the returned code.
// Default: false
sourceMap: true,
// Set `file` on returned source map.
// Default: `filename` option.
sourceMapName: "filename",
// Set `sources[0]` on returned source map.
// Default: `filename` option.
sourceFileName: "filename"
}
```
#### Require hook
All subsequent files required by node with the extensions `.es6` and `.js` will
be transformed by 6to5. The polyfill specified in [Polyfill](#polyfill) is also
required.
```javascript
require("6to5/register");
```
**NOTE:** By default all requires to `node_modules` will be ignored. You can
override this by passing an ignore regex via:
```javascript
require("6to5/register")(/regex/);
```
You can also customise the file extensions that the require hook will use via:
```javascript
require("6to5/register")({
// optional ignore regex
ignoreRegex: /regex/,
// this will remove the currently hooked extensions of .es6 and .js so you'll
// have to add them back if you want them to be used again
extensions: [".js", ".es6"]
});
```
### Browser
You can build a browser version of the compiler by running the following in the
6to5 directory:
$ make build
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
Just include one of those in the browser and access the transform method via the
global `to5`.
```javascript
to5("class Test {}").code;
```
#### Test
To test 6to5 in your browser run:
$ make test-browser
And open `test/browser.html` in your browser if it doesn't open automatically.
## Modules
6to5 modules compile straight to CommonJS, because of this various liberties are
taken into account to make their usage easier.
```javascript
import "foo"; // require("foo");
import foo from "foo"; // var foo = require("foo").default;
import * as foo from "foo"; // var foo = require("foo");
import {bar} from "foo"; // var bar = require("foo").bar;
import {foo as bar} from "foo"; // var bar = require("foo").foo;
export {test}; // exports.test = test;
export var test = 5; // var test = 5; exports.test = test;
export default test; // exports.default = test;
```
If you'd like to disable this behaviour and use the more ES6-like
[es6-module-transpiler](https://github.com/esnext/es6-module-transpiler) you can
use the following:
$ 6to5 script.js -o script-compiled.js --blacklist modules
$ compile-modules convert script-compiled.js -o script-compiled.js
## Caveats
### Polyfill
6to5 does not include a runtime nor polyfill and it's up to the developer to
include one in compiled browser code.
#### Node
A polyfill is included with the 6to5 module that can be included in node like
so:
```javascript
require("6to5/polyfill");
```
This is simply a wrapper around the
[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the
[es6-shim](https://github.com/paulmillr/es6-shim) and
[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills.
#### Browser
If you're planning on using 6to5 output in the browser then it's up to you
to include polyfills. [es6-symbol](https://github.com/medikoo/es6-symbol#browser)
and [es6-shim](https://raw.githubusercontent.com/paulmillr/es6-shim/master/es6-shim.js)
fill the vast majority of polyfill concerns.
### For-of
A polyfill is required for for-of functionality that implements `Symbol` and
adds `prototype[Symbol.iterator]` behaviour to built-ins. Using the polyfills
specified in [polyfill](#polyfill) suffices.
### Classes
Built-in classes such as `Date`, `Array` and `DOM` cannot be subclassed due to
limitations in ES5 implementations.
If you're inheriting from a class then static properties are inherited from it
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
this is widely supported but you may run into problems with much older browsers.
### Generators
The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js)
and an [ES6 polyfill](#polyfill) are required in order for generators to work.
## Differences
### Philosophy
The fundamental concept behind 6to5 is that the generated code must be close as
possible to the original, retaining all the same formatting and readability.
Many other transpilers are just concerned with making the code work while 6to5
is concerned with making sure it works **and** is readable at the same time.
For example, given the following array comprehension:
```javascript
var seattlers = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }];
```
is generated to the following with 6to5:
```javascript
var seattlers = customers.filter(function (c) {
return c.city == "Seattle";
}).map(function (c) {
return {
name: c.name,
age: c.age
};
});
```
The following is what Traceur generates:
```javascript
var seattlers = (function() {
var c;
var $__20 = 0,
$__21 = [];
for (var $__22 = customers[$traceurRuntime.toProperty(Symbol.iterator)](),
$__23; !($__23 = $__22.next()).done; ) {
c = $__23.value;
if (c.city == "Seattle")
$traceurRuntime.setProperty($__21, $__20++, {
name: c.name,
age: c.age
});
}
return $__21;
}());
```
As you can tell, it's not very pretty, unreadable even. Instead of mapping
directly to a runtime, like other transpilers, 6to5 maps directly to the
equivalent ES5.
I'm not saying 6to5 is for everyone or even suited for everything. Traceur is
better suited if you'd like a full ES6 environment with polyfills and all.
### Comparison to other transpilers
| | 6to5 | Traceur | esnext | es6now | es6-transpiler | jstransform |
| ---------------------------- | ---- | ------- | ------ | ------ | -------------- | ----------- |
| No runtime | ✓ | | | | ✓ | ✓ |
| Source maps | ✓ | ✓ | ✓ | | ✓ | ✓ |
| No compiler global pollution | ✓ | | ✓ | | ✓ | ✓ |
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Constants | ✓ | ✓ | | | ✓ | |
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Generators | ✓ | ✓ | ✓ | | | |
| Let scoping | ✓ | ✓ | | | ✓ | |
| Modules | ✓ | ✓ | | ✓ | | |
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Unicode regex | ✓ | ✓ | | | ✓ | |
#### [Traceur](https://github.com/google/traceur-compiler)
Traceur requires quite a bulky runtime (~75KB) and produces quite verbose code.
While this can be trimmed down by selectively building the runtime, it's an
unneccesary step when a runtime can be eliminated entirely.
#### [es6now](https://github.com/zenparsing/es6now)
es6now doesn't output sourcemaps. This is cited as a positive as line-to-line
mapping is the goal. This however obviously doesn't retain column mapping
resulting in the output code not being very pleasant.
#### [es6-transpiler](https://github.com/termi/es6-transpiler)
The es6-transpiler compiler requires shims to operate which pollutes the global
scope resulting in possible collisions.
es6-transpiler maps line-by-line, just like es6now, this results in the same
issues such as lack of column information and unpleasant code output.
For more information view the [documentation](https://6to5.github.io).

17
appveyor.yml Normal file
View File

@@ -0,0 +1,17 @@
environment:
matrix:
- nodejs_version: "0.10"
- nodejs_version: "0.11"
install:
- "npm install"
- "cinst make"
test_script:
- "node --version"
- "npm --version"
- "make test-spec"
build: "off"
version: "{build}"

View File

@@ -7,17 +7,19 @@ var es6now = require("es6now");
var esnext = require("esnext");
var to5 = require("../lib/6to5");
var uglify = require("uglify-js");
//var uglify = require("uglify-js");
var matcha = require("matcha");
var stream = require("stream");
var path = require("path");
var zlib = require("zlib");
var fs = require("fs");
var vm = require("vm");
var _ = require("lodash");
var readResolve = function (filename) {
return fs.readFileSync(require.resolve(filename), "utf8");
try {
filename = require.resolve(filename);
} catch (err) {
return null;
}
return fs.readFileSync(filename, "utf8");
};
var getVersion = function (name) {
@@ -38,6 +40,7 @@ _.each([
var compilers = {
"6to5": {
version: getVersion(".."),
compile: function (code, filename) {
return to5.transform(code, { filename: filename }).code;
}
@@ -45,7 +48,7 @@ var compilers = {
traceur: {
runtime: readResolve("traceur/bin/traceur-runtime.js"),
compile: function (code, filename) {
compile: function (code) {
return traceur.compile(code, {
modules: "commonjs",
experimental: true
@@ -54,21 +57,21 @@ var compilers = {
},
esnext: {
runtime: readResolve("esnext/node_modules/regenerator/runtime.js"),
compile: function (code, filename) {
runtime: readResolve("esnext/node_modules/regenerator/runtime.js") || readResolve("regenerator/runtime.js"),
compile: function (code) {
return esnext.compile(code).code;
}
},
es6now: {
runtime: readResolve("es6now/runtime/ES6.js"),
compile: function (code, filename) {
compile: function (code) {
return es6now.translate(code);
}
},
"es6-transpiler": {
compile: function (code, filename) {
compile: function (code) {
var result = es6tr.run({ src: code });
if (result.errors.length) throw new Error(result.join("; "));
return result.src;
@@ -76,7 +79,7 @@ var compilers = {
},
jstransform: {
compile: function (code, filename) {
compile: function (code) {
return jsTrans.transform(jsTransVisitors, code).code;
}
}
@@ -84,10 +87,10 @@ var compilers = {
// versions
var uglifyTitle = "uglify v" + getVersion("uglify-js");
//var uglifyTitle = "uglify v" + getVersion("uglify-js");
_.each(compilers, function (compiler, name) {
compiler.title = name + " v" + getVersion(name);
compiler.title = name + " v" + (compiler.version || getVersion(name));
});
//
@@ -96,14 +99,13 @@ var sizeBenchmark = function (code, loc, name, compiler) {
var log = function (output, title) {
title = [compiler.title].concat(title || []).join(" + ");
var kilo = (output.length / 1024).toFixed(2);
var text;
var color;
if (output === false) {
if (output.stack) {
text = "error";
color = "red";
} else {
var kilo = (output.length / 1024).toFixed(2);
text = kilo + "KB";
color = "cyan";
}
@@ -111,6 +113,10 @@ var sizeBenchmark = function (code, loc, name, compiler) {
text = matcha.utils.color(matcha.utils.padBefore(text, 22), color);
console.log(text, matcha.utils.color("» " + title, "gray"));
if (output.stack) {
console.error(output.stack);
}
};
var go = function (getOutput, title) {
@@ -118,7 +124,7 @@ var sizeBenchmark = function (code, loc, name, compiler) {
try {
code = getOutput();
} catch (err) {
log(false, title);
log(err, title);
return;
}
@@ -127,13 +133,13 @@ var sizeBenchmark = function (code, loc, name, compiler) {
var output;
go(function () {
return output = output || compiler.compile(code, loc);
return output = compiler.compile(code, loc);
});
if (!output) return;
go(function () {
return uglify.minify(output, { fromString: true }).code;
}, uglifyTitle);
//go(function () {
// return uglify.minify(output, { fromString: true }).code;
//}, uglifyTitle);
};
//
@@ -153,7 +159,7 @@ _.each(fs.readdirSync(__dirname + "/fixtures"), function (name) {
});
});
_.each(compilers, function (compiler, name) {
_.each(compilers, function (compiler) {
bench(compiler.title, function () {
compiler.compile(code, loc);
});

View File

@@ -1,84 +1,56 @@
#!/usr/bin/env node
var commander = require("commander");
var Module = require("module");
var util = require("../lib/6to5/util");
var path = require("path");
var repl = require("repl");
var to5 = require("../lib/6to5");
var vm = require("vm");
var _ = require("lodash");
/**
* This tiny wrapper file checks for known node flags and appends them
* when found, before invoking the "real" _6to5-node(1) executable.
*/
commander.option("-e, --eval [script]", "evaluate script");
commander.option("-p, --print", "evaluate script and print result");
commander.option("-i, --ignore [regex]", "ignore all files that match this regex when using the require hook");
commander.option("-x, --extensions [extensions]", "list of extensions to hook into [.es6,.js]", util.list);
var spawn = require("child_process").spawn;
var args = ["--harmony", __dirname + "/_6to5-node"];
var pkg = require("../package.json");
commander.version(pkg.version);
commander.usage("[options] [ -e script | script.js ] [arguments]");
commander.parse(process.argv);
process.argv.slice(2).forEach(function(arg){
var flag = arg.split("=")[0];
//
var registerOpts = {};
if (commander.ignore) {
registerOpts.ignoreRegex = new RegExp(commander.ignore);
}
if (commander.extensions && commander.extensions.length) {
registerOpts.extensions = commander.extensions
}
to5.register(registerOpts);
//
var _eval = function (code, filename) {
code = to5.transform(code, { filename: filename }).code;
return vm.runInThisContext(code, filename);
};
if (commander.eval) {
var result = _eval(commander.eval, "eval");
if (commander.print) console.log(result);
} else {
var filenames = commander.args;
if (filenames.length) {
_.each(filenames, function (filename) {
if (!util.isAbsolute(filename)) {
filename = path.join(process.cwd(), filename);
}
require(require.resolve(filename));
});
} else {
replStart();
switch (flag) {
case "-d":
args.unshift("--debug");
args.push("--no-timeouts");
break;
case "debug":
case "--debug":
case "--debug-brk":
args.unshift(arg);
args.push("--no-timeouts");
break;
case "-gc":
case "--expose-gc":
args.unshift("--expose-gc");
break;
case "--gc-global":
case "--harmony":
case "--harmony-proxies":
case "--harmony-collections":
case "--harmony-generators":
case "--no-deprecation":
case "--prof":
case "--throw-deprecation":
case "--trace-deprecation":
args.unshift(arg);
break;
default:
if (0 == arg.indexOf("--trace")) args.unshift(arg);
else args.push(arg);
break;
}
}
});
function replStart() {
repl.start({
prompt: "> ",
input: process.stdin,
output: process.stdout,
eval: replEval,
useGlobal: true
var proc = spawn(process.argv[0], args, { stdio: "inherit" });
proc.on("exit", function (code, signal) {
process.on("exit", function (){
if (signal) {
process.kill(process.pid, signal);
} else {
process.exit(code);
}
});
}
function replEval(code, context, filename, callback) {
var err;
var result;
try {
code = code.slice(1, -2); // remove "(" and "\n)"
result = _eval(code, filename);
} catch (e) {
err = e;
}
callback(err, result);
}
});

4
bin/6to5-runtime Executable file
View File

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

View File

@@ -6,7 +6,7 @@ var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
module.exports = function (commander, filenames, opts) {
module.exports = function (commander, filenames) {
var results = [];
var buildResult = function () {
@@ -48,7 +48,7 @@ module.exports = function (commander, filenames, opts) {
return {
map: map,
code: code
}
};
};
var output = function () {
@@ -100,8 +100,8 @@ module.exports = function (commander, filenames, opts) {
}
});
_.each(_filenames, function (filename, i) {
results.push(util.compile(filename, { _noStrict: i != 0 }));
_.each(_filenames, function (filename) {
results.push(util.compile(filename));
});
output();

View File

@@ -1,13 +1,8 @@
#!/usr/bin/env node
var commander = require("commander");
var sourceMap = require("source-map");
var transform = require("../../lib/6to5/transform");
var chokidar = require("chokidar");
var mkdirp = require("mkdirp");
var util2 = require("../../lib/6to5/util");
var util = require("./util");
var path = require("path");
var transform = require("../../lib/6to5/transformation/transform");
var util = require("../../lib/6to5/util");
var fs = require("fs");
var _ = require("lodash");
@@ -15,20 +10,29 @@ commander.option("-t, --source-maps-inline", "Append sourceMappingURL comment to
commander.option("-s, --source-maps", "Save source map alongside the compiled code");
commander.option("-f, --filename [filename]", "Filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]", "stdin");
commander.option("-w, --watch", "Recompile files on changes");
commander.option("-r, --runtime", "Replace 6to5 declarations with references to a runtime");
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util2.list);
commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util2.list);
commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common");
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list);
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
commander.on("--help", function(){
console.log(" Transformers:");
console.log();
_.each(_.keys(transform.transformers).sort(), function (key) {
if (key[0] === "_") return;
console.log(" - " + key);
});
console.log();
var outKeys = function (title, obj) {
console.log(" " + title + ":");
console.log();
_.each(_.keys(obj).sort(), function (key) {
if (key[0] === "_") return;
console.log(" - " + key);
});
console.log();
};
outKeys("Transformers", transform.transformers);
outKeys("Module formatters", transform.moduleFormatters);
});
var pkg = require("../../package.json");
@@ -83,7 +87,9 @@ exports.opts = {
sourceMapName: commander.outFile,
blacklist: commander.blacklist,
whitelist: commander.whitelist,
sourceMap: commander.sourceMaps || commander.sourceMapsInline
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
runtime: commander.runtime,
modules: commander.modules
};
var fn;

View File

@@ -6,7 +6,9 @@ var fs = require("fs");
var _ = require("lodash");
exports.readdirFilter = function (filename) {
return readdir(filename).filter(util.canCompile);
return readdir(filename).filter(function (filename) {
return util.canCompile(filename);
});
};
exports.transform = function (filename, code, opts) {

86
bin/_6to5-node Normal file
View File

@@ -0,0 +1,86 @@
#!/usr/bin/env node
var commander = require("commander");
var path = require("path");
var repl = require("repl");
var to5 = require("../lib/6to5");
var util = require("../lib/6to5/util");
var vm = require("vm");
var _ = require("lodash");
commander.option("-e, --eval [script]", "evaluate script");
commander.option("-p, --print", "evaluate script and print result");
commander.option("-i, --ignore [regex]", "ignore all files that match this regex when using the require hook");
commander.option("-x, --extensions [extensions]", "list of extensions to hook into [.es6,.js]", util.list);
var pkg = require("../package.json");
commander.version(pkg.version);
commander.usage("[options] [ -e script | script.js ] [arguments]");
commander.parse(process.argv);
//
var registerOpts = {};
if (commander.ignore) {
registerOpts.ignoreRegex = new RegExp(commander.ignore);
}
if (commander.extensions && commander.extensions.length) {
registerOpts.extensions = commander.extensions;
}
to5.register(registerOpts);
//
var _eval = function (code, filename) {
code = to5.transform(code, { filename: filename, blacklist: ["useStrict"] }).code;
return vm.runInThisContext(code, filename);
};
if (commander.eval) {
var result = _eval(commander.eval, "eval");
if (commander.print) console.log(result);
} else {
var filenames = commander.args;
if (filenames.length) {
_.each(filenames, function (filename) {
if (!util.isAbsolute(filename)) {
filename = path.join(process.cwd(), filename);
}
require(require.resolve(filename));
});
} else {
replStart();
}
}
function replStart() {
repl.start({
prompt: "> ",
input: process.stdin,
output: process.stdout,
eval: replEval,
useGlobal: true
});
}
function replEval(code, context, filename, callback) {
var err;
var result;
try {
if (/^\((.*?)\n\)$/.test(code)) {
code = code.slice(1, -2); // remove "(" and "\n)"
}
result = _eval(code, filename);
} catch (e) {
err = e;
}
callback(err, result);
}

5
bin/cache-tests Normal file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env node
var fs = require("fs");
var cache = require("../test/_helper").cache;
fs.writeFileSync("tests.json", JSON.stringify(cache));

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env node
var helper = require("../test/_helper");
var util = require("../lib/6to5/util");
console.log("(" + helper.run + ")(" + JSON.stringify(helper.getTests()) + ", to5, proclaim)");

49
doc/browser.md Normal file
View File

@@ -0,0 +1,49 @@
# Browser
A browser version of 6to5 is available from `browser.js` inside the 6to5
directory in an npm release.
## API
```javascript
to5.transform("class Test {}").code;
```
## Scripts
While it's not recommended for serious use, when the browser version is included
all scripts with the type `text/ecmascript-6` and `text/6to5` are automatically
compiled and ran.
For example:
```html
<script src="node_modules/6to5/browser.js"></script>
<script type="text/6to5">
class Test {
test() {
return "test";
}
}
var test = new Test;
test.test();
</script>
```
## Build
You can build a browser version of the compiler by running the following in the
6to5 directory:
$ make build
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
## Test
To test 6to5 in your browser run:
$ make test-browser
And open `test/browser.html` in your browser if it doesn't open automatically.

43
doc/caveats.md Normal file
View File

@@ -0,0 +1,43 @@
# Caveats
## Classes
Built-in classes such as `Date`, `Array` and `DOM` cannot be subclassed due to
limitations in ES5 implementations.
If you're inheriting from a class then static properties are inherited from it
via [\_\_proto\_\_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto),
this is widely supported but you may run into problems with much older browsers.
**NOTE:** `__proto__` is not supported on IE <= 9 so static properties
**will not** be inherited. A possible workaround is to use `super();`:
```javascript
class Foo {
static foo() {
}
}
class Bar extends Foo {
static foo() {
super();
}
}
```
## For-of
A polyfill is required for for-of functionality that implements `Symbol` and
adds `prototype[Symbol.iterator]` behaviour to built-ins. Using the polyfills
specified in [polyfill](polyfill.md) suffices.
## Generators
The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js)
and an [ES6 polyfill](polyfill.md) are required in order for generators to work.
## Spread
An [ES6 polyfill](polyfill.md) is required in order for spread to work. More
specifically a polyfill for `Array.from`.

103
doc/differences.md Normal file
View File

@@ -0,0 +1,103 @@
# Differences
## Philosophy
The fundamental concept behind 6to5 is that the generated code must be close as
possible to the original, retaining all the same formatting and readability.
Many other transpilers are just concerned with making the code work while 6to5
is concerned with making sure it works **and** is readable at the same time.
For example, given the following array comprehension:
```javascript
var seattlers = [for (c of customers) if (c.city == "Seattle") { name: c.name, age: c.age }];
```
is generated to the following with 6to5:
```javascript
var seattlers = customers.filter(function (c) {
return c.city == "Seattle";
}).map(function (c) {
return {
name: c.name,
age: c.age
};
});
```
The following is what Traceur generates:
```javascript
var seattlers = (function() {
var c;
var $__20 = 0,
$__21 = [];
for (var $__22 = customers[$traceurRuntime.toProperty(Symbol.iterator)](),
$__23; !($__23 = $__22.next()).done; ) {
c = $__23.value;
if (c.city == "Seattle")
$traceurRuntime.setProperty($__21, $__20++, {
name: c.name,
age: c.age
});
}
return $__21;
}());
```
As you can tell, it's not very pretty, unreadable even. Instead of mapping
directly to a runtime, like other transpilers, 6to5 maps directly to the
equivalent ES5.
I'm not saying 6to5 is for everyone or even suited for everything. Traceur is
better suited if you'd like a full ES6 environment with polyfills and all.
## Comparison to other transpilers
| | 6to5 | Traceur | esnext | es6now | es6-transpiler | jstransform |
| ---------------------------- | ---- | ------- | ------ | ------ | -------------- | ----------- |
| No runtime | ✓ | | | | ✓ | ✓ |
| Source maps | ✓ | ✓ | ✓ | | ✓ | ✓ |
| No compiler global pollution | ✓ | | ✓ | | ✓ | ✓ |
| Browser support | ✓ | ✓ | ✓ | | | |
| Array comprehension | ✓ | ✓ | | | ✓ | |
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Async functions | ✓ | | ✓ | | | |
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Constants | ✓ | ✓ | | | ✓ | |
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Generators | ✓ | ✓ | ✓ | | | |
| Generator comprehension | ✓ | ✓ | | | | |
| Let scoping | ✓ | ✓ | | | ✓ | |
| Modules | ✓ | ✓ | | ✓ | | |
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Unicode regex | ✓ | ✓ | | | ✓ | |
### [Traceur](https://github.com/google/traceur-compiler)
Traceur requires quite a bulky runtime (~75KB) and produces quite verbose code.
While this can be trimmed down by selectively building the runtime, it's an
unneccesary step when a runtime can be eliminated entirely.
### [es6now](https://github.com/zenparsing/es6now)
es6now doesn't output sourcemaps. This is cited as a positive as line-to-line
mapping is the goal. This however obviously doesn't retain column mapping
resulting in the output code not being very pleasant.
### [es6-transpiler](https://github.com/termi/es6-transpiler)
The es6-transpiler compiler requires shims to operate which pollutes the global
scope resulting in possible collisions.
es6-transpiler maps line-by-line, just like es6now, this results in the same
issues such as lack of column information and unpleasant code output.

View File

@@ -6,6 +6,16 @@
[for (i of [1, 2, 3]) i * i]; // [1, 4, 9]
```
## Async functions
```javascript
async function chainAnimationsAsync(elem, animations) {
for (var anim of animations) {
await anim(elem);
}
}
```
## Arrow functions
```javascript
@@ -85,6 +95,11 @@ for (var i of [1, 2, 3]) {
```javascript
```
## Generator comprehension
```javascript
```
## Modules
```javascript

36
doc/index.md Normal file
View File

@@ -0,0 +1,36 @@
**6to5** turns ES6 code into vanilla ES5, so you can use ES6 features **today.**
- **Readable** - formatting is retained if possible so your generated code is as similar as possible.
- **Extensible** - with a large range of [plugins](plugins.md) and **browser support**.
- **Lossless** - **source map support** so you can debug your compiled code with ease.
- **Compact** - maps directly to the equivalent ES5 with **no runtime**[\*](caveats.md#generators).
## Installation
It's as easy as:
$ npm install -g 6to5
## [Features](features.md)
- [Array comprehension](features.md#array-comprehension)
- [Async functions](features.md#async-functions) via [regenerator](https://github.com/facebook/regenerator)
- [Arrow functions](features.md#arrow-functions)
- [Classes](features.md#classes)
- [Computed property names](features.md#computed-property-names)
- [Constants](features.md#constants)
- [Default parameters](features.md#default-parameters)
- [Destructuring](features.md#destructuring)
- [For-of](features.md#for-of)
- [Generators](features.md#generators) via [regenerator](https://github.com/facebook/regenerator)
- [Generator comprehension](features.md#generator-comprehension)
- [Let scoping](features.md#let-scoping)
- [Modules](features.md#modules)
- [Numeric literals](features.md#numeric-literals)
- [Property method assignment](features.md#property-method-assignment)
- [Property name shorthand](features.md#property-name-shorthand)
- [React/JSX](react.md)
- [Rest parameters](features.md#rest-parameters)
- [Spread](features.md#spread)
- [Template literals](features.md#template-literals)
- [Unicode regex](features.md#unicode-regex)

170
doc/modules.md Normal file
View File

@@ -0,0 +1,170 @@
# Modules
## Usage
### CLI
$ 6to5 --modules common script.js
### Node
```javascript
var to5 = require("6to5");
to5.transform('import "foo";', { modules: "common" });
```
## Formats
### Common (Default)
**In**
```javascript
import "foo";
import foo from "foo";
import * as foo from "foo";
import {bar} from "foo";
import {foo as bar} from "foo";
export {test};
export var test = 5;
export default test;
```
**Out**
```javascript
require("foo");
var foo = require("foo").default;
var foo = require("foo");
var bar = require("foo").bar;
var bar = require("foo").foo;
exports.test = test;
var test = 5; exports.test = test;
exports.default = test;
```
### AMD
**In**
```javascript
import foo from "foo";
export function bar() {
return foo("foobar");
}
```
**Out**
```javascript
define(["exports", "foo"], function (exports, _foo) {
exports.bar = bar;
var foo = _foo.default;
function bar() {
return foo("foobar");
}
});
```
### UMD
**In**
```javascript
import foo from "foo";
export function bar() {
return foo("foobar");
}
```
**Out**
```javascript
(function (factory) {
if (typeof define === "function" && define.amd) {
define(["exports", "foo"], factory);
} else if (typeof exports !== "undefined") {
factory(exports, require("foo"));
}
})(function (exports) {
exports.bar = bar;
var foo = _foo.default;
function bar() {
return foo("foobar");
}
});
```
### Ignore
**In**
```javascript
import foo from "foo";
export function bar() {
return foo("foobar");
}
```
**Out**
```javascript
function bar() {
return foo("foobar");
}
```
## Custom
You can alternatively specify module names instead of one of the built-in types.
$ 6to5 --modules custom-module-formatter
**node_modules/custom-module-formatter/index.js**
```javascript
module.exports = ModuleFormatter;
function ModuleFormatter() {
}
ModuleFormatter.prototype.transform = function (ast) {
// this is ran after all transformers have had their turn at modifying the ast
// feel free to modify this however
};
ModuleFormatter.prototype.import = function (node, nodes) {
// node is an ImportDeclaration
};
ModuleFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
// specifier is an ImportSpecifier
// node is an ImportDeclaration
};
ModuleFormatter.prototype.export = function (node, nodes) {
// node is an ExportDeclaration
};
ModuleFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
// specifier is an ExportSpecifier
// node is an ExportDeclaration
};
```

51
doc/optional-runtime.md Normal file
View File

@@ -0,0 +1,51 @@
# Optional runtime
6to5 has a few helper functions that'll be placed at the top of the generated
code if needed so it's not inlined multiple times throughout that file. This may
become an issue if you have multiple files, especially when you're sending them
to the browser. gzip alleviates most of this concern but it's still not ideal.
You can tell 6to5 to not place any declarations at the top of your files and
instead just point them to a reference contained within the runtime.
Simply use the following option if you're using the [Node API](usage.md#node):
```javascript
{
runtime: true
}
```
or the following flag if you're using the [CLI](usage.md#cli):
$ 6to5 --runtime
Then just include the runtime before your generated code.
## Getting the runtime
You can get the runtime via either:
$ 6to5-runtime
or
```javascript
require("6to5").runtime();
```
or from an npm release in `runtime.js` from the 6to5 directory.
## Customising namespace
You can also customise the runtime namespace by passing an optional namespace
argument:
```javascript
require("6to5").runtime("myCustomNamespace");
```
$ 6to5-runtime myCustomNamespace
See [Options - runtime](usage.md#options) for documentation on changing the
reference in generated code.

15
doc/plugins.md Normal file
View File

@@ -0,0 +1,15 @@
# Plugins
- [Broccoli](https://github.com/very-geek/broccoli-6to5-transpiler)
- [Browserify](https://github.com/6to5/6to5-browserify)
- [Brunch](https://github.com/es128/6to5-brunch)
- [Duo](https://github.com/bdo-labs/duo6to5)
- [Connect](https://github.com/6to5/6to5-connect)
- [Gulp](https://github.com/sindresorhus/gulp-6to5)
- [Grunt](https://github.com/sindresorhus/grunt-6to5)
- [Jade](https://github.com/Apoxx/jade-6to5)
- [Jest](https://github.com/6to5/6to5-jest)
- [Karma](https://github.com/shuhei/karma-6to5-preprocessor)
- [Mocha](https://github.com/6to5/6to5-mocha)
- [Rails](https://github.com/6to5/6to5-rails)
- [webpack](https://github.com/Couto/6to5-loader)

17
doc/polyfill.md Normal file
View File

@@ -0,0 +1,17 @@
# Polyfill
6to5 includes a polyfill that includes the
[regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js) and the
[es6-shim](https://github.com/paulmillr/es6-shim) and
[es6-symbol](https://github.com/medikoo/es6-symbol) polyfills.
## Node
```javascript
require("6to5/polyfill");
```
## Browser
Available from the `browser-polyfill.js` file within the 6to5 directory of an
npm release.

16
doc/react.md Normal file
View File

@@ -0,0 +1,16 @@
# React/JSX
6to5 has built-in support for React v0.12. Tags are automatically transformed to
their equivalent `React.createElement(...)` and `displayName` is automatically
inferred and added to all `React.createClass` calls.
## Blacklist
To disable this behaviour add `react` to your blacklist:
```javascript
to5.transform("code", { blacklist: ["react"] });
```
$ 6to5 --blacklist react

149
doc/usage.md Normal file
View File

@@ -0,0 +1,149 @@
# Usage
## CLI
Compile the file `script.js` and output it to stdout.
$ 6to5 script.js
Compile the file `script.js` and output it to `script-compiled.js`.
$ 6to5 script.js --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` and save a
source map to `script-compiled.js.map`.
$ 6to5 script.js --source-maps --out-file script-compiled.js
Compile the file `script.js` and output it to `script-compiled.js` with a source
map embedded in a comment at the bottom.
$ 6to5 script.js --source-maps-inline --out-file script-compiled.js
Compile the entire `src` directory and output it to the `lib` directory.
$ 6to5 src --out-dir lib
Compile the entire `src` directory and output it to the one concatenated file.
$ 6to5 src --out-file script-compiled.js
Pipe a file in via stdin and output it to `script-compiled.js`
$ 6to5 --out-file script-compiled.js < script.js
### Node
Launch a repl.
$ 6to5-node
Evaluate code.
$ 6to5-node -e "class Test { }"
Compile and run `test.js`.
$ 6to5-node test
## Node
```javascript
var to5 = require("6to5");
var result = to5.transform("code();", options);
result.code;
result.map;
result.ast;
to5.transformFileSync("filename.js", options).code;
to5.transformFile("filename.js", options, function (err, result) {
});
```
#### Options
```javascript
{
// Filename for use in errors etc.
// Default: "unknown"
filename: "filename",
// List of transformers to EXCLUDE.
// Run `6to5 --help` to see a full list of transformers.
blacklist: [],
// List of transformers to ONLY use.
// Run `6to5 --help` to see a full list of transformers.
whitelist: [],
// Module formatter to use
// Run `6to5 --help` to see a full list of module formatters.
// Default: "common"
modules: "common",
// If truthy, adds a `map` property to returned output.
// If set to "inline", a comment with a sourceMappingURL directive is added to
// the bottom of the returned code.
// Default: false
sourceMap: true,
// Set `file` on returned source map.
// Default: `filename` option.
sourceMapName: "filename",
// Set `sources[0]` on returned source map.
// Default: `filename` option.
sourceFileName: "filename",
// Optionally replace all 6to5 helper declarations with a referenece to this
// variable. If set to `true` then the default namespace is used "to5Runtime".
// Default: false
runtime: true
}
```
### Require hook
All subsequent files required by node with the extensions `.es6` and `.js` will
be transformed by 6to5. The polyfill specified in [Polyfill](polyfill.md) is
also required.
```javascript
require("6to5/register");
```
**NOTE:** By default all requires to `node_modules` will be ignored. You can
override this by passing an ignore regex via:
```javascript
require("6to5/register")({
// This will override `node_modules` ignoring - you can alternatively pass
// a regex
ignore: false
});
```
#### Options
```javascript
require("6to5/register")({
// Optional ignore regex - if any filenames **do** match this regex then they
// aren't compiled
ignore: /regex/,
// Optional only regex - if any filenames **don't** match this regex then they
// aren't compiled
only: /my_es6_folder/,
// See options above for usage
whitelist: [],
blacklist: [],
// This will remove the currently hooked extensions of .es6 and .js so you'll
// have to add them back if you want them to be used again.
extensions: [".js", ".es6"]
});
```

87
lib/6to5/browser.js Normal file
View File

@@ -0,0 +1,87 @@
var transform = module.exports = require("./transformation/transform");
transform.transform = transform;
transform.eval = function (code, opts) {
opts = opts || {};
opts.filename = opts.filename || "eval";
opts.sourceMap = "inline";
return eval(transform(code, opts).code);
};
transform.run = function (code, opts) {
opts = opts || {};
opts.sourceMap = "inline";
return new Function(transform(code, opts).code)();
};
transform.load = function (url, callback, opts, hold) {
opts = opts || {};
opts.filename = opts.filename || url;
var xhr = window.ActiveXObject ? new window.ActiveXObject("Microsoft.XMLHTTP") : new window.XMLHttpRequest();
xhr.open("GET", url, true);
if ("overrideMimeType" in xhr) xhr.overrideMimeType("text/plain");
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return;
var status = xhr.status;
if (status === 0 || status === 200) {
var param = [xhr.responseText, opts];
if (!hold) transform.run.apply(transform, param);
if (callback) callback(param);
} else {
throw new Error("Could not load " + url);
}
};
xhr.send(null);
};
var runScripts = function () {
var scripts = [];
var types = ["text/ecmascript-6", "text/6to5"];
var index = 0;
var exec = function () {
var param = scripts[index];
if (param instanceof Array) {
transform.run.apply(transform, param);
index++;
exec();
}
};
var run = function (script, i) {
var opts = {};
if (script.src) {
transform.load(script.src, function (param) {
scripts[i] = param;
exec();
}, opts, true);
} else {
opts.filename = "embedded";
scripts[i] = [script.innerHTML, opts];
}
};
var _scripts = window.document.getElementsByTagName("script");
for (var i in _scripts) {
var _script = _scripts[i];
if (types.indexOf(_script.type) >= 0) scripts.push(_script);
}
for (i in scripts) {
run(scripts[i], i);
}
exec();
};
if (window.addEventListener) {
window.addEventListener("DOMContentLoaded", runScripts, false);
} else {
window.attachEvent("onload", runScripts);
}

View File

@@ -2,40 +2,71 @@ module.exports = File;
var SHEBANG_REGEX = /^\#\!.*/;
var transform = require("./transform");
var recast = require("recast");
var transform = require("./transformation/transform");
var generate = require("./generation/generator");
var Scope = require("./traverse/scope");
var util = require("./util");
var b = require("recast").types.builders;
var t = require("./types");
var _ = require("lodash");
function File(opts) {
this.opts = File.normaliseOptions(opts);
this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
this.declarations = {};
this.uids = {};
this.opts = File.normaliseOptions(opts);
this.ast = {};
}
File.declarations = ["extends", "class-props", "slice", "apply-constructor"];
File.normaliseOptions = function (opts) {
opts = opts || {};
opts = _.cloneDeep(opts || {});
_.defaults(opts, {
blacklist: [],
whitelist: [],
sourceMap: false,
filename: "unknown"
whitespace: true,
blacklist: [],
whitelist: [],
sourceMap: false,
filename: "unknown",
modules: "common",
runtime: false,
code: true
});
// normalise windows path separators to unix
opts.filename = opts.filename.replace(/\\/g, "/");
_.defaults(opts, {
sourceFileName: opts.filename,
sourceMapName: opts.filename
});
if (opts.runtime === true) {
opts.runtime = "to5Runtime";
}
transform._ensureTransformerNames("blacklist", opts.blacklist);
transform._ensureTransformerNames("whitelist", opts.whitelist);
return opts;
};
File.prototype.getModuleFormatter = function (type) {
var ModuleFormatter = transform.moduleFormatters[type];
if (!ModuleFormatter) {
var loc = util.resolve(type);
if (loc) ModuleFormatter = require(loc);
}
if (!ModuleFormatter) {
throw new ReferenceError("unknown module formatter type " + type);
}
return new ModuleFormatter(this);
};
File.prototype.parseShebang = function (code) {
var shebangMatch = code.match(SHEBANG_REGEX);
if (shebangMatch) {
@@ -49,71 +80,106 @@ File.prototype.parseShebang = function (code) {
};
File.prototype.addDeclaration = function (name) {
if (!_.contains(File.declarations, name)) {
throw new ReferenceError("unknown declaration " + name);
}
var declar = this.declarations[name];
if (declar) return declar.uid;
var uid = b.identifier(this.generateUid(name));
var ref;
var runtimeNamespace = this.opts.runtime;
if (runtimeNamespace) {
name = t.identifier(t.toIdentifier(name));
return t.memberExpression(t.identifier(runtimeNamespace), name);
} else {
ref = util.template(name);
}
var uid = t.identifier(this.generateUid(name));
this.declarations[name] = {
uid: uid,
node: util.template(name)
node: ref
};
return uid;
};
File.prototype.errorWithNode = function (node, msg, Error) {
Error = Error || SyntaxError;
var loc = node.loc.start;
var err = new Error("Line " + loc.line + ": " + msg);
err.loc = loc;
return err;
};
File.prototype.parse = function (code) {
code = (code || "") + "";
var self = this;
this.code = code;
code = this.parseShebang(code);
return util.parse(this.opts, code, function (tree) {
return self.transform(tree);
self.transform(tree);
return self.generate();
});
};
File.prototype.transform = function (ast) {
this.ast = ast;
this.scope = new Scope(null, ast.program);
var self = this;
_.each(transform.transformers, function (transformer) {
transformer.transform(self);
});
return this.generate();
};
File.prototype.generate = function () {
var opts = this.opts;
var ast = this.ast;
var printOpts = {
tabWidth: 2
};
if (opts.sourceMap) {
printOpts.sourceMapName = opts.sourceMapName;
if (!opts.code) {
return {
code: "",
map: null,
ast: ast
};
}
var result = recast.print(ast, printOpts);
var code = result.code;
var result = generate(ast, opts, this.code);
if (this.shebang) {
// add back shebang
code = this.shebang + code;
result.code = this.shebang + "\n" + result.code;
}
if (opts.sourceMap === "inline") {
code += "\n" + util.sourceMapToComment(result.map);
result.code += "\n" + util.sourceMapToComment(result.map);
}
return {
code: code,
map: result.map || null,
ast: ast
};
result.ast = result;
return result;
};
File.prototype.generateUid = function (name) {
File.prototype.generateUid = function (name, scope) {
name = t.toIdentifier(name);
scope = scope || this.scope;
var uid;
do {
uid = this._generateUid(name);
} while (scope.has(uid));
return uid;
};
File.prototype._generateUid = function (name) {
var uids = this.uids;
var i = uids[name] || 1;

View File

@@ -0,0 +1,125 @@
module.exports = Buffer;
var util = require("../util");
var _ = require("lodash");
function Buffer(position, format) {
this.position = position;
this._indent = format.indent.base;
this.format = format;
this.buf = "";
}
Buffer.prototype.get = function () {
return util.trimRight(this.buf);
};
Buffer.prototype.getIndent = function () {
if (this.format.compact) {
return "";
} else {
return util.repeat(this._indent, this.format.indent.style);
}
};
Buffer.prototype.indentSize = function () {
return this.getIndent().length;
};
Buffer.prototype.indent = function () {
this._indent++;
};
Buffer.prototype.dedent = function () {
this._indent--;
};
Buffer.prototype.semicolon = function () {
if (this.format.semicolons) this.push(";");
};
Buffer.prototype.ensureSemicolon = function () {
if (!this.isLast(";")) this.semicolon();
};
Buffer.prototype.rightBrace = function () {
this.newline(true);
this.push("}");
};
Buffer.prototype.keyword = function (name) {
this.push(name);
this.push(" ");
};
Buffer.prototype.space = function () {
if (this.buf && !this.isLast([" ", "\n"])) {
this.push(" ");
}
};
Buffer.prototype.removeLast = function (cha) {
if (!this.isLast(cha)) return;
this.buf = this.buf.slice(0, -1);
this.position.unshift(cha);
};
Buffer.prototype.newline = function (i, removeLast) {
if (!this.buf) return;
if (this.format.compact) return;
if (this.endsWith("{\n")) return;
if (_.isBoolean(i)) {
removeLast = i;
i = null;
}
if (_.isNumber(i)) {
if (this.endsWith(util.repeat(i, "\n"))) return;
var self = this;
_.times(i, function () {
self.newline(null, removeLast);
});
return;
}
if (removeLast && this.isLast("\n")) this.removeLast("\n");
this.removeLast(" ");
this.buf = this.buf.replace(/\n +$/, "\n");
this._push("\n");
};
Buffer.prototype.push = function (str, noIndent) {
if (this._indent && !noIndent && str !== "\n") {
// we have an indent level and we aren't pushing a newline
var indent = this.getIndent();
// replace all newlines with newlines with the indentation
str = str.replace(/\n/g, "\n" + indent);
// we've got a newline before us so prepend on the indentation
if (this.isLast("\n")) str = indent + str;
}
this._push(str);
};
Buffer.prototype._push = function (str) {
this.position.push(str);
this.buf += str;
};
Buffer.prototype.endsWith = function (str) {
return this.buf.slice(-str.length) === str;
};
Buffer.prototype.isLast = function (cha, trimRight) {
var buf = this.buf;
if (trimRight) buf = util.trimRight(buf);
var chars = [].concat(cha);
return _.contains(chars, _.last(buf));
};

View File

@@ -0,0 +1,298 @@
module.exports = function (ast, opts, code) {
var gen = new CodeGenerator(ast, opts, code);
return gen.generate();
};
module.exports.CodeGenerator = CodeGenerator;
var Whitespace = require("./whitespace");
var SourceMap = require("./source-map");
var Position = require("./position");
var Buffer = require("./buffer");
var util = require("../util");
var n = require("./node");
var t = require("../types");
var _ = require("lodash");
function CodeGenerator(ast, opts, code) {
opts = opts || {};
this.comments = ast.comments || [];
this.tokens = ast.tokens || [];
this.format = CodeGenerator.normaliseOptions(opts);
this.ast = ast;
this.whitespace = new Whitespace(this.tokens, this.comments);
this.position = new Position;
this.map = new SourceMap(this.position, opts, code);
this.buffer = new Buffer(this.position, this.format);
}
_.each(Buffer.prototype, function (fn, key) {
CodeGenerator.prototype[key] = function () {
return fn.apply(this.buffer, arguments);
};
});
CodeGenerator.normaliseOptions = function (opts) {
opts = opts.format || {};
opts = _.merge({
parentheses: true,
semicolons: true,
comments: true,
compact: false,
indent: {
adjustMultilineComment: true,
style: " ",
base: 0
}
}, opts);
return opts;
};
CodeGenerator.generators = {
templateLiterals: require("./generators/template-literals"),
comprehensions: require("./generators/comprehensions"),
expressions: require("./generators/expressions"),
statements: require("./generators/statements"),
classes: require("./generators/classes"),
methods: require("./generators/methods"),
modules: require("./generators/modules"),
types: require("./generators/types"),
base: require("./generators/base"),
jsx: require("./generators/jsx")
};
_.each(CodeGenerator.generators, function (generator) {
_.extend(CodeGenerator.prototype, generator);
});
CodeGenerator.prototype.generate = function () {
var ast = this.ast;
this.print(ast);
return {
map: this.map.get(),
code: this.buffer.get()
};
};
CodeGenerator.prototype.buildPrint = function (parent) {
var self = this;
var print = function (node, opts) {
return self.print(node, parent, opts);
};
print.sequence = function (nodes, opts) {
opts = opts || {};
opts.statement = true;
return self.printJoin(print, nodes, opts);
};
print.join = function (nodes, opts) {
return self.printJoin(print, nodes, opts);
};
print.block = function (node) {
return self.printBlock(print, node);
};
print.indentOnComments = function (node) {
return self.printAndIndentOnComments(print, node);
};
return print;
};
CodeGenerator.prototype.print = function (node, parent, opts) {
if (!node) return "";
var self = this;
opts = opts || {};
var newline = function (leading) {
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
return;
}
var lines = 0;
if (node.start != null) {
// user node
if (leading) {
lines = self.whitespace.getNewlinesBefore(node);
} else {
lines = self.whitespace.getNewlinesAfter(node);
}
} else {
// generated node
if (!leading) lines++; // always include at least a single line after
var needs = n.needsWhitespaceAfter;
if (leading) needs = n.needsWhitespaceBefore;
lines += needs(node, parent);
}
self.newline(lines);
};
if (this[node.type]) {
this.printLeadingComments(node, parent);
newline(true);
if (opts.before) opts.before();
this.map.mark(node, "start");
// only compute if this node needs parens if our parent has been changed
// since acorn would've wrapped us in a ParanthesizedExpression
var needsParens = parent !== node._parent && n.needsParens(node, parent);
if (needsParens) this.push("(");
this[node.type](node, this.buildPrint(node), parent);
if (needsParens) this.push(")");
this.map.mark(node, "end");
if (opts.after) opts.after();
newline(false);
this.printTrailingComments(node, parent);
} else {
throw new ReferenceError("unknown node " + node.type + " " + JSON.stringify(node));
}
};
CodeGenerator.prototype.printJoin = function (print, nodes, opts) {
opts = opts || {};
var self = this;
var len = nodes.length;
if (opts.indent) self.indent();
_.each(nodes, function (node, i) {
print(node, {
statement: opts.statement,
after: function () {
if (opts.iterator) {
opts.iterator(node, i);
}
if (opts.separator && i < len - 1) {
self.push(opts.separator);
}
}
});
});
if (opts.indent) self.dedent();
};
CodeGenerator.prototype.printAndIndentOnComments = function (print, node) {
var indent = !!node.leadingComments;
if (indent) this.indent();
print(node);
if (indent) this.dedent();
};
CodeGenerator.prototype.printBlock = function (print, node) {
if (t.isEmptyStatement(node)) {
this.semicolon();
} else {
this.push(" ");
print(node);
}
};
CodeGenerator.prototype.generateComment = function (comment) {
var val = comment.value;
if (comment.type === "Line") {
val = "//" + val;
} else {
val = "/*" + val + "*/";
}
return val;
};
CodeGenerator.prototype.printTrailingComments = function (node, parent) {
this._printComments(this.getComments("trailingComments", node, parent));
};
CodeGenerator.prototype.printLeadingComments = function (node, parent) {
this._printComments(this.getComments("leadingComments", node, parent));
};
CodeGenerator.prototype.getComments = function (key, node, parent) {
if (t.isExpressionStatement(parent)) {
return [];
}
var comments = [];
var nodes = [node];
var self = this;
if (t.isExpressionStatement(node)) {
nodes.push(node.argument);
}
_.each(nodes, function (node) {
comments = comments.concat(self._getComments(key, node));
});
return comments;
};
CodeGenerator.prototype._getComments = function (key, node) {
return (node && node[key]) || [];
};
CodeGenerator.prototype._printComments = function (comments) {
if (this.format.compact) return;
if (!this.format.comments) return;
if (!comments || !comments.length) return;
var self = this;
_.each(comments, function (comment) {
// whitespace before
self.newline(self.whitespace.getNewlinesBefore(comment));
var column = self.position.column;
var val = self.generateComment(comment);
if (column && !self.isLast(["\n", " ", "[", "{"])) {
self._push(" ");
column++;
}
//
if (comment.type === "Block" && self.format.indent.adjustMultilineComment) {
var offset = comment.loc.start.column;
if (offset) {
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
val = val.replace(newlineRegex, "\n");
}
var indent = Math.max(self.indentSize(), column);
val = val.replace(/\n/g, "\n" + util.repeat(indent));
}
if (column === 0) {
val = self.getIndent() + val;
}
//
self._push(val);
// whitespace after
self.newline(self.whitespace.getNewlinesAfter(comment));
});
};

View File

@@ -0,0 +1,19 @@
exports.File = function (node, print) {
print(node.program);
};
exports.Program = function (node, print) {
print.sequence(node.body);
};
exports.BlockStatement = function (node, print) {
if (node.body.length === 0) {
this.push("{}");
} else {
this.push("{");
this.newline();
print.sequence(node.body, { indent: true });
this.removeLast("\n");
this.rightBrace();
}
};

View File

@@ -0,0 +1,32 @@
exports.ClassExpression =
exports.ClassDeclaration = function (node, print) {
this.push("class");
if (node.id) {
this.space();
print(node.id);
}
if (node.superClass) {
this.push(" extends ");
print(node.superClass);
}
this.space();
print(node.body);
};
exports.ClassBody = function (node, print) {
if (node.body.length === 0) {
this.push("{}");
} else {
this.push("{");
this.newline();
this.indent();
print.sequence(node.body);
this.dedent();
this.rightBrace();
}
};

View File

@@ -0,0 +1,27 @@
exports.ComprehensionBlock = function (node, print) {
this.keyword("for");
this.push("(");
print(node.left);
this.push(" of ");
print(node.right);
this.push(")");
};
exports.ComprehensionExpression = function (node, print) {
this.push(node.generator ? "(" : "[");
print.join(node.blocks, { separator: " " });
this.space();
if (node.filter) {
this.keyword("if");
this.push("(");
print(node.filter);
this.push(")");
this.space();
}
print(node.body);
this.push(node.generator ? ")" : "]");
};

View File

@@ -0,0 +1,111 @@
var t = require("../../types");
exports.UnaryExpression = function (node, print) {
var hasSpace = /[a-z]$/.test(node.operator);
var arg = node.argument;
if (t.isUpdateExpression(arg) || t.isUnaryExpression(arg)) {
hasSpace = true;
}
if (t.isUnaryExpression(arg) && arg.operator === "!") {
hasSpace = false;
}
this.push(node.operator);
if (hasSpace) this.space();
print(node.argument);
};
exports.ParenthesizedExpression = function (node, print) {
this.push("(");
print(node.expression);
this.push(")");
};
exports.UpdateExpression = function (node, print) {
if (node.prefix) {
this.push(node.operator);
print(node.argument);
} else {
print(node.argument);
this.push(node.operator);
}
};
exports.ConditionalExpression = function (node, print) {
print(node.test);
this.push(" ? ");
print(node.consequent);
this.push(" : ");
print(node.alternate);
};
exports.NewExpression = function (node, print) {
this.push("new ");
print(node.callee);
if (node.arguments.length || this.format.parentheses) {
this.push("(");
print.join(node.arguments, { separator: ", " });
this.push(")");
}
};
exports.SequenceExpression = function (node, print) {
print.join(node.expressions, { separator: ", " });
};
exports.ThisExpression = function () {
this.push("this");
};
exports.CallExpression = function (node, print) {
print(node.callee);
this.push("(");
print.join(node.arguments, { separator: ", " });
this.push(")");
};
var buildYieldAwait = function (keyword) {
return function (node, print) {
this.push(keyword);
if (node.delegate) this.push("*");
if (node.argument) {
this.space();
print(node.argument);
}
};
};
exports.YieldExpression = buildYieldAwait("yield");
exports.AwaitExpression = buildYieldAwait("await");
exports.EmptyStatement = function () {
this.semicolon();
};
exports.ExpressionStatement = function (node, print) {
print(node.expression);
this.semicolon();
};
exports.BinaryExpression =
exports.LogicalExpression =
exports.AssignmentExpression = function (node, print) {
print(node.left);
this.push(" " + node.operator + " ");
print(node.right);
};
exports.MemberExpression = function (node, print) {
print(node.object);
if (node.computed) {
this.push("[");
print(node.property);
this.push("]");
} else {
this.push(".");
print(node.property);
}
};

View File

@@ -0,0 +1,78 @@
var t = require("../../types");
var _ = require("lodash");
exports.XJSAttribute = function (node, print) {
print(node.name);
if (node.value) {
this.push("=");
print(node.value);
}
};
exports.XJSIdentifier = function (node) {
this.push(node.name);
};
exports.XJSNamespacedName = function (node, print) {
print(node.namespace);
this.push(":");
print(node.name);
};
exports.XJSMemberExpression = function (node, print) {
print(node.object);
this.push(".");
print(node.property);
};
exports.XJSSpreadAttribute = function (node, print) {
this.push("{...");
print(node.argument);
this.push("}");
};
exports.XJSExpressionContainer = function (node, print) {
this.push("{");
print(node.expression);
this.push("}");
};
exports.XJSElement = function (node, print) {
var self = this;
var open = node.openingElement;
print(open);
if (open.selfClosing) return;
this.indent();
_.each(node.children, function (child) {
if (t.isLiteral(child)) {
self.push(child.value);
} else {
print(child);
}
});
this.dedent();
print(node.closingElement);
};
exports.XJSOpeningElement = function (node, print) {
this.push("<");
print(node.name);
if (node.attributes.length > 0) {
this.space();
print.join(node.attributes, { separator: " " });
}
this.push(node.selfClosing ? " />" : ">");
};
exports.XJSClosingElement = function (node, print) {
this.push("</");
print(node.name);
this.push(">");
};
exports.XJSEmptyExpression = function () {
this.push("null");
};

View File

@@ -0,0 +1,85 @@
var t = require("../../types");
exports._params = function (node, print) {
var self = this;
this.push("(");
print.join(node.params, {
separator: ", ",
iterator: function (param, i) {
var def = node.defaults && node.defaults[i];
if (def) {
self.push(" = ");
print(def);
}
}
});
if (node.rest) {
if (node.params.length) {
this.push(", ");
}
this.push("...");
print(node.rest);
}
this.push(")");
};
exports._method = function (node, print) {
var value = node.value;
var kind = node.kind;
var key = node.key;
if (!kind || kind === "init") {
if (value.generator) {
this.push("*");
}
} else {
this.push(kind + " ");
}
if (node.computed) {
this.push("[");
print(key);
this.push("]");
} else {
print(key);
}
this._params(value, print);
this.space();
print(value.body);
};
exports.MethodDefinition = function (node, print) {
if (node.static) {
this.push("static ");
}
this._method(node, print);
};
exports.FunctionDeclaration =
exports.FunctionExpression = function (node, print) {
this.push("function");
if (node.generator) this.push("*");
this.space();
if (node.id) print(node.id);
this._params(node, print);
this.space();
print(node.body);
};
exports.ArrowFunctionExpression = function (node, print) {
if (node.params.length === 1 && !node.defaults.length && !node.rest && t.isIdentifier(node.params[0])) {
print(node.params[0]);
} else {
this._params(node, print);
}
this.push(" => ");
print(node.body);
};

View File

@@ -0,0 +1,86 @@
var t = require("../../types");
var _ = require("lodash");
exports.ImportSpecifier =
exports.ExportSpecifier = function (node, print) {
print(node.id);
if (node.name) {
this.push(" as ");
print(node.name);
}
};
exports.ExportBatchSpecifier = function () {
this.push("*");
};
exports.ExportDeclaration = function (node, print) {
this.push("export ");
var specifiers = node.specifiers;
if (node.default) {
this.push("default ");
}
if (node.declaration) {
print(node.declaration);
} else {
if (specifiers.length === 1 && t.isExportBatchSpecifier(specifiers[0])) {
this.push("*");
} else {
this.push("{");
if (specifiers.length) {
this.space();
print.join(specifiers, { separator: ", " });
this.space();
}
this.push("}");
}
if (node.source) {
this.push(" from ");
print(node.source);
}
}
this.ensureSemicolon();
};
exports.ImportDeclaration = function (node, print) {
var self = this;
this.push("import ");
var specfiers = node.specifiers;
if (specfiers && specfiers.length) {
var foundImportSpecifier = false;
_.each(node.specifiers, function (spec, i) {
if (+i > 0) {
self.push(", ");
}
if (!spec.default && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) {
foundImportSpecifier = true;
self.push("{ ");
}
print(spec);
});
if (foundImportSpecifier) {
this.push(" }");
}
this.push(" from ");
}
print(node.source);
this.semicolon();
};
exports.ImportBatchSpecifier = function (node, print) {
this.push("* as ");
print(node.name);
};

View File

@@ -0,0 +1,188 @@
var t = require("../../types");
exports.WithStatement = function (node, print) {
this.keyword("with");
this.push("(");
print(node.object);
print.block(node.body);
};
exports.IfStatement = function (node, print) {
this.keyword("if");
this.push("(");
print(node.test);
this.push(") ");
print.indentOnComments(node.consequent);
if (node.alternate) {
if (this.isLast("}")) this.space();
this.keyword("else");
print.indentOnComments(node.alternate);
}
};
exports.ForStatement = function (node, print) {
this.keyword("for");
this.push("(");
print(node.init);
this.push(";");
if (node.test) {
this.space();
print(node.test);
}
this.push(";");
if (node.update) {
this.space();
print(node.update);
}
this.push(")");
print.block(node.body);
};
exports.WhileStatement = function (node, print) {
this.keyword("while");
this.push("(");
print(node.test);
this.push(")");
print.block(node.body);
};
var buildForXStatement = function (op) {
return function (node, print) {
this.keyword("for");
this.push("(");
print(node.left);
this.push(" " + op + " ");
print(node.right);
this.push(")");
print.block(node.body);
};
};
exports.ForInStatement = buildForXStatement("in");
exports.ForOfStatement = buildForXStatement("of");
exports.DoWhileStatement = function (node, print) {
this.keyword("do");
print(node.body);
this.space();
this.keyword("while");
this.push("(");
print(node.test);
this.push(");");
};
var buildLabelStatement = function (prefix, key) {
return function (node, print) {
this.push(prefix);
var label = node[key || "label"];
if (label) {
this.space();
print(label);
}
this.semicolon();
};
};
exports.ContinueStatement = buildLabelStatement("continue");
exports.ReturnStatement = buildLabelStatement("return", "argument");
exports.BreakStatement = buildLabelStatement("break");
exports.LabeledStatement = function (node, print) {
print(node.label);
this.push(": ");
print(node.body);
};
exports.TryStatement = function (node, print) {
this.keyword("try");
print(node.block);
this.space();
print(node.handler);
if (node.finalizer) {
this.space();
this.push("finally ");
print(node.finalizer);
}
};
exports.CatchClause = function (node, print) {
this.keyword("catch");
this.push("(");
print(node.param);
this.push(") ");
print(node.body);
};
exports.ThrowStatement = function (node, print) {
this.push("throw ");
print(node.argument);
this.semicolon();
};
exports.SwitchStatement = function (node, print) {
this.keyword("switch");
this.push("(");
print(node.discriminant);
this.push(") {");
print.sequence(node.cases, { indent: true });
this.push("}");
//if (node.cases.length) {
// this.newline();
// print.sequence(node.cases, { indent: true });
// this.newline();
// this.rightBrace();
//} else {
// this.push("}");
//}
};
exports.SwitchCase = function (node, print) {
if (node.test) {
this.push("case ");
print(node.test);
this.push(":");
} else {
this.push("default:");
}
if (node.consequent.length === 1) {
this.space();
print(node.consequent[0]);
} else if (node.consequent.length > 1) {
this.newline();
print.sequence(node.consequent, { indent: true });
}
};
exports.DebuggerStatement = function () {
this.push("debugger;");
};
exports.VariableDeclaration = function (node, print, parent) {
this.push(node.kind + " ");
print.join(node.declarations, { separator: ", " });
if (!t.isFor(parent)) {
this.semicolon();
}
};
exports.VariableDeclarator = function (node, print) {
if (node.init) {
print(node.id);
this.push(" = ");
print(node.init);
} else {
print(node.id);
}
};

View File

@@ -0,0 +1,30 @@
var _ = require("lodash");
exports.TaggedTemplateExpression = function (node, print) {
print(node.tag);
print(node.quasi);
};
exports.TemplateElement = function (node) {
this._push(node.value.raw);
};
exports.TemplateLiteral = function (node, print) {
this.push("`");
var quasis = node.quasis;
var self = this;
var len = quasis.length;
_.each(quasis, function (quasi, i) {
print(quasi);
if (i + 1 < len) {
self.push("${ ");
print(node.expressions[i]);
self.push(" }");
}
});
this._push("`");
};

View File

@@ -0,0 +1,86 @@
var _ = require("lodash");
exports.Identifier = function (node) {
this.push(node.name);
};
exports.SpreadElement = function (node, print) {
this.push("...");
print(node.argument);
};
exports.ObjectExpression =
exports.ObjectPattern = function (node, print) {
var props = node.properties;
if (props.length) {
this.push("{");
this.space();
print.join(props, { separator: ", ", indent: true });
this.space();
this.push("}");
} else {
this.push("{}");
}
};
exports.Property = function (node, print) {
if (node.method || node.kind === "get" || node.kind === "set") {
this._method(node, print);
} else {
if (node.computed) {
this.push("[");
print(node.key);
this.push("]");
} else {
print(node.key);
if (node.shorthand) return;
}
this.push(": ");
print(node.value);
}
};
exports.ArrayExpression =
exports.ArrayPattern = function (node, print) {
var elems = node.elements;
var self = this;
var len = elems.length;
this.push("[");
_.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
// two (or more) holes, we need to write out two (or more)
// commas so that the resulting code is interpreted with
// both (all) of the holes.
self.push(",");
} else {
if (i > 0) self.push(" ");
print(elem);
if (i < len - 1) self.push(",");
}
});
this.push("]");
};
exports.Literal = function (node) {
var val = node.value;
var type = typeof val;
if (type === "boolean" || type === "number" || type === "string") {
this.push(JSON.stringify(val));
} else if (node.regex) {
this.push("/" + node.regex.pattern + "/" + node.regex.flags);
} else if (val === null) {
this.push("null");
} else if (node.raw) {
this.push(node.raw);
}
};

View File

@@ -0,0 +1,90 @@
module.exports = Node;
var whitespace = require("./whitespace");
var parens = require("./parentheses");
var t = require("../../types");
var _ = require("lodash");
var find = function (obj, node, parent) {
var result;
_.each(obj, function (fn, type) {
if (t["is" + type](node)) {
result = fn(node, parent);
if (result != null) return false;
}
});
return result;
};
function Node(node, parent) {
this.parent = parent;
this.node = node;
}
Node.prototype.isUserWhitespacable = function () {
//var parent = this.parent;
var node = this.node;
if (t.isUserWhitespacable(node)) {
return true;
}
//if (t.isArrayExpression(parent)) {
// return true;
//}
return false;
};
Node.prototype.needsWhitespace = function (type) {
var parent = this.parent;
var node = this.node;
if (!node) return 0;
if (t.isExpressionStatement(node)) {
node = node.expression;
}
var lines = find(whitespace[type].nodes, node, parent);
if (lines) return lines;
_.each(find(whitespace[type].list, node, parent), function (expr) {
lines = Node.needsWhitespace(expr, node, type);
if (lines) return false;
});
return lines || 0;
};
Node.prototype.needsWhitespaceBefore = function () {
return this.needsWhitespace("before");
};
Node.prototype.needsWhitespaceAfter = function () {
return this.needsWhitespace("after");
};
Node.prototype.needsParens = function () {
var parent = this.parent;
var node = this.node;
if (!parent) return false;
if (t.isNewExpression(parent) && parent.callee === node) {
return t.isCallExpression(node) || _.some(node, function (val) {
return t.isCallExpression(val);
});
}
return find(parens, node, parent);
};
_.each(Node.prototype, function (fn, key) {
Node[key] = function (node, parent) {
var n = new Node(node, parent);
var args = _.toArray(arguments).slice(2);
return n[key].apply(n, args);
};
});

View File

@@ -0,0 +1,150 @@
var t = require("../../types");
var _ = require("lodash");
var PRECEDENCE = {};
_.each([
["||"],
["&&"],
["|"],
["^"],
["&"],
["==", "===", "!=", "!=="],
["<", ">", "<=", ">=", "in", "instanceof"],
[">>", "<<", ">>>"],
["+", "-"],
["*", "/", "%"]
], function (tier, i) {
_.each(tier, function (op) {
PRECEDENCE[op] = i;
});
});
exports.Binary = function (node, parent) {
if (t.isCallExpression(parent) && parent.callee === node) {
return true;
}
if (t.isUnaryLike(parent)) {
return true;
}
if (t.isMemberExpression(parent) && parent.object === node) {
return true;
}
if (t.isBinary(parent)) {
var parentOp = parent.operator;
var parentPos = PRECEDENCE[parentOp];
var nodeOp = node.operator;
var nodePos = PRECEDENCE[nodeOp];
if (parentPos > nodePos) {
return true;
}
if (parentPos === nodePos && parent.right === node) {
return true;
}
}
};
exports.BinaryExpression = function (node, parent) {
if (node.operator === "in") {
// var i = (1 in []);
if (t.isVariableDeclarator(parent)) {
return true;
}
// for ((1 in []);;);
if (t.isFor(parent)) {
return true;
}
}
};
exports.SequenceExpression = function (node, parent) {
if (t.isForStatement(parent)) {
// Although parentheses wouldn't hurt around sequence
// expressions in the head of for loops, traditional style
// dictates that e.g. i++, j++ should not be wrapped with
// parentheses.
return false;
}
if (t.isExpressionStatement(parent) && parent.expression === node) {
return false;
}
// Otherwise err on the side of overparenthesization, adding
// explicit exceptions above if this proves overzealous.
return true;
};
exports.YieldExpression = function (node, parent) {
return t.isBinary(parent) ||
t.isUnaryLike(parent) ||
t.isCallExpression(parent) ||
t.isMemberExpression(parent) ||
t.isNewExpression(parent) ||
t.isConditionalExpression(parent) ||
t.isYieldExpression(parent);
};
exports.Literal = function (node, parent) {
// (1).valueOf()
if (_.isNumber(node.value) && t.isMemberExpression(parent) && parent.object === node) {
return true;
}
};
exports.ClassExpression = function (node, parent) {
return t.isExpressionStatement(parent);
};
exports.UnaryLike = function (node, parent) {
return t.isMemberExpression(parent) && parent.object === node;
};
exports.FunctionExpression = function (node, parent) {
// function () {};
if (t.isExpressionStatement(parent)) {
return true;
}
// (function test() {}).name;
if (t.isMemberExpression(parent) && parent.object === node) {
return true;
}
// (function () {})();
if (t.isCallExpression(parent) && parent.callee === node) {
return true;
}
};
exports.AssignmentExpression =
exports.ConditionalExpression = function (node, parent) {
if (t.isUnaryLike(parent)) {
return true;
}
if (t.isBinary(parent)) {
return true;
}
if (t.isCallExpression(parent) && parent.callee === node) {
return true;
}
if (t.isConditionalExpression(parent) && parent.test === node) {
return true;
}
if (t.isMemberExpression(parent) && parent.object === node) {
return true;
}
return false;
};

View File

@@ -0,0 +1,60 @@
var _ = require("lodash");
var t = require("../../types");
exports.before = {
nodes: {
Property: function (node, parent) {
if (parent.properties[0] === node) {
return 1;
}
},
SwitchCase: function (node, parent) {
if (parent.cases[0] === node) {
return 1;
}
},
CallExpression: function (node) {
if (t.isFunction(node.callee)) {
return 1;
}
}
}
};
exports.after = {
nodes: {},
list: {
VariableDeclaration: function (node) {
return _.map(node.declarations, "init");
},
ArrayExpression: function (node) {
return node.elements;
},
ObjectExpression: function (node) {
return node.properties;
}
}
};
_.each({
Function: 1,
Class: 1,
For: 1,
SwitchStatement: 1,
IfStatement: { before: 1 },
CallExpression: { after: 1 },
Literal: { after: 1 }
}, function (amounts, type) {
if (_.isNumber(amounts)) amounts = { after: amounts, before: amounts };
_.each(amounts, function (amount, key) {
exports[key].nodes[type] = function () {
return amount;
};
});
});

View File

@@ -0,0 +1,33 @@
module.exports = Position;
var _ = require("lodash");
function Position() {
this.line = 1;
this.column = 0;
}
Position.prototype.push = function (str) {
var self = this;
_.each(str, function (cha) {
if (cha === "\n") {
self.line++;
self.column = 0;
} else {
self.column++;
}
});
};
Position.prototype.unshift = function (str) {
var self = this;
_.each(str, function (cha) {
if (cha === "\n") {
self.line--;
} else {
self.column--;
}
});
};

View File

@@ -0,0 +1,55 @@
module.exports = SourceMap;
var sourceMap = require("source-map");
var t = require("../types");
function SourceMap(position, opts, code) {
this.position = position;
this.opts = opts;
if (opts.sourceMap) {
this.map = new sourceMap.SourceMapGenerator({
file: opts.sourceMapName
});
this.map.setSourceContent(opts.sourceFileName, code);
} else {
this.map = null;
}
}
SourceMap.prototype.get = function () {
var map = this.map;
if (map) {
return map.toJSON();
} else {
return map;
}
};
SourceMap.prototype.mark = function (node, type) {
var loc = node.loc;
if (!loc) return; // no location info
var map = this.map;
if (!map) return; // no source map
if (t.isProgram(node) || t.isFile(node)) return; // illegal mapping nodes
var position = this.position;
var generated = {
line: position.line,
column: position.column
};
var original = loc[type];
if (generated.line === original.line && generated.column === original.column) return; // nothing to map
map.addMapping({
source: this.opts.sourceFileName,
generated: generated,
original: original
});
};

View File

@@ -0,0 +1,58 @@
module.exports = Whitespace;
var _ = require("lodash");
function Whitespace(tokens, comments) {
this.tokens = _.sortBy(tokens.concat(comments), "start");
this.used = [];
}
Whitespace.prototype.getNewlinesBefore = function (node) {
var startToken;
var endToken;
var tokens = this.tokens;
_.each(tokens, function (token, i) {
// this is the token this node starts with
if (node.start === token.start) {
startToken = tokens[i - 1];
endToken = token;
return false;
}
});
return this.getNewlinesBetween(startToken, endToken);
};
Whitespace.prototype.getNewlinesAfter = function (node) {
var startToken;
var endToken;
var tokens = this.tokens;
_.each(tokens, function (token, i) {
// this is the token this node ends with
if (node.end === token.end) {
startToken = token;
endToken = tokens[i + 1];
return false;
}
});
return this.getNewlinesBetween(startToken, endToken);
};
Whitespace.prototype.getNewlinesBetween = function (startToken, endToken) {
var start = startToken ? startToken.loc.end.line : 1;
var end = endToken.loc.start.line;
var lines = 0;
for (var line = start; line < end; line++) {
if (!_.contains(this.used, line)) {
this.used.push(line);
lines++;
}
}
return lines;
};

View File

@@ -1,8 +1,9 @@
var transform = require("./transform");
var transform = require("./transformation/transform");
var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
exports.util = require("./util");
exports.runtime = require("./runtime");
exports.register = function (opts) {
var register = require("./register");
@@ -14,6 +15,8 @@ exports.polyfill = function () {
require("./polyfill");
};
exports.canCompile = util.canCompile;
exports.transform = transform;
exports.transformFile = function (filename, opts, callback) {

28
lib/6to5/patch.js Normal file
View File

@@ -0,0 +1,28 @@
var t = require("./types");
var _ = require("lodash");
var types = require("ast-types");
var def = types.Type.def;
// Program wrapper
def("File")
.bases("Node")
.build("program")
.field("program", def("Program"));
// Non-standard Acorn type
def("ParenthesizedExpression")
.bases("Expression")
.build("expression")
.field("expression", def("Expression"));
// Same as ImportNamespaceSpecifier but `id` is `name`
def("ImportBatchSpecifier")
.bases("Specifier")
.build("name")
.field("name", def("Identifier"));
types.finalize();
var estraverse = require("estraverse");
_.extend(estraverse.VisitorKeys, t.VISITOR_KEYS);

View File

@@ -1,3 +1,6 @@
require("es6-symbol/implement");
if (typeof Symbol === "undefined") {
require("es6-symbol/implement");
}
require("es6-shim");
require("regenerator").runtime();
require("regenerator-6to5/runtime");

View File

@@ -6,7 +6,7 @@ var _ = require("lodash");
sourceMapSupport.install({
retrieveSourceMap: function (source) {
var map = maps[source];
var map = maps && maps[source];
if (map) {
return {
url: null,
@@ -20,17 +20,57 @@ sourceMapSupport.install({
//
var blacklist = [];
var blacklistTest = function (transformer, code) {
try {
if (_.isFunction(code)) {
code();
} else {
new Function(code);
}
blacklist.push(transformer);
} catch (err) {
if (err.name !== "SyntaxError") throw err;
}
};
blacklistTest("arrayComprehension", "var foo = [for (foo of bar) foo * foo];");
//blacklistTest("generatorComprehension", "");
blacklistTest("arrowFunctions", "var foo = x => x * x;");
blacklistTest("classes", "class Foo {}");
blacklistTest("computedPropertyNames", "var foo = { [foo]: bar };");
//blacklistTest("constants", "const foo = 0;");
blacklistTest("defaultParamaters", "var foo = function (bar = 0) {};");
blacklistTest("destructuring", "var { x, y } = { x: 0, y: 0 };");
blacklistTest("forOf", "for (var foo of bar) {}");
blacklistTest("generators", "function* foo() {}");
blacklistTest("letScoping", "let foo = 0;");
blacklistTest("modules", 'import foo from "from";');
blacklistTest("propertyMethodAssignment", "{ get foo() {} }");
blacklistTest("propertyNameShorthand", "var foo = { x, y };");
blacklistTest("restParameters", "function foo(...bar) {}");
blacklistTest("spread", "foo(...bar);");
blacklistTest("templateLiterals", "var foo = `foo`;");
blacklistTest("unicodeRegex", function () { new RegExp("foo", "u"); });
//
var ignoreRegex = /node_modules/;
var exts = [];
var onlyRegex;
var whitelist = [];
var exts = {};
var maps = {};
var old = require.extensions[".js"];
var loader = function (m, filename) {
if (ignoreRegex && ignoreRegex.test(filename)) {
if ((ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename))) {
return old.apply(this, arguments);
}
var result = to5.transformFileSync(filename, {
whitelist: whitelist,
blacklist: blacklist,
sourceMap: true
});
@@ -40,13 +80,14 @@ var loader = function (m, filename) {
};
var hookExtensions = function (_exts) {
_.each(exts, function (ext) {
delete require.extensions[ext];
_.each(exts, function (old, ext) {
require.extensions[ext] = old;
});
exts = _exts;
exts = {};
_.each(exts, function (ext) {
_.each(_exts, function (ext) {
exts[ext] = require.extensions[ext];
require.extensions[ext] = loader;
});
};
@@ -54,12 +95,16 @@ var hookExtensions = function (_exts) {
hookExtensions([".es6", ".js"]);
module.exports = function (opts) {
// normalise options
opts = opts || {};
if (_.isRegExp(opts)) opts = { ignoreRegex: opts };
if (_.isRegExp(opts)) opts = { ignore: opts };
if (opts.ignoreRegex != null) opts.ignore = opts.ignoreRegex;
if (opts.ignoreRegex != null) {
ignoreRegex = opts.ignoreRegex;
}
if (opts.only != null) onlyRegex = opts.only;
if (opts.ignore != null) ignoreRegex = opts.ignore;
if (opts.extensions) hookExtensions(opts.extensions);
if (opts.blacklist) blacklist = opts.blacklist;
if (opts.whitelist) whitelist = opts.whitelist;
};

31
lib/6to5/runtime.js Normal file
View File

@@ -0,0 +1,31 @@
var generator = require("./generation/generator");
var util = require("./util");
var File = require("./file");
var t = require("./types");
var _ = require("lodash");
module.exports = function (namespace) {
namespace = t.identifier(namespace || "to5Runtime");
var body = [];
var container = t.functionExpression(null, [], t.blockStatement(body));
var tree = t.program([t.expressionStatement(t.callExpression(container, []))]);
body.push(util.template("self-global", true));
body.push(t.variableDeclaration("var", [
t.variableDeclarator(
namespace,
t.assignmentExpression("=", t.memberExpression(t.identifier("self"), namespace), t.objectExpression([]))
)
]));
_.each(File.declarations, function (name) {
var key = t.identifier(t.toIdentifier(name));
body.push(t.expressionStatement(
t.assignmentExpression("=", t.memberExpression(namespace, key), util.template(name))
));
});
return generator(tree).code;
};

View File

@@ -0,0 +1,5 @@
(function (Constructor, args) {
var bindArgs = [null].concat(args);
var Factory = Constructor.bind.apply(Constructor, bindArgs);
return new Factory;
});

View File

@@ -1 +0,0 @@
[].concat(ARGUMENT);

View File

@@ -1 +0,0 @@
CLASS_NAME.__proto__ = SUPER_NAME;

View File

@@ -1,8 +0,0 @@
CLASS_NAME.prototype = Object.create(SUPER_NAME.prototype, {
constructor: {
value: CLASS_NAME,
enumerable: false,
writable: true,
configurable: true
}
});

View File

@@ -0,0 +1,4 @@
(function (child, staticProps, instanceProps) {
if (staticProps) Object.defineProperties(child, staticProps);
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
})

View File

@@ -0,0 +1 @@
exports.VARIABLE_NAME = OBJECT.KEY;

View File

@@ -1 +0,0 @@
exports.VARIABLE_NAME = require(MODULE_NAME).KEY;

View File

@@ -2,4 +2,4 @@
for (var i in obj) {
exports[i] = obj[i];
}
}(require(MODULE_NAME)));
})(OBJECT);

View File

@@ -0,0 +1,11 @@
(function (child, parent) {
child.prototype = Object.create(parent.prototype, {
constructor: {
value: child,
enumerable: false,
writable: true,
configurable: true
}
});
child.__proto__ = parent;
})

View File

@@ -0,0 +1 @@
if (typeof RETURN === "object") return RETURN.v;

View File

@@ -0,0 +1 @@
var self = typeof global === "undefined" ? window : global;

View File

@@ -0,0 +1,7 @@
(function (factory) {
if (typeof define === "function" && define.amd) {
define(AMD_ARGUMENTS, factory);
} else if (typeof exports !== "undefined") {
factory(exports, COMMON_ARGUMENTS);
}
});

View File

@@ -0,0 +1,82 @@
module.exports = AMDFormatter;
var CommonJSFormatter = require("./common");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
function AMDFormatter(file) {
this.file = file;
this.ids = {};
}
util.inherits(AMDFormatter, CommonJSFormatter);
AMDFormatter.prototype.transform = function (ast) {
var program = ast.program;
var body = program.body;
// build an array of module names
var names = [t.literal("exports")];
_.each(this.ids, function (id, name) {
names.push(t.literal(name));
});
names = t.arrayExpression(names);
// build up define container
var params = _.values(this.ids);
params.unshift(t.identifier("exports"));
var container = t.functionExpression(null, params, t.blockStatement(body));
var call = t.callExpression(t.identifier("define"), [names, container]);
program.body = [t.expressionStatement(call)];
};
AMDFormatter.prototype._push = function (node) {
var id = node.source.value;
var ids = this.ids;
if (ids[id]) {
return ids[id];
} else {
return this.ids[id] = t.identifier(this.file.generateUid(id));
}
};
AMDFormatter.prototype.import = function (node) {
this._push(node);
};
AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var key = t.getSpecifierName(specifier);
var id = specifier.id;
// import foo from "foo";
if (specifier.default) {
id = t.identifier("default");
}
var ref;
if (t.isImportBatchSpecifier(specifier)) {
// import * as bar from "foo";
ref = this._push(node);
} else {
// import foo from "foo";
ref = t.memberExpression(this._push(node), id, false);
}
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(key, ref)
]));
};
AMDFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
var self = this;
return this._exportSpecifier(function () {
return self._push(node);
}, specifier, node, nodes);
};

View File

@@ -0,0 +1,132 @@
module.exports = CommonJSFormatter;
var util = require("../../util");
var t = require("../../types");
function CommonJSFormatter(file) {
this.file = file;
}
CommonJSFormatter.prototype.import = function (node, nodes) {
// import "foo";
nodes.push(util.template("require", {
//inherits: node,
MODULE_NAME: node.source.raw
}, true));
};
CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var variableName = t.getSpecifierName(specifier);
// import foo from "foo";
if (specifier.default) {
specifier.id = t.identifier("default");
}
var templateName = "require-assign";
// import * as bar from "foo";
if (specifier.type !== "ImportBatchSpecifier") templateName += "-key";
nodes.push(util.template(templateName, {
//inherits: node.specifiers.length === 1 && node,
VARIABLE_NAME: variableName,
MODULE_NAME: node.source.raw,
KEY: specifier.id
}));
};
CommonJSFormatter.prototype.export = function (node, nodes) {
var declar = node.declaration;
if (node.default) {
var ref = declar;
if (t.isClass(ref) || t.isFunction(ref)) {
if (ref.id) {
nodes.push(t.toStatement(ref));
ref = ref.id;
}
}
nodes.push(util.template("exports-default", {
//inherits: node,
VALUE: ref
}, true));
} else {
var assign;
if (t.isVariableDeclaration(declar)) {
var decl = declar.declarations[0];
if (decl.init) {
decl.init = util.template("exports-assign", {
//inherits: node,
VALUE: decl.init,
KEY: decl.id
});
}
nodes.push(declar);
} else {
assign = util.template("exports-assign", {
//inherits: node,
VALUE: declar.id,
KEY: declar.id
}, true);
nodes.push(t.toStatement(declar));
nodes.push(assign);
if (t.isFunctionDeclaration(declar)) {
assign._blockHoist = true;
}
}
}
};
CommonJSFormatter.prototype._exportSpecifier = function (getRef, specifier, node, nodes) {
var variableName = t.getSpecifierName(specifier);
var inherits = false;
if (node.specifiers.length === 1) inherits = node;
if (node.source) {
if (t.isExportBatchSpecifier(specifier)) {
// export * from "foo";
nodes.push(util.template("exports-wildcard", {
//inherits: inherits,
OBJECT: getRef()
}, true));
} else {
// export { foo } from "test";
nodes.push(util.template("exports-assign-key", {
//inherits: inherits,
VARIABLE_NAME: variableName.name,
OBJECT: getRef(),
KEY: specifier.id
}, true));
}
} else {
// export { foo };
nodes.push(util.template("exports-assign", {
//inherits: inherits,
VALUE: specifier.id,
KEY: variableName
}, true));
}
};
CommonJSFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
return this._exportSpecifier(function () {
return t.callExpression(t.identifier("require"), [node.source]);
}, specifier, node, nodes);
};

View File

@@ -0,0 +1,24 @@
module.exports = IgnoreFormatter;
var t = require("../../types");
function IgnoreFormatter() {
}
IgnoreFormatter.prototype.import = function () {
};
IgnoreFormatter.prototype.importSpecifier = function () {
};
IgnoreFormatter.prototype.export = function (node, nodes) {
var declar = t.toStatement(node.declaration, true);
if (declar) nodes.push(t.inherits(declar, node));
};
IgnoreFormatter.prototype.exportSpecifier = function () {
};

View File

@@ -0,0 +1,47 @@
module.exports = UMDFormatter;
var AMDFormatter = require("./amd");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
function UMDFormatter(file) {
this.file = file;
this.ids = {};
}
util.inherits(UMDFormatter, AMDFormatter);
UMDFormatter.prototype.transform = function (ast) {
var program = ast.program;
var body = program.body;
// build an array of module names
var names = [];
_.each(this.ids, function (id, name) {
names.push(t.literal(name));
});
// factory
var ids = _.values(this.ids);
var args = [t.identifier("exports")].concat(ids);
var factory = t.functionExpression(null, args, t.blockStatement(body));
// runner
var runner = util.template("umd-runner-body", {
AMD_ARGUMENTS: t.arrayExpression([t.literal("exports")].concat(names)),
COMMON_ARGUMENTS: names.map(function (name) {
return t.callExpression(t.identifier("require"), [name]);
})
});
//
var call = t.callExpression(runner, [factory]);
program.body = [t.expressionStatement(call)];
};

View File

@@ -1,111 +1,63 @@
module.exports = transform;
var Transformer = require("./transformer");
var sourceMap = require("source-map");
var recast = require("recast");
var File = require("./file");
var util = require("./util");
var File = require("../file");
var _ = require("lodash");
function transform(code, opts) {
opts = opts || {};
code = (code || "") + "";
var file = new File(opts);
return file.parse(code);
}
transform.test = function (task, assert) {
var actual = task.actual;
var expect = task.expect;
var opts = task.options;
var exec = task.exec;
var getOpts = function (filename) {
return _.merge({ filename: filename }, opts);
};
var execCode = exec.code.trim();
var result;
if (execCode) {
result = transform(execCode, getOpts(exec.filename));
execCode = result.code;
require("./polyfill");
var fn = new Function("assert", execCode);
fn(assert);
} else {
var actualCode = actual.code.trim();
var expectCode = expect.code.trim();
var printOpts = { tabWidth: 2 };
result = transform(actualCode, getOpts(actual.filename));
actualCode = recast.prettyPrint(result.ast, printOpts).code;
var expectAst = util.parse(expect, expectCode);
var expectResult = recast.prettyPrint(expectAst, printOpts);
expectCode = expectResult.code;
assert.equal(actualCode, expectCode);
}
if (task.sourceMap) {
assert.deepEqual(task.sourceMap, result.map);
}
if (task.sourceMappings) {
var consumer = new sourceMap.SourceMapConsumer(result.map);
_.each(task.sourceMappings, function (mapping, i) {
var generated = mapping.generated;
var original = mapping.original;
var pos = consumer.originalPositionFor(generated);
var msg = "source mapping " + i + " - generated: " + generated.line + ":" + generated.column;
assert.equal(pos.line + ":" + pos.column, original.line + ":" + original.column, msg);
});
}
};
transform._ensureTransformerNames = function (type, keys) {
_.each(keys, function (key) {
if (key[0] === "_" || !_.has(transform.transformers, key)) {
if (!_.has(transform.transformers, key)) {
throw new ReferenceError("unknown transformer " + key + " specified in " + type);
}
});
};
transform.transformers = {
transform.transformers = {};
transform.moduleFormatters = {
common: require("./modules/common"),
ignore: require("./modules/ignore"),
amd: require("./modules/amd"),
umd: require("./modules/umd")
};
_.each({
modules: require("./transformers/modules"),
computedPropertyNames: require("./transformers/computed-property-names"),
propertyNameShorthand: require("./transformers/property-name-shorthand"),
constants: require("./transformers/constants"),
arrayComprehension: require("./transformers/array-comprehension"),
generatorComprehension: require("./transformers/generator-comprehension"),
arrowFunctions: require("./transformers/arrow-functions"),
classes: require("./transformers/classes"),
_propertyLiterals: require("./transformers/_property-literals"),
computedPropertyNames: require("./transformers/computed-property-names"),
spread: require("./transformers/spread"),
templateLiterals: require("./transformers/template-literals"),
propertyMethodAssignment: require("./transformers/property-method-assignment"),
defaultParameters: require("./transformers/default-parameters"),
letScoping: require("./transformers/let-scoping"),
restParameters: require("./transformers/rest-parameters"),
destructuring: require("./transformers/destructuring"),
letScoping: require("./transformers/let-scoping"),
forOf: require("./transformers/for-of"),
unicodeRegex: require("./transformers/unicode-regex"),
generators: require("./transformers/generators"),
react: require("./transformers/react"),
jsx: require("./transformers/jsx"),
_aliasFunctions: require("./transformers/_alias-functions"),
_blockHoist: require("./transformers/_block-hoist"),
_declarations: require("./transformers/_declarations"),
useStrict: require("./transformers/use-strict")
};
generators: require("./transformers/generators"),
useStrict: require("./transformers/use-strict"),
_.each(transform.transformers, function (transformer, key) {
_moduleFormatter: require("./transformers/_module-formatter")
}, function (transformer, key) {
transform.transformers[key] = new Transformer(key, transformer);
});

View File

@@ -1,6 +1,7 @@
module.exports = Transformer;
var traverse = require("./traverse");
var traverse = require("../traverse");
var t = require("../types");
var _ = require("lodash");
function Transformer(key, transformer) {
@@ -11,13 +12,14 @@ function Transformer(key, transformer) {
Transformer.normalise = function (transformer) {
if (_.isFunction(transformer)) {
transformer = { ast: transformer };
} else {
_.each(transformer, function (fns, type) {
if (type === "ast") return;
if (_.isFunction(fns)) fns = { enter: fns };
transformer[type] = fns;
});
}
_.each(transformer, function (fns, type) {
if (type[0] === "_") return;
if (_.isFunction(fns)) fns = { enter: fns };
transformer[type] = fns;
});
return transformer;
};
@@ -27,14 +29,18 @@ Transformer.prototype.transform = function (file) {
var transformer = this.transformer;
var ast = file.ast;
if (transformer.ast) {
transformer.ast(ast, file);
}
var astRun = function (key) {
if (transformer.ast && transformer.ast[key]) {
transformer.ast[key](ast, file);
}
};
astRun("enter");
var build = function (exit) {
return function (node, parent) {
return function (node, parent, scope) {
// add any node type aliases that exist
var types = [node.type].concat(traverse.aliases[node.type] || []);
var types = [node.type].concat(t.ALIAS_KEYS[node.type] || []);
var fns = transformer.all;
@@ -49,7 +55,7 @@ Transformer.prototype.transform = function (file) {
if (exit) fn = fns.exit;
if (!fn) return;
return fn(node, parent, file);
return fn(node, parent, file, scope);
};
};
@@ -57,18 +63,21 @@ Transformer.prototype.transform = function (file) {
enter: build(),
exit: build(true)
});
astRun("exit");
};
Transformer.prototype.canRun = function (file) {
if (this.key[0] === "_") return true;
var opts = file.opts;
var key = this.key;
var blacklist = opts.blacklist;
if (blacklist.length && _.contains(blacklist, this.key)) return false;
if (blacklist.length && _.contains(blacklist, key)) return false;
var whitelist = opts.whitelist;
if (whitelist.length && !_.contains(whitelist, this.key)) return false;
if (key[0] !== "_") {
var whitelist = opts.whitelist;
if (whitelist.length && !_.contains(whitelist, key)) return false;
}
return true;
};

View File

@@ -0,0 +1,82 @@
var traverse = require("../../traverse");
var t = require("../../types");
var go = function (getBody, node, file, scope) {
var argumentsId;
var thisId;
var getArgumentsId = function () {
return argumentsId = argumentsId || t.identifier(file.generateUid("arguments", scope));
};
var getThisId = function () {
return thisId = thisId || t.identifier(file.generateUid("this", scope));
};
// traverse the function and find all alias functions so we can alias
// `arguments` and `this` if necessary
traverse(node, function (node) {
if (!node._aliasFunction) {
if (t.isFunction(node)) {
// stop traversal of this node as it'll be hit again by this transformer
return false;
} else {
return;
}
}
// traverse all child nodes of this function and find `arguments` and `this`
traverse(node, function (node, parent) {
if (t.isFunction(node) && !node._aliasFunction) {
return false;
}
if (node._ignoreAliasFunctions) return;
var getId;
if (t.isIdentifier(node) && node.name === "arguments") {
getId = getArgumentsId;
} else if (t.isThisExpression(node)) {
getId = getThisId;
} else {
return;
}
if (t.isReferenced(node, parent)) return getId();
});
return false;
});
var body;
var pushDeclaration = function (id, init) {
body = body || getBody();
body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(id, init)
]));
};
if (argumentsId) {
pushDeclaration(argumentsId, t.identifier("arguments"));
}
if (thisId) {
pushDeclaration(thisId, t.identifier("this"));
}
};
exports.Program = function (node, parent, file, scope) {
go(function () {
return node.body;
}, node, file, scope);
};
exports.FunctionDeclaration =
exports.FunctionExpression = function (node, parent, file, scope) {
go(function () {
t.ensureBlock(node);
return node.body.body;
}, node, file, scope);
};

View File

@@ -1,12 +1,12 @@
var b = require("recast").types.builders;
var t = require("../../types");
var _ = require("lodash");
module.exports = function (ast, file) {
var body = ast.program.body;
_.each(file.declarations, function (declar) {
body.unshift(b.variableDeclaration("var", [
b.variableDeclarator(declar.uid, declar.node)
body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(declar.uid, declar.node)
]));
});
};

View File

@@ -0,0 +1,11 @@
var transform = require("../transform");
exports.ast = {
exit: function (ast, file) {
if (!transform.transformers.modules.canRun(file)) return;
if (file.moduleFormatter.transform) {
file.moduleFormatter.transform(ast);
}
}
};

View File

@@ -0,0 +1,15 @@
var esutils = require("esutils");
var t = require("../../types");
var _ = require("lodash");
exports.Property = function (node) {
// ignore key literals that are valid identifiers
var key = node.key;
if (t.isLiteral(key) && _.isString(key.value) && esutils.keyword.isIdentifierName(key.value)) {
key.type = "Identifier";
key.name = key.value;
delete key.value;
node.computed = false;
}
};

View File

@@ -0,0 +1,81 @@
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var singleArrayExpression = function (node) {
var block = node.blocks[0];
var templateName = "array-expression-comprehension-map";
if (node.filter) templateName = "array-expression-comprehension-filter";
var result = util.template(templateName, {
STATEMENT: node.body,
FILTER: node.filter,
ARRAY: block.right,
KEY: block.left
});
_.each([result.callee.object, result], function (call) {
if (t.isCallExpression(call)) {
call.arguments[0]._aliasFunction = true;
}
});
return result;
};
var multiple = function (node, file) {
var uid = file.generateUid("arr");
var container = util.template("array-comprehension-container", {
KEY: uid
});
container.callee.expression._aliasFunction = true;
var block = container.callee.expression.body;
var body = block.body;
var returnStatement = body.pop();
body.push(exports._build(node, function () {
return util.template("array-push", {
STATEMENT: node.body,
KEY: uid
}, true);
}));
body.push(returnStatement);
return container;
};
exports._build = function (node, buildBody) {
var self = node.blocks.shift();
if (!self) return;
var child = exports._build(node, buildBody);
if (!child) {
// last item
child = buildBody();
// add a filter as this is our final stop
if (node.filter) {
child = t.ifStatement(node.filter, t.blockStatement([child]));
}
}
return t.forOfStatement(
t.variableDeclaration("var", [t.variableDeclarator(self.left)]),
self.right,
t.blockStatement([child])
);
};
exports.ComprehensionExpression = function (node, parent, file) {
if (node.generator) return;
if (node.blocks.length === 1 && t.isArrayExpression(node.blocks[0].right)) {
return singleArrayExpression(node);
} else {
return multiple(node, file);
}
};

View File

@@ -1,9 +1,9 @@
var util = require("../util");
var t = require("../../types");
exports.ArrowFunctionExpression = function (node) {
util.ensureBlock(node);
t.ensureBlock(node);
node._aliasFunction = "arrows";
node._aliasFunction = true;
node.expression = false;
node.type = "FunctionExpression";

View File

@@ -0,0 +1,262 @@
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
exports.ClassDeclaration = function (node, parent, file, scope) {
return t.variableDeclaration("var", [
t.variableDeclarator(node.id, new Class(node, file, scope).run())
]);
};
exports.ClassExpression = function (node, parent, file, scope) {
return new Class(node, file, scope).run();
};
var getMemberExpressionObject = function (node) {
while (t.isMemberExpression(node)) {
node = node.object;
}
return node;
};
/**
* Description
*
* @param {Node} node
* @param {File} file
* @param {Scope} scope
*/
function Class(node, file, scope) {
this.scope = scope;
this.node = node;
this.file = file;
this.instanceMutatorMap = {};
this.staticMutatorMap = {};
this.hasConstructor = false;
this.className = node.id || t.identifier(file.generateUid("class", scope));
this.superName = node.superClass;
}
/**
* Description
*
* @returns {Array}
*/
Class.prototype.run = function () {
var superClassArgument = this.superName;
var superClassCallee = this.superName;
var superName = this.superName;
var className = this.className;
var file = this.file;
if (superName) {
if (t.isMemberExpression(superName)) {
superClassArgument = superClassCallee = getMemberExpressionObject(superName);
} else if (!t.isIdentifier(superName)) {
superClassArgument = superName;
superClassCallee = superName = t.identifier(file.generateUid("ref", this.scope));
}
}
this.superName = superName;
var container = util.template("class", {
CLASS_NAME: className
});
var block = container.callee.expression.body;
var body = this.body = block.body;
var constructor = this.constructor = body[0].declarations[0].init;
if (this.node.id) constructor.id = className;
var returnStatement = body.pop();
if (superName) {
body.push(t.expressionStatement(t.callExpression(file.addDeclaration("extends"), [className, superName])));
container.arguments.push(superClassArgument);
container.callee.expression.params.push(superClassCallee);
}
this.buildBody();
if (body.length === 1) {
// only a constructor so no need for a closure container
return constructor;
} else {
body.push(returnStatement);
return container;
}
};
/**
* Description
*/
Class.prototype.buildBody = function () {
var constructor = this.constructor;
var className = this.className;
var superName = this.superName;
var classBody = this.node.body.body;
var body = this.body;
var self = this;
_.each(classBody, function (node) {
self.replaceInstanceSuperReferences(node);
if (node.key.name === "constructor") {
self.pushConstructor(node);
} else {
self.pushMethod(node);
}
});
if (!this.hasConstructor && superName) {
constructor.body.body.push(util.template("class-super-constructor-call", {
SUPER_NAME: superName
}, true));
}
var instanceProps;
var staticProps;
if (!_.isEmpty(this.instanceMutatorMap)) {
var protoId = util.template("prototype-identifier", {
CLASS_NAME: className
});
instanceProps = util.buildDefineProperties(this.instanceMutatorMap, protoId);
}
if (!_.isEmpty(this.staticMutatorMap)) {
staticProps = util.buildDefineProperties(this.staticMutatorMap, className);
}
if (instanceProps || staticProps) {
staticProps = staticProps || t.literal(null);
var args = [className, staticProps];
if (instanceProps) args.push(instanceProps);
body.push(t.expressionStatement(
t.callExpression(this.file.addDeclaration("class-props"), args)
));
}
};
/**
* Push a method to it's respective mutatorMap.
*
* @param {Node} node MethodDefinition
*/
Class.prototype.pushMethod = function (node) {
var methodName = node.key;
var mutatorMap = this.instanceMutatorMap;
if (node.static) mutatorMap = this.staticMutatorMap;
var kind = node.kind;
if (kind === "") {
kind = "value";
util.pushMutatorMap(mutatorMap, methodName, "writable", t.identifier("true"));
}
util.pushMutatorMap(mutatorMap, methodName, kind, node);
};
/**
* Given a `methodNode`, produce a `MemberExpression` super class reference.
*
* @param {Node} methodNode MethodDefinition
* @param {Node} node Identifier
* @param {Node} parent
*
* @returns {Node}
*/
Class.prototype.superIdentifier = function (methodNode, id, parent) {
var methodName = methodNode.key;
var superName = this.superName || t.identifier("Function");
if (parent.property === id) {
return;
} else if (t.isCallExpression(parent, { callee: id })) {
// super(); -> ClassName.prototype.MethodName.call(this);
parent.arguments.unshift(t.thisExpression());
if (methodName.name === "constructor") {
// constructor() { super(); }
return t.memberExpression(superName, t.identifier("call"));
} else {
id = superName;
// foo() { super(); }
if (!methodNode.static) {
id = t.memberExpression(id, t.identifier("prototype"));
}
id = t.memberExpression(id, methodName, methodNode.computed);
return t.memberExpression(id, t.identifier("call"));
}
} else if (t.isMemberExpression(parent) && !methodNode.static) {
// super.test -> ClassName.prototype.test
return t.memberExpression(superName, t.identifier("prototype"));
} else {
return superName;
}
};
/**
* Replace all `super` references with a reference to our `superClass`.
*
* @param {Node} methodNode MethodDefinition
*/
Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
var method = methodNode.value;
var self = this;
traverse(method, function (node, parent) {
if (t.isIdentifier(node, { name: "super" })) {
return self.superIdentifier(methodNode, node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
// super.test(); -> ClassName.prototype.MethodName.call(this);
callee.property = t.memberExpression(callee.property, t.identifier("call"));
node.arguments.unshift(t.thisExpression());
}
});
};
/**
* Replace the constructor body of our class.
*
* @param {Node} method MethodDefinition
*/
Class.prototype.pushConstructor = function (method) {
if (method.kind !== "") {
throw this.file.errorWithNode(method, "illegal kind for constructor method");
}
var construct = this.constructor;
var fn = method.value;
this.hasConstructor = true;
t.inherits(construct, fn);
construct.defaults = fn.defaults;
construct.params = fn.params;
construct.body = fn.body;
construct.rest = fn.rest;
};

View File

@@ -1,5 +1,5 @@
var util = require("../util");
var b = require("recast").types.builders;
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
exports.ObjectExpression = function (node, parent, file) {
@@ -26,17 +26,17 @@ exports.ObjectExpression = function (node, parent, file) {
OBJECT: node
});
var containerCallee = container.callee;
var containerCallee = container.callee.expression;
var containerBody = containerCallee.body.body;
containerCallee._aliasFunction = "arrows";
containerCallee._aliasFunction = true;
_.each(computed, function (prop) {
containerBody.unshift(
b.expressionStatement(
b.assignmentExpression(
t.expressionStatement(
t.assignmentExpression(
"=",
b.memberExpression(objId, prop.key, true),
t.memberExpression(objId, prop.key, true),
prop.value
)
)

View File

@@ -0,0 +1,49 @@
var traverse = require("../../traverse");
var t = require("../../types");
var _ = require("lodash");
exports.Program =
exports.BlockStatement =
exports.ForInStatement =
exports.ForOfStatement =
exports.ForStatement = function (node, parent, file) {
var constants = [];
var check = function (node, names) {
_.each(names, function (name) {
if (constants.indexOf(name) >= 0) {
throw file.errorWithNode(node, name + " is read-only");
}
});
};
var getIds = function (node) {
return t.getIds(node, false, ["MemberExpression"]);
};
_.each(node.body, function (child) {
if (child && t.isVariableDeclaration(child, { kind: "const" })) {
_.each(child.declarations, function (declar) {
_.each(getIds(declar), function (name) {
check(declar, [name]);
constants.push(name);
});
declar._ignoreConstant = true;
});
child._ignoreConstant = true;
child.kind = "let";
}
});
if (!constants.length) return;
traverse(node, function (child) {
if (child._ignoreConstant) return;
if (t.isVariableDeclarator(child) || t.isDeclaration(child) || t.isAssignmentExpression(child)) {
check(child, getIds(child));
}
});
};

View File

@@ -1,9 +1,10 @@
var util = require("../util");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
exports.Function = function (node) {
if (!node.defaults.length) return;
util.ensureBlock(node);
if (!node.defaults || !node.defaults.length) return;
t.ensureBlock(node);
_.each(node.defaults, function (def, i) {
if (!def) return;

View File

@@ -0,0 +1,198 @@
var t = require("../../types");
var _ = require("lodash");
var buildVariableAssign = function (kind, id, init) {
if (kind === false) {
return t.expressionStatement(t.assignmentExpression("=", id, init));
} else {
return t.variableDeclaration(kind, [
t.variableDeclarator(id, init)
]);
}
};
var push = function (kind, nodes, elem, parentId) {
if (t.isObjectPattern(elem)) {
pushObjectPattern(kind, nodes, elem, parentId);
} else if (t.isArrayPattern(elem)) {
pushArrayPattern(kind, nodes, elem, parentId);
} else if (t.isMemberExpression(elem)) {
nodes.push(buildVariableAssign(false, elem, parentId));
} else {
nodes.push(buildVariableAssign(kind, elem, parentId));
}
};
var pushObjectPattern = function (kind, nodes, pattern, parentId) {
_.each(pattern.properties, function (prop) {
var pattern2 = prop.value;
var patternId2 = t.memberExpression(parentId, prop.key);
if (t.isPattern(pattern2)) {
push(kind, nodes, pattern2, patternId2);
} else {
nodes.push(buildVariableAssign(kind, pattern2, patternId2));
}
});
};
var pushArrayPattern = function (kind, nodes, pattern, parentId) {
_.each(pattern.elements, function (elem, i) {
if (!elem) return;
var newPatternId;
if (t.isSpreadElement(elem)) {
newPatternId = t.callExpression(t.memberExpression(parentId, t.identifier("slice")), [t.literal(i)]);
elem = elem.argument;
} else {
newPatternId = t.memberExpression(parentId, t.literal(i), true);
}
push(kind, nodes, elem, newPatternId);
});
};
var pushPattern = function (opts) {
var kind = opts.kind;
var nodes = opts.nodes;
var pattern = opts.pattern;
var parentId = opts.id;
var file = opts.file;
var scope = opts.scope;
if (!t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
var key = t.identifier(file.generateUid("ref", scope));
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(key, parentId)
]));
parentId = key;
}
push(kind, nodes, pattern, parentId);
};
exports.ForInStatement =
exports.ForOfStatement = function (node, parent, file, scope) {
var declar = node.left;
if (!t.isVariableDeclaration(declar)) return;
var pattern = declar.declarations[0].id;
if (!t.isPattern(pattern)) return;
var key = t.identifier(file.generateUid("ref", scope));
node.left = t.variableDeclaration(declar.kind, [
t.variableDeclarator(key, null)
]);
var nodes = [];
push(declar.kind, nodes, pattern, key);
t.ensureBlock(node);
var block = node.body;
block.body = nodes.concat(block.body);
};
exports.Function = function (node, parent, file, scope) {
var nodes = [];
var hasDestructuring = false;
node.params = node.params.map(function (pattern) {
if (!t.isPattern(pattern)) return pattern;
hasDestructuring = true;
var parentId = t.identifier(file.generateUid("ref", scope));
pushPattern({
kind: "var",
nodes: nodes,
pattern: pattern,
id: parentId,
file: file,
scope: scope
});
return parentId;
});
if (!hasDestructuring) return;
t.ensureBlock(node);
var block = node.body;
block.body = nodes.concat(block.body);
};
exports.ExpressionStatement = function (node, parent, file, scope) {
var expr = node.expression;
if (expr.type !== "AssignmentExpression") return;
if (!t.isPattern(expr.left)) return;
var nodes = [];
var ref = t.identifier(file.generateUid("ref", scope));
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(ref, expr.right)
]));
push(false, nodes, expr.left, ref);
return nodes;
};
exports.VariableDeclaration = function (node, parent, file, scope) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
var nodes = [];
var hasPattern = false;
_.each(node.declarations, function (declar) {
if (t.isPattern(declar.id)) {
hasPattern = true;
return false;
}
});
if (!hasPattern) return;
_.each(node.declarations, function (declar) {
var patternId = declar.init;
var pattern = declar.id;
if (t.isPattern(pattern) && patternId) {
pushPattern({
kind: node.kind,
nodes: nodes,
pattern: pattern,
id: patternId,
file: file,
scope: scope
});
} else {
nodes.push(buildVariableAssign(node.kind, declar.id, declar.init));
}
});
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
var declar;
_.each(nodes, function (node) {
declar = declar || t.variableDeclaration(node.kind, []);
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
throw file.errorWithNode(node, "Cannot use this node within the current parent");
}
declar.declarations = declar.declarations.concat(node.declarations);
});
return declar;
}
return nodes;
};

View File

@@ -0,0 +1,34 @@
var util = require("../../util");
var t = require("../../types");
exports.ForOfStatement = function (node, parent, file, scope) {
var left = node.left;
var declar;
var stepKey = t.identifier(file.generateUid("step", scope));
var stepValueId = t.memberExpression(stepKey, t.identifier("value"));
if (t.isIdentifier(left)) {
declar = t.expressionStatement(t.assignmentExpression("=", left, stepValueId));
} else if (t.isVariableDeclaration(left)) {
declar = t.variableDeclaration(left.kind, [
t.variableDeclarator(left.declarations[0].id, stepValueId)
]);
} else {
return;
}
var node2 = util.template("for-of", {
ITERATOR_KEY: file.generateUid("iterator", scope),
STEP_KEY: stepKey,
OBJECT: node.right
});
t.ensureBlock(node);
var block = node2.body;
block.body.push(declar);
block.body = block.body.concat(node.body.body);
return node2;
};

View File

@@ -0,0 +1,15 @@
var arrayComprehension = require("./array-comprehension");
var t = require("../../types");
exports.ComprehensionExpression = function (node) {
if (!node.generator) return;
var body = [];
var container = t.functionExpression(null, [], t.blockStatement(body), true);
body.push(arrayComprehension._build(node, function () {
return t.expressionStatement(t.yieldExpression(node.body));
}));
return t.callExpression(container, []);
};

View File

@@ -0,0 +1,3 @@
var regenerator = require("regenerator-6to5");
module.exports = regenerator.transform;

View File

@@ -0,0 +1,431 @@
var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types");
var _ = require("lodash");
var isLet = function (node) {
if (!t.isVariableDeclaration(node)) return false;
if (node._let) return true;
if (node.kind !== "let") return false;
node._let = true;
node.kind = "var";
return true;
};
var isVar = function (node) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node);
};
var standardiseLets = function (declars) {
_.each(declars, function (declar) {
delete declar._let;
});
};
exports.VariableDeclaration = function (node) {
isLet(node);
};
exports.For = function (node, parent, file, scope) {
var init = node.left || node.init;
if (isLet(init)) {
t.ensureBlock(node);
node.body._letDeclars = [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, file, scope);
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);
}
};
exports.BlockStatement = function (block, parent, file, scope) {
if (!t.isFor(parent)) {
var letScoping = new LetScoping(false, block, parent, file, scope);
letScoping.run();
}
};
/**
* Description
*
* @param {Boolean|Node} forParent
* @param {Node} block
* @param {Node} parent
* @param {File} file
* @param {Scope} scope
*/
function LetScoping(forParent, block, parent, file, scope) {
this.forParent = forParent;
this.parent = parent;
this.scope = scope;
this.block = block;
this.file = file;
this.letReferences = {};
this.body = [];
this.info = this.getInfo();
}
/**
* Start the ball rolling.
*/
LetScoping.prototype.run = function () {
var block = this.block;
if (block._letDone) return;
block._letDone = true;
// this is a block within a `Function` so we can safely leave it be
if (t.isFunction(this.parent)) return;
// this block has no let references so let's clean up
if (!this.info.keys.length) return this.noClosure();
// returns whether or not there are any outside let references within any
// functions
var referencesInClosure = this.getLetReferences();
// no need for a closure so let's clean up
if (!referencesInClosure) return this.noClosure();
// if we're inside of a for loop then we search to see if there are any
// `break`s, `continue`s, `return`s etc
this.has = this.checkFor();
// hoist var references to retain scope
this.hoistVarDeclarations();
// set let references to plain var references
standardiseLets(this.info.declarators);
// turn letReferences into an array
var letReferences = _.values(this.letReferences);
// build the closure that we're going to wrap the block with
var fn = t.functionExpression(null, letReferences, t.blockStatement(block.body));
fn._aliasFunction = true;
// replace the current block body with the one we're going to build
block.body = this.body;
// change upper scope references with their uid if they have one
var params = this.getParams(letReferences);
// build a call and a unique id that we can assign the return value to
var call = t.callExpression(fn, params);
var ret = t.identifier(this.file.generateUid("ret", this.scope));
this.build(ret, call);
};
/**
* There are no let references accessed within a closure so we can just traverse
* through this block and replace all references that exist in a high scope to
* their uids.
*/
LetScoping.prototype.noClosure = function () {
var replacements = this.info.duplicates;
var declarators = this.info.declarators;
var block = this.block;
standardiseLets(declarators);
if (_.isEmpty(replacements)) return;
traverse(block, function (node, parent) {
if (!t.isIdentifier(node)) return;
if (!t.isReferenced(node, parent)) return;
node.name = replacements[node.name] || node.name;
});
};
/**
* Description
*
* @returns {Object}
*/
LetScoping.prototype.getInfo = function () {
var block = this.block;
var scope = this.scope;
var file = this.file;
var opts = {
// array of `Identifier` names of let variables that appear lexically out of
// this scope but should be accessible - eg. `ForOfStatement`.left
outsideKeys: [],
// array of let `VariableDeclarator`s that are a part of this block
declarators: block._letDeclars || [],
// object of duplicate ids and their aliases - if there's an `Identifier`
// name that's used in an upper scope we generate a unique id and replace
// all references with it
duplicates: {},
// array of `Identifier` names of let variables that are accessible within
// the current block
keys: []
};
_.each(opts.declarators, function (declar) {
opts.declarators.push(declar);
var keys = t.getIds(declar);
opts.outsideKeys = opts.outsideKeys.concat(keys);
opts.keys = opts.keys.concat(keys);
});
_.each(block.body, function (declar) {
if (!isLet(declar)) return;
_.each(t.getIds(declar, true), function (id, key) {
var has = scope.parentGet(key);
if (has && has !== id) {
// there's a variable with this exact name in an upper scope so we need
// to generate a new name
opts.duplicates[key] = id.name = file.generateUid(key, scope);
}
opts.keys.push(key);
});
});
return opts;
};
/**
* If we're inside of a `For*Statement` then traverse it and check if it has one
* of the following node types `ReturnStatement`, `BreakStatement`,
* `ContinueStatement` and replace it with a return value we can track later on.
*
* @returns {Object}
*/
LetScoping.prototype.checkFor = function () {
var has = {
hasContinue: false,
hasReturn: false,
hasBreak: false,
};
if (this.forParent) {
traverse(this.block, function (node) {
var replace;
if (t.isFunction(node) || t.isFor(node)) {
return false;
} else if (t.isBreakStatement(node) && !node.label) {
has.hasBreak = true;
replace = t.returnStatement(t.literal("break"));
} else if (t.isContinueStatement(node) && !node.label) {
has.hasContinue = true;
replace = t.returnStatement(t.literal("continue"));
} else if (t.isReturnStatement(node)) {
has.hasReturn = true;
replace = t.returnStatement(t.objectExpression([
t.property("init", t.identifier("v"), node.argument || t.identifier("undefined"))
]));
}
if (replace) return t.inherits(replace, node);
});
}
return has;
};
/**
* Hoist all var declarations in this block to before it so they retain scope
* once we wrap everything is in a closure.
*/
LetScoping.prototype.hoistVarDeclarations = function () {
var self = this;
traverse(this.block, function (node) {
if (t.isForStatement(node)) {
if (isVar(node.init)) {
node.init = t.sequenceExpression(self.pushDeclar(node.init));
}
} else if (t.isFor(node)) {
if (isVar(node.left)) {
node.left = node.left.declarations[0].id;
}
} else if (isVar(node)) {
return self.pushDeclar(node).map(t.expressionStatement);
} else if (t.isFunction(node)) {
return false;
}
});
};
/**
* Build up a parameter list that we'll call our closure wrapper with, replacing
* all duplicate ids with their uid.
*
* @param {Array} params
* @returns {Array}
*/
LetScoping.prototype.getParams = function (params) {
var info = this.info;
params = _.cloneDeep(params);
_.each(params, function (param) {
param.name = info.duplicates[param.name] || param.name;
});
return params;
};
/**
* Get all let references within this block. Stopping whenever we reach another
* block.
*/
LetScoping.prototype.getLetReferences = function () {
var closurify = false;
var self = this;
// traverse through this block, stopping on functions and checking if they
// contain any outside let references
traverse(this.block, function (node, parent, scope) {
if (t.isFunction(node)) {
traverse(node, function (node, parent) {
// not an identifier so we have no use
if (!t.isIdentifier(node)) return;
// not a direct reference
if (!t.isReferenced(node, parent)) return;
// this scope has a variable with the same name so it couldn't belong
// to our let scope
if (scope.hasOwn(node.name)) return;
closurify = true;
// this key doesn't appear just outside our scope
if (!_.contains(self.info.outsideKeys, node.name)) return;
// push this badboy
self.letReferences[node.name] = node;
});
return false;
} else if (t.isFor(node)) {
return false;
}
});
return closurify;
};
/**
* Turn a `VariableDeclaration` into an array of `AssignmentExpressions` with
* their declarations hoisted to before the closure wrapper.
*
* @param {Node} node VariableDeclaration
* @returns {Array}
*/
LetScoping.prototype.buildPushDeclar = function (node) {
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
return t.variableDeclarator(declar.id);
})));
var replace = [];
_.each(node.declarations, function (declar) {
if (!declar.init) return;
var expr = t.assignmentExpression("=", declar.id, declar.init);
replace.push(t.inherits(expr, declar));
});
return replace;
};
/**
* Push the closure to the body.
*
* @param {Node} ret Identifier
* @param {Node} call CallExpression
*/
LetScoping.prototype.build = function (ret, call) {
var has = this.has;
if (has.hasReturn || has.hasBreak || has.hasContinue) {
this.buildHas(ret, call);
} else {
this.body.push(t.expressionStatement(call));
}
};
/**
* Description
*
* @param {Node} ret Identifier
* @param {Node} call CallExpression
*/
LetScoping.prototype.buildHas = function (ret, call) {
var body = this.body;
body.push(t.variableDeclaration("var", [
t.variableDeclarator(ret, call)
]));
var forParent = this.forParent;
var retCheck;
var has = this.has;
var cases = [];
if (has.hasReturn) {
// typeof ret === "object"
retCheck = util.template("let-scoping-return", {
RETURN: ret
});
}
if (has.hasBreak || has.hasContinue) {
// ensure that the parent has a label as we're building a switch and we
// need to be able to access it
var label = forParent.label = forParent.label || t.identifier(this.file.generateUid("loop", this.scope));
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)]));
}
if (has.hasReturn) {
cases.push(t.switchCase(null, [retCheck]));
}
if (cases.length === 1) {
var single = cases[0];
body.push(t.ifStatement(
t.binaryExpression("===", ret, single.test),
single.consequent[0]
));
} else {
body.push(t.switchStatement(ret, cases));
}
} else {
if (has.hasReturn) body.push(retCheck);
}
};

View File

@@ -0,0 +1,29 @@
var _ = require("lodash");
exports.ImportDeclaration = function (node, parent, file) {
var nodes = [];
if (node.specifiers.length) {
_.each(node.specifiers, function (specifier) {
file.moduleFormatter.importSpecifier(specifier, node, nodes);
});
} else {
file.moduleFormatter.import(node, nodes);
}
return nodes;
};
exports.ExportDeclaration = function (node, parent, file) {
var nodes = [];
if (node.declaration) {
file.moduleFormatter.export(node, nodes);
} else {
_.each(node.specifiers, function (specifier) {
file.moduleFormatter.exportSpecifier(specifier, node, nodes);
});
}
return nodes;
};

View File

@@ -1,4 +1,4 @@
var util = require("../util");
var util = require("../../util");
var _ = require("lodash");
exports.Property = function (node) {
@@ -10,7 +10,7 @@ exports.ObjectExpression = function (node, parent, file) {
node.properties = node.properties.filter(function (prop) {
if (prop.kind === "get" || prop.kind === "set") {
util.pushMutatorMap(mutatorMap, prop.key.name, prop.kind, prop.value);
util.pushMutatorMap(mutatorMap, prop.key, prop.kind, prop.value);
return false;
} else {
return true;
@@ -24,6 +24,9 @@ exports.ObjectExpression = function (node, parent, file) {
return util.template("object-define-properties-closure", {
KEY: objId,
OBJECT: node,
CONTENT: util.buildDefineProperties(mutatorMap, objId).expression
CONTENT: util.template("object-define-properties", {
OBJECT: objId,
PROPS: util.buildDefineProperties(mutatorMap)
})
});
};

View File

@@ -0,0 +1,182 @@
// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser)
// https://github.com/RReverser/jsx-transpiler
// jsx
var esutils = require("esutils");
var t = require("../../types");
var _ = require("lodash");
exports.XJSIdentifier = function (node) {
if (esutils.keyword.isIdentifierName(node.name)) {
node.type = "Identifier";
} else {
return t.literal(node.name);
}
};
exports.XJSNamespacedName = function (node, parent, file) {
throw file.errorWithNode(node, "Namespace tags are not supported. ReactJSX is not XML.");
};
exports.XJSMemberExpression = {
exit: function (node) {
node.computed = t.isLiteral(node.property);
node.type = "MemberExpression";
}
};
exports.XJSExpressionContainer = function (node) {
return node.expression;
};
exports.XJSAttribute = {
exit: function (node) {
var value = node.value || t.literal(true);
return t.property("init", node.name, value);
}
};
exports.XJSOpeningElement = {
exit: function (node) {
var tagExpr = node.name;
var args = [];
var tagName;
if (t.isIdentifier(tagExpr)) {
tagName = tagExpr.name;
} else if (t.isLiteral(tagExpr)) {
tagName = tagExpr.value;
}
if (tagName && (/[a-z]/.exec(tagName[0]) || _.contains(tagName, "-"))) {
args.push(t.literal(tagName));
} else {
args.push(tagExpr);
}
var props = node.attributes;
if (props.length) {
var _props = [];
var objs = [];
var pushProps = function () {
if (!_props.length) return;
objs.push(t.objectExpression(_props));
_props = [];
};
while (props.length) {
var prop = props.shift();
if (t.isXJSSpreadAttribute(prop)) {
pushProps();
objs.push(prop.argument);
} else {
_props.push(prop);
}
}
pushProps();
if (objs.length === 1) {
props = objs[0];
} else {
if (!t.isObjectExpression(objs[0])) {
objs.unshift(t.objectExpression([]));
}
props = t.callExpression(
t.memberExpression(t.identifier("React"), t.identifier("__spread")),
objs
);
}
} else {
props = t.literal(null);
}
args.push(props);
tagExpr = t.memberExpression(t.identifier("React"), t.identifier("createElement"));
return t.callExpression(tagExpr, args);
}
};
exports.XJSElement = {
exit: function (node) {
var callExpr = node.openingElement;
var childrenToRender = node.children.filter(function(child) {
return !(t.isLiteral(child) && _.isString(child.value) && child.value.match(/^[ \t]*[\r\n][ \t\r\n]*$/));
});
_.each(childrenToRender, function (child) {
callExpr.arguments.push(child);
});
return t.inherits(callExpr, node);
}
};
// display names
var addDisplayName = function (id, call) {
if (!call || !t.isCallExpression(call)) return;
var callee = call.callee;
if (!t.isMemberExpression(callee)) return;
// not React
var obj = callee.object;
if (!t.isIdentifier(obj, { name: "React" })) return;
// not createClass
var prop = callee.property;
if (!t.isIdentifier(prop, { name: "createClass" })) return;
// no arguments
var args = call.arguments;
if (args.length !== 1) return;
// not an object
var first = args[0];
if (!t.isObjectExpression(first)) return;
var props = first.properties;
var safe = true;
_.each(props, function (prop) {
if (t.isIdentifier(prop.key, { name: "displayName" })) {
return safe = false;
}
});
if (safe) {
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
}
};
exports.AssignmentExpression =
exports.Property =
exports.VariableDeclarator = function (node) {
var left, right;
if (t.isAssignmentExpression(node)) {
left = node.left;
right = node.right;
} else if (t.isProperty(node)) {
left = node.key;
right = node.value;
} else if (t.isVariableDeclarator(node)) {
left = node.id;
right = node.init;
}
if (t.isMemberExpression(left)) {
left = left.property;
}
if (t.isIdentifier(left)) {
addDisplayName(left.name, right);
}
};

View File

@@ -0,0 +1,24 @@
var util = require("../../util");
var t = require("../../types");
exports.Function = function (node, parent, file) {
if (!node.rest) return;
var rest = node.rest;
delete node.rest;
var templateName = "arguments-slice-assign";
if (node.params.length) templateName += "-arg";
t.ensureBlock(node);
var template = util.template(templateName, {
SLICE_KEY: file.addDeclaration("slice"),
VARIABLE_NAME: rest,
SLICE_ARG: t.literal(node.params.length)
});
template.declarations[0].init.arguments[0]._ignoreAliasFunctions = true;
node.body.body.unshift(template);
};

View File

@@ -0,0 +1,113 @@
var t = require("../../types");
var _ = require("lodash");
var getSpreadLiteral = function (spread) {
var literal = spread.argument;
if (!t.isArrayExpression(literal)) {
literal = t.callExpression(
t.memberExpression(t.identifier("Array"), t.identifier("from")),
[literal]
);
}
return literal;
};
var hasSpread = function (nodes) {
var has = false;
_.each(nodes, function (node) {
if (t.isSpreadElement(node)) {
has = true;
return false;
}
});
return has;
};
var build = function (props) {
var nodes = [];
var _props = [];
var push = function () {
if (!_props.length) return;
nodes.push(t.arrayExpression(_props));
_props = [];
};
_.each(props, function (prop) {
if (t.isSpreadElement(prop)) {
push();
nodes.push(getSpreadLiteral(prop));
} else {
_props.push(prop);
}
});
push();
return nodes;
};
exports.ArrayExpression = function (node) {
var elements = node.elements;
if (!hasSpread(elements)) return;
var nodes = build(elements);
var first = nodes.shift();
if (!nodes.length) return first;
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
};
exports.CallExpression = function (node) {
var args = node.arguments;
if (!hasSpread(args)) return;
var contextLiteral = t.literal(null);
node.arguments = [];
var nodes = build(args);
var first = nodes.shift();
if (nodes.length) {
node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
} else {
node.arguments.push(first);
}
var callee = node.callee;
if (t.isMemberExpression(callee)) {
contextLiteral = callee.object;
if (callee.computed) {
callee.object = t.memberExpression(callee.object, callee.property, true);
callee.property = t.identifier("apply");
callee.computed = false;
} else {
callee.property = t.memberExpression(callee.property, t.identifier("apply"));
}
} else {
node.callee = t.memberExpression(node.callee, t.identifier("apply"));
}
node.arguments.unshift(contextLiteral);
};
exports.NewExpression = function (node, parent, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
var nodes = build(args);
var first = nodes.shift();
if (nodes.length) {
args = t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
} else {
args = first;
}
return t.callExpression(file.addDeclaration("apply-constructor"), [node.callee, args]);
};

View File

@@ -1,8 +1,8 @@
var b = require("recast").types.builders;
var t = require("../../types");
var _ = require("lodash");
var buildBinaryExpression = function (left, right) {
return b.binaryExpression("+", left, right);
return t.binaryExpression("+", left, right);
};
exports.TaggedTemplateExpression = function (node) {
@@ -10,31 +10,34 @@ exports.TaggedTemplateExpression = function (node) {
var quasi = node.quasi;
var strings = quasi.quasis.map(function (elem) {
return b.literal(elem.value.raw);
return t.literal(elem.value.raw);
});
args.push(b.arrayExpression(strings));
args.push(t.arrayExpression(strings));
_.each(quasi.expressions, function (expr) {
args.push(expr);
});
return b.callExpression(node.tag, args);
return t.callExpression(node.tag, args);
};
exports.TemplateLiteral = function (node) {
var nodes = [];
_.each(node.quasis, function (elem) {
nodes.push(b.literal(elem.value.raw));
nodes.push(t.literal(elem.value.raw));
var expr = node.expressions.shift();
if (expr) nodes.push(expr);
if (expr) {
if (t.isBinary(expr)) expr = t.parenthesizedExpression(expr);
nodes.push(expr);
}
});
if (nodes.length > 1) {
// remove redundant '' at the end of the expression
var last = _.last(nodes);
if (last.type === "Literal" && last.value === "") nodes.pop();
if (t.isLiteral(last, { value: "" })) nodes.pop();
var root = buildBinaryExpression(nodes.shift(), nodes.shift());

View File

@@ -1,5 +1,4 @@
var rewritePattern = require("regexpu/rewrite-pattern");
var b = require("recast").types.builders;
var _ = require("lodash");
exports.Literal = function (node) {
@@ -10,6 +9,6 @@ exports.Literal = function (node) {
if (!_.contains(regex.flags, "u")) return;
_.pull(flags, "u");
var pattern = rewritePattern(regex.pattern, regex.flags);
return b.literal(new RegExp(pattern, flags.join("")));
regex.pattern = rewritePattern(regex.pattern, regex.flags);
regex.flags = flags.join("");
};

View File

@@ -0,0 +1,12 @@
var t = require("../../types");
module.exports = function (ast) {
var body = ast.program.body;
var first = body[0];
var noStrict = !first || !t.isExpressionStatement(first) || !t.isLiteral(first.expression) || first.expression.value !== "use strict";
if (noStrict) {
body.unshift(t.expressionStatement(t.literal("use strict")));
}
};

View File

@@ -1,84 +0,0 @@
var traverse = require("../traverse");
var util = require("../util");
var b = require("recast").types.builders;
var go = function (getBody, node, file) {
var argumentsId;
var thisId;
var getArgumentsId = function () {
return argumentsId = argumentsId || b.identifier(file.generateUid("arguments"));
};
var getThisId = function () {
return thisId = thisId || b.identifier(file.generateUid("this"));
};
// traverse the function and find all alias functions so we can alias
// arguments and this if neccesary
traverse(node, function (node) {
var _aliasFunction = node._aliasFunction;
if (!_aliasFunction) {
if (traverse.isFunction(node)) {
// stop traversal of this node as it'll be hit again by this transformer
return false;
} else {
return;
}
}
// traverse all child nodes of this function and find arguments and this
traverse(node, function (node, parent) {
if (_aliasFunction === "arrows") {
if (traverse.isFunction(node) && node._aliasFunction !== "arrows") {
return false;
}
}
var getId;
if (node.type === "Identifier" && node.name === "arguments") {
getId = getArgumentsId;
} else if (node.type === "ThisExpression") {
getId = getThisId;
} else {
return;
}
if (util.isReferenced(node, parent)) return getId();
});
return false;
});
var body;
var pushDeclaration = function (id, init) {
body = body || getBody();
body.unshift(b.variableDeclaration("var", [
b.variableDeclarator(id, init)
]));
};
if (argumentsId) {
pushDeclaration(argumentsId, b.identifier("arguments"));
}
if (thisId) {
pushDeclaration(thisId, b.identifier("this"));
}
};
exports.Program = function (node, parent, file) {
go(function () {
return node.body;
}, node, file);
};
exports.FunctionDeclaration =
exports.FunctionExpression = function (node, parent, file) {
go(function () {
util.ensureBlock(node);
return node.body.body;
}, node, file);
};

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