Compare commits

..

223 Commits

Author SHA1 Message Date
Sebastian McKenzie
a4c6660d21 v3.6.2 2015-02-13 21:07:45 +11:00
Sebastian McKenzie
9676666e7c 3.6.1 2015-02-13 21:05:56 +11:00
Sebastian McKenzie
388133642d add support for UnaryExpression to getBindingIdentifiers and add it as a reassignment in the scope tracking 2015-02-13 21:05:52 +11:00
Sebastian McKenzie
23b5eeb72f use Symbol.iterator in for symbol detection and add the conversion of it to the selfContained transformer - @zloirock 2015-02-13 21:05:21 +11:00
Sebastian McKenzie
db36c3a7c2 v3.6.1 2015-02-13 20:50:37 +11:00
Sebastian McKenzie
e841b88cbc fix 6to5-node test collisions 2015-02-13 20:48:52 +11:00
Sebastian McKenzie
3d874f2479 update sliceToArray helper, again... 2015-02-13 20:45:43 +11:00
Sebastian McKenzie
228719102a update sliceToArray tests 2015-02-13 20:39:37 +11:00
Sebastian McKenzie
c6ce1a248c better slicedToArray helper 2015-02-13 20:38:28 +11:00
Sebastian McKenzie
ba9b85f64b only use functions returnType if it hasn't been reassigned 2015-02-13 20:36:43 +11:00
Sebastian McKenzie
56c868efee fix incorrect generateUid references in File 2015-02-13 18:27:53 +11:00
Sebastian McKenzie
1f3c3832ba fix linting errors 2015-02-13 18:25:34 +11:00
Sebastian McKenzie
3b04a8c648 fix linting errors 2015-02-13 18:24:24 +11:00
Sebastian McKenzie
2270057b54 add 3.6.1 changelog 2015-02-13 18:23:46 +11:00
Sebastian McKenzie
c3206aa9a4 move File::generateUid to Scope and add return type inferrence 2015-02-13 18:21:28 +11:00
Sebastian McKenzie
1912d1b26a remove ExportSpecifier from t.getBindingIdentifiers as it has none 2015-02-13 18:19:27 +11:00
Sebastian McKenzie
9208e7e594 update common standard import test 2015-02-13 17:47:46 +11:00
Sebastian McKenzie
ce332b3384 fix module binding resolution - fixes #762 2015-02-13 17:37:35 +11:00
Sebastian McKenzie
a567531f77 ignore member expressions in constants transformer - fixes #770 2015-02-13 17:18:42 +11:00
Sebastian McKenzie
9cce72def0 update tests that use the toSlicedArray helper 2015-02-13 17:04:18 +11:00
Sebastian McKenzie
2d8581c6dc Merge branch 'master' of github.com:6to5/6to5
Conflicts:
	lib/6to5/transformation/transformers/minification/dead-code-elimination.js
2015-02-13 16:54:09 +11:00
Sebastian McKenzie
14a000396a add error message to the sliced-to-array helper on a non-iterable param - fixes #766 2015-02-13 16:50:03 +11:00
Sebastian McKenzie
4c41f5a22f bump acorn-6to5 and 6to5 devDependency 2015-02-13 15:09:28 +11:00
Sebastian McKenzie
6be2a6e02a add extra note to minification dead code elimination transformer 2015-02-13 15:09:17 +11:00
Sebastian McKenzie
0a4fc16ca0 add type inferrence that expires when a binding is reassigned 2015-02-13 15:08:58 +11:00
Sebastian McKenzie
25d8377411 normalise JSX attribute strings 2015-02-13 15:08:39 +11:00
Brian Donovan
14267a788d Fix a typo. 2015-02-12 19:12:09 -08:00
Sebastian McKenzie
ba5c5760b1 Merge pull request #769 from 6to5/if-truthy-minification-returns-consequent
Return the consequent if the test is truthy.
2015-02-13 14:08:32 +11:00
Brian Donovan
49904b3ab3 Fix a small grammar issue. 2015-02-12 19:07:54 -08:00
Brian Donovan
a212f035e4 Return the consequent if the test is truthy. 2015-02-12 19:06:06 -08:00
Brian Donovan
ea471a6a17 Fix a few typos. 2015-02-12 18:47:08 -08:00
Brian Donovan
f5bae0b696 Remove redundant variable. 2015-02-12 18:46:53 -08:00
Brian Donovan
9ec9e13aeb Update the jsdoc to indicate that key is optional. 2015-02-12 18:36:36 -08:00
Brian Donovan
0b042b2681 Use the posessive form of "its", not a contraction of "it is". 2015-02-12 18:36:02 -08:00
Brian Donovan
83b4d12884 Correct a jsdoc comment parameter name. 2015-02-12 18:35:35 -08:00
Brian Donovan
98d555498d Remove unused variable. 2015-02-12 18:29:14 -08:00
Sebastian McKenzie
fdc05cb977 Merge pull request #767 from 6to5/templates-should-not-recurse
Ensure that templates do not recurse.
2015-02-13 11:13:30 +11:00
Brian Donovan
928ebda5bc Ensure that templates do not recurse.
Closes #765.
2015-02-12 16:10:13 -08:00
Sebastian McKenzie
0a2003af66 3.6.0 2015-02-12 21:59:37 +11:00
Sebastian McKenzie
02392635ef v3.6.0 2015-02-12 21:57:18 +11:00
Sebastian McKenzie
298cfac7f4 fix linting errors 2015-02-12 21:55:31 +11:00
Sebastian McKenzie
476b683f0f upgrade core-js 2015-02-12 21:53:51 +11:00
Sebastian McKenzie
5c5b66df54 add 3.6.0 changelog 2015-02-12 21:53:45 +11:00
Sebastian McKenzie
e7f6572a3b track arrays to avoid turning something into an array multiple times - closes #757 2015-02-12 21:30:48 +11:00
Sebastian McKenzie
e9cfd2df3e fix toConsumableArray helper 2015-02-12 16:53:00 +11:00
Sebastian McKenzie
a425136680 allow loose = true as an alias for loose = "all" 2015-02-12 16:36:17 +11:00
Sebastian McKenzie
8d06a4301c pdate tests to reflect toConsumableArray updates 2015-02-12 16:35:55 +11:00
Sebastian McKenzie
1909a16dc7 copy over files that we can't compile when specifying a directory in bin/6to5 2015-02-12 16:35:41 +11:00
Sebastian McKenzie
3bfa1f610c add bootstrapping base 2015-02-12 16:35:04 +11:00
Sebastian McKenzie
4faf2b7730 fix namespace name 2015-02-12 16:00:54 +11:00
Sebastian McKenzie
4e5d6ee976 rice up toConsumableArray helper 2015-02-12 16:00:43 +11:00
Sebastian McKenzie
afb1ee79a1 fix autoenabling of playground/experimental when used in whitelist/optional 2015-02-12 16:00:26 +11:00
Sebastian McKenzie
efe3f30741 make minification.renameLocalVariables work 2015-02-12 07:46:34 +11:00
Sebastian McKenzie
5ff0285ba7 use space helper instead of pushing a space in IfStatement generation 2015-02-12 07:46:21 +11:00
Sebastian McKenzie
d7bea2f325 remove legacy jshint comment 2015-02-12 07:46:03 +11:00
Sebastian McKenzie
32316ad942 clean up t.is 2015-02-12 07:45:55 +11:00
Sebastian McKenzie
7953eb560e force experimental and playground flag when whitelisting/optionalising transformers 2015-02-12 07:45:50 +11:00
Sebastian McKenzie
faa10df84c add toConsumableArray helper for spread - fixes #757 2015-02-12 07:37:40 +11:00
Sebastian McKenzie
ae344aa23e recurse over and duplicate array in toArray in order to handle sparse arrays - fixes #754 2015-02-12 00:33:04 +11:00
Sebastian McKenzie
e0bfc72700 fix tail call deopt check 2015-02-11 20:16:50 +11:00
Sebastian McKenzie
bf8f80faf7 add general support for declarations to Scope::rename - closes #751 2015-02-11 20:14:41 +11:00
Sebastian McKenzie
77fa8bf01c fix isReferenced on AssignmentPattern 2015-02-11 20:14:21 +11:00
Sebastian McKenzie
34ca1ac04f delay binding reassignment to after reference replacements - #751 2015-02-11 19:48:54 +11:00
Sebastian McKenzie
85d33536e0 add deopt logging to tail call transformer 2015-02-11 15:59:15 +11:00
Sebastian McKenzie
a4932e0e0f add messages to make it easier to make error messages 2015-02-11 15:57:30 +11:00
Sebastian McKenzie
4ebd0a1e8a upgrade regenerator-6to5 2015-02-11 12:12:43 +11:00
Sebastian McKenzie
14e92e9e3f remove kexec from optionalDependencies 2015-02-11 12:00:38 +11:00
Sebastian McKenzie
13687d98ed bump regenerator-6to5 2015-02-11 11:52:16 +11:00
Sebastian McKenzie
db93c52182 opt out of tail recursion optimisation if the owner id has been reassigned - fixes #744 2015-02-11 11:27:50 +11:00
Sebastian McKenzie
56a953df64 add basic support for class property initializers - #619 2015-02-11 10:59:44 +11:00
Sebastian McKenzie
c38edbbb42 Merge branch 'master' of github.com:6to5/6to5 2015-02-11 08:29:08 +11:00
Sebastian McKenzie
017bb6427a Merge pull request #743 from chicoxyzzy/master
optimise lodash usage
2015-02-11 08:28:58 +11:00
Sebastian McKenzie
714ad40cb0 update contributing guide 2015-02-11 08:28:47 +11:00
Ingvar Stepanyan
904a72fb3a Fix rename not establishing binding. 2015-02-10 17:18:46 +02:00
chico
146835e0f1 fix broken code, lint and codestyle fixes 2015-02-10 18:16:54 +03:00
chico
79ba97872c optimise lodash usage; change contains function to includes for convenience 2015-02-10 17:40:53 +03:00
Sebastian McKenzie
897566ccb3 more reliable scope construction 2015-02-11 00:38:59 +11:00
Sebastian McKenzie
4df1b6700b remove acorn node patching 2015-02-11 00:37:59 +11:00
Sebastian McKenzie
50f903caf7 proper optional builder keys 2015-02-11 00:13:27 +11:00
Sebastian McKenzie
7b8118d8bd default newName in scope.rename to a new uid 2015-02-11 00:13:21 +11:00
Sebastian McKenzie
0c1e1e757c default optional builder keys to false 2015-02-11 00:02:51 +11:00
Sebastian McKenzie
62fa583fc1 fix linting errors 2015-02-10 23:55:11 +11:00
Sebastian McKenzie
8598000a69 restructure Scope API and internal data structure 2015-02-10 23:52:23 +11:00
Sebastian McKenzie
edc8bee38e test for falsy nodes in tail call transformer subtransform 2015-02-10 22:39:46 +11:00
Sebastian McKenzie
45b70d7fba fix bad ctrl+f Class -> ClassTransformer replacement 2015-02-10 22:39:21 +11:00
Sebastian McKenzie
49a53b26bb add scope renaming helper method - fixes #645 - @RReverser 2015-02-10 22:39:07 +11:00
Sebastian McKenzie
329b4e9d21 append Transformer to the end of transformer classes 2015-02-10 22:12:36 +11:00
Sebastian McKenzie
f1bca0013e refactor tail call transformer into a class - @RReverser 2015-02-10 22:11:22 +11:00
Sebastian McKenzie
87af83f1cb Merge pull request #742 from douglasduteil/patch-1
chore(travis): run tests on nodejs 0.12 too
2015-02-10 20:30:30 +11:00
Douglas Duteil
5156574bf2 chore(travis): run tests on nodejs 0.12 too 2015-02-10 10:29:05 +01:00
Sebastian McKenzie
ac098255be fix allowPartial in t.buildMatchMemberExpression 2015-02-10 18:34:16 +11:00
Sebastian McKenzie
47b803ef24 remove old tail call transformer 2015-02-10 18:33:51 +11:00
Sebastian McKenzie
7f61c8b65e add descriptor falsy check to defaults helper - #739 2015-02-10 18:33:29 +11:00
Sebastian McKenzie
4fa9aa63a3 Merge branch 'better-tail-recursion' 2015-02-10 18:04:05 +11:00
Sebastian McKenzie
d582c7c93a Merge pull request #739 from lukescott/defaults-fix
fix defaults helper in strict mode - #738
2015-02-10 18:00:26 +11:00
Sebastian McKenzie
6266f5b924 finish minification.removeConsoleCall transformer #740 2015-02-10 17:56:31 +11:00
Luke Scott
c6920a0e60 fix defaults helper in strict mode - #738 2015-02-09 20:38:57 -08:00
Sebastian McKenzie
825d84ba52 fix defaults helper iteration - #738 2015-02-10 13:20:19 +11:00
Sebastian McKenzie
94a0eb5b06 copy over descriptors and handle non-enumerable properties in defaults helper - fixes #738 2015-02-10 13:06:26 +11:00
Sebastian McKenzie
b6d708caf2 add SpreadProperty to t.getBindingIdentifiers - fixes #734 2015-02-10 09:04:27 +11:00
Ingvar Stepanyan
0d542b61d3 Performance improvements for TCO.
http://jsperf.com/tco/17
2015-02-09 19:00:31 +02:00
Ingvar Stepanyan
5a842ab623 Fix statement substitution in templates. 2015-02-09 17:34:59 +02:00
Sebastian McKenzie
26d4b5f2cf normalise opts.sourceRoot path - 6to5/karma-6to5-preprocessor#5 2015-02-09 23:38:54 +11:00
Sebastian McKenzie
ba0dfac53d add uid scope kind 2015-02-09 21:28:51 +11:00
Sebastian McKenzie
8a4296a948 remove binding kind from pushing bindings to the function scope, better block scoped collision logic, and track label ids as references 2015-02-09 21:21:25 +11:00
Sebastian McKenzie
478f9e028f put function params into the param kind 2015-02-09 20:16:38 +11:00
Sebastian McKenzie
c4e56894d9 ignore hoisted kind when checking for block scoped collisions 2015-02-09 20:03:59 +11:00
Sebastian McKenzie
c6f13844ed move FunctionDeclarations into a hoisted kind 2015-02-09 19:53:46 +11:00
Sebastian McKenzie
5e81653680 change function params binding kind to let 2015-02-09 19:45:03 +11:00
Sebastian McKenzie
8e2df3f1f9 add kinds to binding registration and rename declaration scope methods to bindings 2015-02-09 19:42:52 +11:00
Sebastian McKenzie
a2cc384172 move rest parameters transformer above default parameters 2015-02-09 10:59:31 +11:00
Sebastian McKenzie
d37bf292a1 rename declarationKinds to bindingKinds in scope tracker 2015-02-09 10:59:20 +11:00
Sebastian McKenzie
70eb641530 fix element name in default parameters 2015-02-09 08:46:06 +11:00
Sebastian McKenzie
f845a9b2c4 ignore binding elements when finding the last non-default param - fixes #723 2015-02-09 08:25:58 +11:00
Sebastian McKenzie
ee5cb8d9ed clean up tail call transformer 2015-02-08 22:47:50 +11:00
Sebastian McKenzie
9020a21ba2 3.5.3 2015-02-08 22:17:36 +11:00
Sebastian McKenzie
fdda013d07 v3.5.3 2015-02-08 22:17:05 +11:00
Sebastian McKenzie
64477d934d add 3.5.3 changelog 2015-02-08 22:10:00 +11:00
Sebastian McKenzie
45c507056a add back old tail call implementation 2015-02-08 22:09:41 +11:00
Sebastian McKenzie
730b96c195 3.5.2 2015-02-08 21:23:55 +11:00
Sebastian McKenzie
a185f91433 v3.5.2 2015-02-08 21:23:24 +11:00
Sebastian McKenzie
d053622802 add 3.5.2 changelog 2015-02-08 21:21:38 +11:00
Sebastian McKenzie
74d6b61973 disable es6 tail call tests 2015-02-08 21:21:32 +11:00
Sebastian McKenzie
97784c8cca comment out tailCall transformer 2015-02-08 21:19:01 +11:00
Sebastian McKenzie
812d93553a temporairly disable tailCall transformer 2015-02-08 21:17:21 +11:00
Sebastian McKenzie
d251b4cb56 3.5.1 2015-02-08 21:16:34 +11:00
Sebastian McKenzie
caf38e1962 v3.5.1 2015-02-08 21:04:05 +11:00
Sebastian McKenzie
4ccbee4639 fix linting errors 2015-02-08 20:59:48 +11:00
Sebastian McKenzie
84196a3a07 add 3.5.1 changelog 2015-02-08 20:57:58 +11:00
Ingvar Stepanyan
29361c055a Fix #718. 2015-02-08 11:56:39 +02:00
Sebastian McKenzie
4277265591 Merge branch 'master' of github.com:6to5/6to5 2015-02-08 20:40:47 +11:00
Sebastian McKenzie
812a2b315d bump acorn-6to5 2015-02-08 20:40:30 +11:00
Ingvar Stepanyan
0a1724fc3f Remove no more needed returnBlock helper. 2015-02-08 11:31:19 +02:00
Sebastian McKenzie
bcc9e016b1 only evaluate object destructuring pattern once 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
4ea0175ca7 simplify set template 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
799445c745 add property method assignment wrapper generator template 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
481ea12999 add cleanup internal transformer 2015-02-08 20:23:22 +11:00
Sebastian McKenzie
de6b608dda add _declarations and _scopeInfo to t.inherits 2015-02-08 20:23:21 +11:00
Sebastian McKenzie
606f813822 enable traceur test suite by default 2015-02-08 20:23:21 +11:00
Sebastian McKenzie
e06c8cd106 support generators in nameMethod helper 2015-02-08 20:23:21 +11:00
Ingvar Stepanyan
9e3c67a8a2 Clean up functionChildrenVisitor a bit. 2015-02-08 10:53:09 +02:00
Ingvar Stepanyan
91362f80b1 Clean up transformations after #714.
Since now we have runtime helper, we don't need
expression -> statement conversions anymore.
2015-02-08 10:40:03 +02:00
Sebastian McKenzie
cde988f99f update 3.5.0 changelog 2015-02-08 16:53:33 +11:00
Sebastian McKenzie
9ec0854659 3.5.0 2015-02-08 16:37:13 +11:00
Sebastian McKenzie
bb17571e56 v3.5.0 2015-02-08 16:35:45 +11:00
Sebastian McKenzie
9161af58c0 fix linting errors 2015-02-08 16:32:08 +11:00
Sebastian McKenzie
e39f4e8025 update 3.5.0 changelog 2015-02-08 16:31:24 +11:00
Sebastian McKenzie
f5e9909e71 Merge pull request #716 from daliwali/master
Make `__esModule` property not enumerable
2015-02-08 16:30:26 +11:00
Sebastian McKenzie
46913fc55f add 3.5.0 changelog 2015-02-08 16:22:12 +11:00
Dali Zheng
d358a86e98 make __esModule property not enumerable 2015-02-07 21:19:11 -08:00
Sebastian McKenzie
055545980c update traceur test runner 2015-02-08 16:19:05 +11:00
Sebastian McKenzie
6fd7f9868e upgrade acorn-6to5 2015-02-08 16:18:54 +11:00
Sebastian McKenzie
e8184a9bc5 fix browser api location in browser test 2015-02-08 14:34:43 +11:00
Sebastian McKenzie
f74de3ef55 move destructuring and parameters.rest transformer to above blockScoping 2015-02-08 14:34:34 +11:00
Sebastian McKenzie
9624f8287d add checkNode to block scoped functions transformer 2015-02-08 14:34:10 +11:00
Sebastian McKenzie
e42d5a889e make destructuring in catch clauses block scoped and add support for non-variable destructuring in for-in/of heads 2015-02-08 14:33:55 +11:00
Sebastian McKenzie
4c8e6481b6 make default parameters iife invocation less serious 2015-02-08 09:54:24 +11:00
Sebastian McKenzie
0867df2691 fix ForOf block body not properly inheriting declarations 2015-02-08 09:50:12 +11:00
Sebastian McKenzie
b06f99ab30 add iife detection to non-identifier params in default parameters 2015-02-08 09:37:06 +11:00
Sebastian McKenzie
9afa3f6b58 add opts param to t.isReferencedIdentifier 2015-02-08 09:31:41 +11:00
Sebastian McKenzie
785cb4b72f allow optional transformer to be set via the whitelist 2015-02-08 09:31:30 +11:00
Sebastian McKenzie
dabe69856a add additional checks to transformers 2015-02-08 09:31:19 +11:00
Sebastian McKenzie
24e70802b5 fix block scoped tracking in functions - fixes #710 2015-02-08 09:31:04 +11:00
Sebastian McKenzie
c1ba55a52d Merge pull request #714 from RReverser/master
Added complete TCO (tail call optimization).
2015-02-08 08:55:19 +11:00
Ingvar Stepanyan
4c318166e1 Added complete TCO (tail call optimization).
Works across functions and generates simpler and faster code than #701.
Works even across files when used in conjunction with `runtime` option.

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

```
$ bin/6to5/index.js --help | grep "\-i,"
    -i, --optional [list]        List of optional transformers to enable
    -i, --module-ids             Insert module id in modules
```
2015-02-07 16:37:38 +09:00
Sebastian McKenzie
6b49958f7c Merge branch 'master' of github.com:6to5/6to5 2015-02-07 15:59:15 +11:00
Sebastian McKenzie
e75ce94578 move reactCompat option onto an optional transformer 2015-02-07 15:59:00 +11:00
Sebastian McKenzie
f666473724 Merge pull request #705 from cesarandreu/patch-2
Add 6to5-runtime README
2015-02-07 13:54:58 +11:00
Cesar Andreu
ae817e3c9c Add 6to5-runtime README 2015-02-06 18:53:42 -08:00
Sebastian McKenzie
2e9352de14 3.4.0 2015-02-07 10:44:06 +11:00
Sebastian McKenzie
1e9e55ddef fix browser build location in makefile 2015-02-07 10:42:28 +11:00
Sebastian McKenzie
0799ed7116 v3.4.0 2015-02-07 10:41:38 +11:00
Sebastian McKenzie
5537250d4f fix linting errors 2015-02-07 10:40:01 +11:00
Sebastian McKenzie
7ada50937b add 3.4.0 changelog 2015-02-07 10:39:24 +11:00
Sebastian McKenzie
f2ae88af93 add commonStandard module formatter - fixes #675
will be merged into strict formatters in next major
TODO: rewrite all module formatters as they've gotten out of han
2015-02-07 10:31:52 +11:00
Sebastian McKenzie
726451f86f reverts d6b39bc89b 2015-02-07 09:54:18 +11:00
Sebastian McKenzie
306cfc6328 fix 3.3.12 changelog misspelling 2015-02-07 09:53:18 +11:00
Sebastian McKenzie
a051a47048 reorder types requires 2015-02-07 08:11:42 +11:00
Ingvar Stepanyan
5b2216b348 Add tail recursion optimization.
As per ES6, VMs should perform tail call optimization and prevent growth of call stack.
This adds tail call optimization for recursion case (when function has explicit name and calls itself in `return`).
Cross-function optimization is not currently performed as it's more complicated and requires value tracking.
2015-02-06 16:34:35 +02:00
Sebastian McKenzie
ad60d49611 fix bindingEquals in constants transformer 2015-02-06 23:35:19 +11:00
Sebastian McKenzie
a6d1a5a724 add bindingEquals, typeEquals, referenceEquals helper methods to Scope 2015-02-06 23:07:10 +11:00
Sebastian McKenzie
399d835285 fix linting errors 2015-02-06 23:06:54 +11:00
Sebastian McKenzie
b66367ddde change namespace of minification.propertyLiterals and minifciation.memberExpressionLiterals to es3 2015-02-06 22:42:16 +11:00
Sebastian McKenzie
37d29b7a6f clean up function scope collection - @RReverser 2015-02-06 22:04:13 +11:00
Sebastian McKenzie
1e708fb373 fix traverse test 2015-02-06 01:59:45 +11:00
Sebastian McKenzie
76ae1682a3 remove context arg in favor of this, rename TraversalIteration to TraversalPath, and remove ast handlers 2015-02-06 01:47:43 +11:00
Sebastian McKenzie
2ef0aa95c5 clean up indentation 2015-02-06 01:17:42 +11:00
Sebastian McKenzie
9cbb49c6b2 don't return the sourcemap when inline is requested - 6to5/grunt-6to5#18 2015-02-05 22:25:33 +11:00
Sebastian McKenzie
f04a734838 fix module ids shorthand arg - fixes #696 2015-02-05 22:19:39 +11:00
Sebastian McKenzie
beb5ccab25 split up traversal so it's easier to maintain and extend later on 2015-02-05 19:42:08 +11:00
Sebastian McKenzie
b8f8f24e82 add newline to es6 destructuring member expression test 2015-02-05 19:41:53 +11:00
Sebastian McKenzie
c35a007401 simplify replace supers helper 2015-02-05 19:41:37 +11:00
Sebastian McKenzie
e639c82f2f fix internal refactoring... 2015-02-05 14:08:02 +11:00
Sebastian McKenzie
f365cc1248 more internal rearchitecturing 2015-02-05 14:05:15 +11:00
Sebastian McKenzie
2b75c67448 better scope traversal inferType todo comments 2015-02-05 11:16:13 +11:00
Sebastian McKenzie
e5e9ae7e0f v3.3.12 2015-02-05 10:32:14 +11:00
Sebastian McKenzie
009422e997 add 3.3.12 changelog 2015-02-05 10:15:15 +11:00
Sebastian McKenzie
386e221a0f don't override core supported member expressions if there's a local binding 2015-02-05 09:53:12 +11:00
Sebastian McKenzie
58db94401e 3.3.11 2015-02-05 08:53:29 +11:00
276 changed files with 3720 additions and 2009 deletions

5
.6to5rc Normal file
View File

@@ -0,0 +1,5 @@
{
"experimental": true,
"playground": true,
"loose": true
}

View File

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

View File

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

View File

@@ -3,6 +3,7 @@ language: node_js
node_js:
- "0.10"
- "0.11"
- "0.12"
branches:
except:

View File

@@ -11,6 +11,87 @@
_Note: Gaps between patch versions are faulty/broken releases._
## 3.6.1
* **Bug Fix**
* Multiline JSX string literals are now supported.
* Fix scope tracking import specifiers incorrectly.
* Fix templates incorrectly recursing into their replacements.
* **Internal**
* Type inferrence now extends to function return types.
* Upgrade `acorn-6to5`.
## 3.6.0
* **New Feature**
* Add playground class property initializers.
* **Polish**
* Completely reimplemented scope tracking, can now track types and optimise certain helpers based on it.
* Extremely fast tail recursion optimisation implementation. Thanks [@RReverser](https://github.com/RReverser)!
* **Internal**
* `kexec` has been removed as an optional dependency and must be user installed.
* Upgrade `regenerator-6to5`.
* Upgrade `acorn-6to5`.
* Upgrade `core-js`.
## 3.5.3
* Enable `es6.tailCall` transformer with the first implementation that only works with self referencing calls until we can implement nested tail calls elegantly.
## 3.5.2
* Disable `es6.tailCall` temporairly after reports of it breaking.
## 3.5.1
* **Polish**
* Allow tail calls to work across files without the runtime.
* **Internal**
* Upgrade `acorn-6to5`.
## 3.5.0
* **Bug Fix**
* Destructuring patterns as the left operator in `ForInStatement`/`ForOfStatement`.
* **Polish**
* Make default parameter IIFE invocation smarter.
* Make `__esModule` flag non-enumerable. Thanks [@daliwali](https://github.com/daliwali)!
* **Internal**
* More performance improvements.
* Parsing is now ~30% faster thanks to [marijnh/acorn@7264bc0178e7e6af7cfe02e9e0c6b26ee0e6007f](https://github.com/marijnh/acorn/commit/7264bc0178e7e6af7cfe02e9e0c6b26ee0e6007f).
* **New Feature**
* Optional `es6.blockScopingTDZ` is now completely functional and handles all edgecases.
* `super` in object literals.
* Tail call optimisation. Thanks [@RReverser](https://github.com/RReverser)!
## 3.4.1
* **Bug Fix**
* Fix conflicting `--module-ids` shorthand arg in `$ 6to5`.
* Add require hook options to cache key.
* Fix strict module formatter.
## 3.4.0
* **New Feature**
* Add `commonStandard` module formatter.
* **Bug Fix**
* Fix conflicting `--module-ids` shorthand arg in `$ 6to5`.
* **Internal**
* Lots of internal refactoring with scope tracking and traversal.
* **Polish**
* Don't return `map` in the API result if `sourceMap` was set to `"inline"`.
## 3.3.12
* **Bug Fix**
* Don't override `MemberExpression`s with `core-js` in `selfContained` if a local binding exists.
## 3.3.11
* **Bug Fix**
* Fix the require cache.
## 3.3.10
* **Internal**

View File

@@ -1,6 +1,12 @@
# Contributing
Contributions are always welcome, no matter how large or small. Before contributing, please read the [code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
Contributions are always welcome, no matter how large or small. Before
contributing, please read the
[code of conduct](https://github.com/6to5/6to5/blob/master/CODE_OF_CONDUCT.md).
**NOTE:** Please do not send pull requests that fix linting issues. It's highly
likely that they've already been fixed by the time it's submitted and it just
pollutes the git tree.
## Developing
@@ -12,7 +18,8 @@ Contributions are always welcome, no matter how large or small. Before contribut
* Link your forked clone (`npm link`)
* Develop your changes ensuring you're fetching updates from upstream often
* Ensure the test are passing (`make test`)
* Create new pull request explaining your proposed change or reference an issue in your commit message
* Create new pull request explaining your proposed change or reference an issue
in your commit message
#### Code Standards

View File

@@ -5,10 +5,17 @@ UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
JSHINT_CMD = node_modules/jshint/bin/jshint
MOCHA_CMD = node_modules/mocha/bin/_mocha
JSCS_CMD = node_modules/jscs/bin/jscs
6TO5_CMD = node_modules/6to5/bin/6to5
export NODE_ENV = test
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime build-core watch-core
build-core:
#node $(6TO5_CMD) src --out-dir lib
watch-core:
#node $(6TO5_CMD) src --out-dir lib --watch
build:
mkdir -p dist
@@ -18,7 +25,7 @@ build:
node $(BROWSERIFY_CMD) -e lib/6to5/polyfill.js >dist/polyfill.js
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
node $(BROWSERIFY_CMD) lib/6to5/browser.js -s to5 >dist/6to5.js
node $(BROWSERIFY_CMD) lib/6to5/api/browser.js -s to5 >dist/6to5.js
node $(UGLIFY_CMD) dist/6to5.js >dist/6to5.min.js
node bin/6to5-runtime >dist/runtime.js
@@ -55,7 +62,7 @@ test-cov:
export SIMPLE_6TO5_TESTS=1; \
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
test-travis: bootstrap
test-travis: build-core bootstrap
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi
@@ -92,7 +99,7 @@ publish:
make publish-core
make publish-runtime
rm -rf templates.json browser.js browser-polyfill.js
rm -rf templates.json browser.js browser-polyfill.js runtime.js
publish-runtime:
cd packages; \

View File

@@ -1,17 +0,0 @@
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

@@ -37,8 +37,13 @@ module.exports = function (commander, filenames, opts) {
if (stat.isDirectory(filename)) {
var dirname = filename;
_.each(util.readdirFilter(dirname), function (filename) {
write(path.join(dirname, filename), filename);
_.each(util.readdir(dirname), function (filename) {
var src = path.join(dirname, filename);
if (util.canCompile(filename)) {
write(src, filename);
} else {
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
}
});
} else {
write(filename, filename);

View File

@@ -23,7 +23,7 @@ commander.option("-L, --loose [list]", "List of transformers to enable loose mod
commander.option("-o, --out-file [out]", "Compile all input files into a single file");
commander.option("-d, --out-dir [out]", "Compile an input directory of modules into an output directory");
commander.option("-c, --remove-comments", "Remove comments from the compiled code", false);
commander.option("-m, --module-ids", "Insert module id in modules", false);
commander.option("-M, --module-ids", "Insert module id in modules", false);
commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code");
commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false);

View File

@@ -2,7 +2,7 @@ var readdir = require("fs-readdir-recursive");
var index = require("./index");
var util = require("../../lib/6to5/util");
var path = require("path");
var to5 = require("../../lib/6to5");
var to5 = require("../../lib/6to5/api/node");
var fs = require("fs");
var _ = require("lodash");
@@ -12,6 +12,10 @@ exports.readdirFilter = function (filename) {
});
};
exports.readdir = readdir;
exports.canCompile = util.canCompile;
exports.addSourceMappingUrl = function (code, loc) {
return code + "\n//# sourceMappingURL=" + path.basename(loc);
};

View File

@@ -4,7 +4,7 @@ var commander = require("commander");
var Module = require("module");
var path = require("path");
var repl = require("repl");
var to5 = require("../lib/6to5");
var to5 = require("../lib/6to5/api/node");
var util = require("../lib/6to5/util");
var vm = require("vm");
var _ = require("lodash");

View File

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

View File

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

View File

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

View File

@@ -1,14 +1,14 @@
"use strict";
require("./polyfill");
require("../../polyfill");
var sourceMapSupport = require("source-map-support");
var registerCache = require("./register-cache");
var util = require("./util");
var to5 = require("./index");
var fs = require("fs");
var registerCache = require("./cache");
var extend = require("lodash/object/extend");
var each = require("lodash/collection/each");
var util = require("../../util");
var to5 = require("../node");
var fs = require("fs");
sourceMapSupport.install({
retrieveSourceMap: function (source) {
@@ -44,8 +44,10 @@ var mtime = function (filename) {
var compile = function (filename) {
var result;
var cacheKey = filename + ":" + JSON.stringify(transformOpts);
if (cache) {
var cached = cache[filename];
var cached = cache[cacheKey];
if (cached && cached.mtime === mtime(filename)) {
result = cached;
}
@@ -60,7 +62,7 @@ var compile = function (filename) {
if (cache) {
result.mtime = mtime(filename);
cache[filename] = result;
cache[cacheKey] = result;
}
maps[filename] = result.map;

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
var t = require("../types");
var _ = require("lodash");
var includes = require("lodash/collection/includes");
exports.AssignmentExpression = function (node, parent, detected) {
if (node.operator === "**=") {
@@ -38,7 +38,7 @@ exports.Property = function (node, parent, detected) {
};
exports.AssignmentPattern = function (node, parent, detected) {
if (t.isFunction(parent) && _.contains(parent.params, node)) {
if (t.isFunction(parent) && includes(parent.params, node)) {
detected("es6.parameters.default");
}
};

View File

@@ -2,10 +2,10 @@
module.exports = Buffer;
var util = require("../util");
var isNumber = require("lodash/lang/isNumber");
var isBoolean = require("lodash/lang/isBoolean");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var isNumber = require("lodash/lang/isNumber");
var util = require("../util");
function Buffer(position, format) {
this.position = position;
@@ -159,7 +159,7 @@ Buffer.prototype.isLast = function (cha, trimRight) {
var last = buf[buf.length - 1];
if (Array.isArray(cha)) {
return contains(cha, last);
return includes(cha, last);
} else {
return cha === last;
}

View File

@@ -21,7 +21,7 @@ exports.IfStatement = function (node, print) {
print.indentOnComments(node.consequent);
if (node.alternate) {
if (this.isLast("}")) this.push(" ");
if (this.isLast("}")) this.space();
this.keyword("else");
if (this.format.format && !t.isBlockStatement(node.alternate)) {

View File

@@ -12,12 +12,12 @@ var Whitespace = require("./whitespace");
var SourceMap = require("./source-map");
var Position = require("./position");
var Buffer = require("./buffer");
var extend = require("lodash/object/extend");
var merge = require("lodash/object/merge");
var each = require("lodash/collection/each");
var util = require("../util");
var n = require("./node");
var t = require("../types");
var each = require("lodash/collection/each");
var extend = require("lodash/object/extend");
var merge = require("lodash/object/merge");
function CodeGenerator(ast, opts, code) {
opts = opts || {};
@@ -25,6 +25,7 @@ function CodeGenerator(ast, opts, code) {
this.comments = ast.comments || [];
this.tokens = ast.tokens || [];
this.format = CodeGenerator.normalizeOptions(code, opts);
this.opts = opts;
this.ast = ast;
this.whitespace = new Whitespace(this.tokens, this.comments);

View File

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

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

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

48
lib/6to5/messages.js Normal file
View File

@@ -0,0 +1,48 @@
var util = require("util");
exports.messages = {
tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence",
JSXNamespacedTags: "Namespace tags are not supported. ReactJSX is not XML.",
classesIllegalBareSuper: "Illegal use of bare super",
classesIllegalSuperCall: "Direct super call is illegal in non-constructor, use super.$1() instead",
classesIllegalConstructorKind: "Illegal kind for constructor method",
scopeDuplicateDeclaration: "Duplicate declaration $1",
undeclaredVariable: "Reference to undeclared variable $1",
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
settersInvalidParamLength: "Setters must have only one parameter",
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
expectedMemberExpressionOrIdentifier: "Expected type MemeberExpression or Identifier",
invalidParentForThisNode: "We don't know how to handle this node within the current parent - please open an issue",
readOnly: "$1 is read-only",
modulesIllegalExportName: "Illegal export $1",
unknownForHead: "Unknown node type $1 in ForStatement"
};
exports.get = function (key) {
var msg = exports.messages[key];
if (!msg) throw new ReferenceError("Unknown message `" + key + "`");
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
args = exports.parseArgs(args);
return msg.replace(/\$(\d+)/g, function (str, i) {
return args[--i];
});
};
exports.parseArgs = function (args) {
return args.map(function (val) {
if (val != null && val.inspect) {
return val.inspect();
} else {
try {
return JSON.stringify(val) || val + "";
} catch (e) {
return util.inspect(val);
}
}
});
};

View File

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

View File

@@ -5,16 +5,17 @@ module.exports = File;
var SHEBANG_REGEX = /^\#\!.*/;
var isFunction = require("lodash/lang/isFunction");
var transform = require("./transformation");
var generate = require("./generation");
var transform = require("./index");
var generate = require("../generation");
var defaults = require("lodash/object/defaults");
var contains = require("lodash/collection/contains");
var clone = require("./helpers/clone");
var Scope = require("./traverse/scope");
var util = require("./util");
var includes = require("lodash/collection/includes");
var clone = require("../helpers/clone");
var parse = require("../helpers/parse");
var Scope = require("../traversal/scope");
var util = require("../util");
var path = require("path");
var each = require("lodash/collection/each");
var t = require("./types");
var t = require("../types");
function File(opts) {
this.dynamicImportIds = {};
@@ -40,6 +41,7 @@ File.helpers = [
"tagged-template-literal-loose",
"interop-require",
"to-array",
"to-consumable-array",
"sliced-to-array",
"object-without-properties",
"has-own",
@@ -53,7 +55,10 @@ File.helpers = [
"get",
"set",
"class-call-check",
"object-destructuring-empty"
"object-destructuring-empty",
"temporal-undefined",
"temporal-assert-defined",
"tail-call"
];
File.validOptions = [
@@ -119,7 +124,10 @@ File.prototype.normalizeOptions = function (opts) {
});
// normalize windows path separators to unix
opts.filename = opts.filename.replace(/\\/g, "/");
opts.filename = util.normalisePathSeparator(opts.filename);
if (opts.sourceRoot) {
opts.sourceRoot = util.normalisePathSeparator(opts.sourceRoot);
}
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
@@ -128,7 +136,7 @@ File.prototype.normalizeOptions = function (opts) {
opts.optional = util.arrayify(opts.optional);
opts.loose = util.arrayify(opts.loose);
if (contains(opts.loose, "all")) {
if (includes(opts.loose, "all") || includes(opts.loose, true)) {
opts.loose = Object.keys(transform.transformers);
}
@@ -159,14 +167,29 @@ File.prototype.normalizeOptions = function (opts) {
opts.blacklist = transform._ensureTransformerNames("blacklist", opts.blacklist);
opts.whitelist = transform._ensureTransformerNames("whitelist", opts.whitelist);
opts.optional = transform._ensureTransformerNames("optional", opts.optional);
opts.loose = transform._ensureTransformerNames("loose", opts.loose);
opts.optional = transform._ensureTransformerNames("optional", opts.optional);
opts.loose = transform._ensureTransformerNames("loose", opts.loose);
if (opts.reactCompat) {
opts.optional.push("reactCompat");
console.error("The reactCompat option has been moved into the optional transformer " +
"`reactCompat` - backwards compatibility will be removed in v4.0.0");
}
var ensureEnabled = function (key) {
var namespace = transform.transformerNamespaces[key];
if (namespace === "es7") opts.experimental = true;
if (namespace === "playground") opts.playground = true;
};
each(opts.whitelist, ensureEnabled);
each(opts.optional, ensureEnabled);
return opts;
};
File.prototype.isLoose = function (key) {
return contains(this.opts.loose, key);
return includes(this.opts.loose, key);
};
File.prototype.buildTransformers = function () {
@@ -197,20 +220,10 @@ File.prototype.buildTransformers = function () {
this.transformers = transformers;
};
File.prototype.toArray = function (node, i) {
if (t.isArrayExpression(node)) {
return node;
} else if (t.isIdentifier(node) && node.name === "arguments") {
return t.callExpression(t.memberExpression(this.addHelper("slice"), t.identifier("call")), [node]);
} else {
var declarationName = "to-array";
var args = [node];
if (i) {
args.push(t.literal(i));
declarationName = "sliced-to-array";
}
return t.callExpression(this.addHelper(declarationName), args);
}
File.prototype.debug = function (msg) {
var parts = this.opts.filename;
if (msg) parts += ": " + msg;
util.debug(parts);
};
File.prototype.getModuleFormatter = function (type) {
@@ -265,7 +278,7 @@ File.prototype.addImport = function (source, name) {
var id = this.dynamicImportIds[name];
if (!id) {
id = this.dynamicImportIds[name] = this.generateUidIdentifier(name);
id = this.dynamicImportIds[name] = this.scope.generateUidIdentifier(name);
var specifiers = [t.importSpecifier(t.identifier("default"), id)];
var declar = t.importDeclaration(specifiers, t.literal(source));
@@ -283,8 +296,8 @@ File.prototype.isConsequenceExpressionStatement = function (node) {
};
File.prototype.addHelper = function (name) {
if (!contains(File.helpers, name)) {
throw new ReferenceError("unknown declaration " + name);
if (!includes(File.helpers, name)) {
throw new ReferenceError("Unknown helper " + name);
}
var program = this.ast.program;
@@ -299,7 +312,7 @@ File.prototype.addHelper = function (name) {
} else {
var ref = util.template(name);
ref._compact = true;
var uid = this.generateUidIdentifier(name);
var uid = this.scope.generateUidIdentifier(name);
this.scope.push({
key: name,
id: uid,
@@ -309,6 +322,10 @@ File.prototype.addHelper = function (name) {
}
};
File.prototype.logDeopt = function () {
// todo, (node, msg)
};
File.prototype.errorWithNode = function (node, msg, Error) {
Error = Error || SyntaxError;
@@ -334,16 +351,14 @@ File.prototype.parse = function (code) {
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
//opts.strictMode = this.transformers.useStrict.canRun();
return util.parse(opts, code, function (tree) {
return parse(opts, code, function (tree) {
self.transform(tree);
return self.generate();
});
};
File.prototype.transform = function (ast) {
var self = this;
util.debug(this.opts.filename);
this.debug();
this.ast = ast;
this.lastStatements = t.getLastStatements(ast.program);
@@ -356,42 +371,46 @@ File.prototype.transform = function (ast) {
this.checkNode(ast);
var astRun = function (key) {
each(self.transformerStack, function (pass) {
pass.astRun(key);
});
};
astRun("enter");
this.call("pre");
each(this.transformerStack, function (pass) {
pass.transform();
});
astRun("exit");
this.call("post");
};
var checkTransformerVisitor = {
enter: function (node, parent, scope, context, state) {
state.check(node, scope);
File.prototype.call = function (key) {
var stack = this.transformerStack;
for (var i = 0; i < stack.length; i++) {
var transformer = stack[i].transformer;
if (transformer[key]) {
transformer[key](this);
}
}
};
var checkTransformerVisitor = {
enter: function (node, parent, scope, state) {
checkNode(state.stack, node, scope);
}
};
var checkNode = function (stack, node, scope) {
each(stack, function (pass) {
if (pass.shouldRun) return;
pass.checkNode(node, scope);
});
};
File.prototype.checkNode = function (node, scope) {
var self = this;
var stack = this.transformerStack;
scope = scope || this.scope;
var check = function (node, scope) {
each(self.transformerStack, function (pass) {
if (pass.shouldRun) return;
pass.checkNode(node, scope);
});
};
check(node, scope);
checkNode(stack, node, scope);
scope.traverse(node, checkTransformerVisitor, {
check: check
stack: stack
});
};
@@ -419,34 +438,8 @@ File.prototype.generate = function () {
if (opts.sourceMap === "inline") {
result.code += "\n" + util.sourceMapToComment(result.map);
result.map = null;
}
return result;
};
File.prototype.generateUid = function (name, scope) {
name = t.toIdentifier(name).replace(/^_+/, "");
scope = scope || this.scope;
var uid;
var i = 0;
do {
uid = this._generateUid(name, i);
i++;
} while (scope.hasReference(uid));
return uid;
};
File.prototype.generateUidIdentifier = function (name, scope) {
scope = scope || this.scope;
var id = t.identifier(this.generateUid(name, scope));
scope.addDeclarationToFunctionScope("var", id);
return id;
};
File.prototype._generateUid = function (name, i) {
var id = name;
if (i > 1) id += i;
return "_" + id;
};

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
var cloneDeep = require("lodash/lang/cloneDeep");
var traverse = require("../../traverse");
var clone = require("lodash/lang/clone");
var traverse = require("../../traversal");
var clone = require("lodash/lang/clone");
var each = require("lodash/collection/each");
var has = require("lodash/object/has");
var t = require("../../types");

View File

@@ -18,7 +18,7 @@ var getObjRef = function (node, nodes, file, scope) {
} else if (t.isMemberExpression(node)) {
ref = node.object;
if (t.isIdentifier(ref) && scope.hasReference(ref.name)) {
if (t.isIdentifier(ref) && scope.hasGlobal(ref.name)) {
// the object reference that we need to save is locally declared
// so as per the previous comment we can be 100% sure evaluating
// it multiple times will be safe

View File

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

View File

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

View File

@@ -3,8 +3,8 @@
var t = require("../../types");
var visitor = {
enter: function (node, parent, scope, context) {
if (t.isFunction(node)) context.skip();
enter: function (node) {
if (t.isFunction(node)) this.skip();
if (t.isAwaitExpression(node)) {
node.type = "YieldExpression";

View File

@@ -2,19 +2,24 @@
module.exports = ReplaceSupers;
var t = require("../../types");
var messages = require("../../messages");
var t = require("../../types");
/**
* Description
*
* @param {Object} opts
* @param {Boolean} [inClass]
*/
function ReplaceSupers(opts) {
this.topLevelThisReference = null;
function ReplaceSupers(opts, inClass) {
this.topLevelThisReference = opts.topLevelThisReference;
this.methodNode = opts.methodNode;
this.className = opts.className;
this.superName = opts.superName;
this.isStatic = opts.isStatic;
this.hasSuper = false;
this.inClass = inClass;
this.isLoose = opts.isLoose;
this.scope = opts.scope;
this.file = opts.file;
@@ -28,16 +33,23 @@ function ReplaceSupers(opts) {
* _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this)
*
* @param {Node} property
* @param {boolean} isStatic
* @param {boolean} isComputed
* @param {Node} value
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic, isComputed, thisExpression) {
ReplaceSupers.prototype.setSuperProperty = function (property, value, isComputed, thisExpression) {
return t.callExpression(
this.file.addHelper("set"),
[
isStatic ? this.superName : t.memberExpression(this.superName, t.identifier("prototype")),
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
value,
thisExpression
@@ -53,17 +65,22 @@ ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic,
* _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
*
* @param {Node} property
* @param {boolean} isStatic
* @param {boolean} isComputed
* @param {Boolean} isComputed
* @param {Node} thisExpression
*
* @returns {Node}
*/
ReplaceSupers.prototype.getSuperProperty = function (property, isStatic, isComputed, thisExpression) {
ReplaceSupers.prototype.getSuperProperty = function (property, isComputed, thisExpression) {
return t.callExpression(
this.file.addHelper("get"),
[
isStatic ? this.superName : t.memberExpression(this.superName, t.identifier("prototype")),
t.callExpression(
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
[
this.isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
]
),
isComputed ? property : t.literal(property.name),
thisExpression
]
@@ -79,19 +96,19 @@ ReplaceSupers.prototype.replace = function () {
};
var visitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
var topLevel = state.topLevel;
var self = state.self;
if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
// we need to call traverseLevel again so we're context aware
self.traverseLevel(node, false);
return context.skip();
return this.skip();
}
if (t.isProperty(node, { method: true }) || t.isMethodDefinition(node)) {
// break on object methods
return context.skip();
return this.skip();
}
var getThisReference = topLevel ?
@@ -126,7 +143,7 @@ ReplaceSupers.prototype.getThisReference = function () {
if (this.topLevelThisReference) {
return this.topLevelThisReference;
} else {
var ref = this.topLevelThisReference = this.file.generateUidIdentifier("this");
var ref = this.topLevelThisReference = this.scope.generateUidIdentifier("this");
this.methodNode.value.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(this.topLevelThisReference, t.thisExpression())
]));
@@ -143,7 +160,8 @@ ReplaceSupers.prototype.getThisReference = function () {
* @returns {Object}
*/
ReplaceSupers.prototype.getLooseSuperProperty = function (methodNode, id, parent) {
ReplaceSupers.prototype.getLooseSuperProperty = function (id, parent) {
var methodNode = this.methodNode;
var methodName = methodNode.key;
var superName = this.superName || t.identifier("Function");
@@ -185,13 +203,15 @@ ReplaceSupers.prototype.getLooseSuperProperty = function (methodNode, id, parent
ReplaceSupers.prototype.looseHandle = function (getThisReference, node, parent) {
if (t.isIdentifier(node, { name: "super" })) {
return this.getLooseSuperProperty(this.methodNode, node, parent);
this.hasSuper = true;
return this.getLooseSuperProperty(node, parent);
} else if (t.isCallExpression(node)) {
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
// super.test(); -> ClassName.prototype.MethodName.call(this);
this.hasSuper = true;
t.appendToMemberExpression(callee, t.identifier("call"));
node.arguments.unshift(getThisReference());
}
@@ -212,13 +232,13 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
var args;
var thisReference;
if (t.isIdentifier(node, { name: "super" })) {
if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
throw this.file.errorWithNode(node, "illegal use of bare super");
}
} else if (t.isCallExpression(node)) {
if (isIllegalBareSuper(node, parent)) {
throw this.file.errorWithNode(node, messages.get("classesIllegalBareSuper"));
}
if (t.isCallExpression(node)) {
var callee = node.callee;
if (t.isIdentifier(callee, { name: "super" })) {
if (isSuper(callee, node)) {
// super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
property = methodNode.key;
computed = methodNode.computed;
@@ -227,38 +247,32 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
// bare `super` call is illegal inside non-constructors
// - https://esdiscuss.org/topic/super-call-in-methods
// - https://twitter.com/wycats/status/544553184396836864
if (methodNode.key.name !== "constructor") {
if (methodNode.key.name !== "constructor" || !this.inClass) {
var methodName = methodNode.key.name || "METHOD_NAME";
throw this.file.errorWithNode(node, "Direct super call is illegal in non-constructor, use super." + methodName + "() instead");
throw this.file.errorWithNode(node, messages.get("classesIllegalSuperCall", methodName));
}
} else {
if (!t.isMemberExpression(callee)) return;
if (callee.object.name !== "super") return;
} else if (t.isMemberExpression(callee) && isSuper(callee.object, callee)) {
// super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
property = callee.property;
computed = callee.computed;
args = node.arguments;
}
} else if (t.isMemberExpression(node)) {
if (!t.isIdentifier(node.object, { name: "super" })) return;
} else if (t.isMemberExpression(node) && isSuper(node.object, node)) {
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
property = node.property;
computed = node.computed;
} else if (t.isAssignmentExpression(node)) {
if (!t.isIdentifier(node.left.object, { name: "super" })) return;
if (methodNode.kind !== "set") return;
thisReference = getThisReference();
} else if (t.isAssignmentExpression(node) && isSuper(node.left.object, node.left) && methodNode.kind === "set") {
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
return this.setSuperProperty(node.left.property, node.right, methodNode.static, node.left.computed, thisReference);
this.hasSuper = true;
return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference());
}
if (!property) return;
this.hasSuper = true;
thisReference = getThisReference();
var superProperty = this.getSuperProperty(property, methodNode.static, computed, thisReference);
var superProperty = this.getSuperProperty(property, computed, thisReference);
if (args) {
if (args.length === 1 && t.isSpreadElement(args[0])) {
// super(...arguments);
@@ -276,3 +290,14 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
return superProperty;
}
};
var isIllegalBareSuper = function (node, parent) {
if (!isSuper(node, parent)) return false;
if (t.isMemberExpression(parent, { computed: false })) return false;
if (t.isCallExpression(parent, { callee: node })) return false;
return true;
};
var isSuper = function (node, parent) {
return t.isIdentifier(node, { name: "super" }) && t.isReferenced(node, parent);
};

View File

@@ -2,11 +2,11 @@
module.exports = transform;
var Transformer = require("./transformer");
var object = require("../helpers/object");
var File = require("../file");
var util = require("../util");
var each = require("lodash/collection/each");
var normalizeAst = require("../helpers/normalize-ast");
var Transformer = require("./transformer");
var object = require("../helpers/object");
var File = require("./file");
var each = require("lodash/collection/each");
function transform(code, opts) {
var file = new File(opts);
@@ -14,7 +14,7 @@ function transform(code, opts) {
}
transform.fromAst = function (ast, code, opts) {
ast = util.normalizeAst(ast);
ast = normalizeAst(ast);
var file = new File(opts);
file.addCode(code);
@@ -56,8 +56,9 @@ transform._ensureTransformerNames = function (type, rawKeys) {
return keys;
};
transform.transformers = object();
transform.namespaces = object();
transform.transformerNamespaces = object();
transform.transformers = object();
transform.namespaces = object();
transform.deprecatedTransformerMap = require("./transformers/deprecated");
transform.moduleFormatters = require("./modules");
@@ -66,8 +67,10 @@ var rawTransformers = require("./transformers");
each(rawTransformers, function (transformer, key) {
var namespace = key.split(".")[0];
transform.namespaces[namespace] = transform.namespaces[namespace] || [];
transform.namespaces[namespace].push(key);
transform.transformerNamespaces[key] = namespace;
transform.transformers[key] = new Transformer(key, transformer);
});

View File

@@ -2,14 +2,16 @@
module.exports = DefaultFormatter;
var messages = require("../../messages");
var extend = require("lodash/object/extend");
var object = require("../../helpers/object");
var util = require("../../util");
var t = require("../../types");
var extend = require("lodash/object/extend");
function DefaultFormatter(file) {
this.file = file;
this.ids = object();
this.scope = file.scope;
this.file = file;
this.ids = object();
this.hasNonDefaultExports = false;
@@ -27,7 +29,7 @@ function DefaultFormatter(file) {
}
DefaultFormatter.prototype.doDefaultExportInterop = function (node) {
return node.default && !this.noInteropRequire && !this.hasNonDefaultExports;
return node.default && !this.noInteropRequireExport && !this.hasNonDefaultExports;
};
DefaultFormatter.prototype.bumpImportOccurences = function (node) {
@@ -38,7 +40,7 @@ DefaultFormatter.prototype.bumpImportOccurences = function (node) {
};
var exportsVisitor = {
enter: function (node, parent, scope, context, formatter) {
enter: function (node, parent, scope, formatter) {
var declar = node && node.declaration;
if (t.isExportDeclaration(node)) {
formatter.hasLocalImports = true;
@@ -63,7 +65,7 @@ DefaultFormatter.prototype.getLocalExports = function () {
};
var importsVisitor = {
enter: function (node, parent, scope, context, formatter) {
enter: function (node, parent, scope, formatter) {
if (t.isImportDeclaration(node)) {
formatter.hasLocalImports = true;
extend(formatter.localImports, t.getBindingIdentifiers(node));
@@ -77,9 +79,9 @@ DefaultFormatter.prototype.getLocalImports = function () {
};
var remapVisitor = {
enter: function (node, parent, scope, context, formatter) {
enter: function (node, parent, scope, formatter) {
if (t.isUpdateExpression(node) && formatter.isLocalReference(node.argument, scope)) {
context.skip();
this.skip();
// expand to long file assignment expression
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
@@ -107,7 +109,7 @@ var remapVisitor = {
}
if (t.isAssignmentExpression(node) && formatter.isLocalReference(node.left, scope)) {
context.skip();
this.skip();
return formatter.remapExportAssignment(node);
}
}
@@ -124,13 +126,6 @@ DefaultFormatter.prototype.isLocalReference = function (node) {
return t.isIdentifier(node) && localImports[node.name] && localImports[node.name] !== node;
};
DefaultFormatter.prototype.checkLocalReference = function (node) {
var file = this.file;
if (this.isLocalReference(node)) {
throw file.errorWithNode(node, "Illegal assignment of module import");
}
};
DefaultFormatter.prototype.remapExportAssignment = function (node) {
return t.assignmentExpression(
"=",
@@ -146,7 +141,7 @@ DefaultFormatter.prototype.remapExportAssignment = function (node) {
DefaultFormatter.prototype.isLocalReference = function (node, scope) {
var localExports = this.localExports;
var name = node.name;
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBinding(name);
return t.isIdentifier(node) && localExports[name] && localExports[name] === scope.getBindingIdentifier(name);
};
DefaultFormatter.prototype.getModuleName = function () {
@@ -213,14 +208,11 @@ DefaultFormatter.prototype.getExternalReference = function (node, nodes) {
DefaultFormatter.prototype.checkExportIdentifier = function (node) {
if (t.isIdentifier(node, { name: "__esModule" })) {
throw this.file.errorWithNode(node, "Illegal export __esModule - this is used internally for CommonJS interop");
throw this.file.errorWithNode(node, messages.get("modulesIllegalExportName", node.name));
}
};
DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
var inherits = false;
if (node.specifiers.length === 1) inherits = node;
if (node.source) {
var ref = this.getExternalReference(node, nodes);
@@ -228,7 +220,7 @@ DefaultFormatter.prototype.exportSpecifier = function (specifier, node, nodes) {
// export * from "foo";
nodes.push(this.buildExportsWildcard(ref, node));
} else {
if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
if (t.isSpecifierDefault(specifier) && !this.noInteropRequireExport) {
// importing a default so we need to normalize it
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {

View File

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

View File

@@ -6,7 +6,7 @@ var DefaultFormatter = require("./_default");
var CommonFormatter = require("./common");
var util = require("../../util");
var t = require("../../types");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var values = require("lodash/object/values");
function AMDFormatter() {
@@ -29,9 +29,8 @@ AMDFormatter.prototype.buildDependencyLiterals = function () {
* Wrap the entire body in a `define` wrapper.
*/
AMDFormatter.prototype.transform = function (ast) {
var program = ast.program;
var body = program.body;
AMDFormatter.prototype.transform = function (program) {
var body = program.body;
// build an array of module names
@@ -71,7 +70,7 @@ AMDFormatter.prototype.getModuleName = function () {
};
AMDFormatter.prototype._getExternalReference = function (node) {
return this.file.generateUidIdentifier(node.source.value);
return this.scope.generateUidIdentifier(node.source.value);
};
AMDFormatter.prototype.importDeclaration = function (node) {
@@ -82,12 +81,12 @@ AMDFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
var key = t.getSpecifierName(specifier);
var ref = this.getExternalReference(node);
if (contains(this.file.dynamicImported, node)) {
if (includes(this.file.dynamicImported, node)) {
// Prevent unnecessary renaming of dynamic imports.
this.ids[node.source.value] = ref;
} else if (t.isImportBatchSpecifier(specifier)) {
// import * as bar from "foo";
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequire) {
} else if (t.isSpecifierDefault(specifier) && !this.noInteropRequireImport) {
// import foo from "foo";
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
} else {

View File

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

View File

@@ -3,7 +3,7 @@
module.exports = CommonJSFormatter;
var DefaultFormatter = require("./_default");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var util = require("../../util");
var t = require("../../types");
@@ -14,8 +14,13 @@ function CommonJSFormatter() {
util.inherits(CommonJSFormatter, DefaultFormatter);
CommonJSFormatter.prototype.init = function () {
if (this.hasNonDefaultExports) {
this.file.ast.program.body.push(util.template("exports-module-declaration", true));
var file = this.file;
var scope = file.scope;
scope.rename("module");
if (!this.noInteropRequireImport && this.hasNonDefaultExports) {
file.ast.program.body.push(util.template("exports-module-declaration", true));
}
};
@@ -26,20 +31,24 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes)
// import foo from "foo";
if (t.isSpecifierDefault(specifier)) {
if (!contains(this.file.dynamicImported, node)) {
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
if (!includes(this.file.dynamicImported, node)) {
if (this.noInteropRequireImport) {
ref = t.memberExpression(ref, t.identifier("default"));
} else {
ref = t.callExpression(this.file.addHelper("interop-require"), [ref]);
}
}
nodes.push(t.variableDeclaration("var", [t.variableDeclarator(variableName, ref)]));
} else {
if (specifier.type === "ImportBatchSpecifier") {
if (!this.noInteropRequireImport) {
ref = t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]);
}
// import * as bar from "foo";
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(
variableName,
t.callExpression(this.file.addHelper("interop-require-wildcard"), [
ref
])
)
t.variableDeclarator(variableName, ref)
]));
} else {
// import { foo } from "foo";
@@ -84,7 +93,7 @@ CommonJSFormatter.prototype._getExternalReference = function (node, nodes) {
var call = t.callExpression(t.identifier("require"), [node.source]);
if (this.localImportOccurences[source] > 1) {
var uid = this.file.generateUidIdentifier(source);
var uid = this.scope.generateUidIdentifier(source);
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(uid, call)
]));

View File

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

View File

@@ -12,8 +12,9 @@ var each = require("lodash/collection/each");
var map = require("lodash/collection/map");
function SystemFormatter(file) {
this.exportIdentifier = file.generateUidIdentifier("export");
this.noInteropRequire = true;
this.exportIdentifier = file.scope.generateUidIdentifier("export");
this.noInteropRequireExport = true;
this.noInteropRequireImport = true;
DefaultFormatter.apply(this, arguments);
}
@@ -28,7 +29,7 @@ SystemFormatter.prototype._addImportSource = function (node, exportNode) {
};
SystemFormatter.prototype.buildExportsWildcard = function (objectIdentifier, node) {
var leftIdentifier = this.file.generateUidIdentifier("key");
var leftIdentifier = this.scope.generateUidIdentifier("key");
var valIdentifier = t.memberExpression(objectIdentifier, leftIdentifier, true);
var left = t.variableDeclaration("var", [
@@ -68,7 +69,7 @@ SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
};
var runnerSettersVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (node._importSource === state.source) {
if (t.isVariableDeclaration(node)) {
each(node.declarations, function (declar) {
@@ -81,7 +82,7 @@ var runnerSettersVisitor = {
state.nodes.push(node);
}
context.remove();
this.remove();
}
}
};
@@ -103,10 +104,10 @@ SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators
};
var hoistVariablesVisitor = {
enter: function (node, parent, scope, context, hoistDeclarators) {
enter: function (node, parent, scope, hoistDeclarators) {
if (t.isFunction(node)) {
// nothing inside is accessible
return context.skip();
return this.skip();
}
if (t.isVariableDeclaration(node)) {
@@ -148,19 +149,17 @@ var hoistVariablesVisitor = {
};
var hoistFunctionsVisitor = {
enter: function (node, parent, scope, context, handlerBody) {
if (t.isFunction(node)) context.skip();
enter: function (node, parent, scope, handlerBody) {
if (t.isFunction(node)) this.skip();
if (t.isFunctionDeclaration(node) || node._blockHoist) {
handlerBody.push(node);
context.remove();
this.remove();
}
}
};
SystemFormatter.prototype.transform = function (ast) {
var program = ast.program;
SystemFormatter.prototype.transform = function (program) {
var hoistDeclarators = [];
var moduleName = this.getModuleName();
var moduleNameLiteral = t.literal(moduleName);

View File

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

View File

@@ -0,0 +1,3 @@
{
"blacklist": ["useStrict"]
}

View File

@@ -0,0 +1 @@
CORE_ID.$for.isIterable(VALUE);

View File

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

View File

@@ -1,7 +1,10 @@
(function (obj, defaults) {
for (var key in defaults) {
if (obj[key] === undefined) {
obj[key] = defaults[key];
var keys = Object.getOwnPropertyNames(defaults);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = Object.getOwnPropertyDescriptor(defaults, key);
if (value && value.configurable && obj[key] === undefined) {
Object.defineProperty(obj, key, value);
}
}
return obj;

View File

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

View File

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

View File

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

View File

@@ -1,12 +1,14 @@
(function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else {
} else if (Symbol.iterator in Object(arr)) {
var _arr = [];
for (var _iterator = arr[Symbol.iterator](), _step; !(_step = _iterator.next()).done;) {
_arr.push(_step.value);
if (i && _arr.length === i) break;
}
return _arr;
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
});

View File

@@ -0,0 +1,3 @@
{
FUNCTION_ID:while (true) BLOCK
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,8 @@
(function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
});

View File

@@ -1,7 +1,6 @@
module.exports = TransformerPass;
var util = require("../util");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
/**
* This class is responsible for traversing over the provided `File`s
@@ -15,17 +14,6 @@ function TransformerPass(file, transformer) {
this.file = file;
}
TransformerPass.prototype.astRun = function (key) {
if (!this.shouldRun) return;
var handlers = this.handlers;
var file = this.file;
if (handlers.ast && handlers.ast[key]) {
handlers.ast[key](file.ast, file);
}
};
TransformerPass.prototype.canRun = function () {
var transformer = this.transformer;
@@ -37,14 +25,14 @@ TransformerPass.prototype.canRun = function () {
// blacklist
var blacklist = opts.blacklist;
if (blacklist.length && contains(blacklist, key)) return false;
if (blacklist.length && includes(blacklist, key)) return false;
// whitelist
var whitelist = opts.whitelist;
if (whitelist.length && !contains(whitelist, key)) return false;
if (whitelist.length) return includes(whitelist, key);
// optional
if (transformer.optional && !contains(opts.optional, key)) return false;
if (transformer.optional && !includes(opts.optional, key)) return false;
// experimental
if (transformer.experimental && !opts.experimental) return false;
@@ -64,31 +52,12 @@ TransformerPass.prototype.checkNode = function (node) {
}
};
var transformVisitor = {
enter: function (node, parent, scope, context, state) {
var fns = state.handlers[node.type];
if (!fns) return;
return fns.enter(node, parent, scope, context, state.file, state.pass);
},
exit: function (node, parent, scope, context, state) {
var fns = state.handlers[node.type];
if (!fns) return;
return fns.exit(node, parent, scope, context, state.file, state.pass);
}
};
TransformerPass.prototype.transform = function () {
if (!this.shouldRun) return;
var file = this.file;
util.debug(file.opts.filename + ": Running transformer " + this.transformer.key);
file.debug("Running transformer " + this.transformer.key);
this.astRun("before");
var state = { file: file, handlers: this.handlers, pass: this };
file.scope.traverse(file.ast, transformVisitor, state);
this.astRun("after");
file.scope.traverse(file.ast, this.handlers, file);
};

View File

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

View File

@@ -34,6 +34,8 @@
"coreAliasing": "selfContained",
"undefinedToVoid": "spec.undefinedToVoid",
"undeclaredVariableCheck": "validation.undeclaredVariableCheck",
"specPropertyLiterals": "minification.propertyLiterals",
"specMemberExpressionLiterals": "minification.memberExpressionLiterals"
"specPropertyLiterals": "es3.propertyLiterals",
"specMemberExpressionLiterals": "es3.memberExpressionLiterals",
"minification.propertyLiterals": "es3.propertyLiterals",
"minification.memberExpressionLiterals": "es3.memberExpressionLiterals"
}

View File

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

View File

@@ -1,6 +1,6 @@
"use strict";
var traverse = require("../../../traverse");
var traverse = require("../../../traversal");
var object = require("../../../helpers/object");
var util = require("../../../util");
var t = require("../../../types");
@@ -17,7 +17,7 @@ var isLet = function (node, parent) {
if (node.kind !== "let") return false;
// https://github.com/6to5/6to5/issues/255
if (!t.isFor(parent) || t.isFor(parent) && parent.left !== node) {
if (isLetInitable(node, parent)) {
for (var i = 0; i < node.declarations.length; i++) {
var declar = node.declarations[i];
declar.init = declar.init || t.identifier("undefined");
@@ -29,6 +29,10 @@ var isLet = function (node, parent) {
return true;
};
var isLetInitable = function (node, parent) {
return !t.isFor(parent) || t.isFor(parent) && parent.left !== node;
};
var isVar = function (node, parent) {
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
};
@@ -39,11 +43,29 @@ var standardizeLets = function (declars) {
}
};
exports.VariableDeclaration = function (node, parent) {
isLet(node, parent);
exports.VariableDeclaration = function (node, parent, scope, file) {
if (!isLet(node, parent)) return;
if (isLetInitable(node) && file.transformers["es6.blockScopingTDZ"].canRun()) {
var nodes = [node];
for (var i = 0; i < node.declarations.length; i++) {
var decl = node.declarations[i];
if (decl.init) {
var assign = t.assignmentExpression("=", decl.id, decl.init);
assign._ignoreBlockScopingTDZ = true;
nodes.push(t.expressionStatement(assign));
}
decl.init = file.addHelper("temporal-undefined");
}
node._blockHoist = 2;
return nodes;
}
};
exports.Loop = function (node, parent, scope, context, file) {
exports.Loop = function (node, parent, scope, file) {
var init = node.left || node.init;
if (isLet(init, node)) {
t.ensureBlock(node);
@@ -54,7 +76,7 @@ exports.Loop = function (node, parent, scope, context, file) {
};
exports.Program =
exports.BlockStatement = function (block, parent, scope, context, file) {
exports.BlockStatement = function (block, parent, scope, file) {
if (!t.isLoop(parent)) {
var blockScoping = new BlockScoping(false, block, parent, scope, file);
blockScoping.run();
@@ -108,19 +130,19 @@ BlockScoping.prototype.run = function () {
}
};
function replace(node, parent, scope, context, remaps) {
function replace(node, parent, scope, remaps) {
if (!t.isReferencedIdentifier(node, parent)) return;
var remap = remaps[node.name];
if (!remap) return;
var ownBinding = scope.getBinding(node.name);
var ownBinding = scope.getBindingIdentifier(node.name);
if (ownBinding === remap.binding) {
node.name = remap.uid;
} else {
// scope already has it's own binding that doesn't
// match the one we have a stored replacement for
if (context) context.skip();
if (this) this.skip();
}
}
@@ -129,7 +151,7 @@ var replaceVisitor = {
};
function traverseReplace(node, parent, scope, remaps) {
replace(node, parent, scope, null, remaps);
replace(node, parent, scope, remaps);
scope.traverse(node, replaceVisitor, remaps);
}
@@ -153,7 +175,7 @@ BlockScoping.prototype.remap = function () {
// this is the defining identifier of a declaration
var ref = letRefs[key];
if (scope.parentHasReference(key)) {
if (scope.parentHasBinding(key) || scope.hasGlobal(key)) {
var uid = scope.generateUidIdentifier(ref.name).name;
ref.name = uid;
@@ -225,7 +247,7 @@ BlockScoping.prototype.needsClosure = function () {
};
var letReferenceFunctionVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
// not a direct reference
if (!t.isReferencedIdentifier(node, parent)) return;
@@ -241,10 +263,10 @@ var letReferenceFunctionVisitor = {
};
var letReferenceBlockVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isFunction(node)) {
scope.traverse(node, letReferenceFunctionVisitor, state);
return context.skip();
return this.skip();
}
}
};
@@ -310,7 +332,7 @@ var loopNodeTo = function (node) {
};
var loopVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
var replace;
if (t.isLoop(node)) {
@@ -320,7 +342,7 @@ var loopVisitor = {
}
if (t.isFunction(node) || t.isLoop(node)) {
return context.skip();
return this.skip();
}
var loopText = loopNodeTo(node);
@@ -362,7 +384,7 @@ var loopVisitor = {
};
var loopLabelVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isLabeledStatement(node)) {
state.innerLabels.push(node.label.name);
}
@@ -395,7 +417,7 @@ BlockScoping.prototype.checkLoop = function () {
};
var hoistVarDeclarationsVisitor = {
enter: function (node, parent, scope, context, self) {
enter: function (node, parent, scope, self) {
if (t.isForStatement(node)) {
if (isVar(node.init, node)) {
node.init = t.sequenceExpression(self.pushDeclar(node.init));
@@ -407,7 +429,7 @@ var hoistVarDeclarationsVisitor = {
} else if (isVar(node, parent)) {
return self.pushDeclar(node).map(t.expressionStatement);
} else if (t.isFunction(node)) {
return context.skip();
return this.skip();
}
}
};

View File

@@ -3,16 +3,17 @@
var ReplaceSupers = require("../../helpers/replace-supers");
var nameMethod = require("../../helpers/name-method");
var defineMap = require("../../helpers/define-map");
var messages = require("../../../messages");
var util = require("../../../util");
var t = require("../../../types");
exports.check = t.isClass;
exports.ClassDeclaration = function (node, parent, scope, context, file) {
return new Class(node, file, scope, true).run();
exports.ClassDeclaration = function (node, parent, scope, file) {
return new ClassTransformer(node, file, scope, true).run();
};
exports.ClassExpression = function (node, parent, scope, context, file) {
exports.ClassExpression = function (node, parent, scope, file) {
if (!node.id) {
if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) {
// var o = { foo: class {} };
@@ -25,7 +26,7 @@ exports.ClassExpression = function (node, parent, scope, context, file) {
}
}
return new Class(node, file, scope, false).run();
return new ClassTransformer(node, file, scope, false).run();
};
/**
@@ -34,10 +35,10 @@ exports.ClassExpression = function (node, parent, scope, context, file) {
* @param {Node} node
* @param {File} file
* @param {Scope} scope
* @param {Boolean} closure
* @param {Boolean} isStatement
*/
function Class(node, file, scope, isStatement) {
function ClassTransformer(node, file, scope, isStatement) {
this.isStatement = isStatement;
this.scope = scope;
this.node = node;
@@ -61,7 +62,7 @@ function Class(node, file, scope, isStatement) {
* @returns {Array}
*/
Class.prototype.run = function () {
ClassTransformer.prototype.run = function () {
var superName = this.superName;
var className = this.className;
var file = this.file;
@@ -98,8 +99,7 @@ Class.prototype.run = function () {
closureArgs.push(superName);
if (!t.isIdentifier(superName)) {
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
superName = superRef;
superName = this.scope.generateUidBasedOnNode(superName, this.file);
}
closureParams.push(superName);
@@ -138,7 +138,7 @@ Class.prototype.run = function () {
* Description
*/
Class.prototype.buildBody = function () {
ClassTransformer.prototype.buildBody = function () {
var constructor = this.constructor;
var className = this.className;
var superName = this.superName;
@@ -152,10 +152,11 @@ Class.prototype.buildBody = function () {
methodNode: node,
className: this.className,
superName: this.superName,
isStatic: node.static,
isLoose: this.isLoose,
scope: this.scope,
file: this.file
});
}, true);
replaceSupers.replace();
if (node.key.name === "constructor") {
@@ -166,6 +167,8 @@ Class.prototype.buildBody = function () {
} else if (t.isPrivateDeclaration(node)) {
this.closure = true;
body.unshift(node);
} else if (t.isClassProperty(node)) {
this.pushProperty(node);
}
}
@@ -203,12 +206,12 @@ Class.prototype.buildBody = function () {
};
/**
* Push a method to it's respective mutatorMap.
* Push a method to its respective mutatorMap.
*
* @param {Node} node MethodDefinition
*/
Class.prototype.pushMethod = function (node) {
ClassTransformer.prototype.pushMethod = function (node) {
var methodName = node.key;
var kind = node.kind;
@@ -244,15 +247,39 @@ Class.prototype.pushMethod = function (node) {
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
};
/**
* Description
*
* @param {Node} node
*/
ClassTransformer.prototype.pushProperty = function (node) {
if (!node.value) return;
var key;
if (node.static) {
key = t.memberExpression(this.className, node.key);
this.body.push(
t.expressionStatement(t.assignmentExpression("=", key, node.value))
);
} else {
key = t.memberExpression(t.thisExpression(), node.key);
this.constructor.body.body.unshift(
t.expressionStatement(t.assignmentExpression("=", key, node.value))
);
}
};
/**
* Replace the constructor body of our class.
*
* @param {Node} method MethodDefinition
*/
Class.prototype.pushConstructor = function (method) {
ClassTransformer.prototype.pushConstructor = function (method) {
if (method.kind) {
throw this.file.errorWithNode(method, "illegal kind for constructor method");
throw this.file.errorWithNode(method, messages.get("classesIllegalConstructorKind"));
}
var construct = this.constructor;

View File

@@ -1,43 +1,48 @@
"use strict";
var t = require("../../../types");
var messages = require("../../../messages");
var t = require("../../../types");
exports.check = function (node) {
return t.isVariableDeclaration(node, { kind: "const" });
};
var visitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isAssignmentExpression(node) || t.isUpdateExpression(node)) {
if (t.isMemberExpression(node.left || node.argument)) return;
var ids = t.getBindingIdentifiers(node);
for (var key in ids) {
var id = ids[key];
for (var name in ids) {
var id = ids[name];
var constant = state.constants[key];
var constant = state.constants[name];
// no constant exists
if (!constant) continue;
var constantIdentifier = constant.identifier;
// check if the assignment id matches the constant declaration id
// if it does then it was the id used to initially declare the
// constant so we can just ignore it
if (id === constant) continue;
if (id === constantIdentifier) continue;
var localBinding = scope.getBinding(key);
if (localBinding !== constant) continue;
// check if there's been a local binding that shadows this constant
if (!scope.bindingIdentifierEquals(name, constantIdentifier)) continue;
throw state.file.errorWithNode(id, key + " is read-only");
throw state.file.errorWithNode(id, messages.get("readOnly", name));
}
} else if (t.isScope(node)) {
context.skip();
} else if (t.isScope(node, parent)) {
this.skip();
}
}
};
exports.Scope = function (node, parent, scope, context, file) {
exports.Scopable = function (node, parent, scope, file) {
scope.traverse(node, visitor, {
constants: scope.getAllDeclarationsOfKind("const"),
constants: scope.getAllBindingsOfKind("const"),
file: file
});
};

View File

@@ -1,10 +1,11 @@
"use strict";
var t = require("../../../types");
var messages = require("../../../messages");
var t = require("../../../types");
exports.check = t.isPattern;
function Destructuring(opts) {
function DestructuringTransformer(opts) {
this.blockHoist = opts.blockHoist;
this.operator = opts.operator;
this.nodes = opts.nodes;
@@ -13,7 +14,7 @@ function Destructuring(opts) {
this.kind = opts.kind;
}
Destructuring.prototype.buildVariableAssignment = function (id, init) {
DestructuringTransformer.prototype.buildVariableAssignment = function (id, init) {
var op = this.operator;
if (t.isMemberExpression(id)) op = "=";
@@ -32,7 +33,7 @@ Destructuring.prototype.buildVariableAssignment = function (id, init) {
return node;
};
Destructuring.prototype.buildVariableDeclaration = function (id, init) {
DestructuringTransformer.prototype.buildVariableDeclaration = function (id, init) {
var declar = t.variableDeclaration("var", [
t.variableDeclarator(id, init)
]);
@@ -40,7 +41,7 @@ Destructuring.prototype.buildVariableDeclaration = function (id, init) {
return declar;
};
Destructuring.prototype.push = function (elem, parentId) {
DestructuringTransformer.prototype.push = function (elem, parentId) {
if (t.isObjectPattern(elem)) {
this.pushObjectPattern(elem, parentId);
} else if (t.isArrayPattern(elem)) {
@@ -52,7 +53,7 @@ Destructuring.prototype.push = function (elem, parentId) {
}
};
Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
DestructuringTransformer.prototype.pushAssignmentPattern = function (pattern, parentId) {
var tempParentId = this.scope.generateUidBasedOnNode(parentId);
var declar = t.variableDeclaration("var", [
@@ -71,7 +72,7 @@ Destructuring.prototype.pushAssignmentPattern = function (pattern, parentId) {
));
};
Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
DestructuringTransformer.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
@@ -92,7 +93,7 @@ Destructuring.prototype.pushObjectSpread = function (pattern, parentId, prop, i)
this.nodes.push(this.buildVariableAssignment(prop.argument, value));
};
Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
DestructuringTransformer.prototype.pushObjectProperty = function (prop, parentId) {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern2 = prop.value;
@@ -105,13 +106,19 @@ Destructuring.prototype.pushObjectProperty = function (prop, parentId) {
}
};
Destructuring.prototype.pushObjectPattern = function (pattern, parentId) {
DestructuringTransformer.prototype.pushObjectPattern = function (pattern, parentId) {
if (!pattern.properties.length) {
this.nodes.push(t.expressionStatement(
t.callExpression(this.file.addHelper("object-destructuring-empty"), [parentId])
));
}
if (pattern.properties.length > 1 && t.isMemberExpression(parentId)) {
var temp = this.scope.generateUidBasedOnNode(parentId, this.file);
this.nodes.push(this.buildVariableDeclaration(temp, parentId));
parentId = temp;
}
for (var i = 0; i < pattern.properties.length; i++) {
var prop = pattern.properties[i];
if (t.isSpreadProperty(prop)) {
@@ -131,18 +138,20 @@ var hasRest = function (pattern) {
return false;
};
Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
DestructuringTransformer.prototype.pushArrayPattern = function (pattern, parentId) {
if (!pattern.elements) return;
// if we have a rest then we need all the elements
var count = !hasRest(pattern) && pattern.elements.length;
var toArray = this.file.toArray(parentId, count);
var toArray = this.scope.toArray(parentId, count);
var _parentId = this.scope.generateUidBasedOnNode(parentId, this.file);
var _parentId = this.scope.generateUidBasedOnNode(parentId);
this.nodes.push(this.buildVariableDeclaration(_parentId, toArray));
parentId = _parentId;
this.scope.assignTypeGeneric(parentId.name, "Array");
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
@@ -152,7 +161,7 @@ Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
var newPatternId;
if (t.isRestElement(elem)) {
newPatternId = this.file.toArray(parentId);
newPatternId = this.scope.toArray(parentId);
if (i > 0) {
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
@@ -167,7 +176,7 @@ Destructuring.prototype.pushArrayPattern = function (pattern, parentId) {
}
};
Destructuring.prototype.init = function (pattern, parentId) {
DestructuringTransformer.prototype.init = function (pattern, parentId) {
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
var key = this.scope.generateUidBasedOnNode(parentId);
this.nodes.push(this.buildVariableDeclaration(key, parentId));
@@ -178,22 +187,41 @@ Destructuring.prototype.init = function (pattern, parentId) {
};
exports.ForInStatement =
exports.ForOfStatement = function (node, parent, scope, context, file) {
var declar = node.left;
if (!t.isVariableDeclaration(declar)) return;
exports.ForOfStatement = function (node, parent, scope, file) {
var left = node.left;
var pattern = declar.declarations[0].id;
if (t.isPattern(left)) {
// for ({ length: k } in { abc: 3 });
var temp = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration("var", [
t.variableDeclarator(temp)
]);
t.ensureBlock(node);
node.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(left, temp)
]));
return;
}
if (!t.isVariableDeclaration(left)) return;
var pattern = left.declarations[0].id;
if (!t.isPattern(pattern)) return;
var key = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration(declar.kind, [
node.left = t.variableDeclaration(left.kind, [
t.variableDeclarator(key, null)
]);
var nodes = [];
var destructuring = new Destructuring({
kind: declar.kind,
var destructuring = new DestructuringTransformer({
kind: left.kind,
file: file,
scope: scope,
nodes: nodes
@@ -207,18 +235,18 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
block.body = nodes.concat(block.body);
};
exports.Function = function (node, parent, scope, context, file) {
exports.Function = function (node, parent, scope, file) {
var nodes = [];
var hasDestructuring = false;
var hasDestructuringTransformer = false;
node.params = node.params.map(function (pattern, i) {
if (!t.isPattern(pattern)) return pattern;
hasDestructuring = true;
hasDestructuringTransformer = true;
var parentId = scope.generateUidIdentifier("ref");
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
blockHoist: node.params.length - i,
nodes: nodes,
scope: scope,
@@ -230,7 +258,7 @@ exports.Function = function (node, parent, scope, context, file) {
return parentId;
});
if (!hasDestructuring) return;
if (!hasDestructuringTransformer) return;
t.ensureBlock(node);
@@ -238,7 +266,7 @@ exports.Function = function (node, parent, scope, context, file) {
block.body = nodes.concat(block.body);
};
exports.CatchClause = function (node, parent, scope, context, file) {
exports.CatchClause = function (node, parent, scope, file) {
var pattern = node.param;
if (!t.isPattern(pattern)) return;
@@ -247,8 +275,8 @@ exports.CatchClause = function (node, parent, scope, context, file) {
var nodes = [];
var destructuring = new Destructuring({
kind: "var",
var destructuring = new DestructuringTransformer({
kind: "let",
file: file,
scope: scope,
nodes: nodes
@@ -256,9 +284,11 @@ exports.CatchClause = function (node, parent, scope, context, file) {
destructuring.init(pattern, ref);
node.body.body = nodes.concat(node.body.body);
return node;
};
exports.ExpressionStatement = function (node, parent, scope, context, file) {
exports.ExpressionStatement = function (node, parent, scope, file) {
var expr = node.expression;
if (expr.type !== "AssignmentExpression") return;
if (!t.isPattern(expr.left)) return;
@@ -271,7 +301,7 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
t.variableDeclarator(ref, expr.right)
]));
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
operator: expr.operator,
file: file,
scope: scope,
@@ -282,7 +312,7 @@ exports.ExpressionStatement = function (node, parent, scope, context, file) {
return nodes;
};
exports.AssignmentExpression = function (node, parent, scope, context, file) {
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!t.isPattern(node.left)) return;
var ref = scope.generateUidIdentifier("temp");
@@ -294,7 +324,7 @@ exports.AssignmentExpression = function (node, parent, scope, context, file) {
var nodes = [];
nodes.push(t.assignmentExpression("=", ref, node.right));
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
operator: node.operator,
file: file,
scope: scope,
@@ -316,7 +346,7 @@ var variableDeclarationhasPattern = function (node) {
return false;
};
exports.VariableDeclaration = function (node, parent, scope, context, file) {
exports.VariableDeclaration = function (node, parent, scope, file) {
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
if (!variableDeclarationhasPattern(node)) return;
@@ -329,7 +359,7 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
var patternId = declar.init;
var pattern = declar.id;
var destructuring = new Destructuring({
var destructuring = new DestructuringTransformer({
nodes: nodes,
scope: scope,
kind: node.kind,
@@ -360,7 +390,7 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
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");
throw file.errorWithNode(node, messages.get("invalidParentForThisNode"));
}
declar.declarations = declar.declarations.concat(node.declarations);

View File

@@ -1,15 +1,16 @@
"use strict";
var util = require("../../../util");
var t = require("../../../types");
var messages = require("../../../messages");
var util = require("../../../util");
var t = require("../../../types");
exports.check = t.isForOfStatement;
exports.ForOfStatement = function (node, parent, scope, context, file) {
exports.ForOfStatement = function (node, parent, scope, file) {
var callback = spec;
if (file.isLoose("es6.forOf")) callback = loose;
var build = callback(node, parent, scope, context, file);
var build = callback(node, parent, scope, file);
var declar = build.declar;
var loop = build.loop;
var block = loop.body;
@@ -17,7 +18,7 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
// inherit comments from the original loop
t.inheritsComments(loop, node);
// ensure that it's a block so we can take all it's statemetns
// ensure that it's a block so we can take all its statements
t.ensureBlock(node);
// add the value declaration to the new loop body
@@ -28,13 +29,15 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
// push the rest of the original loop body onto our new body
block.body = block.body.concat(node.body.body);
t.inherits(loop, node);
// todo: find out why this is necessary? #538
loop._scopeInfo = node._scopeInfo;
return loop;
};
var loose = function (node, parent, scope, context, file) {
var loose = function (node, parent, scope, file) {
var left = node.left;
var declar, id;
@@ -48,7 +51,7 @@ var loose = function (node, parent, scope, context, file) {
t.variableDeclarator(left.declarations[0].id, id)
]);
} else {
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
throw file.errorWithNode(left, messages.get("unknownForHead", left.type));
}
var loop = util.template("for-of-loose", {
@@ -71,7 +74,7 @@ var loose = function (node, parent, scope, context, file) {
};
};
var spec = function (node, parent, scope, context, file) {
var spec = function (node, parent, scope, file) {
var left = node.left;
var declar;
@@ -87,7 +90,7 @@ var spec = function (node, parent, scope, context, file) {
t.variableDeclarator(left.declarations[0].id, stepValue)
]);
} else {
throw file.errorWithNode(left, "Unknown node type " + left.type + " in ForOfStatement");
throw file.errorWithNode(left, messages.get("unknownForHead", left.type));
}
var loop = util.template("for-of", {

View File

@@ -4,7 +4,7 @@ var t = require("../../../types");
exports.check = require("../internal/modules").check;
exports.ImportDeclaration = function (node, parent, scope, context, file) {
exports.ImportDeclaration = function (node, parent, scope, file) {
var nodes = [];
if (node.specifiers.length) {
@@ -23,7 +23,7 @@ exports.ImportDeclaration = function (node, parent, scope, context, file) {
return nodes;
};
exports.ExportDeclaration = function (node, parent, scope, context, file) {
exports.ExportDeclaration = function (node, parent, scope, file) {
var nodes = [];
var i;

View File

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

View File

@@ -9,21 +9,23 @@ exports.check = function (node) {
var hasDefaults = function (node) {
for (var i = 0; i < node.params.length; i++) {
if (t.isAssignmentPattern(node.params[i])) return true;
if (!t.isIdentifier(node.params[i])) return true;
}
return false;
};
var iifeVisitor = {
enter: function (node, parent, scope, context, state) {
if (t.isReferencedIdentifier(node, parent) && state.scope.hasOwnReference(node.name)) {
state.iife = true;
context.stop();
}
enter: function (node, parent, scope, state) {
if (!t.isReferencedIdentifier(node, parent)) return;
if (!state.scope.hasOwnBinding(node.name)) return;
if (state.scope.bindingIdentifierEquals(node.name, node)) return;
state.iife = true;
this.stop();
}
};
exports.Function = function (node, parent, scope) {
exports.Function = function (node, parent, scope, file) {
if (!hasDefaults(node)) return;
t.ensureBlock(node);
@@ -37,35 +39,53 @@ exports.Function = function (node, parent, scope) {
var state = { iife: false, scope: scope };
var pushDefNode = function (left, right, i) {
var defNode = util.template("default-parameter", {
VARIABLE_NAME: left,
DEFAULT_VALUE: right,
ARGUMENT_KEY: t.literal(i),
ARGUMENTS: argsIdentifier
}, true);
file.checkNode(defNode);
defNode._blockHoist = node.params.length - i;
body.push(defNode);
};
for (var i = 0; i < node.params.length; i++) {
var param = node.params[i];
if (!t.isAssignmentPattern(param)) {
lastNonDefaultParam = +i + 1;
if (!t.isRestElement(param)) {
lastNonDefaultParam = i + 1;
}
if (!t.isIdentifier(param)) {
scope.traverse(param, iifeVisitor, state);
}
if (file.transformers["es6.blockScopingTDZ"].canRun()) {
pushDefNode(param, t.identifier("undefined"), i);
}
continue;
}
var left = param.left;
var right = param.right;
node.params[i] = scope.generateUidIdentifier("x");
var placeholder = scope.generateUidIdentifier("x");
placeholder._isDefaultPlaceholder = true;
node.params[i] = placeholder;
if (!state.iife) {
if (t.isIdentifier(right) && scope.hasOwnReference(right.name)) {
if (t.isIdentifier(right) && scope.hasOwnBinding(right.name)) {
state.iife = true;
} else {
scope.traverse(right, iifeVisitor, state);
}
}
var defNode = util.template("default-parameter", {
VARIABLE_NAME: left,
DEFAULT_VALUE: right,
ARGUMENT_KEY: t.literal(+i),
ARGUMENTS: argsIdentifier
}, true);
defNode._blockHoist = node.params.length - i;
body.push(defNode);
pushDefNode(left, right, i);
}
// we need to cut off all trailing default parameters

View File

@@ -60,6 +60,8 @@ exports.Function = function (node, parent, scope) {
node.body.body.unshift(restDeclar);
}
scope.assignTypeGeneric(rest.name, "Array");
var loop = util.template("rest", {
ARGUMENTS: argsId,
ARRAY_KEY: arrKey,

View File

@@ -6,7 +6,7 @@ exports.check = function (node) {
return t.isProperty(node) && node.computed;
};
exports.ObjectExpression = function (node, parent, scope, context, file) {
exports.ObjectExpression = function (node, parent, scope, file) {
var hasComputed = false;
for (var i = 0; i < node.properties.length; i++) {

View File

@@ -8,7 +8,7 @@ exports.check = function (node) {
return t.isProperty(node) && (node.method || node.shorthand);
};
exports.Property = function (node, parent, scope, context, file) {
exports.Property = function (node, parent, scope, file) {
if (node.method) {
node.method = false;
nameMethod.property(node, file, scope);

View File

@@ -1,12 +1,12 @@
"use strict";
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var t = require("../../../types");
exports.check = t.isSpreadElement;
var getSpreadLiteral = function (spread, file) {
return file.toArray(spread.argument);
var getSpreadLiteral = function (spread, scope) {
return scope.toArray(spread.argument, true);
};
var hasSpread = function (nodes) {
@@ -18,7 +18,7 @@ var hasSpread = function (nodes) {
return false;
};
var build = function (props, file) {
var build = function (props, scope) {
var nodes = [];
var _props = [];
@@ -33,7 +33,7 @@ var build = function (props, file) {
var prop = props[i];
if (t.isSpreadElement(prop)) {
push();
nodes.push(getSpreadLiteral(prop, file));
nodes.push(getSpreadLiteral(prop, scope));
} else {
_props.push(prop);
}
@@ -44,11 +44,11 @@ var build = function (props, file) {
return nodes;
};
exports.ArrayExpression = function (node, parent, scope, context, file) {
exports.ArrayExpression = function (node, parent, scope) {
var elements = node.elements;
if (!hasSpread(elements)) return;
var nodes = build(elements, file);
var nodes = build(elements, scope);
var first = nodes.shift();
if (!t.isArrayExpression(first)) {
@@ -59,7 +59,7 @@ exports.ArrayExpression = function (node, parent, scope, context, file) {
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
};
exports.CallExpression = function (node, parent, scope, context, file) {
exports.CallExpression = function (node, parent, scope) {
var args = node.arguments;
if (!hasSpread(args)) return;
@@ -71,10 +71,10 @@ exports.CallExpression = function (node, parent, scope, context, file) {
if (args.length === 1 && args[0].argument.name === "arguments") {
nodes = [args[0].argument];
} else {
nodes = build(args, file);
nodes = build(args, scope);
}
var first = nodes.shift();
var first = nodes.shift();
if (nodes.length) {
node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
} else {
@@ -99,13 +99,13 @@ exports.CallExpression = function (node, parent, scope, context, file) {
node.arguments.unshift(contextLiteral);
};
exports.NewExpression = function (node, parent, scope, context, file) {
exports.NewExpression = function (node, parent, scope, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
var nativeType = t.isIdentifier(node.callee) && contains(t.NATIVE_TYPE_NAMES, node.callee.name);
var nativeType = t.isIdentifier(node.callee) && includes(t.NATIVE_TYPE_NAMES, node.callee.name);
var nodes = build(args, file);
var nodes = build(args, scope);
if (nativeType) {
nodes.unshift(t.arrayExpression([t.literal(null)]));

View File

@@ -0,0 +1,359 @@
"use strict";
var reduceRight = require("lodash/collection/reduceRight");
var messages = require("../../../messages");
var flatten = require("lodash/array/flatten");
var util = require("../../../util");
var map = require("lodash/collection/map");
var t = require("../../../types");
function returnBlock(expr) {
return t.blockStatement([t.returnStatement(expr)]);
}
function TailCallTransformer(node, scope, file) {
this.hasTailRecursion = false;
this.needsArguments = false;
this.setsArguments = false;
this.needsThis = false;
this.ownerId = node.id;
this.vars = [];
this.scope = scope;
this.file = file;
this.node = node;
}
TailCallTransformer.prototype.getArgumentsId = function () {
return this.argumentsId = this.argumentsId || this.scope.generateUidIdentifier("arguments");
};
TailCallTransformer.prototype.getThisId = function () {
return this.thisId = this.thisId || this.scope.generateUidIdentifier("this");
};
TailCallTransformer.prototype.getLeftId = function () {
return this.leftId = this.leftId || this.scope.generateUidIdentifier("left");
};
TailCallTransformer.prototype.getFunctionId = function () {
return this.functionId = this.functionId || this.scope.generateUidIdentifier("function");
};
TailCallTransformer.prototype.getParams = function () {
var params = this.params;
if (!params) {
params = this.node.params;
this.paramDecls = [];
for (var i = 0; i < params.length; i++) {
var param = params[i];
if (!param._isDefaultPlaceholder) {
this.paramDecls.push(t.variableDeclarator(
param,
params[i] = this.scope.generateUidIdentifier("x")
));
}
}
}
return this.params = params;
};
TailCallTransformer.prototype.hasDeopt = function () {
// check if the ownerId has been reassigned, if it has then it's not safe to
// perform optimisations
var ownerIdInfo = this.scope.getBindingInfo(this.ownerId.name);
return ownerIdInfo && ownerIdInfo.reassigned;
};
TailCallTransformer.prototype.run = function () {
var scope = this.scope;
var node = this.node;
// only tail recursion can be optimized as for now, so we can skip anonymous
// functions entirely
var ownerId = this.ownerId;
if (!ownerId) return;
// traverse the function and look for tail recursion
scope.traverse(node, firstPass, this);
if (!this.hasTailRecursion) return;
if (this.hasDeopt()) {
this.file.logDeopt(node, messages.get("tailCallReassignmentDeopt"));
return;
}
//
scope.traverse(node, secondPass, this);
if (!this.needsThis || !this.needsArguments) {
scope.traverse(node, thirdPass, this);
}
var body = t.ensureBlock(node).body;
if (this.vars.length > 0) {
var declarations = flatten(map(this.vars, function (decl) {
return decl.declarations;
}, this));
var statement = reduceRight(declarations, function (expr, decl) {
return t.assignmentExpression("=", decl.id, expr);
}, t.identifier("undefined"));
body.unshift(t.expressionStatement(statement));
}
var paramDecls = this.paramDecls;
if (paramDecls.length > 0) {
body.unshift(t.variableDeclaration("var", paramDecls));
}
node.body = util.template("tail-call-body", {
THIS_ID: this.thisId,
ARGUMENTS_ID: this.argumentsId,
FUNCTION_ID: this.getFunctionId(),
BLOCK: node.body
});
var topVars = [];
if (this.needsThis) {
topVars.push(t.variableDeclarator(this.getThisId(), t.thisExpression()));
}
if (this.needsArguments || this.setsArguments) {
var decl = t.variableDeclarator(this.getArgumentsId());
if (this.needsArguments) {
decl.init = t.identifier("arguments");
}
topVars.push(decl);
}
var leftId = this.leftId;
if (leftId) {
topVars.push(t.variableDeclarator(leftId));
}
if (topVars.length > 0) {
node.body.body.unshift(t.variableDeclaration("var", topVars));
}
};
TailCallTransformer.prototype.subTransform = function (node) {
if (!node) return;
var handler = this["subTransform" + node.type];
if (handler) return handler.call(this, node);
};
TailCallTransformer.prototype.subTransformConditionalExpression = function (node) {
var callConsequent = this.subTransform(node.consequent);
var callAlternate = this.subTransform(node.alternate);
if (!callConsequent && !callAlternate) {
return;
}
// if ternary operator had tail recursion in value, convert to optimized if-statement
node.type = "IfStatement";
node.consequent = callConsequent ? t.toBlock(callConsequent) : returnBlock(node.consequent);
if (callAlternate) {
node.alternate = t.isIfStatement(callAlternate) ? callAlternate : t.toBlock(callAlternate);
} else {
node.alternate = returnBlock(node.alternate);
}
return [node];
};
TailCallTransformer.prototype.subTransformLogicalExpression = function (node) {
// only call in right-value of can be optimized
var callRight = this.subTransform(node.right);
if (!callRight) return;
// cache left value as it might have side-effects
var leftId = this.getLeftId();
var testExpr = t.assignmentExpression(
"=",
leftId,
node.left
);
if (node.operator === "&&") {
testExpr = t.unaryExpression("!", testExpr);
}
return [t.ifStatement(testExpr, returnBlock(leftId))].concat(callRight);
};
TailCallTransformer.prototype.subTransformSequenceExpression = function (node) {
var seq = node.expressions;
// only last element can be optimized
var lastCall = this.subTransform(seq[seq.length - 1]);
if (!lastCall) {
return;
}
// remove converted expression from sequence
// and convert to regular expression if needed
if (--seq.length === 1) {
node = seq[0];
}
return [t.expressionStatement(node)].concat(lastCall);
};
TailCallTransformer.prototype.subTransformCallExpression = function (node) {
var callee = node.callee, thisBinding, args;
if (t.isMemberExpression(callee, { computed: false }) && t.isIdentifier(callee.property)) {
switch (callee.property.name) {
case "call":
args = t.arrayExpression(node.arguments.slice(1));
break;
case "apply":
args = node.arguments[1] || t.identifier("undefined");
break;
default:
return;
}
thisBinding = node.arguments[0];
callee = callee.object;
}
// only tail recursion can be optimized as for now
if (!t.isIdentifier(callee) || !this.scope.bindingIdentifierEquals(callee.name, this.ownerId)) {
return;
}
this.hasTailRecursion = true;
if (this.hasDeopt()) return;
var body = [];
if (!t.isThisExpression(thisBinding)) {
body.push(t.expressionStatement(t.assignmentExpression(
"=",
this.getThisId(),
thisBinding || t.identifier("undefined")
)));
}
if (!args) {
args = t.arrayExpression(node.arguments);
}
var argumentsId = this.getArgumentsId();
var params = this.getParams();
body.push(t.expressionStatement(t.assignmentExpression(
"=",
argumentsId,
args
)));
var i, param;
if (t.isArrayExpression(args)) {
var elems = args.elements;
for (i = 0; i < elems.length && i < params.length; i++) {
param = params[i];
var elem = elems[i] || (elems[i] = t.identifier("undefined"));
if (!param._isDefaultPlaceholder) {
elems[i] = t.assignmentExpression("=", param, elem);
}
}
} else {
this.setsArguments = true;
for (i = 0; i < params.length; i++) {
param = params[i];
if (!param._isDefaultPlaceholder) {
body.push(t.expressionStatement(t.assignmentExpression(
"=",
param,
t.memberExpression(argumentsId, t.literal(i), true)
)));
}
}
}
body.push(t.continueStatement(this.getFunctionId()));
return body;
};
// looks for and replaces tail recursion calls
var firstPass = {
enter: function (node, parent, scope, state) {
if (t.isReturnStatement(node)) {
this.skip();
return state.subTransform(node.argument);
} else if (t.isTryStatement(parent)) {
if (node === parent.block) {
this.skip();
} else if (parent.finalizer && node !== parent.finalizer) {
this.skip();
}
} else if (t.isFunction(node)) {
this.skip();
} else if (t.isVariableDeclaration(node)) {
this.skip();
state.vars.push(node);
}
}
};
// hoists up function declarations, replaces `this` and `arguments` and marks
// them as needed
var secondPass = {
enter: function (node, parent, scope, state) {
if (t.isThisExpression(node)) {
state.needsThis = true;
return state.getThisId();
} else if (t.isReferencedIdentifier(node, parent, { name: "arguments" })) {
state.needsArguments = true;
return state.getArgumentsId();
} else if (t.isFunction(node)) {
this.skip();
if (t.isFunctionDeclaration(node)) {
node = t.variableDeclaration("var", [
t.variableDeclarator(node.id, t.toExpression(node))
]);
node._blockHoist = 2;
return node;
}
}
}
};
// optimizes recursion by removing `this` and `arguments` if they aren't used
var thirdPass = {
enter: function (node, parent, scope, state) {
if (!t.isExpressionStatement(node)) return;
var expr = node.expression;
if (!t.isAssignmentExpression(expr)) return;
if (!state.needsThis && expr.left === state.getThisId()) {
this.remove();
} else if (!state.needsArguments && expr.left === state.getArgumentsId() && t.isArrayExpression(expr.right)) {
return map(expr.right.elements, function (elem) {
return t.expressionStatement(elem);
});
}
}
};
exports.Function = function (node, parent, scope, file) {
var tailCall = new TailCallTransformer(node, scope, file);
tailCall.run();
};

View File

@@ -10,7 +10,7 @@ exports.check = function (node) {
return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node);
};
exports.TaggedTemplateExpression = function (node, parent, scope, context, file) {
exports.TaggedTemplateExpression = function (node, parent, scope, file) {
var args = [];
var quasi = node.quasi;

View File

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

View File

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

View File

@@ -19,7 +19,7 @@ var hasSpread = function (node) {
return false;
};
exports.ObjectExpression = function (node, parent, scope, context, file) {
exports.ObjectExpression = function (node, parent, scope, file) {
if (!hasSpread(node)) return;
var args = [];

View File

@@ -11,6 +11,7 @@ module.exports = {
"playground.memoizationOperator": require("./playground/memoization-operator"),
"playground.objectGetterMemoization": require("./playground/object-getter-memoization"),
reactCompat: require("./other/react-compat"),
react: require("./other/react"),
_modules: require("./internal/modules"),
@@ -27,9 +28,9 @@ module.exports = {
asyncToGenerator: require("./other/async-to-generator"),
bluebirdCoroutines: require("./other/bluebird-coroutines"),
"es6.objectSuper": require("./es6/object-super"),
"es7.objectRestSpread": require("./es7/object-rest-spread"),
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
"es6.spread": require("./es6/spread"),
"es6.templateLiterals": require("./es6/template-literals"),
"es5.properties.mutators": require("./es5/properties.mutators"),
@@ -45,6 +46,18 @@ module.exports = {
"es6.constants": require("./es6/constants"),
// needs to be before `es6.parameters.default` as default parameters will destroy the rest param
"es6.parameters.rest": require("./es6/parameters.rest"),
// needs to be after `es6.parameters.rest` as we use `toArray` and avoid turning an already known array into one
"es6.spread": require("./es6/spread"),
// needs to be before `es6.blockScoping` as default parameters have a TDZ
"es6.parameters.default": require("./es6/parameters.default"),
// needs to be before `es6.blockScoping` as let variables may be produced
"es6.destructuring": require("./es6/destructuring"),
// needs to be before `_aliasFunction` due to block scopes sometimes being wrapped in a
// closure
"es6.blockScoping": require("./es6/block-scoping"),
@@ -52,10 +65,9 @@ module.exports = {
// needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks
"es6.blockScopingTDZ": require("./es6/block-scoping-tdz"),
"es6.parameters.default": require("./es6/parameters.default"),
"es6.parameters.rest": require("./es6/parameters.rest"),
"es6.destructuring": require("./es6/destructuring"),
// needs to be after `es6.parameters.*` and `es6.blockScoping` due to needing pure
// identifiers in parameters and variable declarators
"es6.tailCall": require("./es6/tail-call"),
regenerator: require("./other/regenerator"),
@@ -79,11 +91,13 @@ module.exports = {
"spec.typeofSymbol": require("./spec/typeof-symbol"),
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
"minification.propertyLiterals": require("./minification/property-literals"),
"minification.memberExpressionLiterals": require("./minification/member-expression-literals"),
"es3.propertyLiterals": require("./es3/property-literals"),
"es3.memberExpressionLiterals": require("./es3/member-expression-literals"),
"minification.removeDebugger": require("./minification/remove-debugger"),
"minification.removeConsoleCalls": require("./minification/remove-console-calls"),
"minification.deadCodeElimination": require("./minification/dead-code-elimination"),
"minification.renameLocalVariables": require("./minification/rename-local-variables")
"minification.renameLocalVariables": require("./minification/rename-local-variables"),
_cleanUp: require("./internal/cleanup")
};

View File

@@ -3,12 +3,12 @@
var t = require("../../../types");
var functionChildrenVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (t.isFunction(node) && !node._aliasFunction) {
return context.skip();
return this.skip();
}
if (node._ignoreAliasFunctions) return context.skip();
if (node._ignoreAliasFunctions) return this.skip();
var getId;
@@ -25,11 +25,11 @@ var functionChildrenVisitor = {
};
var functionVisitor = {
enter: function (node, parent, scope, context, state) {
enter: function (node, parent, scope, state) {
if (!node._aliasFunction) {
if (t.isFunction(node)) {
// stop traversal of this node as it'll be hit again by this transformer
return context.skip();
return this.skip();
} else {
return;
}
@@ -38,7 +38,7 @@ var functionVisitor = {
// traverse all child nodes of this function and find `arguments` and `this`
scope.traverse(node, functionChildrenVisitor, state);
return context.skip();
return this.skip();
}
};

View File

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

View File

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

View File

@@ -8,7 +8,7 @@
var t = require("../../../types");
var resolveModuleSource = function (node, parent, scope, context, file) {
var resolveModuleSource = function (node, parent, scope, file) {
var resolveModuleSource = file.opts.resolveModuleSource;
if (node.source && resolveModuleSource) {
node.source.value = resolveModuleSource(node.source.value);

View File

@@ -2,8 +2,9 @@ var t = require("../../../types");
exports.optional = true;
exports.ExpressionStatement = function (node, parent, scope, context) {
// remove consequenceless expressions such as local variables and literals
exports.ExpressionStatement = function (node) {
// remove consequence-less expressions such as local variables and literals
// note: will remove directives
//
// var foo = true; foo; -> var foo = true;
// "foo"; ->
@@ -11,12 +12,12 @@ exports.ExpressionStatement = function (node, parent, scope, context) {
var expr = node.expression;
if (t.isLiteral(expr) || (t.isIdentifier(node) && t.hasBinding(node.name))) {
context.remove();
this.remove();
}
};
exports.IfStatement = {
exit: function (node, parent, scope, context) {
exit: function (node) {
// todo: in scenarios where we can just return the consequent or
// alternate we should drop the block statement if it contains no
// block scoped variables
@@ -25,7 +26,7 @@ exports.IfStatement = {
var alternate = node.alternate;
var test = node.test;
// we can check if a test will be truthy 100% and if so we can inline
// we can check if a test will be truthy 100% and if so then we can inline
// the consequent and completely ignore the alternate
//
// if (true) { foo; } -> { foo; }
@@ -33,11 +34,11 @@ exports.IfStatement = {
//
if (t.isLiteral(test) && test.value) {
return alternate;
return consequent;
}
// we can check if a test will be falsy 100% and if so we can inline
// the alternate if there is one and completely remove the consequent
// we can check if a test will be falsy 100% and if so we can inline the
// alternate if there is one and completely remove the consequent
//
// if ("") { bar; } else { foo; } -> { foo; }
// if ("") { bar; } ->
@@ -47,7 +48,7 @@ exports.IfStatement = {
if (alternate) {
return alternate;
} else {
return context.remove();
return this.remove();
}
}
@@ -60,15 +61,13 @@ exports.IfStatement = {
alternate = node.alternate = null;
}
// turn alternate blocks into a consequent and flip the test if the
// consequent block is empty
// if the consequent block is empty turn alternate blocks into a consequent
// and flip the test
//
// if (foo) {} else { bar; }
// if (!foo) { bar; }
// if (foo) {} else { bar; } -> if (!foo) { bar; }
//
if (t.blockStatement(consequent) && !consequent.body.length &&
t.isBlockStatement(alternate) && alternate.body.length) {
if (t.blockStatement(consequent) && !consequent.body.length && t.isBlockStatement(alternate) && alternate.body.length) {
node.consequent = node.alternate;
node.alternate = null;
node.test = t.unaryExpression("!", test, true);

View File

@@ -6,8 +6,12 @@ var isConsole = t.buildMatchMemberExpression("console", true);
exports.optional = true;
exports.CallExpression = function (node, parent, scope, context) {
exports.CallExpression = function (node, parent) {
if (isConsole(node.callee)) {
context.remove();
if (t.isExpressionStatement(parent)) {
this.parentPath.remove();
} else {
this.remove();
}
}
};

View File

@@ -2,8 +2,8 @@ var t = require("../../../types");
exports.optional = true;
exports.ExpressionStatement = function (node, parent, scope, context) {
exports.ExpressionStatement = function (node) {
if (t.isIdentifier(node.expression, { name: "debugger" })) {
context.remove();
this.remove();
}
};

View File

@@ -2,9 +2,8 @@
exports.optional = true;
exports.Scope = function () {
// todo: get all binding identifiers, generate compact names
// that wont collide and then call the remap identifier helper
// this transformer **has** to be ran last as it will absolutley
// destroy the scope tree
exports.Scopable = function () {
//for (var name in scope.bindings) {
// scope.rename(name, scope.generateUidIdentifier("a").name);
//}
};

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,10 +7,9 @@ exports.check = function (node) {
return t.isFunction(node) && (node.async || node.generator);
};
exports.ast = {
before: function (ast, file) {
regenerator.transform(ast, {
includeRuntime: file.opts.includeRegenerator && "if used"
});
exports.Program = {
enter: function (ast) {
regenerator.transform(ast);
this.stop();
}
};

View File

@@ -4,7 +4,7 @@ var util = require("../../../util");
var core = require("core-js/library");
var t = require("../../../types");
var has = require("lodash/object/has");
var contains = require("lodash/collection/contains");
var includes = require("lodash/collection/includes");
var coreHas = function (node) {
return node.name !== "_" && has(core, node.name);
@@ -20,7 +20,7 @@ var ALIASABLE_CONSTRUCTORS = [
];
var astVisitor = {
enter: function (node, parent, scope, context, file) {
enter: function (node, parent, scope, file) {
var prop;
if (t.isMemberExpression(node) && t.isReferenced(node, parent)) {
@@ -30,30 +30,44 @@ var astVisitor = {
if (!t.isReferenced(obj, node)) return;
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name)) {
context.skip();
if (!node.computed && coreHas(obj) && has(core[obj.name], prop.name) && !scope.getBindingIdentifier(obj.name)) {
this.skip();
return t.prependToMemberExpression(node, file.get("coreIdentifier"));
}
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && contains(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBinding(node.name)) {
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && includes(ALIASABLE_CONSTRUCTORS, node.name) && !scope.getBindingIdentifier(node.name)) {
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
return t.memberExpression(file.get("coreIdentifier"), node);
} else if (t.isCallExpression(node)) {
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
if (node.arguments.length) return;
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (!callee.computed) return;
if (node.arguments.length) return false;
if (!t.isMemberExpression(callee)) return false;
if (!callee.computed) return false;
prop = callee.property;
if (!t.isIdentifier(prop.object, { name: "Symbol" })) return;
if (!t.isIdentifier(prop.property, { name: "iterator" })) return;
if (!t.isIdentifier(prop.object, { name: "Symbol" })) return false;
if (!t.isIdentifier(prop.property, { name: "iterator" })) return false;
return util.template("corejs-iterator", {
CORE_ID: file.get("coreIdentifier"),
VALUE: callee.object
});
} else if (t.isBinaryExpression(node)) {
// Symbol.iterator in arr -> core.$for.isIterable(arr)
if (node.operator !== "in") return;
var left = node.left;
if (!t.isMemberExpression(left)) return;
if (!t.isIdentifier(left.object, { name: "Symbol" })) return;
if (!t.isIdentifier(left.property, { name: "iterator" })) return;
return util.template("corejs-is-iterator", {
CORE_ID: file.get("coreIdentifier"),
VALUE: node.right
});
}
}
};
@@ -64,28 +78,26 @@ exports.manipulateOptions = function (opts) {
if (opts.whitelist.length) opts.whitelist.push("es6.modules");
};
exports.ast = {
enter: function (ast, file) {
file.setDynamic("runtimeIdentifier", function () {
return file.addImport("6to5-runtime/helpers", "to5Helpers");
});
file.setDynamic("coreIdentifier", function () {
return file.addImport("6to5-runtime/core-js", "core");
});
file.setDynamic("regeneratorIdentifier", function () {
return file.addImport("6to5-runtime/regenerator", "regeneratorRuntime");
});
},
after: function (ast, file) {
file.scope.traverse(ast, astVisitor, file);
}
exports.post = function (file) {
file.scope.traverse(file.ast, astVisitor, file);
};
exports.Identifier = function (node, parent, scope, context, file) {
if (node.name === "regeneratorRuntime" && t.isReferenced(node, parent)) {
exports.pre = function (file) {
file.setDynamic("runtimeIdentifier", function () {
return file.addImport("6to5-runtime/helpers", "to5Helpers");
});
file.setDynamic("coreIdentifier", function () {
return file.addImport("6to5-runtime/core-js", "core");
});
file.setDynamic("regeneratorIdentifier", function () {
return file.addImport("6to5-runtime/regenerator", "regeneratorRuntime");
});
};
exports.Identifier = function (node, parent, scope, file) {
if (t.isReferencedIdentifier(node, parent, { name: "regeneratorRuntime" })) {
return file.get("regeneratorIdentifier");
}
};

View File

@@ -3,17 +3,16 @@
var useStrict = require("../../helpers/use-strict");
var t = require("../../../types");
exports.ast = {
exit: function (ast) {
if (!useStrict.has(ast.program)) {
ast.program.body.unshift(t.expressionStatement(t.literal("use strict")));
}
exports.post = function (file) {
var program = file.ast.program;
if (!useStrict.has(program)) {
program.body.unshift(t.expressionStatement(t.literal("use strict")));
}
};
exports.FunctionDeclaration =
exports.FunctionExpression = function (node, parent, scope, context) {
context.skip();
exports.FunctionExpression = function () {
this.skip();
};
exports.ThisExpression = function () {

View File

@@ -1,7 +1,8 @@
"use strict";
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
var t = require("../../../types");
var messages = require("../../../messages");
var build = require("../../helpers/build-conditional-assignment-operator-transformer");
var t = require("../../../types");
exports.playground = true;
@@ -11,7 +12,7 @@ build(exports, {
if (is) {
var left = node.left;
if (!t.isMemberExpression(left) && !t.isIdentifier(left)) {
throw file.errorWithNode(left, "Expected type MemeberExpression or Identifier");
throw file.errorWithNode(left, messages.get("expectedMemberExpressionOrIdentifier"));
}
return true;
}

View File

@@ -26,7 +26,7 @@ exports.BindMemberExpression = function (node, parent, scope) {
}
};
exports.BindFunctionExpression = function (node, parent, scope, context, file) {
exports.BindFunctionExpression = function (node, parent, scope) {
var buildCall = function (args) {
var param = scope.generateUidIdentifier("val");
return t.functionExpression(null, [param], t.blockStatement([
@@ -34,7 +34,7 @@ exports.BindFunctionExpression = function (node, parent, scope, context, file) {
]));
};
var temp = scope.generateTemp(file, "args");
var temp = scope.generateTemp("args");
return t.sequenceExpression([
t.assignmentExpression("=", temp, t.arrayExpression(node.arguments)),

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