Compare commits

..

511 Commits

Author SHA1 Message Date
Sebastian McKenzie
86a49e2b1d v5.6.19 2015-07-13 16:41:15 +01:00
Sebastian McKenzie
5cd8822888 remove DoExpression generator 2015-07-13 16:39:30 +01:00
Sebastian McKenzie
420492388b remove do expressions 2015-07-13 16:37:08 +01:00
Sebastian McKenzie
d5be4bb5b9 v5.6.18 2015-07-12 00:39:50 +01:00
Sebastian McKenzie
d6dc29ec6a remove templates doc 2015-07-12 00:37:55 +01:00
James Kyle
f3e77c7a0d Merge pull request #1983 from chicoxyzzy/code-docs-additions-by-chicoxyzzy
add some useful links
2015-07-11 15:09:29 -07:00
chico
b08012cf12 add some useful links 2015-07-12 01:05:50 +03:00
Sebastian McKenzie
ef275da1c2 Merge pull request #1897 from babel/code-docs
Code docs
2015-07-11 22:56:24 +01:00
James Kyle
cc6eb50f28 parenthesis -> parentheses 2015-07-11 14:48:40 -07:00
James Kyle
a260b6859f Clarify what the arrow function transformer does 2015-07-11 14:27:14 -07:00
James Kyle
eb182ccbe0 fix typo 2015-07-11 13:09:11 -07:00
James Kyle
fe1e99c799 Create generation/generators README 2015-07-11 12:53:46 -07:00
James Kyle
deeb75a5d1 Add descriptions to transformation/transformers/es6/destructuring 2015-07-11 12:53:46 -07:00
James Kyle
961d482269 Add content to tools README 2015-07-11 12:53:46 -07:00
James Kyle
1c8f0dcab4 Add content to helpers README 2015-07-11 12:53:46 -07:00
James Kyle
5dc39439ed Add content to generation README 2015-07-11 12:53:46 -07:00
James Kyle
58e029a064 Add content to api README 2015-07-11 12:53:46 -07:00
James Kyle
01ea72790d Add descriptions to types/flow 2015-07-11 12:53:45 -07:00
James Kyle
118ac2e62d Add descriptions to traversal/scope/index 2015-07-11 12:53:45 -07:00
James Kyle
3207a387a7 Add descriptions to transformation/transformers/es6/constants 2015-07-11 12:53:45 -07:00
James Kyle
90a5b96480 Add descriptions to transformation/transformers/es6/arrow-functions 2015-07-11 12:53:45 -07:00
James Kyle
74cf5ac552 Add descriptions to transformation/transformers/es5/properties.mutators 2015-07-11 12:53:45 -07:00
James Kyle
dce1a3548c Add descriptions to transformation/transformers/es3/property-literals 2015-07-11 12:53:45 -07:00
James Kyle
d67ba39d1c Add descriptions to transformation/transformers/es3/member-expression-literals 2015-07-11 12:53:45 -07:00
James Kyle
894c3fe481 Add descriptions to transformation/file/options/parsers 2015-07-11 12:53:29 -07:00
James Kyle
27cce1446c Add descriptions to transformation/file/options/index 2015-07-11 12:53:28 -07:00
James Kyle
7e64bcd85a Add descriptions to tools/protect 2015-07-11 12:53:28 -07:00
James Kyle
4a851130ee Add descriptions to helpers/parse 2015-07-11 12:53:28 -07:00
James Kyle
6a9b14563e Add descriptions to helpers/object 2015-07-11 12:53:28 -07:00
James Kyle
4f11c6a4be Add descriptions to helpers/normalize-ast 2015-07-11 12:53:28 -07:00
James Kyle
d7a669e96b Add descriptions to helpers/merge 2015-07-11 12:53:28 -07:00
James Kyle
4b6a5f4ea9 Add descriptions to helpers/code-frame 2015-07-11 12:53:28 -07:00
James Kyle
9c60c633d2 Add descriptions to generation/whitespace 2015-07-11 12:53:27 -07:00
James Kyle
3b428e45a3 Add descriptions to generation/source-map 2015-07-11 12:53:27 -07:00
James Kyle
d961e2d291 Add descriptions to generation/position 2015-07-11 12:53:27 -07:00
James Kyle
2d884c282a Add descriptions to generation/index 2015-07-11 12:53:27 -07:00
James Kyle
350a3b664f Add descriptions to generation/buffer 2015-07-11 12:53:27 -07:00
James Kyle
9e4ec19487 Add descriptions to generation/node/whitespace 2015-07-11 12:53:27 -07:00
James Kyle
d613975feb Add descriptions to generation/node/printer 2015-07-11 12:53:27 -07:00
James Kyle
77e9387c5f Add descriptions to generation/node/parenthesis 2015-07-11 12:53:26 -07:00
James Kyle
ac00de44a7 Add descriptions to generation/node/index 2015-07-11 12:53:26 -07:00
James Kyle
8e03a2b720 Add descriptions to generation/generators/types 2015-07-11 12:53:26 -07:00
James Kyle
4e660f7b3e Add descriptions to generation/generators/template-literals 2015-07-11 12:53:26 -07:00
James Kyle
63618f876c Add descriptions to generation/generators/statements 2015-07-11 12:53:26 -07:00
James Kyle
155f3407bc Add descriptions to generation/generators/modules 2015-07-11 12:53:26 -07:00
James Kyle
bf62042fe6 Add descriptions to generation/generators/methods 2015-07-11 12:53:26 -07:00
James Kyle
2a226b3a2b Add descriptions to generation/generators/jsx 2015-07-11 12:53:26 -07:00
James Kyle
f996d6bfa6 Add descriptions to generation/generators/flow 2015-07-11 12:53:25 -07:00
James Kyle
89b1c387a0 Add descriptions to generation/generators/expressions 2015-07-11 12:53:25 -07:00
James Kyle
dfea7368e1 Add descriptions to generation/generators/comprehensions 2015-07-11 12:53:25 -07:00
James Kyle
06867dd52b Add descriptions to generation/generators/classes 2015-07-11 12:53:25 -07:00
James Kyle
3f72a4b200 Add descriptions to generation/generators/base 2015-07-11 12:53:25 -07:00
James Kyle
ee286ed482 Add descriptions to api/node 2015-07-11 12:53:25 -07:00
James Kyle
8604c0c2cd Add descriptions to api/browser 2015-07-11 12:53:25 -07:00
James Kyle
b2476b3603 Add descriptions to api/register/node 2015-07-11 12:53:24 -07:00
James Kyle
c2ebe7f26d Add descriptions to api/register/cache 2015-07-11 12:53:24 -07:00
James Kyle
4809747304 Add placeholders 2015-07-11 12:53:23 -07:00
James Kyle
e572d25640 Add README files to be filled out 2015-07-11 12:43:56 -07:00
James Kyle
07e3d9a8df Add intro inside of src/ directory 2015-07-11 12:43:56 -07:00
Sebastian McKenzie
7763c74563 Merge branch 'master' of github.com:babel/babel 2015-07-11 10:35:57 +01:00
Sebastian McKenzie
e45dc0fbaf Merge pull request #1974 from loganfsmyth/hoist-class-inherits
Hoist class inheritance call so it runs before prototype use.
2015-07-11 09:59:47 +01:00
Sebastian McKenzie
8539182452 Merge pull request #1976 from cpojer/import-typeof
Add support for `import typeof`, fixes #1975
2015-07-11 09:58:49 +01:00
cpojer
18380d2aee Add support for import typeof, fixes #1975 2015-07-11 01:54:25 -07:00
Logan Smyth
19b1032474 Hoist class inheritance call so it runs before prototype use - fixes #1972 2015-07-10 19:51:53 -07:00
Sebastian McKenzie
f7761982cd fix logo url 2015-07-10 16:21:38 +01:00
Sebastian McKenzie
950d3d2280 Merge pull request #1969 from christophehurpeau/patch-1
option help add "separated by comma" for options whitelist, blacklist…
2015-07-10 15:29:36 +01:00
Christophe Hurpeau
12d7b33f62 option help add "separated by comma" for options whitelist, blacklist and optional 2015-07-10 16:29:07 +02:00
Sebastian McKenzie
f9c7d0d095 add validation to plugins 2015-07-10 02:59:50 +01:00
Sebastian McKenzie
efaa0608af removed unused variable 2015-07-09 21:28:53 +01:00
Sebastian McKenzie
b522bfe822 update babel/register to work with new option manager and add filename option type 2015-07-09 21:25:06 +01:00
Sebastian McKenzie
9efb02f60f rewrite options handling to be MUCH more maintainable and less like spaghetti 2015-07-09 21:11:51 +01:00
Sebastian McKenzie
9805c0387f reenable travis node 0.10 testing 2015-07-09 19:17:12 +01:00
Sebastian McKenzie
81019ec76d v5.6.17 2015-07-09 19:04:26 +01:00
Sebastian McKenzie
b0d0adda9b add 5.6.17 changelog 2015-07-09 19:03:32 +01:00
Sebastian McKenzie
d335535f04 Revert "Move into for block"
This reverts commit 1945f849c3.

# Conflicts:
#	src/babel/generation/index.js
2015-07-09 19:01:37 +01:00
Sebastian McKenzie
f738c95c8d Merge branch 'master' into development 2015-07-09 18:22:22 +01:00
Sebastian McKenzie
7fec1c98e5 Merge pull request #1962 from benjamn/development
Update regenerator to v0.8.34, and remove recast and ast-types from package.json.
2015-07-09 18:21:17 +01:00
Sebastian McKenzie
33ae022e4d add ClassProperty handling to t.isReferenced - fixes #1961 2015-07-09 18:19:20 +01:00
Ben Newman
eac9e9b372 Update regenerator to v0.8.34, and remove recast and ast-types.
This version of Regenerator pegs recast to v0.10.18, which pegs ast-types
to v0.8.2, which contains special support for all Babel AST types:
https://github.com/benjamn/ast-types/blob/master/def/babel.js

This version of Regenerator also exports the ast-types module object that
it uses (as regenerator.types), so that consumers like Babel can refer to
the exact same copy of ast-types when necessary, rather than requiring
ast-types themselves. Why that was risky: #1958.
2015-07-09 13:12:58 -04:00
Sebastian McKenzie
eb6b38d3a8 add 5.6.13-5.6.16 changelogs 2015-07-09 16:30:45 +01:00
Sebastian McKenzie
8111ab28d7 v5.6.16 2015-07-09 16:13:06 +01:00
Sebastian McKenzie
ed25845152 remove accidental stackTraceLimit assignment 2015-07-09 16:12:06 +01:00
Sebastian McKenzie
457638e904 add type comments to t.valueToNode 2015-07-09 16:11:57 +01:00
Sebastian McKenzie
2e5255dbf5 peg recast version - fixes #1958 2015-07-09 16:11:46 +01:00
Brian Donovan
86095d9dac Merge pull request #1951 from zbraniecki/traverse-in-plugins-typo
Fix a typo in plugin-manager import of traverse
2015-07-08 13:13:19 -07:00
Zibi Braniecki
02dd785d02 Fix a typo in plugin-manager import of traverse 2015-07-08 13:06:59 -07:00
Sebastian McKenzie
205fab2ed8 split up badges 2015-07-08 14:58:31 +01:00
Sebastian McKenzie
d01b26951b channel -> community 2015-07-08 14:45:56 +01:00
Sebastian McKenzie
fc15c91b2a replace descriptor.writable assignment in createDecoraredObject helper - fixes #1949 2015-07-08 14:45:50 +01:00
Sebastian McKenzie
421b01865f add Generated/User/Directive virtual node types 2015-07-08 11:35:56 +01:00
Sebastian McKenzie
af7510adec fix some bugs in PathHoister - fixes babel-plugins/babel-plugin-react-constant-elements#1
- Don't hoist constant elements to the same function as their original paths function parent.
 - Push each violation paths ancestry to the breakOnScopePaths collection to avoid constant hoisting to nested paths.
2015-07-08 11:35:34 +01:00
Sebastian McKenzie
ec7c40fbf6 add quiet option to CLI - fixes #1931 2015-07-07 11:26:45 +01:00
Sebastian McKenzie
4a36a9fb31 check for functions in util.shouldIgnore - closes #1865, closes #1859 2015-07-07 11:23:31 +01:00
Sebastian McKenzie
4d25b0d96a Merge branch 'master' of github.com:babel/babel 2015-07-07 11:12:42 +01:00
Sebastian McKenzie
babc9c90b4 fix tail call recursion on functions with less arguments than parameters - fixes #1938 2015-07-07 11:11:58 +01:00
Sebastian McKenzie
288293ca11 Merge pull request #1936 from loganfsmyth/system-module-hoisting
Only special-case for..on declaration hoisting - fixes #1929
2015-07-07 10:54:26 +01:00
Sebastian McKenzie
a262e99abd strip flow directives in flow transformer - fixes #1934 2015-07-07 10:52:43 +01:00
Logan Smyth
b518394a3f Only special-case for..on/of declaration hoisting - fixes #1929 2015-07-06 21:06:11 -07:00
Sebastian McKenzie
337c51df5c fixes out of bounds check to default parameter template - #1845 - cc @RReverser 2015-07-06 21:25:33 +01:00
Sebastian McKenzie
0509fb148f add out of bounds check to default parameter template - addresses #1845 - cc @RReverser 2015-07-06 20:12:10 +01:00
Sebastian McKenzie
bb5f1120b7 Merge branch 'master' of github.com:babel/babel 2015-07-05 21:41:58 +01:00
Sebastian McKenzie
38d46012a7 Merge pull request #1926 from loganfsmyth/systemjs-modules-export
Optimize export-from in System.register - fixes #1722
2015-07-05 21:39:30 +01:00
Logan Smyth
cdb8e3aefa Optimize export-from in System.register - fixes #1722 2015-07-05 11:40:33 -07:00
Sebastian McKenzie
4a84cd785a Merge pull request #1915 from loganfsmyth/destructuring-default-hoisting
Ensure _blockHoist is set on function destructuring defaults
2015-07-05 19:24:01 +01:00
Logan Smyth
f47d17345c Ensure _blockHoist is set on function destructuring defaults - fixes #1908 2015-07-05 09:10:09 -07:00
Sebastian McKenzie
8746ca8d31 add Statement virtual type 2015-07-05 01:23:37 +02:00
Sebastian McKenzie
76e954bc36 add reference to issue #1920 2015-07-05 01:23:32 +02:00
Sebastian McKenzie
64903d0dcf Merge branch 'master' of github.com:babel/babel 2015-07-04 23:33:33 +02:00
Sebastian McKenzie
1fd0b1f741 delay this assignment when referencing this inside an arrow function pre-bare super in derived class constructors - fixes #1920 2015-07-04 23:32:11 +02:00
Sebastian McKenzie
cda2bfce38 enable do expression tests 2015-07-04 21:51:57 +02:00
Sebastian McKenzie
0e4bb5ee3f clean up verifyConstructor classes visitor and disallow super.* before super() in derived class constructors - fixes #1921 2015-07-04 21:38:22 +02:00
Sebastian McKenzie
e9793b1f16 Merge pull request #1916 from conradz/inline-single-child
Handle single child when using React inlining
2015-07-04 11:23:15 +02:00
Conrad Zimmerman
224db29c05 Handle single child when using React inlining
Changes optimisation.react.inlineElements to handle a single child as the
value of the `children` property instead of wrapping it with an array.
This matches the behavior of `React.createElement`.
2015-07-03 18:55:38 -04:00
Sebastian McKenzie
bd1bd38556 add undeclared type variable 2015-07-03 00:14:40 +02:00
Sebastian McKenzie
1f39114126 Merge branch 'master' into development 2015-07-03 00:07:53 +02:00
Sebastian McKenzie
4c0b8599f1 add optional context parameter to NodePath#get 2015-07-03 00:07:37 +02:00
Sebastian McKenzie
848909620c add more comments to path methods 2015-07-03 00:07:23 +02:00
Sebastian McKenzie
c40215497d Merge pull request #1900 from samccone/sjs/opt2
rework findCommonStringDelimiter
2015-07-02 23:54:52 +02:00
Sebastian McKenzie
6450f5263e Merge pull request #1901 from loganfsmyth/constructor-scope-fix
Properly regenerate scope for replaced nodes - fixes #1773
2015-07-02 23:54:28 +02:00
Sam Saccone
74c59c94ce 2015-07-02 16:57:12 -04:00
Logan Smyth
3f38a83600 Properly regenerate scope for replaced nodes - fixes #1773 2015-07-01 22:06:05 -07:00
Sam Saccone
1945f849c3 Move into for block
https://www.youtube.com/watch?v=FHDwRECFL8M
2015-07-01 20:36:24 -07:00
Sam Saccone
5b0b7ba226 🍴 Switch to ternary for return
https://www.youtube.com/watch?v=XAbY2cmEsS0
2015-07-01 20:36:17 -07:00
James Kyle
42de6bc716 Merge pull request #1894 from samccone/patch-4
🐳
2015-07-02 01:06:50 +01:00
James Kyle
fb66f347b9 Merge pull request #1895 from samccone/patch-5
remove 💀 comment lines
2015-07-02 01:05:51 +01:00
Brian Donovan
5e28bd4e68 Merge pull request #1893 from samccone/patch-1
🍕 Fix grammatical issue
2015-07-01 16:16:20 -07:00
Sam Saccone
9869566963 remove 💀 comment lines
Added in 
3561efdb86

if this is a style thing you want to keep around then my all means close away.
2015-07-01 15:59:05 -07:00
Sam Saccone
4a27b10e8a 👶 2015-07-01 15:56:11 -07:00
Sam Saccone
c3b5ed5b3d 💄 Fix grammatical issue 2015-07-01 15:51:56 -07:00
Sebastian McKenzie
afa4871a08 Merge pull request #1892 from samccone/patch-1
📝 better english
2015-07-02 00:48:57 +02:00
Sam Saccone
70c739250b 📝 better english 2015-07-01 15:48:00 -07:00
Sebastian McKenzie
722e706a8c Merge pull request #1891 from samccone/patch-1
️  this that this
2015-07-02 00:42:05 +02:00
Sam Saccone
f3973c8397 📝 clarify how it inherits this 2015-07-01 15:41:15 -07:00
Sebastian McKenzie
47c3792d34 Merge pull request #1890 from samccone/patch-1
️  Add link to ESTree
2015-07-02 00:39:23 +02:00
Sam Saccone
456accb4b3 📝 Add link to ESTree 2015-07-01 15:37:20 -07:00
Sebastian McKenzie
72771ed439 update escape regex test to use new lodash result 2015-06-30 23:56:47 +01:00
Sebastian McKenzie
7cb7ea4248 Merge pull request #1884 from arthurvr/resolve
Add `resolve` to `CONTRIBUTING.md`
2015-06-30 23:39:33 +01:00
Arthur Verschaeve
301df15921 Add resolve to CONTRIBUTING.md
Introduced in aaf4cbf06f
2015-06-30 23:56:30 +02:00
Sebastian McKenzie
15535406bd Merge pull request #1883 from arthurvr/patch-1
Remove `user-home` from `CONTRIBUTING.md`
2015-06-30 22:43:42 +01:00
Arthur Verschaeve
63f53e3773 Remove user-home from CONTRIBUTING.md
In favor of `user-or-tmp`

Ref 90b8826e73
2015-06-30 23:40:24 +02:00
Brian Donovan
03a979a6bd Merge pull request #1867 from arthurvr/deps
Add `path-exists` to `CONTRIBUTING.md`
2015-06-30 14:31:24 -07:00
Sebastian McKenzie
910622e66e fix linting errors 2015-06-30 15:17:26 +01:00
Sebastian McKenzie
c5a8702021 clean up derived classes, fixes super path referencing user constructor instead of our new function - #1877 2015-06-30 14:55:11 +01:00
Sebastian McKenzie
336c65fe2c restructure classes transformer, fix class name inference - #1877 2015-06-30 14:49:04 +01:00
Sebastian McKenzie
092d98fb27 add constructor to body in order that it was supplied in - fixes #1877 2015-06-30 10:10:52 +01:00
Sebastian McKenzie
e55ce575cd move up template literal simplification logic - fixes #1874 2015-06-29 23:36:06 +01:00
Sebastian McKenzie
d63ae5fce8 remove loose console.log 2015-06-29 22:59:23 +01:00
Sebastian McKenzie
541309c4bb fix collisions for getBindingIdentifiers 2015-06-29 22:04:17 +01:00
Sebastian McKenzie
2d289150d1 Merge pull request #1868 from benjamn/patch-2
Upgrade Regenerator to 0.8.32.
2015-06-29 20:47:05 +01:00
Ben Newman
b9f6169ed4 Upgrade Regenerator to 0.8.32.
This includes some major runtime performance improvements:
https://github.com/facebook/regenerator/pull/207
https://github.com/facebook/regenerator/pull/208

And also some bug fixes relating to async generator functions:
https://github.com/facebook/regenerator/commit/29d81b6929
https://github.com/facebook/regenerator/commit/7d2a052ddb
https://github.com/facebook/regenerator/commit/5b9dd1086d
2015-06-29 10:43:54 -04:00
Arthur Verschaeve
ce372281cd Add path-exists to CONTRIBUTING.md 2015-06-29 12:35:37 +02:00
Sebastian McKenzie
0044100e3d perform function name inference on functions in properties before they're properly visited - fixes #1860 2015-06-29 00:20:47 +01:00
Sebastian McKenzie
81edc4c6ab add make comment-issues skeleton 2015-06-28 00:59:24 +01:00
Sebastian McKenzie
3b1a9a0adb trim eval code in babel-node 2015-06-28 00:59:12 +01:00
Sebastian McKenzie
8ab90aacd3 add babel-core version to babel-cli version - closes #1861 2015-06-28 00:59:05 +01:00
Sebastian McKenzie
a1a46882fd v5.6.15 2015-06-27 00:07:24 +01:00
Sebastian McKenzie
12b4e6db40 v5.6.13 2015-06-27 00:06:40 +01:00
Sebastian McKenzie
7f06bb79c0 attempt to fix master fetching for automatic travis merge 2015-06-26 23:58:57 +01:00
Sebastian McKenzie
34218afdae clean up build website script 2015-06-26 23:41:19 +01:00
Sebastian McKenzie
b94118db5e output debug current branch/commit info 2015-06-26 23:32:45 +01:00
Sebastian McKenzie
54819b94e9 skip flow types when finding rest parameter references 2015-06-26 23:29:09 +01:00
Sebastian McKenzie
50ca6b1018 clean up inType tracking in flow parser plugin 2015-06-26 23:26:32 +01:00
Sebastian McKenzie
2d195c4843 add logging for publish cli 2015-06-26 20:30:24 +01:00
Sebastian McKenzie
2f0d0c94ef try alternate merge parameter 2015-06-26 20:30:16 +01:00
Sebastian McKenzie
5e3ea5b6e7 add update-ref master to merge-development-with-master script 2015-06-26 19:48:48 +01:00
Sebastian McKenzie
95128f98bc Merge branch 'master' into development 2015-06-26 16:59:49 +01:00
Sebastian McKenzie
c4d1d58167 +x 2015-06-26 16:59:43 +01:00
Sebastian McKenzie
7da1d9fadd wrap TRAVIS_COMMIT variable in curlies for consistency 2015-06-26 16:48:52 +01:00
Sebastian McKenzie
6ab57fd367 rebuild website on new version, automatically merge development branch with master - closes #1854, closes #1849 2015-06-26 16:46:52 +01:00
Sebastian McKenzie
d4edce6559 only publish babel-cli when the directory has had changes since the last version - fixes #1848 2015-06-26 16:21:37 +01:00
Sebastian McKenzie
9c8cb33a09 remove babel-core from babel-cli packag.ejson 2015-06-26 16:19:22 +01:00
Sebastian McKenzie
a2fb70bae3 fix deprecated return from visitor method api 2015-06-26 15:16:31 +01:00
Sebastian McKenzie
273a81fe1f fix up babel-eslint dependency 2015-06-26 15:15:19 +01:00
Sebastian McKenzie
72a0ac5e02 v5.6.14 2015-06-26 15:09:03 +01:00
Sebastian McKenzie
c5ace10536 update babel-eslint 2015-06-26 15:07:56 +01:00
Sebastian McKenzie
b833614b87 update travis with new npm api key 2015-06-26 14:10:05 +01:00
Sebastian McKenzie
ae067a08b7 switch to mocha dot reporter 2015-06-26 13:23:15 +01:00
Sebastian McKenzie
f56337541f change readme tagline 2015-06-26 13:23:08 +01:00
Sebastian McKenzie
1fe8447a1a add test release explanation to changelog 2015-06-26 12:25:40 +01:00
Sebastian McKenzie
13bbfa041d v5.6.13 2015-06-26 12:25:00 +01:00
Sebastian McKenzie
c43bbb9bf6 use npm to publis new version - fixes #1847 2015-06-26 12:24:01 +01:00
Sebastian McKenzie
1bca59a921 clean up readme - add back badges 2015-06-26 11:54:51 +01:00
Sebastian McKenzie
f80fdf7359 5.6.12 2015-06-26 11:41:34 +01:00
Sebastian McKenzie
aefd69d31e v5.6.12 2015-06-26 11:40:40 +01:00
Sebastian McKenzie
e328031b19 add 5.6.12 changelog 2015-06-26 11:39:47 +01:00
Sebastian McKenzie
571b6a4cd7 check parent node alongside path in shadow functions 2015-06-26 11:39:10 +01:00
Sebastian McKenzie
41cf942391 clean up shadow functions findParent logic - fixes #1846 2015-06-26 11:34:13 +01:00
Sebastian McKenzie
98f28b8e89 5.6.11 2015-06-26 02:40:00 +01:00
Sebastian McKenzie
8f88afc037 v5.6.11 2015-06-26 02:39:04 +01:00
Sebastian McKenzie
6359675a4f make shadowed function findParent target finder more reliable 2015-06-26 02:38:14 +01:00
Sebastian McKenzie
a265c3f25c add missing semi 2015-06-26 02:25:46 +01:00
Sebastian McKenzie
29eb99ee93 rejigger shadowd function findParent logic 2015-06-26 02:24:42 +01:00
Sebastian McKenzie
0c5c1ff989 remove unused variable 2015-06-26 02:22:10 +01:00
Sebastian McKenzie
499951123a add 5.6.11 changelog 2015-06-26 02:21:34 +01:00
Sebastian McKenzie
c0fd4c1f9e merge es6.parameters.rest and es6.parameters.default transformers
This is necessary in order to retain correct function arity and to have
completely correct semantics. Sometimes features are tied together so much
that they would require so much desugaring to retain the correct semantics
that they'd be equivalent to... the normal transpiled output.
2015-06-26 02:20:16 +01:00
Sebastian McKenzie
579e6fecee upgrade internal dev babel dependency to 5.6.10 2015-06-26 02:05:43 +01:00
Sebastian McKenzie
bb3665a3b6 5.6.10 2015-06-26 01:12:50 +01:00
Sebastian McKenzie
e6de688234 v5.6.10 2015-06-26 01:11:32 +01:00
Sebastian McKenzie
4c233e88ff add use strict 2015-06-26 01:09:47 +01:00
Sebastian McKenzie
ae2ba0b5a3 add 5.6.10 changelog 2015-06-26 01:08:36 +01:00
Sebastian McKenzie
e34d950793 require babel-core at the top of the file 2015-06-26 01:07:54 +01:00
Sebastian McKenzie
e4083fbbd7 add support for trailing commas in arrow function parameter lists - fixes #1841 2015-06-26 00:37:33 +01:00
Sebastian McKenzie
59ed7977ef 5.6.9 2015-06-25 23:59:12 +01:00
Sebastian McKenzie
dc441e9a8f v5.6.9 2015-06-25 23:58:07 +01:00
Sebastian McKenzie
2e21795f57 add index.js to fix internal api error 2015-06-25 23:57:16 +01:00
Sebastian McKenzie
5c988f7fc8 5.6.8 2015-06-25 23:35:34 +01:00
Sebastian McKenzie
493826973e v5.6.8 2015-06-25 23:34:30 +01:00
Sebastian McKenzie
1acc71aa4e fix api module id relative tests 2015-06-25 23:32:43 +01:00
Sebastian McKenzie
bbab5f72ec add 5.6.8 changelog 2015-06-25 23:31:07 +01:00
Sebastian McKenzie
58ff9e387a remove root internals protect 2015-06-25 23:30:43 +01:00
Sebastian McKenzie
5a0d099984 don't add protect to register either 2015-06-25 23:28:27 +01:00
Sebastian McKenzie
05c95e04f7 don't add protect to polyfill 2015-06-25 23:26:24 +01:00
Sebastian McKenzie
88430b4be2 forgive hotlinking to polyfill 2015-06-25 23:24:45 +01:00
Sebastian McKenzie
19adcfae4d add type import 2015-06-25 23:22:42 +01:00
Sebastian McKenzie
7c4fe984ce start linting babel-cli/bin - fixes #1836 2015-06-25 23:22:38 +01:00
Sebastian McKenzie
4476e8311c use relative tools/protect.js filenames 2015-06-25 23:20:18 +01:00
Sebastian McKenzie
2a3142273d add path-exists dependency to babel-cli 2015-06-25 23:20:08 +01:00
Sebastian McKenzie
bbcb889a49 Merge branch 'master' of github.com:babel/babel 2015-06-25 23:04:24 +01:00
Sebastian McKenzie
c87f85815b used filter rather than setting init properties to null in properties.computed transformer - fixes #1831 2015-06-25 23:04:17 +01:00
Sebastian McKenzie
48d0df17d0 Merge pull request #1832 from Mark-Simulacrum/path-exists
Use path-exists module instead of fs.exists.
2015-06-25 22:57:27 +01:00
Sebastian McKenzie
01b243347f add NodePath#baseTypeStrictlyMatches method 2015-06-25 22:55:46 +01:00
Sebastian McKenzie
45a5cbf72f use capitalised builder method 2015-06-25 22:55:35 +01:00
Sebastian McKenzie
05efae1c58 complete t.createTypeAnnotationBasedOnTypeof 2015-06-25 22:55:25 +01:00
Sebastian McKenzie
c08fff4b44 add node builder for normal AST node type 2015-06-25 22:55:12 +01:00
Sebastian McKenzie
13e910ea83 force spaces for binary expressions - fixes #1835 2015-06-25 22:55:00 +01:00
Mark-Simulacrum
b308602098 Use path-exists instead of fs.exists.
fs.exists is being deprecated, see: https://github.com/nodejs/io.js/issues/103.
2015-06-25 12:39:39 -06:00
Sebastian McKenzie
560a044d8f Merge pull request #1821 from kpdecker/destructure-performance
Avoid deopt in iterable destructure template
2015-06-25 15:23:53 +01:00
Sebastian McKenzie
619fbe4c3b Merge pull request #1830 from kpdecker/avoid-define-property
Avoid defineProperty when not needed
2015-06-25 15:23:39 +01:00
kpdecker
1d83ad6cce Avoid defineProperty when not needed
This lets us use the fast path for most object literal assignments and then utilizes the defineProperty path when there is a chance that we could hit the setter issue described in #357.

10x performance boosts seen for the six-speed test case, going from 200k operations/sec to 2M ops/sec.
2015-06-25 09:22:03 -05:00
kpdecker
5353ccd773 Move slice iterator helper out of primary call
Avoids overhead of instantiating the helper on each call to the slice to array helper.
2015-06-25 09:18:12 -05:00
Sebastian McKenzie
a8e23d2eb9 ignore templates folder in protect plugin 2015-06-25 14:33:38 +01:00
Sebastian McKenzie
95d830fde0 don't output comma separator for decorator list and output Property decorators - fixes #1811 2015-06-25 12:23:45 +01:00
Sebastian McKenzie
c8a5d7d970 Merge branch 'arthurvr-dep' 2015-06-25 12:12:21 +01:00
Sebastian McKenzie
43481eb2cc Merge branch 'dep' of https://github.com/arthurvr/babel into arthurvr-dep 2015-06-25 12:12:19 +01:00
Sebastian McKenzie
b8bb665691 Merge branch 'arthurvr-tests' 2015-06-25 12:12:05 +01:00
Sebastian McKenzie
e6846b2730 Merge branch 'tests' of https://github.com/arthurvr/babel into arthurvr-tests 2015-06-25 12:12:05 +01:00
Sebastian McKenzie
31c1286a3c protect internal files from hotlinking 2015-06-25 12:10:22 +01:00
Arthur Verschaeve
489f9e92b5 Add tests for util.resolve 2015-06-25 10:10:56 +02:00
Arthur Verschaeve
073809efac Remove leven dependency 2015-06-25 09:37:27 +02:00
Brian Donovan
c9b8e2f3ce Merge pull request #1822 from azu/patch-1
Add missing asterisk in CHANGELOG
2015-06-24 21:23:51 -07:00
azu
c6cb871355 Add missing asterisk in CHANGELOG 2015-06-25 13:17:23 +09:00
kpdecker
1b0e5b3ed1 Avoid deopt in iterable destructure template
The try/catch was forcing deoptimization under most engines. This roughly doubles throughput under V8 and 7x increases were seen under Firefox.

Performance numbers based on https://github.com/kpdecker/six-speed/tree/master/tests/destructuring
2015-06-24 22:42:13 -05:00
Sebastian McKenzie
0f70c76312 5.6.7 2015-06-25 04:18:49 +01:00
Sebastian McKenzie
e8c672bf4f v5.6.7 2015-06-25 04:17:52 +01:00
Sebastian McKenzie
7083ac61ff remove test.js 2015-06-25 04:16:06 +01:00
Sebastian McKenzie
d256809120 Merge branch 'master' of github.com:babel/babel
# Conflicts:
#	src/babel/traversal/path/replacement.js
2015-06-25 04:12:13 +01:00
Sebastian McKenzie
26a19f82d2 add 5.6.7 changelog 2015-06-25 04:11:40 +01:00
Sebastian McKenzie
128d3b5c91 add missing computed loose test - ref #1820 2015-06-25 04:11:32 +01:00
Sebastian McKenzie
c1a080d0ca supress duplicate deprecation messages 2015-06-25 04:11:13 +01:00
Sebastian McKenzie
0b1ce6c9a4 always coerce leading computed property initialisers into the init object - fixes #1820 2015-06-25 04:10:56 +01:00
Sebastian McKenzie
a6f04055c0 fix block scoping transformer 2015-06-25 04:10:32 +01:00
Sebastian McKenzie
c3219e8b88 deprecate returning source strings from visitor methods 2015-06-25 03:51:25 +01:00
Sebastian McKenzie
a35c863341 deprecate returning source strings from visitor methods 2015-06-25 03:50:10 +01:00
Sebastian McKenzie
6f862a4c45 actually push for left declaration to the returned block scoping body - fixes #1819 2015-06-25 03:48:29 +01:00
Sebastian McKenzie
cf38210fd2 5.6.6 2015-06-24 23:28:44 +01:00
Sebastian McKenzie
5c9d564339 v5.6.6 2015-06-24 23:27:44 +01:00
Sebastian McKenzie
031a61515b add labels, and inX properties to lookahead getState 2015-06-24 23:26:59 +01:00
Sebastian McKenzie
d3884fd53b add inType assignment in flow parse declare method 2015-06-24 23:26:48 +01:00
Sebastian McKenzie
c6eef3080e add 5.6.6 changelog 2015-06-24 23:26:35 +01:00
Sebastian McKenzie
25be0a974d fixing linting errors 2015-06-24 23:20:03 +01:00
Sebastian McKenzie
7ccd135e83 fix isKeyword flow overload 2015-06-24 23:18:21 +01:00
Sebastian McKenzie
4fc1bbeb60 acorn resync 2015-06-24 23:15:27 +01:00
Sebastian McKenzie
32a4d7172b optimise generator for compact mode 2015-06-24 23:15:22 +01:00
Sebastian McKenzie
aa25903c05 parse void as an identifier when inside a type annotation to avoid setting void keyword token - cc @DmitrySoshnikov 2015-06-24 23:15:00 +01:00
Sebastian McKenzie
23ec1a455e upgrade babel-plugin-dead-code-elimination 2015-06-24 23:14:08 +01:00
Sebastian McKenzie
e6ac2d049b add 5.6.5 changelog 2015-06-24 13:50:53 +01:00
Sebastian McKenzie
084ae31816 5.6.5 2015-06-24 13:48:43 +01:00
Sebastian McKenzie
8e530afd78 v5.6.5 2015-06-24 13:47:54 +01:00
Sebastian McKenzie
6c66a82b37 Merge branch 'master' of github.com:babel/babel 2015-06-24 13:46:05 +01:00
Sebastian McKenzie
737abca3a9 use this.space() instead of manually pushing 2015-06-24 13:45:56 +01:00
Sebastian McKenzie
9db43ca7a9 clean up t.isReferenced 2015-06-24 13:45:48 +01:00
Sebastian McKenzie
25b0683316 add Path#couldBeBaseType 2015-06-24 13:45:32 +01:00
Sebastian McKenzie
a096f6b1c5 fix noOptimise state being incorrect when recursing into multiple nested functions - fixes #1815 2015-06-24 13:45:14 +01:00
Sebastian McKenzie
e41ab2ab0c Merge pull request #1807 from benjamn/patch-1
Update Regenerator dependency to 0.8.31.
2015-06-23 17:07:25 +01:00
Ben Newman
6a6764fa7b Update Regenerator dependency to 0.8.31.
Fixes #1805.
2015-06-23 12:06:48 -04:00
Sebastian McKenzie
a2358d6863 5.6.4 2015-06-22 20:39:14 +01:00
Sebastian McKenzie
612ef79d35 v5.6.4 2015-06-22 20:38:12 +01:00
Sebastian McKenzie
2dfa6ddf36 add 5.6.4 changelog 2015-06-22 20:37:00 +01:00
Sebastian McKenzie
2910d4f82c fix Program can only be replaced with another Program error 2015-06-22 20:36:34 +01:00
Sebastian McKenzie
4b6c954f5e add ParenthesizedExpression node type for plugins to generate 2015-06-22 20:36:12 +01:00
Sebastian McKenzie
b7e23e3410 5.6.3 2015-06-22 11:57:53 +01:00
Sebastian McKenzie
a19f10e124 v5.6.3 2015-06-22 11:56:46 +01:00
Sebastian McKenzie
8e1f134635 fix rest parameter array allocation loop being incorrectly aliased - fixes #1800 2015-06-22 11:54:57 +01:00
Sebastian McKenzie
aa151016f5 5.6.2 2015-06-22 00:10:56 +01:00
Sebastian McKenzie
ce3c6289a2 v5.6.2 2015-06-22 00:08:52 +01:00
Sebastian McKenzie
0364519869 remove unused import 2015-06-22 00:06:43 +01:00
Sebastian McKenzie
58cda35831 log spread element rest parameter as a candidate instead of replacing it in place - fixes #1796 2015-06-22 00:06:03 +01:00
Sebastian McKenzie
ebaa06f4a2 add ensureBlock path method 2015-06-21 23:59:14 +01:00
Sebastian McKenzie
4b0f624fb3 turn method literal keys into assignments in loose mode - fixes #1797 2015-06-21 23:59:06 +01:00
Sebastian McKenzie
aa0f3ac5d0 5.6.1 2015-06-21 00:07:07 +01:00
Sebastian McKenzie
725906a7dc v5.6.1 2015-06-21 00:05:13 +01:00
Sebastian McKenzie
13d5c94b8b update transformation tests 2015-06-21 00:03:29 +01:00
Sebastian McKenzie
85308a1e8c fix super spread in loose mode 2015-06-21 00:01:19 +01:00
Sebastian McKenzie
83bcaba1a5 downgrade to babel 5.5.7 2015-06-21 00:01:11 +01:00
Sebastian McKenzie
185648cb2c 5.6.0 2015-06-20 23:44:46 +01:00
Sebastian McKenzie
be355fc1c6 fix build-runtime script 2015-06-20 23:37:46 +01:00
Sebastian McKenzie
7795e11d58 v5.6.0 2015-06-20 23:35:51 +01:00
Sebastian McKenzie
8f74e8068c fix generation tests to reflect acorn update 2015-06-20 23:35:02 +01:00
Sebastian McKenzie
4f08a77230 resync with upstream acorn 2015-06-20 23:28:49 +01:00
Sebastian McKenzie
4ac33d62af move spec.functionName transformer to builtin-basic - fixes #1743 2015-06-20 22:51:20 +01:00
Sebastian McKenzie
2710a914e8 add noop transform method to IgnoreFormatter 2015-06-20 22:48:45 +01:00
Sebastian McKenzie
8934e7f9da Merge branch 'master' of github.com:babel/babel 2015-06-20 22:48:00 +01:00
Sebastian McKenzie
b4f18e05fa Merge pull request #1776 from zertosh/matches-pattern-this
matchPattern fixes and "this" handling
2015-06-20 22:47:52 +01:00
Sebastian McKenzie
c07540a2c4 extend module IgnoreFormatter from DefaultFormatter - fixes #1763, closes #1771 2015-06-20 22:47:32 +01:00
Sebastian McKenzie
c409f63bbe Merge pull request #1772 from arthurvr/booleanify-tests
Add tests for util.booleanify
2015-06-20 22:22:08 +01:00
Sebastian McKenzie
d3c30b669f update babel-plugin-runtime 2015-06-20 22:21:44 +01:00
Sebastian McKenzie
d10856d16c don't terminate CLI when watching files fail compilation on init - fixes #1678 2015-06-20 22:14:21 +01:00
Sebastian McKenzie
fb08a519c8 register labels as bindings - fixes #1747 2015-06-20 22:10:29 +01:00
Sebastian McKenzie
6a8ecf2507 add uniq to filenames in babel-cli - fixes #1731 2015-06-20 22:04:33 +01:00
Sebastian McKenzie
100317e0c8 split react displayName addition into a plugin - fixes #1761 2015-06-20 22:01:40 +01:00
Sebastian McKenzie
a32f744341 disable module import receiver when in loose mode - fixes #1788 2015-06-20 21:49:31 +01:00
Sebastian McKenzie
c4feff3cb7 add more whitespace 2015-06-20 21:49:01 +01:00
Sebastian McKenzie
498297ce6b check for invalid binding identifiers when generating inferred method names - fixes #1794 2015-06-20 21:48:42 +01:00
Sebastian McKenzie
2412c1d502 remove bluebird 2015-06-20 21:48:18 +01:00
Sebastian McKenzie
d92e1a4fb8 Merge pull request #1793 from lydell/patch-1
Update to js-tokens@1.0.1
2015-06-20 13:28:27 +01:00
Simon Lydell
1d0d050413 Update to js-tokens@1.0.1 2015-06-20 09:03:26 +02:00
Sebastian McKenzie
a607ac0077 Merge pull request #1786 from callumacrae/update-regenerator
Update regenerator
2015-06-18 17:57:43 +01:00
Callum Macrae
41f5e7c077 removed ^ from regenerator 2015-06-18 17:57:04 +01:00
Callum Macrae
99604362ed update regenerator 2015-06-18 17:52:16 +01:00
Sebastian McKenzie
2c8e374eaf add back non-es5 number guard in literal code gen 2015-06-17 22:56:08 +01:00
Sebastian McKenzie
238c68f829 fix member expression generation on object integers 2015-06-17 22:54:45 +01:00
Ingvar Stepanyan
09b334ad21 Add guard against non-ES5 integer literals. 2015-06-17 21:11:20 +03:00
Sebastian McKenzie
d647ede94b fix up raw number literal 2015-06-17 17:58:03 +01:00
Sebastian McKenzie
6386b60b9a add comments to types generator 2015-06-17 16:53:23 +01:00
Sebastian McKenzie
25749a9933 clear properties to undefined in traverse.removeProperties 2015-06-17 16:53:08 +01:00
Ingvar Stepanyan
fd4c0dae95 Generate original number representation when value was not changed. 2015-06-17 18:20:35 +03:00
Andres Suarez
80d362c534 fix matchesPattern with deep member expressions 2015-06-16 23:37:32 -04:00
Andres Suarez
59820b9a84 matchesPattern recognizes "this" 2015-06-16 22:48:50 -04:00
Sebastian McKenzie
f6ff366edf add getEarliestCommonAncestorFrom jsdoc description 2015-06-17 02:40:15 +01:00
Sebastian McKenzie
c7cac7aaba add deply nested smart insertion of rest parameter allocation 2015-06-17 02:34:42 +01:00
Sebastian McKenzie
0647d374a3 add more comments 2015-06-17 02:09:38 +01:00
Sebastian McKenzie
25c2816a85 fix ancestry index loopup in Path#getEarliestCommonAncestorFrom 2015-06-17 02:07:35 +01:00
Sebastian McKenzie
b57a80ecae optimise rest parameters in spread element position and allocate rest array at the earliest common ancestor of all references - fixes #1768 2015-06-17 01:57:14 +01:00
Sebastian McKenzie
574d47a571 finish removal of esquery 2015-06-17 01:56:01 +01:00
Sebastian McKenzie
7c5d2b19b7 remove esquery 2015-06-17 01:38:49 +01:00
Arthur Verschaeve
c7669f44c1 Add tests for util.booleanify 2015-06-16 20:18:33 +02:00
Sebastian McKenzie
0ed5c5f480 add check for JSXMemberExpression to t.isReferenced 2015-06-16 02:29:59 +01:00
Sebastian McKenzie
94c34e0132 throw error when attemping to replace a Program root node with another node not of type Program - closes #1762 2015-06-16 01:53:53 +01:00
Sebastian McKenzie
92c4bbd003 remove unused import 2015-06-16 00:43:41 +01:00
Sebastian McKenzie
ec8e840841 upgrade babel-plugin-undeclared-variables-check 2015-06-16 00:42:30 +01:00
Sebastian McKenzie
1c3c64c12c add modulesDuplicateDeclarations message 2015-06-16 00:42:21 +01:00
Sebastian McKenzie
cae80d6e9b add scope to addImport importSpecifier call 2015-06-16 00:42:13 +01:00
Sebastian McKenzie
aaf29ddd82 move validation.undeclaredVariableCheck up 2015-06-16 00:42:03 +01:00
Sebastian McKenzie
fb485567b9 support module live bindings in arbitary positions not in Program statement position - fixes #1760 2015-06-16 00:41:53 +01:00
Sebastian McKenzie
050bcec617 add messages property to plugin context and add --copy-files flag to babel-plugin build 2015-06-15 18:55:03 +01:00
Sebastian McKenzie
6231015557 fix spelling mistake in CONTRIBUTING 2015-06-15 18:54:23 +01:00
Sebastian McKenzie
822eb47ee7 move more transformers into plugins 2015-06-15 18:54:14 +01:00
Sebastian McKenzie
91161ae9a1 Merge pull request #1758 from pygy/master
Add tests for IIFEs as default exports.
2015-06-15 18:36:27 +01:00
Pierre-Yves Gerardy
4c1b4b6490 Add tests for IIFEs as default exports. 2015-06-15 19:28:17 +02:00
Sebastian McKenzie
e792256087 add parse and traverse to plugin babel context 2015-06-15 16:36:56 +01:00
Sebastian McKenzie
19ad22f6e8 update tests to reflect new plugin api 2015-06-15 16:36:45 +01:00
Sebastian McKenzie
01818a50fa fix up babel-plugin CLI 2015-06-15 16:36:34 +01:00
Sebastian McKenzie
3247851019 yank out more transformers and put them into plugins 2015-06-15 16:35:41 +01:00
Sebastian McKenzie
939c00d33c Merge branch 'master' of github.com:babel/babel 2015-06-15 15:18:35 +01:00
Sebastian McKenzie
8b096ac705 start movement of core into plugins 2015-06-15 15:17:04 +01:00
Sebastian McKenzie
30c4a0cf06 Merge pull request #1726 from tikotzky/fix-require-hook-under-istanbul
Fix require hook under istanbul
2015-06-15 11:09:41 +01:00
Sebastian McKenzie
e08d400b36 Merge pull request #1733 from hzoo/i-1732
remove empty strings from beginning of template - fixes #1732
2015-06-15 10:46:28 +01:00
Sebastian McKenzie
7e080aa9d2 Merge pull request #1753 from loganfsmyth/optimize-call
Optimize NodePath#call a bit
2015-06-15 10:46:10 +01:00
Sebastian McKenzie
c0e5059634 Merge pull request #1752 from loganfsmyth/hidden-class-change
Initialize properties to avoid hidden class thrashing.
2015-06-15 10:45:30 +01:00
Logan Smyth
f8f5684faa Avoid concatenating callbacks and ensure that callback lists are arrays ahead of time. 2015-06-14 23:00:38 -07:00
Logan Smyth
2c3e9fbc07 Initialize properties to avoid hidden class thrashing. 2015-06-14 22:26:44 -07:00
Sebastian McKenzie
b9d066d953 add special case for null in get helper 2015-06-15 00:15:22 +01:00
Sebastian McKenzie
94e15b0750 remove unused variable 2015-06-14 23:52:09 +01:00
Sebastian McKenzie
3256c1d120 Merge branch 'master' of github.com:babel/babel 2015-06-14 23:44:30 +01:00
Sebastian McKenzie
eba9f0ffbd clean up default constructor in derived classes - fixes #1748 2015-06-14 23:44:21 +01:00
Sebastian McKenzie
52c3c143f9 add BindingIdentifier virtual type 2015-06-14 20:21:02 +01:00
Brian Donovan
b0f797205b Merge pull request #1744 from silfverstrom/bugg/typo-in-messages
Fixed very minor typo in messages.js.
2015-06-14 07:57:25 -07:00
Niklas Silfverström
dd52c6a687 Fixed very minor typo in messages.js. 2015-06-14 08:06:55 +02:00
Mordy Tikotzky
3cf773b528 fix register hook when not registering for .js extension. 2015-06-14 00:31:14 -04:00
Henry Zhu
98424f80af template-literals: remove unnecessary strings, only add "" to beginning if second node isn't a string - fixes #1732 2015-06-13 14:34:33 -04:00
Sebastian McKenzie
708879ff1b fix auxiliary comment option in makefile 2015-06-13 19:01:50 +01:00
Sebastian McKenzie
70042bb0a8 update internal babel version to latest 2015-06-13 18:57:22 +01:00
Sebastian McKenzie
0f7711a202 5.5.8 2015-06-13 18:54:52 +01:00
Sebastian McKenzie
27f039488e v5.5.8 2015-06-13 18:53:41 +01:00
Sebastian McKenzie
e3ce82e12f remove console.log 2015-06-13 18:50:51 +01:00
Sebastian McKenzie
4934ea56a0 change NodePath#inType to use arguments instead of types 2015-06-13 18:50:19 +01:00
Sebastian McKenzie
ce03457b19 add getOpposite path method 2015-06-13 18:50:05 +01:00
Sebastian McKenzie
1298c67949 rename getOwnBindingInfo to getOwnBinding 2015-06-13 18:49:59 +01:00
Sebastian McKenzie
668274edcb remove resolve-rc file 2015-06-13 18:49:37 +01:00
Sebastian McKenzie
0694a7dd06 5.5.7 2015-06-13 02:23:28 +01:00
Sebastian McKenzie
20d19735fc v5.5.7 2015-06-13 02:22:20 +01:00
Sebastian McKenzie
b5b6bf4ad5 add isDirective method, 2015-06-13 02:21:22 +01:00
Sebastian McKenzie
844c10cac0 fix reference to inferers 2015-06-13 02:20:04 +01:00
Sebastian McKenzie
43583e4e9d pick only current constant violation if it's of the same scope 2015-06-13 02:19:57 +01:00
Sebastian McKenzie
f5b921cda9 better errorWithNode that's consolidated across paths and files 2015-06-13 02:19:44 +01:00
Sebastian McKenzie
763892aa79 remove unused variable 2015-06-13 02:19:30 +01:00
Sebastian McKenzie
3e6eae4d1a Merge branch 'master' of github.com:babel/babel 2015-06-13 02:00:22 +01:00
Sebastian McKenzie
7c090c8580 Merge pull request #1740 from zertosh/cli-fixes
Really fix "--help"
2015-06-13 01:56:58 +01:00
Andres Suarez
a5f6c1c389 Really fix "--help" 2015-06-12 20:54:53 -04:00
Sebastian McKenzie
c159f2d982 Merge branch 'master' of github.com:babel/babel 2015-06-13 01:54:33 +01:00
Sebastian McKenzie
9205f10244 Merge pull request #1719 from jmm/internals-docs2
Internals documentation
2015-06-13 01:53:04 +01:00
Sebastian McKenzie
4cd7bcad59 Merge pull request #1727 from zertosh/cli-fixes
Fix "--help" distinguish optional transforms
2015-06-13 01:52:46 +01:00
Andres Suarez
7e9660efd3 Fix "--help" distinguish optional transforms 2015-06-12 20:51:52 -04:00
Sebastian McKenzie
2d66ce5224 Merge pull request #1724 from arthurvr/bool
Update `util.booleanify()` return type
2015-06-13 01:48:30 +01:00
Sebastian McKenzie
1257b2cf40 Merge pull request #1736 from grncdr/patch-1
Remove duplicate keys from alias-keys.json
2015-06-12 20:33:54 +01:00
Stephen Sugden
f21d935de5 Add aliases from JSX* tags to Expression 2015-06-12 12:24:24 -07:00
Stephen Sugden
2e20364793 Remove duplicate keys from alias-keys.json
Fixes #1734
2015-06-12 20:58:41 +02:00
Sebastian McKenzie
e47e8a187a Merge branch 'master' of github.com:babel/babel 2015-06-11 19:06:41 +01:00
Ingvar Stepanyan
26924d5944 Fix dependency reference of Symbol.hasInstance 2015-06-10 22:07:40 +03:00
Arthur Verschaeve
5eb1850a55 Update util.booleanify() return type
Ref 62f37c1e62
2015-06-10 16:54:43 +02:00
Sebastian McKenzie
333e287226 remove special minification.removeConsole ExpressionStatement handling 2015-06-10 13:14:44 +01:00
Sebastian McKenzie
80a77bd6a2 fix linting error 2015-06-10 03:16:07 +01:00
Sebastian McKenzie
c9286a1de1 rewrite option handling - fixes #1636 2015-06-10 03:07:06 +01:00
Sebastian McKenzie
52f614dcdf add better path execution status algo 2015-06-10 01:36:36 +01:00
Sebastian McKenzie
600367ae25 add t.COMPARISON_BINARY_OPERATORS 2015-06-10 01:34:51 +01:00
Sebastian McKenzie
b761cba135 split auxiliary comment option into before and after - fixes #1721 2015-06-10 01:34:44 +01:00
Sebastian McKenzie
947d3e262d push newline after decorator when doing code gen - fixes #1713 2015-06-10 01:19:58 +01:00
Sebastian McKenzie
4061bea528 change execution order of module metadata visitor to resolve module source before building up metadata tree - fixes #1720 2015-06-10 01:15:11 +01:00
Sebastian McKenzie
de195e5bfc Merge branch 'master' of github.com:babel/babel 2015-06-10 01:10:41 +01:00
Sebastian McKenzie
3bcef86973 Merge pull request #1720 from chadhietala/failing-metadata-test
Metadata object does not take in account resolveModuleSource()
2015-06-10 01:10:09 +01:00
Sebastian McKenzie
fa670ac71e visually split up inference inferer methods 2015-06-09 22:52:21 +01:00
Sebastian McKenzie
572261f9ce add support for typecasts in path static evaluation 2015-06-09 22:52:00 +01:00
Chad Hietala
8a320d53a5 Metadata object does not take in account resolveModuleSource()
This adds a failing test to illustrate the metadata object not reflecting what is returned from resolveModuleSource(). I might also not understand resolveModuleSource's purpose. However, this was the hook mentioned here https://github.com/babel/babel/issues/1602.
2015-06-09 14:26:33 -07:00
Jesse McCarthy
0650eedeb6 Add reference to doc dir to CONTRIBUTING. 2015-06-09 15:37:01 -04:00
Jesse McCarthy
2282d066a2 Start doc dir for internals documentation. 2015-06-09 15:37:01 -04:00
Sebastian McKenzie
f4d7cc55c1 split inference logic into separate folder 2015-06-09 14:02:57 +01:00
Sebastian McKenzie
eaaa279aa5 add let binding collision todo 2015-06-09 04:08:44 +01:00
Sebastian McKenzie
0595e06e29 5.5.6 2015-06-09 04:08:36 +01:00
Sebastian McKenzie
9b27a170ae v5.5.6 2015-06-09 04:07:15 +01:00
Sebastian McKenzie
1db232da9e add 5.5.6 changelog 2015-06-09 04:06:06 +01:00
Sebastian McKenzie
4cc844f410 take into consideration assignment expressions in loop heads when replacing let references - fixes #1707 2015-06-09 04:04:14 +01:00
Sebastian McKenzie
024ae670cb fix traceur test blacklist 2015-06-09 03:48:22 +01:00
Sebastian McKenzie
429edda9c0 ignore StringIterator traceur test 2015-06-09 03:40:08 +01:00
Sebastian McKenzie
05b13b9ea3 fix mistyped parameter name of t.createTypeAnnotationBasedOnTypeof 2015-06-09 03:26:40 +01:00
Sebastian McKenzie
b7320ce400 add t.createTypeAnnotationBasedOnTypeof method 2015-06-09 03:23:28 +01:00
Sebastian McKenzie
0c37b7b973 add typeof conditional inference 2015-06-09 03:20:32 +01:00
Sebastian McKenzie
bb36dbd8d9 update to latest traceur and enable now passing tests 2015-06-09 03:20:02 +01:00
Sebastian McKenzie
2dd8c40618 heavily simplify constants transformer 2015-06-09 00:31:18 +01:00
Sebastian McKenzie
33128b0ccf remove unused declaration 2015-06-08 23:59:53 +01:00
Sebastian McKenzie
cf25424295 fix duplicate declaration 2015-06-08 23:49:00 +01:00
Sebastian McKenzie
7492074794 infer types of bindings inside of conditionals based on usage 2015-06-08 23:43:46 +01:00
Sebastian McKenzie
c4a491123e disallow line terminator after async contextual keyword - fixes #1711 2015-06-08 21:25:16 +01:00
Sebastian McKenzie
55ad88fe4e don't override types parameter 2015-06-08 14:59:19 +01:00
Sebastian McKenzie
7170dbced8 Merge branch 'master' of github.com:babel/babel 2015-06-08 14:53:54 +01:00
Sebastian McKenzie
b0971412a2 add inference for null, remove any type parameter from inferred arrays, add todo comment 2015-06-08 14:52:35 +01:00
Sebastian McKenzie
a6b374a681 save union type in _getTypeAnnotationBindingConstantViolations to prevent infinite recursion 2015-06-08 14:52:13 +01:00
Sebastian McKenzie
2d0355b3b9 merge previous bindings constantViolations and path onto new bindings constantViolations 2015-06-08 14:49:09 +01:00
Sebastian McKenzie
7fade101be move down module TypeAlias check 2015-06-08 14:47:58 +01:00
Sebastian McKenzie
0918da8569 Merge pull request #1708 from hawkrives/patch-2
Update README.md for the Slack channel
2015-06-08 12:35:08 +01:00
Hawken Rives
917db622c4 Update README.md
Switch out the gitter link for slack.
2015-06-08 20:33:09 +09:00
Sebastian McKenzie
f7ee6fbd20 move travis notifications from gitter to slack 2015-06-08 12:20:38 +01:00
Sebastian McKenzie
5899e9a0be don't consider type aliases to be a default declaration - fixes #1705 2015-06-08 12:20:30 +01:00
Sebastian McKenzie
d41cb11545 fix registerDeclaration for FlowDeclarations 2015-06-08 01:46:05 +01:00
Sebastian McKenzie
3ad909a4ae add 5.5.5 changelog 2015-06-08 01:45:56 +01:00
Sebastian McKenzie
4bafdf733c 5.5.5 2015-06-08 01:29:54 +01:00
Sebastian McKenzie
b825998c63 v5.5.5 2015-06-08 01:27:46 +01:00
Sebastian McKenzie
6b02ca47c3 add missing semicolon 2015-06-08 01:27:02 +01:00
Sebastian McKenzie
ea1b85bffa fix bug where templates were getting polluted with old traversal paths 2015-06-08 01:25:51 +01:00
Sebastian McKenzie
3cffe47eea fix NodePath#isGenericType method name 2015-06-08 01:00:01 +01:00
Sebastian McKenzie
e5d5a9fb27 remove unused variable 2015-06-08 00:33:41 +01:00
Sebastian McKenzie
ca97fa63a9 Merge branch 'master' of github.com:babel/babel 2015-06-08 00:30:05 +01:00
Sebastian McKenzie
f4cc27bc0e remove unused variable 2015-06-08 00:29:52 +01:00
Sebastian McKenzie
8cea575e2e change NodePath#findParent to only call callback with path instead of node 2015-06-08 00:29:46 +01:00
Sebastian McKenzie
c91baee4d5 add support for flow declarations in scope tracking 2015-06-08 00:04:17 +01:00
Sebastian McKenzie
8055ce29f7 add support for flow declarations in scope tracking 2015-06-07 23:57:19 +01:00
Sebastian McKenzie
4596ae48b8 remove acorn jsx tests as the jsx parser is no longer embedded 2015-06-07 23:57:11 +01:00
Sebastian McKenzie
6c268cdf21 split out path comment methods into a separate file 2015-06-07 23:49:29 +01:00
Sebastian McKenzie
fce977f1d7 update TraversalContext#shouldVisit to check for existence of visitor keys 2015-06-07 23:38:39 +01:00
Sebastian McKenzie
a298075949 check for loc value on comments before attempting to adjust it 2015-06-07 23:37:47 +01:00
Sebastian McKenzie
66599c3779 use scope paths hub instead of manually passing the hub to the scope 2015-06-07 23:37:33 +01:00
Sebastian McKenzie
60340244b1 when constructing a NodePath, inherit parent paths hub if one wasn't passed to us 2015-06-07 23:36:32 +01:00
Sebastian McKenzie
eb72ea3e5a rename path verification methods to introspection and add NodePath#getSource method 2015-06-07 23:36:12 +01:00
Sebastian McKenzie
ede6237b6f add NodePath#addComment method 2015-06-07 23:35:46 +01:00
Sebastian McKenzie
e91e10aae6 add FlowStatement and FlowDeclaration alias keys 2015-06-07 23:35:35 +01:00
Sebastian McKenzie
9c3cca0d25 rename NodePath#isTypeAnnotationGeneric to isTypeAnnotation 2015-06-07 23:35:09 +01:00
Sebastian McKenzie
8eee5367f3 add Noop node 2015-06-07 23:34:35 +01:00
Sebastian McKenzie
40d55a3d44 update makefile browser build filename 2015-06-07 20:24:21 +01:00
Sebastian McKenzie
75330304dc fix linting errors 2015-06-07 20:04:30 +01:00
Sebastian McKenzie
776c508418 add node build to Makefile 2015-06-07 19:41:28 +01:00
Sebastian McKenzie
e804741632 add module metadata - closes #1601 2015-06-07 19:41:20 +01:00
Sebastian McKenzie
3d3cb4be4f completely rework type inferrence, support coercing to union types and be more reliable in the inferrence and always be cautious 2015-06-07 19:39:53 +01:00
Sebastian McKenzie
64f4209119 recurse into type casts when trying to get it's expression - fixes #facebook/react-native#1526 2015-06-07 02:45:06 +01:00
Sebastian McKenzie
2ede226ef9 remove unused variables 2015-06-06 16:35:28 +01:00
Sebastian McKenzie
f5cf641c0a add support for async generators to type inferrence 2015-06-06 16:17:55 +01:00
Sebastian McKenzie
1abd3419f6 simplify NodePath.getScope 2015-06-06 16:17:43 +01:00
Sebastian McKenzie
75699db716 clean up options normalisation and add more comments 2015-06-06 16:17:30 +01:00
Sebastian McKenzie
7c3572f08c fix linting errors 2015-06-06 03:38:12 +01:00
Sebastian McKenzie
9dacde6d07 further implement the concept of a "Hub" that all traversal paths get access to, also add in some assertions to confirm path state when performing manipulation 2015-06-06 03:34:08 +01:00
Sebastian McKenzie
8c3aab9a26 add support for async functions to type inferrence 2015-06-06 03:33:32 +01:00
Sebastian McKenzie
ba4550c953 switch some node-parent based stuff to path-based 2015-06-06 03:33:22 +01:00
Sebastian McKenzie
d0ac65a934 add _paths in t.inherits 2015-06-06 03:32:35 +01:00
Sebastian McKenzie
a4c70bb029 this commit makes the following changes to the way paths are handled:
- store paths on parents instead of containers
 - implement one central hub that all traversal paths and scopes get access to in order to abstract out access to common functions
2015-06-06 03:32:22 +01:00
Sebastian McKenzie
795cf0c0b1 add ignore/only tests to ensure #1693 never happens again 2015-06-05 23:11:10 +01:00
Sebastian McKenzie
e64b90e322 5.5.4 2015-06-05 23:07:27 +01:00
Sebastian McKenzie
d69b0973e1 v5.5.4 2015-06-05 23:03:55 +01:00
Sebastian McKenzie
6296f49653 update minification.constantFolding transformer to deopt bindings that are reassigned in a different function scope 2015-06-05 23:01:31 +01:00
Sebastian McKenzie
9f2b739046 improve Scope#dump to print binding info 2015-06-05 23:00:50 +01:00
Sebastian McKenzie
da1d5e5577 simplify unary resolution and move operators to types 2015-06-05 23:00:06 +01:00
Sebastian McKenzie
7333b4e392 move staticPropBody class concat to after className check in es6.classes transformer 2015-06-05 22:44:03 +01:00
Sebastian McKenzie
b0442d0784 add back shouldIgnore check that went missing around 32f19aff99 - closes #1696, fixes #1693 2015-06-05 22:43:32 +01:00
Sebastian McKenzie
295e69f8f8 fix auxiliaryComment option name for istanbul interop - fixes #1695 2015-06-05 22:40:28 +01:00
Sebastian McKenzie
cfe844fa39 add boolean type to experimental option 2015-06-05 22:36:16 +01:00
Sebastian McKenzie
0f4ea2d2a6 use file.log.deprecate instead of throwing an error - fixes #1694 2015-06-05 22:35:46 +01:00
Sebastian McKenzie
4b85b05839 use actual parameter reference for non-last default parameters - fixes #1690 2015-06-05 14:08:18 +01:00
Sebastian McKenzie
2539d08dce 5.5.3 2015-06-05 14:07:34 +01:00
Sebastian McKenzie
c26fd7a819 fix regenerator version 2015-06-05 14:07:27 +01:00
Sebastian McKenzie
2053610429 v5.5.3 2015-06-05 12:20:22 +01:00
Sebastian McKenzie
cd4f83b299 fix linting errors 2015-06-05 12:19:32 +01:00
Sebastian McKenzie
ec29ba19a9 add 5.5.3 changelog 2015-06-05 12:18:43 +01:00
Sebastian McKenzie
9dc03e0978 traverse over ClassProperty path rather than node 2015-06-05 12:17:55 +01:00
Sebastian McKenzie
bc4258eca9 add type inferrence for template literals 2015-06-05 12:17:45 +01:00
Sebastian McKenzie
b0e58f9770 add completion statement test and enable experimental option on deadCodeElimination tests 2015-06-05 12:17:36 +01:00
Sebastian McKenzie
a1e2641c91 5.5.2 2015-06-05 12:17:18 +01:00
Sebastian McKenzie
9108422f99 v5.5.2 2015-06-05 12:03:38 +01:00
Sebastian McKenzie
9e8f4b25ca add missing semicolon 2015-06-05 12:02:30 +01:00
Sebastian McKenzie
1cecd24823 make experimental warning more scary 2015-06-05 12:01:52 +01:00
Sebastian McKenzie
97f6e1469b add 5.5.2 changelog 2015-06-05 12:01:44 +01:00
Sebastian McKenzie
ec46eaf224 add scary experimental warning for people who use obscure transformers that are still WIP 2015-06-05 11:55:09 +01:00
Sebastian McKenzie
a102692103 when using babel/register always use the cwd - fixes #1689 2015-06-05 11:54:52 +01:00
Sebastian McKenzie
0376ec8ff0 t.isPure -> this.isPure - fixes #1688 2015-06-05 11:33:25 +01:00
Sebastian McKenzie
5932a07610 5.5.1 2015-06-05 09:57:21 +01:00
444 changed files with 11319 additions and 8343 deletions

View File

@@ -2,5 +2,6 @@
"stage": 0,
"loose": ["all"],
"blacklist": ["es6.tailCall"],
"optional": ["optimisation.flow.forOf"]
"optional": ["optimisation.flow.forOf"],
"plugins": ["./tools/build-plugins/protect"]
}

View File

@@ -17,7 +17,9 @@
"no-fallthrough": 0,
"new-cap": 0,
"no-loop-func": 0,
"no-unreachable": 0
"no-unreachable": 0,
"no-labels": 0,
"no-process-exit": 0
},
"env": {
"node": true

1
.gitignore vendored
View File

@@ -15,3 +15,4 @@ test/core/tmp
/packages/babel-runtime/helpers/*.js
/packages/babel-runtime/regenerator/*.js
/lib
_babel.github.io

View File

@@ -13,3 +13,4 @@
/vendor
/packages
/src
_babel.github.io

View File

@@ -1,19 +1,35 @@
#sudo: false
language: node_js
cache:
directories:
- node_modules
- node_modules
node_js:
- "0.12"
- "iojs"
- "0.10"
- "0.12"
- iojs
before_script: "npm install -g codeclimate-test-reporter"
script: "make test-travis"
before_script: ./tools/setup-git.sh
script: make test-travis
after_success: ./tools/merge-development-with-master.sh
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/acf1870e9d223c65e8d5
on_success: always
on_failure: always
on_start: false
slack: babeljs:5Wy4QX13KVkGy9CnU0rmvgeK
before_deploy:
- make prepublish
deploy:
provider: npm
email: sebmck@gmail.com
skip_cleanup: true
api_key:
secure: Q/pZStwherdYPCqCa0aUuiEktLcx6ccBxieyH8j9IXdDgty0ydmnajZfUnlZuCjN13XI9esM44nSJFTWZvntTryDQAQm37c63VXhAEnw/qrAINI06yt0gLBTT69/fKvIAkH8l48nmW32ZS2dse3rHRPZF1CwyQLC/pdMip8I4sM=
on:
branch: master
tags: true
repo: babel/babel
after_deploy:
- make publish-cli
- make publish-runtime
- make build-website
- make comment-issues

View File

@@ -9,10 +9,178 @@
> - [Internal]
> - [Polish]
_Note: Gaps between patch versions are faulty/broken releases._
_Note: Gaps between patch versions are faulty, broken or test releases._
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
## 5.6.19
* Removed do expressions.
## 5.6.17
* **Bug Fix**
* Fix `CodeGenerator.findCommonStringDelimiter` causing a stack overflow.
## 5.6.16
* **Internal**
* Fix `recast` version to avoid pulling in a newer version.
* **New Feature**
* Add support for functions in `util.shouldIgnore`.
* **Polish**
* Strip flow directives in flow transformer.
* Add a check for out of bounds default parameters, drastically improving performance and removes engine deoptimisations.
* Various performance optimisations by [@samccone](https://github.com/samccone) 💅✨
* Delay `this` assignment when referencing this inside an arrow function pre-bare super in derived class constructors.
* Split up class body pushing if the constructor is in the wrong order.
* **Bug Fix**
* Fix hoisting of `ForInStatement` `init` variables in `system` module formatter.
* `PathHoister`: Don't hoist to the same function as their original paths function parent.
* `PathHoister`: Push each violation paths ancestry to the breakOnScopePaths collection to avoid constant hoisting to nested paths.fix tail call recursion on functions with less arguments than parameters.
* Disallow `super.*` before `super()` in derived class constructors.
* Properly regenerate scope for replaced nodes. Thanks [@loganfsmyth](https://github.com/loganfsmyth)!
* Move up template literal simplification logic to avoid breaking on single elements.
## 5.6.13-5.6.15
* Setting up automatic Travis releases.
## 5.6.12
* **Bug Fix**
* Fix finding parent for top-level shadowed functions.
## 5.6.11
** **Internal**
* Merge `es6.parameters.rest` and `es6.parameters.default` transformers. See commit [c0fd4c1f9e0b18231f585c4fa793e4cb0e01aed1](https://github.com/babel/babel/commit/c0fd4c1f9e0b18231f585c4fa793e4cb0e01aed1) for more info.
## 5.6.10
* **Bug Fix**
* Fix faulty internal require check.
* **Polish**
* Add support for trailing commas in arrow function parameter lists.
## 5.6.8
* **Bug Fix**
* Fix binary expressions colliding with unary expression operators in compact mode.
* Fix node properties being set to `null` when using computed properties.
## 5.6.7
* **Bug Fix**
* Fix hoisting of `ForXStatement` `left` `var`s when inserting a block scoping IIFE.
* **Polish**
* Combine all leading computed property initialisers into the root object in loose mode.
* **Internal**
* Deprecate returning of replacement strings from visitor methods.
## 5.6.6
* **Bug Fix**
* Fix weird parser bug where `void` type annotations were being parsed as keywords causing the tokeniser to lose track of context.
## 5.6.5
* **Bug Fix**
* Fix nested functions causing rest parameter optimisation to not properly detect when it should deopt on a reference.
* **Internal**
* Update Regenerator `0.8.31`.
## 5.6.4
* **Internal**
* Add `ParenthesizedExpression` node type.
## 5.6.3
* **Bug Fix**
* Fix rest parameter array allocation loop being incorrectly aliased.
## 5.6.2
* **Bug Fix**
* Fix method key literals not turning into computed member expression in loose mode.
* Elect rest parameters in spread element position as candidates instead of replacing them in place.
## 5.6.0
* **Bug Fix**
* Fix istanbul interop for register hook when registering for non-existence extension.
* Fix super class constructor call differing for no constructor in derived classes.
* Disable module import receiver when in loose mode.
* Fix duplicate filenames when using `babel` CLI when passing multiple matching patterns.
* Register labels as bindings to fix undeclared variable checks.
* **Polish**
* Remove unnecessary string binary expressions when transforming template literals.
* Support module live bindings in arbitary positions not in Program statement position.
* Throw error when attemping to replace a `Program` root node with another node not of type `Program`.
* Optimise rest parameters in spread element position and allocate rest array at the earliest common ancestor of all references.
* Generate original number representation when value was not changed.
* Check for invalid binding identifiers when generating inferred method names.
* Don't terminate CLI when watching files fail compilation on init.
* **New Feature**
* Add new plugin API.
* **Internal**
* Split react displayName addition into a plugin.
* Add check for `JSXMemberExpression` to `t.isReferenced`.
* Move `validation.undeclaredVariableCheck` transformer up.
* Start great core-to-plugin exodus.
* Add `BindingIdentifier` virtual type.
* Hidden class optimisations.
* Array allocation optimisations.
* Update `regenerator`.
* Update `js-tokens`.
* Sync with upstream Acorn.
## 5.5.8
* **Internal**
* Remove extremely unprofessional and harsh error message for those hotlinking to `resolve-rc`.
## 5.5.7
* **Bug Fix**
* Push newline after decorators when doing code gen.
* Rewriting error handling to normalise options before merging them.
* Remove duplicate keys in `alias-keys.json` causing errors in strict mode.
* Fix `$ babel --help` not showing optional transformers as such.
* **New Feature**
* Add `auxiliaryCommentBefore` and `auxiliaryCommentAfter` options.
## 5.5.6
* **Bug Fix**
* Fix `let` binding collision in loop head not properly replacing `AssignmentExpression`s.
## 5.5.5
* **Bug Fix**
* Fix `file.opts` not being set before `file.log.deprecate` was called causing a `ReferenceError` as it was checking for a property on it.
## 5.5.4
* **Bug Fix**
* Add back missing `shouldIgnore` check.
* Log message on deprecated options rather than throw an error.
* Fix name of `auxiliaryComment` option when attempting Istanbul interop in `babel/register`.
## 5.5.3
* **Bug Fix**
* Fix weird state bug when traversing overa `node` `ClassProperty` instead of `path` in the `es6.classes` transformer.
## 5.5.2
* **Bug Fix**
* Fix `NodePath#isPure` on `Property` nodes.
* Use cwd instead of entry file directory when working out relative directory for `babel/register`.
* **Internal**
* Add scary warning for those few who choose to use the WIP experimental transformers.
## 5.5.1
* **Bug Fix**

View File

@@ -12,6 +12,8 @@
<strong><a href="#dependencies">Dependencies</a></strong>
|
<strong><a href="#code-standards">Code Standards</a></strong>
|
<strong><a href="#internals">Internals</a></strong>
</p>
----
@@ -22,11 +24,10 @@ Contributions are always welcome, no matter how large or small. Before
contributing, please read the
[code of conduct](https://github.com/babel/babel/blob/master/CODE_OF_CONDUCT.md).
## Developing
>Note: Babel moves fast. Only the latest release is guaranteed to build correctly.
>Older releases are not officially supported. If you attempt to build them, do that at your own risk.
> Note: Babel moves fast. Only the latest release is guaranteed to build correctly.
> Older releases are not officially supported. If you attempt to build them, do that at your own risk.
#### Setup
@@ -112,8 +113,6 @@ your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-ad
+ [js-tokens](http://ghub.io/js-tokens) This is used to get tokens for syntax error highlighting.
+ [leven](http://ghub.io/leven) A levenstein algorithm to determine how close a word is to another. This is used to offer suggestions when using the utility.undeclaredVariableCheck transformer.
+ [line-numbers](http://ghub.io/line-numbers) Used to produce the code frames in syntax errors.
+ [lodash](http://ghub.io/lodash) Used for various utilities.
@@ -144,8 +143,11 @@ your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-ad
+ [trim-right](http://ghub.io/trim-right) Trims the rightside whitespace.
+ [user-home](http://ghub.io/user-home) Gets the users home directory. This is used to resolve the babel-node/babel/register cache.
+ [path-exists](https://www.npmjs.com/package/path-exists) Checks if a path exists. (replaces the deprecated `fs.exists` methods)
+ [home-or-tmp](https://github.com/sindresorhus/home-or-tmp) Gets the user home directory with fallback to the system temporary directory. This is used to resolve the babel-node/babel/register cache.
+ [resolve](https://www.npmjs.com/package/resolve) Implements the [`require.resolve()` algorithm](http://nodejs.org/docs/v0.12.0/api/all.html#all_require_resolve) such that we can `require.resolve()` on behalf of a file asynchronously and synchronously.
#### Code Standards
@@ -173,3 +175,6 @@ your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-ad
* **Declaration**
* No unused variables
* No pollution of global variables and prototypes
#### Internals
Please see [`/doc`](/doc) for internals documentation relevant to developing babel.

View File

@@ -5,16 +5,17 @@ UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
#UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs --mangle sort
MOCHA_CMD = node_modules/mocha/bin/_mocha
BABEL_CMD = node_modules/babel/bin/babel
BROWSERIFY_IGNORE = -i esprima-fb
export NODE_ENV = test
.PHONY: clean test test-cov test-clean test-travis test-simple test-all test-browser test-parser publish build bootstrap publish-core publish-runtime build-core watch-core build-core-test clean-core
.PHONY: clean test test-cov test-clean test-travis test-simple test-all test-browser test-parser publish build bootstrap publish-core publish-runtime build-website build-core watch-core build-core-test clean-core prepublish
build-core: clean-core
node $(BABEL_CMD) src --out-dir lib --copy-files
build-core-test: clean-core
node $(BABEL_CMD) src --out-dir lib --copy-files --auxiliary-comment "istanbul ignore next"
node $(BABEL_CMD) src --out-dir lib --copy-files --auxiliary-comment-before "istanbul ignore next"
watch-core: clean-core
node $(BABEL_CMD) src --out-dir lib --watch --copy-files
@@ -23,7 +24,7 @@ clean-core:
rm -rf lib
lint:
eslint src/babel
eslint src/babel packages/babel-cli/bin
build:
mkdir -p dist
@@ -34,8 +35,10 @@ build:
node $(BROWSERIFY_CMD) -e lib/babel/polyfill.js >dist/polyfill.js
node $(UGLIFY_CMD) dist/polyfill.js >dist/polyfill.min.js
node $(BROWSERIFY_CMD) lib/babel/api/browser.js -s babel >dist/babel.js
node $(UGLIFY_CMD) dist/babel.js >dist/babel.min.js
node $(BROWSERIFY_CMD) lib/babel/api/browser.js -s babel $(BROWSERIFY_IGNORE) >dist/browser.js
node $(UGLIFY_CMD) dist/browser.js >dist/browser.min.js
node $(BROWSERIFY_CMD) lib/babel/api/node.js --node $(BROWSERIFY_IGNORE) >dist/node.js
node packages/babel-cli/bin/babel-external-helpers >dist/external-helpers.js
node $(UGLIFY_CMD) dist/external-helpers.js >dist/external-helpers.min.js
@@ -78,34 +81,20 @@ test-browser:
publish: lint
git pull --rebase
make test
read -p "Version: " version; \
npm version $$version --message "v%s"
make build
cp dist/babel.js browser.js
cp dist/babel.min.js browser.min.js
cp dist/polyfill.js browser-polyfill.js
cp dist/polyfill.min.js browser-polyfill.min.js
cp dist/external-helpers.js external-helpers.js
cp dist/external-helpers.min.js external-helpers.min.js
node tools/cache-templates
test -f templates.json
npm publish
git push --follow-tags
make publish-cli
make publish-runtime
rm -rf templates.json browser.js browser.min.js browser-polyfill.js browser-polyfill.min.js external-helpers.js external-helpers.min.js
prepublish: build
cp dist/browser.js browser.js
cp dist/browser.min.js browser.min.js
cp dist/polyfill.js browser-polyfill.js
cp dist/polyfill.min.js browser-polyfill.min.js
cp dist/external-helpers.js external-helpers.js
cp dist/external-helpers.min.js external-helpers.min.js
node tools/cache-templates
test -f templates.json
publish-runtime:
cd packages; \
@@ -114,10 +103,13 @@ publish-runtime:
npm publish
publish-cli:
cd packages; \
node build-cli.js; \
cd babel-cli; \
npm publish
@./tools/publish-cli.sh
build-website:
@./tools/build-website.sh
comment-issues:
@./tools/comment-issues.sh
bootstrap:
npm list --global --depth 1 babel >/dev/null 2>&1 && npm uninstall -g babel || true

View File

@@ -1,19 +1,28 @@
<p align="center">
<a href="https://babeljs.io/">
<img alt="babel" src="https://raw.githubusercontent.com/babel/logo/master/logo.png" width="546">
<img alt="babel" src="https://raw.githubusercontent.com/babel/logo/master/babel.png" width="546">
</a>
</p>
<p align="center">
<strong>Babel</strong> is a compiler for writing next generation JavaScript.
The compiler for writing next generation JavaScript.
</p>
<p align="center">
For questions and support please visit the <a href="https://gitter.im/babel/babel">gitter room</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
<a href="https://travis-ci.org/babel/babel"><img alt="Build Status" src="https://img.shields.io/travis/babel/babel.svg?style=flat"></a>
<a href="http://badge.fury.io/js/babel-core"><img alt="npm version" src="https://badge.fury.io/js/babel-core.svg"></a>
<a href="https://npmjs.org/package/babel-core"><img alt="Downloads" src="http://img.shields.io/npm/dm/babel-core.svg"></a>
</p>
<p align="center">
Issues without instructions to reproduce <strong>will be immediately closed<strong>.
<a href="http://issuestats.com/github/babel/babel"><img alt="Issue Stats" src="http://issuestats.com/github/babel/babel/badge/pr?style=flat"></a>
<a href="http://issuestats.com/github/babel/babel"><img alt="Issue Stats" src="http://issuestats.com/github/babel/babel/badge/issue?style=flat"></a>
</p>
----
<p align="center">
For questions and support please visit the <a href="https://babel-slack.herokuapp.com">Slack community</a> or <a href="http://stackoverflow.com/questions/tagged/babeljs">StackOverflow</a>. The Babel issue tracker is <strong>exclusively</strong> for bug reports and feature requests.
</p>
<p align="center">

4
doc/index.md Normal file
View File

@@ -0,0 +1,4 @@
This is a collection of documentation about babel internals, for use in development of babel.
# [Properties of nodes](/doc/node-props.md)
These are properties babel stores in AST node objects for internal use, as opposed to properties that are part of the AST spec (ESTree at the time of this writing).

11
doc/node-props.md Normal file
View File

@@ -0,0 +1,11 @@
# Properties of nodes
These are properties babel stores in AST node objects for internal use, as opposed to properties that are part of the AST spec ([ESTree](https://github.com/estree/estree) at the time of this writing).
## `_blockHoist`
`node._blockHoist != null` triggers the [block-hoist transformer](/src/babel/transformation/transformers/internal/block-hoist.js). Value should be `true` or an integer in the range `0..3`. `true` is equivalent to `2`. The value indicates whether the node should be hoisted and to what degree. See the source code for more detailed information.
## `_paths`
Stores a representation of a node's position in the tree and relationship to other nodes.
## `shadow`
A truthy value on a function node triggers the [shadow-functions transformer](/src/babel/transformation/transformers/internal/shadow-functions.js), which transforms the node so that it references (or inherits) `arguments` and the `this` context from the parent scope. It is invoked for arrow functions, for example.

1
index.js Normal file
View File

@@ -0,0 +1 @@
module.exports = require("./lib/babel/api/node.js");

View File

@@ -1,27 +1,26 @@
{
"name": "babel-core",
"description": "A compiler for writing next generation JavaScript",
"version": "5.5.1",
"version": "5.6.19",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"repository": "babel/babel",
"main": "lib/babel/api/node.js",
"browser": {
"./lib/babel/api/register/node.js": "./lib/babel/api/register/browser.js"
},
"keywords": [
"harmony",
"6to5",
"babel",
"classes",
"modules",
"let",
"const",
"var",
"es6",
"harmony",
"let",
"modules",
"transpile",
"transpiler",
"6to5",
"babel"
"var"
],
"scripts": {
"bench": "make bench",
@@ -29,29 +28,41 @@
},
"dependencies": {
"acorn-jsx": "^1.0.0",
"ast-types": "~0.7.0",
"bluebird": "^2.9.25",
"babel-plugin-constant-folding": "^1.0.1",
"babel-plugin-dead-code-elimination": "^1.0.2",
"babel-plugin-eval": "^1.0.1",
"babel-plugin-inline-environment-variables": "^1.0.1",
"babel-plugin-jscript": "^1.0.1",
"babel-plugin-member-expression-literals": "^1.0.1",
"babel-plugin-property-literals": "^1.0.1",
"babel-plugin-proto-to-assign": "^1.0.3",
"babel-plugin-react-constant-elements": "^1.0.3",
"babel-plugin-react-display-name": "^1.0.3",
"babel-plugin-remove-console": "^1.0.1",
"babel-plugin-remove-debugger": "^1.0.1",
"babel-plugin-runtime": "^1.0.7",
"babel-plugin-undeclared-variables-check": "^1.0.2",
"babel-plugin-undefined-to-void": "^1.1.6",
"chalk": "^1.0.0",
"convert-source-map": "^1.1.0",
"core-js": "^0.9.0",
"debug": "^2.1.1",
"detect-indent": "^3.0.0",
"esquery": "^0.4.0",
"estraverse": "^4.0.0",
"esutils": "^2.0.0",
"fs-readdir-recursive": "^0.1.0",
"globals": "^6.4.0",
"home-or-tmp": "^1.0.0",
"is-integer": "^1.0.4",
"js-tokens": "1.0.0",
"leven": "^1.0.1",
"js-tokens": "1.0.1",
"line-numbers": "0.2.0",
"lodash": "^3.6.0",
"minimatch": "^2.0.3",
"output-file-sync": "^1.1.0",
"path-exists": "^1.0.0",
"path-is-absolute": "^1.0.0",
"private": "^0.1.6",
"regenerator": "^0.8.28",
"regenerator": "0.8.34",
"regexpu": "^1.1.2",
"repeating": "^1.1.2",
"resolve": "^1.1.6",
@@ -64,11 +75,11 @@
"trim-right": "^1.0.0"
},
"devDependencies": {
"babel": "5.3.1",
"babel": "5.6.10",
"babel-eslint": "^3.1.19",
"browserify": "^9.0.8",
"chai": "^2.2.0",
"eslint": "^0.21.2",
"babel-eslint": "^3.1.9",
"esvalid": "^1.1.0",
"istanbul": "^0.3.5",
"matcha": "^0.6.0",

View File

@@ -18,9 +18,9 @@ program.option("-p, --print [code]", "Evaluate script and print result");
program.option("-i, --ignore [regex]", "Ignore all files that match this regex when using the require hook");
program.option("-x, --extensions [extensions]", "List of extensions to hook into [.es6,.js,.es,.jsx]");
program.option("-r, --stage [stage]", "Enable support for specific ECMAScript stages");
program.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
program.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list);
program.option("-o, --optional [optional]", "List of optional transformers to enable", util.list);
program.option("-w, --whitelist [whitelist]", "Whitelist of transformers separated by comma to ONLY use", util.list);
program.option("-b, --blacklist [blacklist]", "Blacklist of transformers separated by comma to NOT use", util.list);
program.option("-o, --optional [optional]", "List of optional transformers separated by comma to enable", util.list);
var pkg = require("../package.json");
program.version(pkg.version);
@@ -41,6 +41,7 @@ babel.register({
//
var _eval = function (code, filename) {
code = code.trim();
if (!code) return undefined;
code = babel.transform(code, {

View File

@@ -0,0 +1,141 @@
#!/usr/bin/env node
var pathExists = require("path-exists");
var readline = require("readline");
var child = require("child_process");
var path = require("path");
var fs = require("fs");
function spawn(cmd, args, callback) {
console.log(">", cmd, args);
var spawn = child.spawn(cmd, args, { stdio: "inherit" });
spawn.on("exit", function (code) {
if (code === 0) {
if (callback) callback();
} else {
console.log("Killing...");
process.exit(1);
}
});
}
function spawnMultiple(cmds) {
function next() {
var cmd = cmds.shift();
if (cmd) {
spawn(cmd.command, cmd.args, next);
} else {
process.exit();
}
}
next();
}
function template(name, data) {
var source = fs.readFileSync(path.join(__dirname, "templates", name), "utf8");
source = source.replace(/[A-Z_]+/g, function (key) {
return data[key] === undefined ? key : data[key];
});
return source;
}
function write(filename, content) {
console.log(filename);
fs.writeFileSync(filename, content);
}
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var BABEL_PLUGIN_PREFIX = "babel-plugin-";
var cmds = {
init: function () {
var name = path.basename(process.cwd());
if (name.indexOf(BABEL_PLUGIN_PREFIX) === 0) {
name = name.slice(BABEL_PLUGIN_PREFIX.length);
}
rl.question("Description (optional): ", function (description) {
rl.question("GitHub Repository (eg. sebmck/babel-plugin-foobar) (optional): ", function (repo) {
rl.close();
var templateData = {
DESCRIPTION: description,
FULL_NAME: BABEL_PLUGIN_PREFIX + name,
NAME: name
};
write("package.json", JSON.stringify({
name: templateData.FULL_NAME,
version: "1.0.0",
description: templateData.DESCRIPTION,
repository: repo || undefined,
license: "MIT",
main: "lib/index.js",
devDependencies: {
babel: "^5.6.0"
},
scripts: {
build: "babel-plugin build",
push: "babel-plugin publish",
test: "babel-plugin test"
},
keywords: ["babel-plugin"]
}, null, " ") + "\n");
write(".npmignore", "node_modules\n*.log\nsrc\n");
write(".gitignore", "node_modules\n*.log\nlib\n");
write("README.md", template("README.md", templateData));
if (!pathExists.sync("src")) {
fs.mkdirSync("src");
write("src/index.js", template("index.js", templateData));
}
});
});
},
build: function () {
spawn("babel", ["src", "--out-dir", "lib", "--copy-files"]);
},
publish: function () {
var pkg = require(process.cwd() + "/package.json");
console.log("Current verison:", pkg.version);
rl.question("New version (enter nothing for patch): ", function (newVersion) {
rl.close();
newVersion = newVersion || "patch";
spawnMultiple([
{ command: "git", args: ["pull"] },
{ command: "git", args: ["push"] },
{ command: "babel-plugin", args: ["build"] },
{ command: "npm", args: ["version", newVersion] },
{ command: "npm", args: ["publish"] },
{ command: "git", args: ["push", "--follow-tags"] }
]);
});
}
};
var cmd = cmds[process.argv[2]];
if (cmd) {
cmd();
} else {
console.error("Unknown command:", cmd);
process.exit(1);
}

View File

@@ -0,0 +1,35 @@
# FULL_NAME
DESCRIPTION
## Installation
```sh
$ npm install FULL_NAME
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["NAME"]
}
```
### Via CLI
```sh
$ babel --plugins NAME script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["NAME"]
});
```

View File

@@ -0,0 +1,7 @@
export default function ({ Plugin, types: t }) {
return new Plugin("NAME", {
visitor: {
// your visitor methods go here
}
});
}

View File

@@ -1,4 +1,5 @@
var outputFileSync = require("output-file-sync");
var pathExists = require("path-exists");
var chokidar = require("chokidar");
var slash = require("slash");
var path = require("path");
@@ -6,7 +7,7 @@ var util = require("./util");
var fs = require("fs");
var _ = require("lodash");
module.exports = function (commander, filenames, opts) {
module.exports = function (commander, filenames) {
var write = function (src, relative) {
// remove extension and then append back on .js
relative = relative.replace(/\.(\w*?)$/, "") + ".js";
@@ -27,7 +28,7 @@ module.exports = function (commander, filenames, opts) {
outputFileSync(dest, data.code);
console.log(src + " -> " + dest);
util.log(src + " -> " + dest);
};
var handleFile = function (src, filename) {
@@ -41,7 +42,7 @@ module.exports = function (commander, filenames, opts) {
};
var handle = function (filename) {
if (!fs.existsSync(filename)) return;
if (!pathExists.sync(filename)) return;
var stat = fs.statSync(filename);

View File

@@ -1,4 +1,5 @@
var convertSourceMap = require("convert-source-map");
var pathExists = require("path-exists");
var sourceMap = require("source-map");
var chokidar = require("chokidar");
var slash = require("slash");
@@ -100,7 +101,7 @@ module.exports = function (commander, filenames, opts) {
results = [];
_.each(filenames, function (filename) {
if (!fs.existsSync(filename)) return;
if (!pathExists.sync(filename)) return;
var stat = fs.statSync(filename);
if (stat.isDirectory()) {
@@ -134,7 +135,7 @@ module.exports = function (commander, filenames, opts) {
ignoreInitial: true
}).on("all", function (type, filename) {
if (type === "add" || type === "change") {
console.log(type, filename);
util.log(type + " " + filename);
try {
walk();
} catch (err) {

View File

@@ -1,14 +1,17 @@
#!/usr/bin/env node
require("babel-core");
var moduleFormatters = require("babel-core/lib/babel/transformation/modules");
var pathExists = require("path-exists");
var commander = require("commander");
var transform = require("babel-core").transform;
var kebabCase = require("lodash/string/kebabCase");
var options = require("babel-core").options;
var util = require("babel-core").util;
var uniq = require("lodash/array/uniq");
var each = require("lodash/collection/each");
var keys = require("lodash/object/keys");
var fs = require("fs");
var glob = require("glob");
each(options, function (option, key) {
@@ -35,13 +38,14 @@ each(options, function (option, key) {
if (option.description) desc.push(option.description);
commander.option(arg, desc.join(" "));
})
});
commander.option("-x, --extensions [extensions]", "List of extensions to compile when a directory has been input [.es6,.js,.es,.jsx]");
commander.option("-w, --watch", "Recompile files on changes");
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("-D, --copy-files", "When compiling a directory copy over non-compilable files");
commander.option("-q, --quiet", "Don't log anything");
commander.on("--help", function () {
var outKeys = function (title, obj) {
@@ -51,7 +55,7 @@ commander.on("--help", function () {
each(keys(obj).sort(), function (key) {
if (key[0] === "_") return;
if (obj[key].optional) key = "[" + key + "]";
if (obj[key].metadata && obj[key].metadata.optional) key = "[" + key + "]";
console.log(" - " + key);
});
@@ -64,7 +68,7 @@ commander.on("--help", function () {
});
var pkg = require("../../package.json");
commander.version(pkg.version);
commander.version(pkg.version + " (babel-core " + require("babel-core").version + ")");
commander.usage("[options] <files ...>");
commander.parse(process.argv);
@@ -84,8 +88,10 @@ var filenames = commander.args.reduce(function (globbed, input) {
return globbed.concat(files);
}, []);
filenames = uniq(filenames);
each(filenames, function (filename) {
if (!fs.existsSync(filename)) {
if (!pathExists.sync(filename)) {
errors.push(filename + " doesn't exist");
}
});
@@ -118,11 +124,16 @@ if (errors.length) {
var opts = exports.opts = {};
each(options, function (opt, key) {
opts[key] = commander[key];
if (commander[key] !== undefined) {
opts[key] = commander[key];
}
});
opts.ignore = util.arrayify(opts.ignore, util.regexify);
opts.only = util.arrayify(opts.only, util.regexify);
if (opts.only) {
opts.only = util.arrayify(opts.only, util.regexify);
}
var fn;

View File

@@ -1,10 +1,11 @@
var readdir = require("fs-readdir-recursive");
var index = require("./index");
var babel = require("babel-core");
var util = require("babel-core").util;
var path = require("path");
var fs = require("fs");
var _ = require("lodash");
var commander = require("commander");
var readdir = require("fs-readdir-recursive");
var index = require("./index");
var babel = require("babel-core");
var util = require("babel-core").util;
var path = require("path");
var fs = require("fs");
var _ = require("lodash");
exports.readdirFilter = function (filename) {
return readdir(filename).filter(function (filename) {
@@ -24,6 +25,10 @@ exports.addSourceMappingUrl = function (code, loc) {
return code + "\n//# sourceMappingURL=" + path.basename(loc);
};
exports.log = function (msg) {
if (!commander.quiet) console.log(msg);
};
exports.transform = function (filename, code, opts) {
opts = _.defaults(opts || {}, index.opts);
opts.filename = filename;
@@ -37,6 +42,15 @@ exports.transform = function (filename, code, opts) {
};
exports.compile = function (filename, opts) {
var code = fs.readFileSync(filename, "utf8");
return exports.transform(filename, code, opts);
try {
var code = fs.readFileSync(filename, "utf8");
return exports.transform(filename, code, opts);
} catch (err) {
if (commander.watch) {
console.error(err.stack);
return { ignored: true };
} else {
throw err;
}
}
};

View File

@@ -1,14 +1,12 @@
{
"name": "babel",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "5.5.0",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://babeljs.io/",
"license": "MIT",
"repository": "babel/babel",
"preferGlobal": true,
"dependencies": {
"babel-core": "^5.5.0",
"chokidar": "^1.0.0",
"commander": "^2.6.0",
"convert-source-map": "^1.1.0",
@@ -16,6 +14,7 @@
"glob": "^5.0.5",
"lodash": "^3.2.0",
"output-file-sync": "^1.1.0",
"path-exists": "^1.0.0",
"path-is-absolute": "^1.0.0",
"source-map": "^0.4.0",
"slash": "^1.0.0"
@@ -23,6 +22,7 @@
"bin": {
"babel": "./bin/babel/index.js",
"babel-node": "./bin/babel-node",
"babel-external-helpers": "./bin/babel-external-helpers"
"babel-external-helpers": "./bin/babel-external-helpers",
"babel-plugin": "./bin/babel-plugin/index.js"
}
}
}

View File

@@ -1,11 +1,10 @@
{
"name": "babel-runtime",
"description": "babel selfContained runtime",
"version": "5.5.0",
"license": "MIT",
"repository": "babel/babel",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"dependencies": {
"core-js": "^0.9.0"
}
}
}

View File

@@ -73,9 +73,8 @@ each(File.helpers, function (helperName) {
writeFile("regenerator/index.js", readFile("regenerator/runtime-module", true));
writeFile("regenerator/runtime.js", selfContainify(readFile("regenerator/runtime")));
//
var coreDefinitions = require("../lib/babel/transformation/transformers/other/runtime/definitions");
var coreDefinitions = require("babel-plugin-runtime/lib/definitions");
var paths = ["is-iterable", "get-iterator"];
@@ -93,6 +92,5 @@ each(paths, function (path) {
writeFile("core-js/" + path + ".js", defaultify('require("core-js/library/fn/' + path + '")'));
});
//
updatePackage();

27
src/README.md Normal file
View File

@@ -0,0 +1,27 @@
## Welcome to the Babel Codebase
Babel is broken down into three parts:
- Parsing
- [Transformation](babel/transformation/)
- [Generation](babel/generation/)
**Parsing** is the process of turning a piece of code into an [ESTree spec](https://github.com/estree/estree) compatible AST (Abstract
Syntax Tree) which is a tree-like object of nodes that _describes_ the code.
This makes it easier to transform the code over direct string manpulation.
**Transformation** is the process of taking an AST and manipulating it into
a new one. For example, Babel might take an ES2015 ArrowFunction and transform
it into a normal Function which will work in ES5 environments.
**Generation** is the process of turning an AST back into code. After Babel is
done transforming the AST, the generation takes over to return normal code.
---
Babel's parsing step is done by [Acorn](https://github.com/marijnh/acorn). However, because Babel is implementing
future standards it maintains a [fork of Acorn](acorn/) in order to do it's job. You can
see that fork in the "acorn" folder.
The transformation and generation steps are both handled inside of the Babel
codebase itself, which is in the "babel" folder here.

View File

@@ -15,6 +15,15 @@ pp.expectRelational = function (op) {
}
}
pp.flow_parseTypeInitialiser = function (tok) {
var oldInType = this.inType
this.inType = true
this.expect(tok || tt.colon)
var type = this.flow_parseType()
this.inType = oldInType
return type;
}
pp.flow_parseDeclareClass = function (node) {
this.next()
this.flow_parseInterfaceish(node, true)
@@ -40,9 +49,7 @@ pp.flow_parseDeclareFunction = function (node) {
typeNode.params = tmp.params
typeNode.rest = tmp.rest
this.expect(tt.parenR)
this.expect(tt.colon)
typeNode.returnType = this.flow_parseType()
typeNode.returnType = this.flow_parseTypeInitialiser()
typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation")
id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation")
@@ -153,15 +160,7 @@ pp.flow_parseTypeAlias = function (node) {
node.typeParameters = null
}
var oldInType = this.inType;
this.inType = true;
this.expect(tt.eq)
node.right = this.flow_parseType()
this.inType = oldInType;
node.right = this.flow_parseTypeInitialiser(tt.eq)
this.semicolon()
return this.finishNode(node, "TypeAlias")
@@ -214,11 +213,9 @@ pp.flow_parseObjectTypeIndexer = function (node, isStatic) {
this.expect(tt.bracketL)
node.id = this.flow_parseObjectPropertyKey()
this.expect(tt.colon)
node.key = this.flow_parseType()
node.key = this.flow_parseTypeInitialiser()
this.expect(tt.bracketR)
this.expect(tt.colon)
node.value = this.flow_parseType()
node.value = this.flow_parseTypeInitialiser()
this.flow_objectTypeSemicolon()
return this.finishNode(node, "ObjectTypeIndexer")
@@ -245,8 +242,7 @@ pp.flow_parseObjectTypeMethodish = function (node) {
node.rest = this.flow_parseFunctionTypeParam()
}
this.expect(tt.parenR)
this.expect(tt.colon)
node.returnType = this.flow_parseType()
node.returnType = this.flow_parseTypeInitialiser()
return this.finishNode(node, "FunctionTypeAnnotation")
}
@@ -265,7 +261,7 @@ pp.flow_parseObjectTypeCallProperty = function (node, isStatic) {
var valueNode = this.startNode()
node.static = isStatic
node.value = this.flow_parseObjectTypeMethodish(valueNode)
this.flow_objectTypeSemicolon()
this.flow_objectTypeSemicolon()
return this.finishNode(node, "ObjectTypeCallProperty")
}
@@ -310,9 +306,8 @@ pp.flow_parseObjectType = function (allowStatic) {
if (this.eat(tt.question)) {
optional = true
}
this.expect(tt.colon)
node.key = propertyKey
node.value = this.flow_parseType()
node.value = this.flow_parseTypeInitialiser()
node.optional = optional
node.static = isStatic
this.flow_objectTypeSemicolon()
@@ -352,12 +347,6 @@ pp.flow_parseGenericType = function (start, id) {
return this.finishNode(node, "GenericTypeAnnotation")
}
pp.flow_parseVoidType = function () {
var node = this.startNode()
this.expect(tt._void)
return this.finishNode(node, "VoidTypeAnnotation")
}
pp.flow_parseTypeofType = function () {
var node = this.startNode()
this.expect(tt._typeof)
@@ -386,9 +375,8 @@ pp.flow_parseFunctionTypeParam = function () {
if (this.eat(tt.question)) {
optional = true
}
this.expect(tt.colon)
node.optional = optional
node.typeAnnotation = this.flow_parseType()
node.typeAnnotation = this.flow_parseTypeInitialiser()
return this.finishNode(node, "FunctionTypeParam")
}
@@ -411,6 +399,9 @@ pp.flow_identToTypeAnnotation = function (start, node, id) {
case "any":
return this.finishNode(node, "AnyTypeAnnotation")
case "void":
return this.finishNode(node, "VoidTypeAnnotation")
case "bool":
case "boolean":
return this.finishNode(node, "BooleanTypeAnnotation")
@@ -524,14 +515,8 @@ pp.flow_parsePrimaryType = function () {
return this.finishNode(node, "StringLiteralTypeAnnotation")
default:
if (this.type.keyword) {
switch (this.type.keyword) {
case "void":
return this.flow_parseVoidType()
case "typeof":
return this.flow_parseTypeofType()
}
if (this.type.keyword === "typeof") {
return this.flow_parseTypeofType()
}
}
@@ -588,13 +573,7 @@ pp.flow_parseType = function () {
pp.flow_parseTypeAnnotation = function () {
var node = this.startNode()
var oldInType = this.inType
this.inType = true
this.expect(tt.colon)
node.typeAnnotation = this.flow_parseType()
this.inType = oldInType
node.typeAnnotation = this.flow_parseTypeInitialiser()
return this.finishNode(node, "TypeAnnotation")
}
@@ -694,6 +673,18 @@ acorn.plugins.flow = function (instance) {
}
})
// don't consider `void` to be a keyword as then it'll use the void token type
// and set startExpr
instance.extend("isKeyword", function (inner) {
return function(name) {
if (this.inType && name === "void") {
return false
} else {
return inner.call(this, name)
}
}
})
instance.extend("readToken", function (inner) {
return function(code) {
if (this.inType && (code === 62 || code === 60)) {
@@ -800,16 +791,15 @@ acorn.plugins.flow = function (instance) {
instance.extend("parseImportSpecifiers", function (inner) {
return function (node) {
node.isType = false
if (this.isContextual("type")) {
var start = this.markPosition()
var typeId = this.parseIdent()
if ((this.type === tt.name && this.value !== "from") || this.type === tt.braceL || this.type === tt.star) {
node.isType = true
} else {
node.specifiers.push(this.parseImportSpecifierDefault(typeId, start))
if (this.isContextual("from")) return
this.eat(tt.comma)
node.importKind = "value"
var kind =
(this.type === tt._typeof ? "typeof" :
(this.isContextual("type") ? "type" : null))
if (kind) {
var lh = this.lookahead()
if ((lh.type === tt.name && lh.value !== "from") || lh.type === tt.braceL || lh.type === tt.star) {
this.next()
node.importKind = kind
}
}
inner.call(this, node)

View File

@@ -29,14 +29,23 @@ const pp = Parser.prototype
// strict mode, init properties are also not allowed to be repeated.
pp.checkPropClash = function(prop, propHash) {
if (this.options.ecmaVersion >= 6) return
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
return
let key = prop.key, name
switch (key.type) {
case "Identifier": name = key.name; break
case "Literal": name = String(key.value); break
default: return
}
let kind = prop.kind || "init", other
let kind = prop.kind
if (this.options.ecmaVersion >= 6) {
if (name === "__proto__" && kind === "init") {
if (propHash.proto) this.raise(key.start, "Redefinition of __proto__ property");
propHash.proto = true
}
return
}
let other
if (has(propHash, name)) {
other = propHash[name]
let isGetSet = kind !== "init"
@@ -260,8 +269,10 @@ pp.parseNoCallExpr = function() {
pp.parseExprAtom = function(refShorthandDefaultPos) {
let node, canBeArrow = this.potentialArrowAt == this.start
switch (this.type) {
case tt._this:
case tt._super:
if (!this.inFunction)
this.raise(this.start, "'super' outside of function or class")
case tt._this:
let type = this.type === tt._this ? "ThisExpression" : "Super"
node = this.startNode()
this.next()
@@ -270,20 +281,6 @@ pp.parseExprAtom = function(refShorthandDefaultPos) {
case tt._yield:
if (this.inGenerator) this.unexpected()
case tt._do:
if (this.options.features["es7.doExpressions"]) {
let node = this.startNode()
this.next()
var oldInFunction = this.inFunction
var oldLabels = this.labels
this.labels = []
this.inFunction = false
node.body = this.parseBlock()
this.inFunction = oldInFunction
this.labels = oldLabels
return this.finishNode(node, "DoExpression")
}
case tt.name:
let start = this.markPosition()
node = this.startNode()
@@ -292,7 +289,7 @@ pp.parseExprAtom = function(refShorthandDefaultPos) {
//
if (this.options.features["es7.asyncFunctions"]) {
// async functions!
if (id.name === "async") {
if (id.name === "async" && !this.canInsertSemicolon()) {
// arrow functions
if (this.type === tt.parenL) {
let expr = this.parseParenAndDistinguishExpression(start, true, true)
@@ -421,9 +418,18 @@ pp.parseParenAndDistinguishExpression = function(start, isAsync, canBeArrow) {
}
let innerStart = this.markPosition(), exprList = [], first = true
let refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart
let refShorthandDefaultPos = {start: 0}, spreadStart, innerParenStart, optionalCommaStart
while (this.type !== tt.parenR) {
first ? first = false : this.expect(tt.comma)
if (first) {
first = false;
} else {
this.expect(tt.comma)
if (this.type === tt.parenR && this.options.features["es7.trailingFunctionCommas"]) {
optionalCommaStart = this.start
break
}
}
if (this.type === tt.ellipsis) {
let spreadNodeStart = this.markPosition()
spreadStart = this.start
@@ -451,6 +457,7 @@ pp.parseParenAndDistinguishExpression = function(start, isAsync, canBeArrow) {
this.unexpected(this.lastTokStart)
}
}
if (optionalCommaStart) this.unexpected(optionalCommaStart)
if (spreadStart) this.unexpected(spreadStart)
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start)
@@ -609,6 +616,14 @@ pp.parseObjPropValue = function (prop, start, isGenerator, isAsync, isPattern, r
prop.kind = prop.key.name
this.parsePropertyName(prop)
prop.value = this.parseMethod(false)
let paramCount = prop.kind === "get" ? 0 : 1
if (prop.value.params.length !== paramCount) {
let start = prop.value.start
if (prop.kind === "get")
this.raise(start, "getter should have no params");
else
this.raise(start, "setter should have exactly one param")
}
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
prop.kind = "init"
if (isPattern) {
@@ -634,12 +649,12 @@ pp.parsePropertyName = function(prop) {
prop.computed = true
prop.key = this.parseMaybeAssign()
this.expect(tt.bracketR)
return
return prop.key
} else {
prop.computed = false
}
}
prop.key = (this.type === tt.num || this.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true)
return prop.key = (this.type === tt.num || this.type === tt.string) ? this.parseExprAtom() : this.parseIdent(true)
}
// Initialize empty function node.

View File

@@ -9,6 +9,7 @@ var STATE_KEYS = [
"lastTokEnd",
"lineStart",
"startLoc",
"curLine",
"endLoc",
"start",
"pos",
@@ -18,7 +19,11 @@ var STATE_KEYS = [
"exprAllowed",
"potentialArrowAt",
"currLine",
"input"
"input",
"inType",
"inFunction",
"inGenerator",
"labels"
];
pp.getState = function () {
@@ -28,6 +33,7 @@ pp.getState = function () {
state[key] = this[key]
}
state.context = this.context.slice()
state.labels = this.labels.slice()
return state
};

View File

@@ -35,6 +35,7 @@ pp.toAssignable = function(node, isBinding) {
case "AssignmentExpression":
if (node.operator === "=") {
node.type = "AssignmentPattern"
delete node.operator
} else {
this.raise(node.left.end, "Only '=' operator can be used for specifying default value.")
}
@@ -171,7 +172,7 @@ pp.checkLVal = function(expr, isBinding, checkClashes) {
break
case "ObjectPattern":
for (let i = 0; i < expr.properties.length; i++) {
for (let i = 0; i < expr.properties.length; i++) {
var prop = expr.properties[i];
if (prop.type === "Property") prop = prop.value;
this.checkLVal(prop, isBinding, checkClashes)
@@ -194,6 +195,10 @@ pp.checkLVal = function(expr, isBinding, checkClashes) {
this.checkLVal(expr.argument, isBinding, checkClashes)
break
case "ParenthesizedExpression":
this.checkLVal(expr.expression, isBinding, checkClashes)
break
default:
this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue")
}

View File

@@ -1,4 +1,4 @@
import {has, isArray} from "./util"
import {has} from "./util"
import {SourceLocation} from "./location"
// A second optional argument can be given to further configure
@@ -94,11 +94,11 @@ export function getOptions(opts) {
for (let opt in defaultOptions)
options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]
if (isArray(options.onToken)) {
if (Array.isArray(options.onToken)) {
let tokens = options.onToken
options.onToken = (token) => tokens.push(token)
}
if (isArray(options.onComment))
if (Array.isArray(options.onComment))
options.onComment = pushComment(options, options.onComment)
return options

View File

@@ -1,13 +1,14 @@
import {reservedWords, keywords} from "./identifier"
import {types as tt, lineBreak} from "./tokentype"
import {types as tt} from "./tokentype"
import {lineBreak} from "./whitespace"
export function Parser(options, input, startPos) {
this.options = options
this.loadPlugins(this.options.plugins)
this.sourceFile = this.options.sourceFile || null
this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5]
this.isReservedWord = reservedWords[this.options.ecmaVersion]
this.input = input
this.loadPlugins(this.options.plugins)
// Set up token state

View File

@@ -83,10 +83,13 @@ pp.parseStatement = function(declaration, topLevel) {
return starttype === tt._import ? this.parseImport(node) : this.parseExport(node)
case tt.name:
if (this.options.features["es7.asyncFunctions"] && this.value === "async" && this.lookahead().type === tt._function) {
this.next();
this.expect(tt._function);
return this.parseFunction(node, true, false, true);
if (this.options.features["es7.asyncFunctions"] && this.value === "async") {
var lookahead = this.lookahead();
if (lookahead.type === tt._function && !this.canInsertSemicolon.call(lookahead)) {
this.next();
this.expect(tt._function);
return this.parseFunction(node, true, false, true);
}
}
// If the statement does not start with a statement keyword or a
@@ -344,7 +347,14 @@ pp.parseLabeledStatement = function(node, maybeName, expr) {
for (let i = 0; i < this.labels.length; ++i)
if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared")
let kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null
this.labels.push({name: maybeName, kind: kind})
for (let i = this.labels.length - 1; i >= 0; i--) {
let label = this.labels[i]
if (label.statementStart == node.start) {
label.statementStart = this.start;
label.kind = kind;
} else break;
}
this.labels.push({name: maybeName, kind: kind, statementStart: this.start})
node.body = this.parseStatement(true)
this.labels.pop()
node.label = expr
@@ -463,6 +473,7 @@ pp.parseClass = function(node, isStatement) {
this.parseClassId(node, isStatement)
this.parseClassSuper(node)
var classBody = this.startNode()
let hadConstructor = false
classBody.body = []
this.expect(tt.braceL)
let decorators = []
@@ -477,16 +488,14 @@ pp.parseClass = function(node, isStatement) {
method.decorators = decorators
decorators = []
}
let isMaybeStatic = this.type === tt.name && this.value === "static"
var isGenerator = this.eat(tt.star), isAsync = false
this.parsePropertyName(method)
if (this.type !== tt.parenL && !method.computed && method.key.type === "Identifier" &&
method.key.name === "static") {
method.static = isMaybeStatic && this.type !== tt.parenL
if (method.static) {
if (isGenerator) this.unexpected()
method['static'] = true
isGenerator = this.eat(tt.star)
this.parsePropertyName(method)
} else {
method['static'] = false
}
if (!isGenerator && method.key.type === "Identifier" && !method.computed && this.isClassProperty()) {
classBody.body.push(this.parseClassProperty(method))
@@ -497,23 +506,39 @@ pp.parseClass = function(node, isStatement) {
isAsync = true
this.parsePropertyName(method)
}
let isGetSet = false
method.kind = "method"
if (!method.computed && !isGenerator && !isAsync) {
if (method.key.type === "Identifier") {
if (this.type !== tt.parenL && (method.key.name === "get" || method.key.name === "set")) {
method.kind = method.key.name
this.parsePropertyName(method)
} else if (!method['static'] && method.key.name === "constructor") {
method.kind = "constructor"
}
} else if (!method['static'] && method.key.type === "Literal" && method.key.value === "constructor") {
if (!method.computed) {
let {key} = method
if (!isAsync && !isGenerator && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
isGetSet = true
method.kind = key.name
key = this.parsePropertyName(method)
}
if (!method.static && (key.type === "Identifier" && key.name === "constructor" ||
key.type === "Literal" && key.value === "constructor")) {
if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class")
if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier")
if (isGenerator) this.raise(key.start, "Constructor can't be a generator")
if (isAsync) this.raise(key.start, "Constructor can't be an async function")
method.kind = "constructor"
hadConstructor = true
}
}
if (method.kind === "constructor" && method.decorators) {
this.raise(method.start, "You can't attach decorators to a class constructor")
}
this.parseClassMethod(classBody, method, isGenerator, isAsync)
if (isGetSet) {
let paramCount = method.kind === "get" ? 0 : 1
if (method.value.params.length !== paramCount) {
let start = method.value.start
if (method.kind === "get")
this.raise(start, "getter should have no params");
else
this.raise(start, "setter should have exactly one param")
}
}
}
if (decorators.length) {
this.raise(this.start, "You have trailing decorators with no method");

View File

@@ -25,6 +25,9 @@ export class Token {
const pp = Parser.prototype
// Are we running under Rhino?
const isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]"
// Move to the next token
pp.next = function() {
@@ -430,23 +433,30 @@ pp.readRegexp = function() {
// negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
// perfectly valid pattern that is equivalent to `[a-b]`, but it would
// be replaced by `[x-b]` which throws an error.
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
tmp = tmp.replace(/\\u\{([0-9a-fA-F]+)\}/g, (match, code, offset) => {
code = Number("0x" + code)
if (code > 0x10FFFF) this.raise(start + offset + 3, "Code point out of bounds")
return "x"
});
tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x")
}
}
// Detect invalid regular expressions.
try {
new RegExp(tmp)
} catch (e) {
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message)
this.raise(e)
}
// Get a regular expression object for this pattern-flag pair, or `null` in
// case the current environment doesn't support the flags it uses.
let value
try {
value = new RegExp(content, mods)
} catch (err) {
value = null
let value = null
// Rhino's regular expression parser is flaky and throws uncatchable exceptions,
// so don't do detection if we are running under Rhino
if (!isRhino) {
try {
new RegExp(tmp)
} catch (e) {
if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message)
this.raise(e)
}
// Get a regular expression object for this pattern-flag pair, or `null` in
// case the current environment doesn't support the flags it uses.
try {
value = new RegExp(content, mods)
} catch (err) {}
}
return this.finishToken(tt.regexp, {pattern: content, flags: mods, value: value})
}
@@ -514,10 +524,10 @@ pp.readCodePoint = function() {
if (ch === 123) {
if (this.options.ecmaVersion < 6) this.unexpected()
++this.pos
let codePos = ++this.pos
code = this.readHexChar(this.input.indexOf('}', this.pos) - this.pos)
++this.pos
if (code > 0x10FFFF) this.unexpected()
if (code > 0x10FFFF) this.raise(codePos, "Code point out of bounds")
} else {
code = this.readHexChar(4)
}
@@ -539,7 +549,7 @@ pp.readString = function(quote) {
if (ch === quote) break
if (ch === 92) { // '\'
out += this.input.slice(chunkStart, this.pos)
out += this.readEscapedChar()
out += this.readEscapedChar(false)
chunkStart = this.pos
} else {
if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant")
@@ -572,7 +582,7 @@ pp.readTmplToken = function() {
}
if (ch === 92) { // '\'
out += this.input.slice(chunkStart, this.pos)
out += this.readEscapedChar()
out += this.readEscapedChar(true)
chunkStart = this.pos
} else if (isNewLine(ch)) {
out += this.input.slice(chunkStart, this.pos)
@@ -600,42 +610,46 @@ pp.readTmplToken = function() {
// Used to read escaped characters
pp.readEscapedChar = function() {
pp.readEscapedChar = function(inTemplate) {
let ch = this.input.charCodeAt(++this.pos)
let octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3))
if (octal) octal = octal[0]
while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1)
if (octal === "0") octal = null
++this.pos
if (octal) {
if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode")
this.pos += octal.length - 1
return String.fromCharCode(parseInt(octal, 8))
} else {
switch (ch) {
case 110: return "\n"; // 'n' -> '\n'
case 114: return "\r"; // 'r' -> '\r'
case 120: return String.fromCharCode(this.readHexChar(2)); // 'x'
case 117: return codePointToString(this.readCodePoint()); // 'u'
case 116: return "\t"; // 't' -> '\t'
case 98: return "\b"; // 'b' -> '\b'
case 118: return "\u000b"; // 'v' -> '\u000b'
case 102: return "\f"; // 'f' -> '\f'
case 48: return "\0"; // 0 -> '\0'
case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
case 10: // ' \n'
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine }
return ""
default: return String.fromCharCode(ch)
switch (ch) {
case 110: return "\n"; // 'n' -> '\n'
case 114: return "\r"; // 'r' -> '\r'
case 120: return String.fromCharCode(this.readHexChar(2)); // 'x'
case 117: return codePointToString(this.readCodePoint()); // 'u'
case 116: return "\t"; // 't' -> '\t'
case 98: return "\b"; // 'b' -> '\b'
case 118: return "\u000b"; // 'v' -> '\u000b'
case 102: return "\f"; // 'f' -> '\f'
case 13: if (this.input.charCodeAt(this.pos) === 10) ++this.pos; // '\r\n'
case 10: // ' \n'
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine }
return ""
default:
if (ch >= 48 && ch <= 55) {
let octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0]
let octal = parseInt(octalStr, 8)
if (octal > 255) {
octalStr = octalStr.slice(0, -1)
octal = parseInt(octalStr, 8)
}
if (octal > 0 && (this.strict || inTemplate)) {
this.raise(this.pos - 2, "Octal literal in strict mode")
}
this.pos += octalStr.length - 1
return String.fromCharCode(octal)
}
return String.fromCharCode(ch)
}
}
// Used to read character escape sequences ('\x', '\u', '\U').
pp.readHexChar = function(len) {
let codePos = this.pos
let n = this.readInt(16, len)
if (n === null) this.raise(this.start, "Bad character escape sequence")
if (n === null) this.raise(codePos, "Bad character escape sequence")
return n
}

View File

@@ -112,7 +112,7 @@ kw("case", beforeExpr)
kw("catch")
kw("continue")
kw("debugger")
kw("default")
kw("default", beforeExpr)
kw("do", {isLoop: true})
kw("else", beforeExpr)
kw("finally")

View File

@@ -1,7 +1,3 @@
export function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]"
}
// Checks if an object has a property.
export function has(obj, propName) {

4
src/babel/README.md Normal file
View File

@@ -0,0 +1,4 @@
## Diving into Babel
If you look around in the various directories in here you'll find some details
about the organization of the Babel codebase.

18
src/babel/api/README.md Normal file
View File

@@ -0,0 +1,18 @@
## API
In this directory you'll find all the public interfaces to using Babel for both
node and the browser.
### Node
There are two ways people use Babel within Node, they either are manipulating
strings of code with `babel.transform` or `babel.parse`, they also might be
running their code through Babel before execution via `register` or `polyfill`.
### Browser
Usage of Babel in the browser is extremely uncommon and in most cases
considered A Bad Idea™. However it works by loading `<script>`'s with XHR,
transforming them and then executing them. These `<script>`'s need to have a
`type` of "text/ecmascript-6", "text/babel", or "module" ("text/6to5" exists as
well for legacy reasons).

View File

@@ -3,16 +3,32 @@
require("./node");
var transform = module.exports = require("../transformation");
/**
* Add `options` and `version` to `babel` global.
*/
transform.options = require("../transformation/file/options");
transform.version = require("../../../package").version;
/**
* Add `transform` api to `babel` global.
*/
transform.transform = transform;
/**
* Tranform and execute script, adding in inline sourcemaps.
*/
transform.run = function (code, opts = {}) {
opts.sourceMaps = "inline";
return new Function(transform(code, opts).code)();
};
/**
* Load scripts via xhr, and `transform` when complete (optional).
*/
transform.load = function (url, callback, opts = {}, hold) {
opts.filename = opts.filename || url;
@@ -20,6 +36,10 @@ transform.load = function (url, callback, opts = {}, hold) {
xhr.open("GET", url, true);
if ("overrideMimeType" in xhr) xhr.overrideMimeType("text/plain");
/**
* When successfully loaded, transform (optional), and call `callback`.
*/
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return;
@@ -36,11 +56,22 @@ transform.load = function (url, callback, opts = {}, hold) {
xhr.send(null);
};
/**
* Load and transform all scripts of `types`.
*
* @example
* <script type="module"></script>
*/
var runScripts = function () {
var scripts = [];
var types = ["text/ecmascript-6", "text/6to5", "text/babel", "module"];
var index = 0;
/**
* Transform and execute script. Ensures correct load order.
*/
var exec = function () {
var param = scripts[index];
if (param instanceof Array) {
@@ -50,6 +81,10 @@ var runScripts = function () {
}
};
/**
* Load, transform, and execute all scripts.
*/
var run = function (script, i) {
var opts = {};
@@ -64,7 +99,9 @@ var runScripts = function () {
}
};
var _scripts = global.document .getElementsByTagName("script");
// Collect scripts with Babel `types`.
var _scripts = global.document.getElementsByTagName("script");
for (var i = 0; i < _scripts.length; ++i) {
var _script = _scripts[i];
@@ -78,6 +115,10 @@ var runScripts = function () {
exec();
};
/**
* Register load event to transform and execute scripts.
*/
if (global.addEventListener) {
global.addEventListener("DOMContentLoaded", runScripts, false);
} else if (global.attachEvent) {

View File

@@ -8,9 +8,10 @@ export { util, acorn, transform };
export { pipeline } from "../transformation";
export { canCompile } from "../util";
export { default as options } from "../transformation/file/options";
export { default as options } from "../transformation/file/options/config";
export { default as Plugin } from "../transformation/plugin";
export { default as Transformer } from "../transformation/transformer";
export { default as TransformerPipeline } from "../transformation/transformer-pipeline";
export { default as Pipeline } from "../transformation/pipeline";
export { default as traverse } from "../traversal";
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
export { version } from "../../../package";
@@ -18,16 +19,28 @@ export { version } from "../../../package";
import * as t from "../types";
export { t as types };
/**
* Register Babel and polyfill globally.
*/
export function register(opts?: Object) {
var callback = require("./register/node-polyfill");
if (opts != null) callback(opts);
return callback;
}
/**
* Register polyfill globally.
*/
export function polyfill() {
require("../polyfill");
}
/**
* Asynchronously transform `filename` with optional `opts`, calls `callback` when complete.
*/
export function transformFile(filename: string, opts?: Object, callback: Function) {
if (isFunction(opts)) {
callback = opts;
@@ -51,11 +64,19 @@ export function transformFile(filename: string, opts?: Object, callback: Functio
});
}
/**
* Synchronous form of `transformFile`.
*/
export function transformFileSync(filename: string, opts?: Object = {}) {
opts.filename = filename;
return transform(fs.readFileSync(filename, "utf8"), opts);
}
/**
* Parse script with Babel's parser.
*/
export function parse(code, opts = {}) {
opts.allowHashBang = true;
opts.sourceType = "module";

View File

@@ -1,21 +1,30 @@
import path from "path";
import fs from "fs";
import homeOrTmp from "home-or-tmp";
import pathExists from "path-exists";
const FILENAME = process.env.BABEL_CACHE_PATH || path.join(homeOrTmp, ".babel.json");
var data = {};
/**
* Write stringified cache to disk.
*/
export function save() {
fs.writeFileSync(FILENAME, JSON.stringify(data, null, " "));
}
/**
* Load cache from disk and parse.
*/
export function load() {
if (process.env.BABEL_DISABLE_CACHE) return;
process.on("exit", save);
process.nextTick(save);
if (!fs.existsSync(FILENAME)) return;
if (!pathExists.sync(FILENAME)) return;
try {
data = JSON.parse(fs.readFileSync(FILENAME));
@@ -24,6 +33,10 @@ export function load() {
}
}
/**
* Retrieve data from cache.
*/
export function get() {
return data;
}

View File

@@ -1,6 +1,6 @@
import sourceMapSupport from "source-map-support";
import * as registerCache from "./cache";
import resolveRc from "../../tools/resolve-rc";
import OptionManager from "../../transformation/file/options/option-manager";
import extend from "lodash/object/extend";
import * as babel from "../node";
import each from "lodash/collection/each";
@@ -8,6 +8,10 @@ import * as util from "../../util";
import fs from "fs";
import path from "path";
/**
* Install sourcemaps into node.
*/
sourceMapSupport.install({
handleUncaughtExceptions: false,
retrieveSourceMap(source) {
@@ -23,12 +27,16 @@ sourceMapSupport.install({
}
});
//
/**
* Load and setup cache.
*/
registerCache.load();
var cache = registerCache.get();
//
/**
* Store options.
*/
var transformOpts = {};
@@ -38,24 +46,34 @@ var only;
var oldHandlers = {};
var maps = {};
var cwd = require.main ? require.main.filename : process.cwd();
var cwd = process.cwd();
/**
* Get path from `filename` relative to the current working directory.
*/
var getRelativePath = function (filename){
return path.relative(cwd, filename);
};
/**
* Get last modified time for a `filename`.
*/
var mtime = function (filename) {
return +fs.statSync(filename).mtime;
};
/**
* Compile a `filename` with optional `opts`.
*/
var compile = function (filename, opts = {}) {
var result;
opts = extend(opts, transformOpts);
// this will be done when the file is transformed anyway but we need all
// the options so we can generate the cache key
resolveRc(filename, opts);
var optsManager = new OptionManager;
optsManager.mergeOptions(transformOpts);
opts = optsManager.init(opts);
var cacheKey = `${filename}:${JSON.stringify(opts)}:${babel.version}`;
@@ -86,14 +104,22 @@ var compile = function (filename, opts = {}) {
return result.code;
};
/**
* Test if a `filename` should be ignored by Babel.
*/
var shouldIgnore = function (filename) {
if (!ignore && !only) {
return getRelativePath(filename).split(path.sep).indexOf("node_modules") >= 0;
} else {
return util.shouldIgnore(filename, ignore || [], only || []);
return util.shouldIgnore(filename, ignore || [], only);
}
};
/**
* Monkey patch istanbul if it is running so that it works properly.
*/
var istanbulMonkey = {};
if (process.env.running_under_istanbul) {
@@ -105,7 +131,7 @@ if (process.env.running_under_istanbul) {
if (istanbulMonkey[filename]) {
delete istanbulMonkey[filename];
var code = compile(filename, {
attachAuxiliaryComment: "istanbul ignore next"
auxiliaryCommentBefore: "istanbul ignore next"
});
istanbulMonkey[filename] = true;
return code;
@@ -115,17 +141,29 @@ if (process.env.running_under_istanbul) {
};
}
/**
* Replacement for the loader for istanbul.
*/
var istanbulLoader = function (m, filename, old) {
istanbulMonkey[filename] = true;
old(m, filename);
};
/**
* Default loader.
*/
var normalLoader = function (m, filename) {
m._compile(compile(filename), filename);
};
/**
* Register a loader for an extension.
*/
var registerExtension = function (ext) {
var old = oldHandlers[ext] || oldHandlers[".js"];
var old = oldHandlers[ext] || oldHandlers[".js"] || require.extensions[".js"];
var loader = normalLoader;
if (process.env.running_under_istanbul) loader = istanbulLoader;
@@ -139,6 +177,10 @@ var registerExtension = function (ext) {
};
};
/**
* Register loader for given extensions.
*/
var hookExtensions = function (_exts) {
each(oldHandlers, function (old, ext) {
if (old === undefined) {
@@ -156,8 +198,16 @@ var hookExtensions = function (_exts) {
});
};
/**
* Register loader for default extensions.
*/
hookExtensions(util.canCompile.EXTENSIONS);
/**
* Update options at runtime.
*/
export default function (opts = {}) {
if (opts.only != null) only = util.arrayify(opts.only, util.regexify);
if (opts.ignore != null) ignore = util.arrayify(opts.ignore, util.regexify);

View File

@@ -0,0 +1,16 @@
## Generation
Here is Babel's code generator, here you'll find all of the code to turn an AST
back into a string of code.
[TBD: To Be Documented:]
- Code Generator
- Buffer
- Source Maps
- Position
- Printer
- Code Style
- Whitespace
- Parenthesis
- Generators

View File

@@ -4,6 +4,10 @@ import isBoolean from "lodash/lang/isBoolean";
import includes from "lodash/collection/includes";
import isNumber from "lodash/lang/isNumber";
/**
* Buffer for collecting generated output.
*/
export default class Buffer {
constructor(position, format) {
this.position = position;
@@ -12,10 +16,18 @@ export default class Buffer {
this.buf = "";
}
/**
* Get the current trimmed buffer.
*/
get() {
return trimRight(this.buf);
}
/**
* Get the current indent.
*/
getIndent() {
if (this.format.compact || this.format.concise) {
return "";
@@ -24,43 +36,80 @@ export default class Buffer {
}
}
/**
* Get the current indent size.
*/
indentSize() {
return this.getIndent().length;
}
/**
* Increment indent size.
*/
indent() {
this._indent++;
}
/**
* Decrement indent size.
*/
dedent() {
this._indent--;
}
/**
* Add a semicolon to the buffer.
*/
semicolon() {
this.push(";");
}
/**
* Ensure last character is a semicolon.
*/
ensureSemicolon() {
if (!this.isLast(";")) this.semicolon();
}
/**
* Add a right brace to the buffer.
*/
rightBrace() {
this.newline(true);
this.push("}");
}
/**
* Add a keyword to the buffer.
*/
keyword(name) {
this.push(name);
this.space();
}
space() {
if (this.format.compact) return;
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) {
/**
* Add a space to the buffer unless it is compact (override with force).
*/
space(force?) {
if (!force && this.format.compact) return;
if (force || this.buf && !this.isLast(" ") && !this.isLast("\n")) {
this.push(" ");
}
}
/**
* Remove the last character.
*/
removeLast(cha) {
if (this.format.compact) return;
if (!this.isLast(cha)) return;
@@ -69,6 +118,11 @@ export default class Buffer {
this.position.unshift(cha);
}
/**
* Add a newline (or many newlines), maintaining formatting.
* Strips multiple newlines if removeLast is true.
*/
newline(i, removeLast) {
if (this.format.compact || this.format.retainLines) return;
@@ -99,6 +153,10 @@ export default class Buffer {
this._newline(removeLast);
}
/**
* Adds a newline unless there is already two previous newlines.
*/
_newline(removeLast) {
// never allow more than two lines
if (this.endsWith("\n\n")) return;
@@ -135,6 +193,10 @@ export default class Buffer {
}
}
/**
* Push a string to the buffer, maintaining indentation and newlines.
*/
push(str, noIndent) {
if (!this.format.compact && this._indent && !noIndent && str !== "\n") {
// we have an indent level and we aren't pushing a newline
@@ -150,15 +212,31 @@ export default class Buffer {
this._push(str);
}
/**
* Push a string to the buffer.
*/
_push(str) {
this.position.push(str);
this.buf += str;
}
endsWith(str) {
return this.buf.slice(-str.length) === str;
/**
* Test if the buffer ends with a string.
*/
endsWith(str, buf = this.buf) {
if (str.length === 1) {
return buf[buf.length - 1] === str;
} else {
return buf.slice(-str.length) === str;
}
}
/**
* Test if a character is last in the buffer.
*/
isLast(cha) {
if (this.format.compact) return false;

View File

@@ -0,0 +1,10 @@
## Generators
Code generation in Babel is broken down into generators by node type, they all
live in this directory.
[TBD: To Be Documented:]
- How generators work
- How to print a node
- How generators related to one another

View File

@@ -1,11 +1,23 @@
/**
* Print File.program
*/
export function File(node, print) {
print.plain(node.program);
}
/**
* Print all nodes in a Program.body.
*/
export function Program(node, print) {
print.sequence(node.body);
}
/**
* Print BlockStatement, collapses empty blocks, prints body.
*/
export function BlockStatement(node, print) {
if (node.body.length === 0) {
this.push("{}");
@@ -17,3 +29,14 @@ export function BlockStatement(node, print) {
this.rightBrace();
}
}
/**
* What is my purpose?
* Why am I here?
* Why are any of us here?
* Does any of this really matter?
*/
export function Noop() {
}

View File

@@ -1,5 +1,9 @@
/**
* Print ClassDeclaration, prints decorators, typeParameters, extends, implements, and body.
*/
export function ClassDeclaration(node, print) {
print.list(node.decorators);
print.list(node.decorators, { separator: "" });
this.push("class");
if (node.id) {
@@ -24,8 +28,16 @@ export function ClassDeclaration(node, print) {
print.plain(node.body);
}
/**
* Alias ClassDeclaration printer as ClassExpression.
*/
export { ClassDeclaration as ClassExpression };
/**
* Print ClassBody, collapses empty blocks, prints body.
*/
export function ClassBody(node, print) {
if (node.body.length === 0) {
this.push("{}");
@@ -41,9 +53,13 @@ export function ClassBody(node, print) {
}
}
/**
* Print ClassProperty, prints decorators, static, key, typeAnnotation, and value.
* Also: semicolons, deal with it.
*/
export function ClassProperty(node, print) {
print.list(node.decorators);
print.list(node.decorators, { separator: "" });
if (node.static) this.push("static ");
print.plain(node.key);
@@ -57,8 +73,12 @@ export function ClassProperty(node, print) {
this.semicolon();
}
/**
* Print MethodDefinition, prints decorations, static, and method.
*/
export function MethodDefinition(node, print) {
print.list(node.decorators);
print.list(node.decorators, { separator: "" });
if (node.static) {
this.push("static ");

View File

@@ -1,3 +1,7 @@
/**
* Prints ComprehensionBlock, prints left and right.
*/
export function ComprehensionBlock(node, print) {
this.keyword("for");
this.push("(");
@@ -7,6 +11,10 @@ export function ComprehensionBlock(node, print) {
this.push(")");
}
/**
* Prints ComprehensionExpression, prints blocks, filter, and body. Handles generators.
*/
export function ComprehensionExpression(node, print) {
this.push(node.generator ? "(" : "[");

View File

@@ -1,30 +1,41 @@
import isInteger from "is-integer";
import isNumber from "lodash/lang/isNumber";
import * as t from "../../types";
/**
* Prints UnaryExpression, prints operator and argument.
*/
export function UnaryExpression(node, print) {
var hasSpace = /[a-z]$/.test(node.operator);
var needsSpace = /[a-z]$/.test(node.operator);
var arg = node.argument;
if (t.isUpdateExpression(arg) || t.isUnaryExpression(arg)) {
hasSpace = true;
needsSpace = true;
}
if (t.isUnaryExpression(arg) && arg.operator === "!") {
hasSpace = false;
needsSpace = false;
}
this.push(node.operator);
if (hasSpace) this.push(" ");
if (needsSpace) this.push(" ");
print.plain(node.argument);
}
export function DoExpression(node, print) {
this.push("do");
this.space();
print.plain(node.body);
/**
* Prints ParenthesizedExpression, prints expression.
*/
export function ParenthesizedExpression(node, print) {
this.push("(");
print.plain(node.expression);
this.push(")");
}
/**
* Prints UpdateExpression, prints operator and argument.
*/
export function UpdateExpression(node, print) {
if (node.prefix) {
this.push(node.operator);
@@ -35,6 +46,10 @@ export function UpdateExpression(node, print) {
}
}
/**
* Prints ConditionalExpression, prints test, consequent, and alternate.
*/
export function ConditionalExpression(node, print) {
print.plain(node.test);
this.space();
@@ -47,6 +62,10 @@ export function ConditionalExpression(node, print) {
print.plain(node.alternate);
}
/**
* Prints NewExpression, prints callee and arguments.
*/
export function NewExpression(node, print) {
this.push("new ");
print.plain(node.callee);
@@ -55,41 +74,59 @@ export function NewExpression(node, print) {
this.push(")");
}
/**
* Prints SequenceExpression.expressions.
*/
export function SequenceExpression(node, print) {
print.list(node.expressions);
}
/**
* Prints ThisExpression.
*/
export function ThisExpression() {
this.push("this");
}
/**
* Prints Super.
*/
export function Super() {
this.push("super");
}
/**
* Prints Decorator, prints expression.
*/
export function Decorator(node, print) {
this.push("@");
print.plain(node.expression);
this.newline();
}
/**
* Prints CallExpression, prints callee and arguments.
*/
export function CallExpression(node, print) {
print.plain(node.callee);
this.push("(");
var separator = ",";
var isPrettyCall = node._prettyCall && !this.format.retainLines;
var isPrettyCall = node._prettyCall && !this.format.retainLines && !this.format.compact;
var separator;
if (isPrettyCall) {
separator += "\n";
separator = ",\n";
this.newline();
this.indent();
} else {
separator += " ";
}
print.list(node.arguments, { separator: separator });
print.list(node.arguments, { separator });
if (isPrettyCall) {
this.newline();
@@ -99,6 +136,11 @@ export function CallExpression(node, print) {
this.push(")");
}
/**
* Builds yield or await expression printer.
* Prints delegate, all, and argument.
*/
var buildYieldAwait = function (keyword) {
return function (node, print) {
this.push(keyword);
@@ -114,40 +156,90 @@ var buildYieldAwait = function (keyword) {
};
};
/**
* Create YieldExpression and AwaitExpression printers.
*/
export var YieldExpression = buildYieldAwait("yield");
export var AwaitExpression = buildYieldAwait("await");
/**
* Prints EmptyStatement.
*/
export function EmptyStatement() {
this.semicolon();
}
/**
* Prints ExpressionStatement, prints expression.
*/
export function ExpressionStatement(node, print) {
print.plain(node.expression);
this.semicolon();
}
/**
* Prints AssignmentPattern, prints left and right.
*/
export function AssignmentPattern(node, print) {
print.plain(node.left);
this.push(" = ");
print.plain(node.right);
}
/**
* Prints AssignmentExpression, prints left, operator, and right.
*/
export function AssignmentExpression(node, print) {
// todo: add cases where the spaces can be dropped when in compact mode
print.plain(node.left);
this.push(" ");
var spaces = node.operator === "in" || node.operator === "instanceof";
spaces = true; // todo: https://github.com/babel/babel/issues/1835
this.space(spaces);
this.push(node.operator);
this.push(" ");
if (!spaces) {
// space is mandatory to avoid outputting <!--
// http://javascript.spec.whatwg.org/#comment-syntax
spaces = node.operator === "<" &&
t.isUnaryExpression(node.right, { prefix: true, operator: "!" }) &&
t.isUnaryExpression(node.right.argument, { prefix: true, operator: "--" });
}
this.space(spaces);
print.plain(node.right);
}
/**
* Prints BindExpression, prints object and callee.
*/
export function BindExpression(node, print) {
print.plain(node.object);
this.push("::");
print.plain(node.callee);
}
/**
* Alias ClassDeclaration printer as ClassExpression,
* and AssignmentExpression printer as LogicalExpression.
*/
export {
AssignmentExpression as BinaryExpression,
AssignmentExpression as LogicalExpression,
AssignmentExpression as AssignmentPattern
AssignmentExpression as LogicalExpression
};
var SCIENTIFIC_NOTATION = /e/i;
/**
* Print MemberExpression, prints object, property, and value. Handles computed.
*/
export function MemberExpression(node, print) {
var obj = node.object;
@@ -167,16 +259,15 @@ export function MemberExpression(node, print) {
print.plain(node.property);
this.push("]");
} else {
// 5..toFixed(2);
if (t.isLiteral(obj) && isInteger(obj.value) && !SCIENTIFIC_NOTATION.test(obj.value.toString())) {
this.push(".");
}
this.push(".");
print.plain(node.property);
}
}
/**
* Print MetaProperty, prints meta and property.
*/
export function MetaProperty(node, print) {
print.plain(node.meta);
this.push(".");

View File

@@ -1,24 +1,44 @@
import * as t from "../../types";
/**
* Prints AnyTypeAnnotation.
*/
export function AnyTypeAnnotation() {
this.push("any");
}
/**
* Prints ArrayTypeAnnotation, prints elementType.
*/
export function ArrayTypeAnnotation(node, print) {
print.plain(node.elementType);
this.push("[");
this.push("]");
}
/**
* Prints BooleanTypeAnnotation.
*/
export function BooleanTypeAnnotation(node) {
this.push("bool");
}
/**
* Prints DeclareClass, prints node.
*/
export function DeclareClass(node, print) {
this.push("declare class ");
this._interfaceish(node, print);
}
/**
* Prints DeclareFunction, prints id and id.typeAnnotation.
*/
export function DeclareFunction(node, print) {
this.push("declare function ");
print.plain(node.id);
@@ -26,6 +46,10 @@ export function DeclareFunction(node, print) {
this.semicolon();
}
/**
* Prints DeclareModule, prints id and body.
*/
export function DeclareModule(node, print) {
this.push("declare module ");
print.plain(node.id);
@@ -33,6 +57,10 @@ export function DeclareModule(node, print) {
print.plain(node.body);
}
/**
* Prints DeclareVariable, prints id and id.typeAnnotation.
*/
export function DeclareVariable(node, print) {
this.push("declare var ");
print.plain(node.id);
@@ -40,6 +68,10 @@ export function DeclareVariable(node, print) {
this.semicolon();
}
/**
* Prints FunctionTypeAnnotation, prints typeParameters, params, and rest.
*/
export function FunctionTypeAnnotation(node, print, parent) {
print.plain(node.typeParameters);
this.push("(");
@@ -68,6 +100,10 @@ export function FunctionTypeAnnotation(node, print, parent) {
print.plain(node.returnType);
}
/**
* Prints FunctionTypeParam, prints name and typeAnnotation, handles optional.
*/
export function FunctionTypeParam(node, print) {
print.plain(node.name);
if (node.optional) this.push("?");
@@ -76,13 +112,26 @@ export function FunctionTypeParam(node, print) {
print.plain(node.typeAnnotation);
}
/**
* Prints InterfaceExtends, prints id and typeParameters.
*/
export function InterfaceExtends(node, print) {
print.plain(node.id);
print.plain(node.typeParameters);
}
/**
* Alias InterfaceExtends printer as ClassImplements,
* and InterfaceExtends printer as GenericTypeAnnotation.
*/
export { InterfaceExtends as ClassImplements, InterfaceExtends as GenericTypeAnnotation };
/**
* Prints interface-like node, prints id, typeParameters, extends, and body.
*/
export function _interfaceish(node, print) {
print.plain(node.id);
print.plain(node.typeParameters);
@@ -94,47 +143,87 @@ export function _interfaceish(node, print) {
print.plain(node.body);
}
/**
* Prints InterfaceDeclaration, prints node.
*/
export function InterfaceDeclaration(node, print) {
this.push("interface ");
this._interfaceish(node, print);
}
/**
* Prints IntersectionTypeAnnotation, prints types.
*/
export function IntersectionTypeAnnotation(node, print) {
print.join(node.types, { separator: " & " });
}
/**
* Prints MixedTypeAnnotation.
*/
export function MixedTypeAnnotation() {
this.push("mixed");
}
/**
* Prints NullableTypeAnnotation, prints typeAnnotation.
*/
export function NullableTypeAnnotation(node, print) {
this.push("?");
print.plain(node.typeAnnotation);
}
/**
* Prints NumberTypeAnnotation.
*/
export function NumberTypeAnnotation() {
this.push("number");
}
/**
* Prints StringLiteralTypeAnnotation, prints value.
*/
export function StringLiteralTypeAnnotation(node) {
this._stringLiteral(node.value);
}
/**
* Prints StringTypeAnnotation.
*/
export function StringTypeAnnotation() {
this.push("string");
}
/**
* Prints TupleTypeAnnotation, prints types.
*/
export function TupleTypeAnnotation(node, print) {
this.push("[");
print.join(node.types, { separator: ", " });
this.push("]");
}
/**
* Prints TypeofTypeAnnotation, prints argument.
*/
export function TypeofTypeAnnotation(node, print) {
this.push("typeof ");
print.plain(node.argument);
}
/**
* Prints TypeAlias, prints id, typeParameters, and right.
*/
export function TypeAlias(node, print) {
this.push("type ");
print.plain(node.id);
@@ -146,6 +235,10 @@ export function TypeAlias(node, print) {
this.semicolon();
}
/**
* Prints TypeAnnotation, prints typeAnnotation, handles optional.
*/
export function TypeAnnotation(node, print) {
this.push(":");
this.space();
@@ -153,14 +246,26 @@ export function TypeAnnotation(node, print) {
print.plain(node.typeAnnotation);
}
/**
* Prints TypeParameterInstantiation, prints params.
*/
export function TypeParameterInstantiation(node, print) {
this.push("<");
print.join(node.params, { separator: ", " });
this.push(">");
}
/**
* Alias TypeParameterInstantiation printer as TypeParameterDeclaration
*/
export { TypeParameterInstantiation as TypeParameterDeclaration };
/**
* Prints ObjectTypeAnnotation, prints properties, callProperties, and indexers.
*/
export function ObjectTypeAnnotation(node, print) {
this.push("{");
var props = node.properties.concat(node.callProperties, node.indexers);
@@ -185,11 +290,19 @@ export function ObjectTypeAnnotation(node, print) {
this.push("}");
}
/**
* Prints ObjectTypeCallProperty, prints value, handles static.
*/
export function ObjectTypeCallProperty(node, print) {
if (node.static) this.push("static ");
print.plain(node.value);
}
/**
* Prints ObjectTypeIndexer, prints id, key, and value, handles static.
*/
export function ObjectTypeIndexer(node, print) {
if (node.static) this.push("static ");
this.push("[");
@@ -203,6 +316,10 @@ export function ObjectTypeIndexer(node, print) {
print.plain(node.value);
}
/**
* Prints ObjectTypeProperty, prints static, key, and value.
*/
export function ObjectTypeProperty(node, print) {
if (node.static) this.push("static ");
print.plain(node.key);
@@ -214,16 +331,28 @@ export function ObjectTypeProperty(node, print) {
print.plain(node.value);
}
/**
* Prints QualifiedTypeIdentifier, prints qualification and id.
*/
export function QualifiedTypeIdentifier(node, print) {
print.plain(node.qualification);
this.push(".");
print.plain(node.id);
}
/**
* Prints UnionTypeAnnotation, prints types.
*/
export function UnionTypeAnnotation(node, print) {
print.join(node.types, { separator: " | " });
}
/**
* Prints TypeCastExpression, prints expression and typeAnnotation.
*/
export function TypeCastExpression(node, print) {
this.push("(");
print.plain(node.expression);
@@ -231,6 +360,10 @@ export function TypeCastExpression(node, print) {
this.push(")");
}
/**
* Prints VoidTypeAnnotation.
*/
export function VoidTypeAnnotation(node) {
this.push("void");
}

View File

@@ -1,5 +1,9 @@
import * as t from "../../types";
/**
* Prints JSXAttribute, prints name and value.
*/
export function JSXAttribute(node, print) {
print.plain(node.name);
if (node.value) {
@@ -8,34 +12,58 @@ export function JSXAttribute(node, print) {
}
}
/**
* Prints JSXIdentifier, prints name.
*/
export function JSXIdentifier(node) {
this.push(node.name);
}
/**
* Prints JSXNamespacedName, prints namespace and name.
*/
export function JSXNamespacedName(node, print) {
print.plain(node.namespace);
this.push(":");
print.plain(node.name);
}
/**
* Prints JSXMemberExpression, prints object and property.
*/
export function JSXMemberExpression(node, print) {
print.plain(node.object);
this.push(".");
print.plain(node.property);
}
/**
* Prints JSXSpreadAttribute, prints argument.
*/
export function JSXSpreadAttribute(node, print) {
this.push("{...");
print.plain(node.argument);
this.push("}");
}
/**
* Prints JSXExpressionContainer, prints expression.
*/
export function JSXExpressionContainer(node, print) {
this.push("{");
print.plain(node.expression);
this.push("}");
}
/**
* Prints JSXElement, prints openingElement, children, and closingElement.
*/
export function JSXElement(node, print) {
var open = node.openingElement;
print.plain(open);
@@ -54,6 +82,10 @@ export function JSXElement(node, print) {
print.plain(node.closingElement);
}
/**
* Prints JSXOpeningElement, prints name and attributes, handles selfClosing.
*/
export function JSXOpeningElement(node, print) {
this.push("<");
print.plain(node.name);
@@ -64,10 +96,18 @@ export function JSXOpeningElement(node, print) {
this.push(node.selfClosing ? " />" : ">");
}
/**
* Prints JSXClosingElement, prints name.
*/
export function JSXClosingElement(node, print) {
this.push("</");
print.plain(node.name);
this.push(">");
}
/**
* Prints JSXEmptyExpression.
*/
export function JSXEmptyExpression() {}

View File

@@ -1,5 +1,9 @@
import * as t from "../../types";
/**
* Prints nodes with params, prints typeParameters, params, and returnType, handles optional params.
*/
export function _params(node, print) {
print.plain(node.typeParameters);
this.push("(");
@@ -16,6 +20,10 @@ export function _params(node, print) {
}
}
/**
* Prints method-like nodes, prints key, value, and body, handles async, generator, computed, and get or set.
*/
export function _method(node, print) {
var value = node.value;
var kind = node.kind;
@@ -42,10 +50,14 @@ export function _method(node, print) {
}
this._params(value, print);
this.push(" ");
this.space();
print.plain(value.body);
}
/**
* Prints FunctionExpression, prints id and body, handles async and generator.
*/
export function FunctionExpression(node, print) {
if (node.async) this.push("async ");
this.push("function");
@@ -63,8 +75,17 @@ export function FunctionExpression(node, print) {
print.plain(node.body);
}
/**
* Alias FunctionExpression printer as FunctionDeclaration.
*/
export { FunctionExpression as FunctionDeclaration };
/**
* Prints ArrowFunctionExpression, prints params and body, handles async.
* Leaves out parentheses when single param.
*/
export function ArrowFunctionExpression(node, print) {
if (node.async) this.push("async ");

View File

@@ -1,5 +1,9 @@
import * as t from "../../types";
/**
* Prints ImportSpecifier, prints imported and local.
*/
export function ImportSpecifier(node, print) {
print.plain(node.imported);
if (node.local && node.local.name !== node.imported.name) {
@@ -8,14 +12,26 @@ export function ImportSpecifier(node, print) {
}
}
/**
* Prints ImportDefaultSpecifier, prints local.
*/
export function ImportDefaultSpecifier(node, print) {
print.plain(node.local);
}
/**
* Prints ExportDefaultSpecifier, prints exported.
*/
export function ExportDefaultSpecifier(node, print) {
print.plain(node.exported);
}
/**
* Prints ExportSpecifier, prints local and exported.
*/
export function ExportSpecifier(node, print) {
print.plain(node.local);
if (node.exported && node.local.name !== node.exported.name) {
@@ -24,11 +40,19 @@ export function ExportSpecifier(node, print) {
}
}
/**
* Prints ExportNamespaceSpecifier, prints exported.
*/
export function ExportNamespaceSpecifier(node, print) {
this.push("* as ");
print.plain(node.exported);
}
/**
* Prints ExportAllDeclaration, prints exported and source.
*/
export function ExportAllDeclaration(node, print) {
this.push("export *");
if (node.exported) {
@@ -40,16 +64,28 @@ export function ExportAllDeclaration(node, print) {
this.semicolon();
}
/**
* Prints ExportNamedDeclaration, delegates to ExportDeclaration.
*/
export function ExportNamedDeclaration(node, print) {
this.push("export ");
ExportDeclaration.call(this, node, print);
}
/**
* Prints ExportDefaultDeclaration, delegates to ExportDeclaration.
*/
export function ExportDefaultDeclaration(node, print) {
this.push("export default ");
ExportDeclaration.call(this, node, print);
}
/**
* Prints ExportDeclaration, prints specifiers, declration, and source.
*/
function ExportDeclaration(node, print) {
var specifiers = node.specifiers;
@@ -87,11 +123,15 @@ function ExportDeclaration(node, print) {
this.ensureSemicolon();
}
/**
* Prints ImportDeclaration, prints specifiers and source, handles isType.
*/
export function ImportDeclaration(node, print) {
this.push("import ");
if (node.isType) {
this.push("type ");
if (node.importKind === "type" || node.importKind === "typeof") {
this.push(node.importKind + " ");
}
var specfiers = node.specifiers;
@@ -119,6 +159,10 @@ export function ImportDeclaration(node, print) {
this.semicolon();
}
/**
* Prints ImportNamespaceSpecifier, prints local.
*/
export function ImportNamespaceSpecifier(node, print) {
this.push("* as ");
print.plain(node.local);

View File

@@ -1,6 +1,10 @@
import repeating from "repeating";
import * as t from "../../types";
/**
* Prints WithStatement, prints object and body.
*/
export function WithStatement(node, print) {
this.keyword("with");
this.push("(");
@@ -9,6 +13,10 @@ export function WithStatement(node, print) {
print.block(node.body);
}
/**
* Prints IfStatement, prints test, consequent, and alternate.
*/
export function IfStatement(node, print) {
this.keyword("if");
this.push("(");
@@ -25,6 +33,10 @@ export function IfStatement(node, print) {
}
}
/**
* Prints ForStatement, prints init, test, update, and body.
*/
export function ForStatement(node, print) {
this.keyword("for");
this.push("(");
@@ -33,13 +45,13 @@ export function ForStatement(node, print) {
this.push(";");
if (node.test) {
this.push(" ");
this.space();
print.plain(node.test);
}
this.push(";");
if (node.update) {
this.push(" ");
this.space();
print.plain(node.update);
}
@@ -47,6 +59,10 @@ export function ForStatement(node, print) {
print.block(node.body);
}
/**
* Prints WhileStatement, prints test and body.
*/
export function WhileStatement(node, print) {
this.keyword("while");
this.push("(");
@@ -55,6 +71,11 @@ export function WhileStatement(node, print) {
print.block(node.body);
}
/**
* Builds ForIn or ForOf statement printers.
* Prints left, right, and body.
*/
var buildForXStatement = function (op) {
return function (node, print) {
this.keyword("for");
@@ -67,9 +88,17 @@ var buildForXStatement = function (op) {
};
};
/**
* Create ForInStatement and ForOfStatement printers.
*/
export var ForInStatement = buildForXStatement("in");
export var ForOfStatement = buildForXStatement("of");
/**
* Prints DoWhileStatement, prints body and test.
*/
export function DoWhileStatement(node, print) {
this.push("do ");
print.plain(node.body);
@@ -80,6 +109,11 @@ export function DoWhileStatement(node, print) {
this.push(");");
}
/**
* Builds continue, return, or break statement printers.
* Prints label (or key).
*/
var buildLabelStatement = function (prefix, key) {
return function (node, print) {
this.push(prefix);
@@ -94,16 +128,28 @@ var buildLabelStatement = function (prefix, key) {
};
};
/**
* Create ContinueStatement, ReturnStatement, and BreakStatement printers.
*/
export var ContinueStatement = buildLabelStatement("continue");
export var ReturnStatement = buildLabelStatement("return", "argument");
export var BreakStatement = buildLabelStatement("break");
/**
* Prints LabeledStatement, prints label and body.
*/
export function LabeledStatement(node, print) {
print.plain(node.label);
this.push(": ");
print.plain(node.body);
}
/**
* Prints TryStatement, prints block, handlers, and finalizer.
*/
export function TryStatement(node, print) {
this.keyword("try");
print.plain(node.block);
@@ -125,6 +171,10 @@ export function TryStatement(node, print) {
}
}
/**
* Prints CatchClause, prints param and body.
*/
export function CatchClause(node, print) {
this.keyword("catch");
this.push("(");
@@ -133,12 +183,20 @@ export function CatchClause(node, print) {
print.plain(node.body);
}
/**
* Prints ThrowStatement, prints argument.
*/
export function ThrowStatement(node, print) {
this.push("throw ");
print.plain(node.argument);
this.semicolon();
}
/**
* Prints SwitchStatement, prints discriminant and cases.
*/
export function SwitchStatement(node, print) {
this.keyword("switch");
this.push("(");
@@ -157,6 +215,10 @@ export function SwitchStatement(node, print) {
this.push("}");
}
/**
* Prints SwitchCase, prints test and consequent.
*/
export function SwitchCase(node, print) {
if (node.test) {
this.push("case ");
@@ -172,10 +234,18 @@ export function SwitchCase(node, print) {
}
}
/**
* Prints DebuggerStatement.
*/
export function DebuggerStatement() {
this.push("debugger;");
}
/**
* Prints VariableDeclaration, prints declarations, handles kind and format.
*/
export function VariableDeclaration(node, print, parent) {
this.push(node.kind + " ");
@@ -190,22 +260,39 @@ export function VariableDeclaration(node, print, parent) {
}
}
var sep = ",";
//
// use a pretty separator when we aren't in compact mode, have initializers and don't have retainLines on
// this will format declarations like:
//
// var foo = "bar", bar = "foo";
//
// into
//
// var foo = "bar",
// bar = "foo";
//
var sep;
if (!this.format.compact && !this.format.concise && hasInits && !this.format.retainLines) {
sep += `\n${repeating(" ", node.kind.length + 1)}`;
} else {
sep += " ";
sep = `,\n${repeating(" ", node.kind.length + 1)}`;
}
//
print.list(node.declarations, { separator: sep });
if (t.isFor(parent)) {
// don't give semicolons to these nodes since they'll be inserted in the parent generator
if (parent.left === node || parent.init === node) return;
}
this.semicolon();
}
/**
* Prints VariableDeclarator, handles id, id.typeAnnotation, and init.
*/
export function VariableDeclarator(node, print) {
print.plain(node.id);
print.plain(node.id.typeAnnotation);

View File

@@ -1,12 +1,24 @@
/**
* Prints TaggedTemplateExpression, prints tag and quasi.
*/
export function TaggedTemplateExpression(node, print) {
print.plain(node.tag);
print.plain(node.quasi);
}
/**
* Prints TemplateElement, prints value.
*/
export function TemplateElement(node) {
this._push(node.value.raw);
}
/**
* Prints TemplateLiteral, prints quasis, and expressions.
*/
export function TemplateLiteral(node, print) {
this.push("`");

View File

@@ -1,18 +1,36 @@
/* eslint quotes: 0 */
import isInteger from "is-integer";
import * as t from "../../types";
/**
* Prints Identifier, prints name.
*/
export function Identifier(node) {
this.push(node.name);
}
/**
* Prints RestElement, prints argument.
*/
export function RestElement(node, print) {
this.push("...");
print.plain(node.argument);
}
/**
* Alias RestElement printer as SpreadElement,
* and RestElement printer as SpreadProperty.
*/
export { RestElement as SpreadElement, RestElement as SpreadProperty };
/**
* Prints ObjectExpression, prints properties.
*/
export function ObjectExpression(node, print) {
var props = node.properties;
@@ -29,9 +47,19 @@ export function ObjectExpression(node, print) {
}
}
/**
* Alias ObjectExpression printer as ObjectPattern.
*/
export { ObjectExpression as ObjectPattern };
/**
* Prints Property, prints decorators, key, and value, handles kind, computed, and shorthand.
*/
export function Property(node, print) {
print.list(node.decorators, { separator: "" });
if (node.method || node.kind === "get" || node.kind === "set") {
this._method(node, print);
} else {
@@ -63,6 +91,10 @@ export function Property(node, print) {
}
}
/**
* Prints ArrayExpression, prints elements.
*/
export function ArrayExpression(node, print) {
var elems = node.elements;
var len = elems.length;
@@ -79,7 +111,7 @@ export function ArrayExpression(node, print) {
// both (all) of the holes.
this.push(",");
} else {
if (i > 0) this.push(" ");
if (i > 0) this.space();
print.plain(elem);
if (i < len - 1) this.push(",");
}
@@ -88,16 +120,43 @@ export function ArrayExpression(node, print) {
this.push("]");
}
/**
* Alias ArrayExpression printer as ArrayPattern.
*/
export { ArrayExpression as ArrayPattern };
export function Literal(node) {
/**
* RegExp for testing scientific notation in literals.
*/
const SCIENTIFIC_NOTATION = /e/i;
/**
* Prints Literal, prints value, regex, raw, handles val type.
*/
export function Literal(node, print, parent) {
var val = node.value;
var type = typeof val;
if (type === "string") {
this._stringLiteral(val);
} else if (type === "number") {
this.push(val + "");
// check to see if this is the same number as the raw one in the original source as asm.js uses
// numbers in the form 5.0 for type hinting
var raw = node.raw;
if (val === +raw && raw[raw.length - 1] !== "." && !/^0[bo]/i.test(raw)) {
val = raw;
}
val = val + "";
if (isInteger(+val) && t.isMemberExpression(parent, { object: node }) && !SCIENTIFIC_NOTATION.test(val)) {
val += ".";
}
this.push(val);
} else if (type === "boolean") {
this.push(val ? "true" : "false");
} else if (node.regex) {
@@ -107,6 +166,10 @@ export function Literal(node) {
}
}
/**
* Prints string literals, handles format.
*/
export function _stringLiteral(val) {
val = JSON.stringify(val);
@@ -116,9 +179,16 @@ export function _stringLiteral(val) {
});
if (this.format.quotes === "single") {
// remove double quotes
val = val.slice(1, -1);
// unescape double quotes
val = val.replace(/\\"/g, '"');
// escape single quotes
val = val.replace(/'/g, "\\'");
// add single quotes
val = `'${val}'`;
}

View File

@@ -11,6 +11,11 @@ import each from "lodash/collection/each";
import n from "./node";
import * as t from "../types";
/**
* Babel's code generator, turns an ast into code, maintaining sourcemaps,
* user preferences, and valid output.
*/
class CodeGenerator {
constructor(ast, opts, code) {
opts = opts || {};
@@ -27,6 +32,13 @@ class CodeGenerator {
this.buffer = new Buffer(this.position, this.format);
}
/**
* Normalize generator options, setting defaults.
*
* - Detects code indentation.
* - If `opts.compact = "auto"` and the code is over 100KB, `compact` will be set to `true`.
*/
static normalizeOptions(code, opts, tokens) {
var style = " ";
if (code) {
@@ -57,6 +69,9 @@ class CodeGenerator {
return format;
}
/**
* Determine if input code uses more single or double quotes.
*/
static findCommonStringDelimiter(code, tokens) {
var occurences = {
single: 0,
@@ -79,7 +94,6 @@ class CodeGenerator {
checked++;
if (checked >= 3) break;
}
if (occurences.single > occurences.double) {
return "single";
} else {
@@ -87,6 +101,10 @@ class CodeGenerator {
}
}
/**
* All node generators.
*/
static generators = {
templateLiterals: require("./generators/template-literals"),
comprehensions: require("./generators/comprehensions"),
@@ -101,6 +119,12 @@ class CodeGenerator {
jsx: require("./generators/jsx")
};
/**
* Generate code and sourcemap from ast.
*
* Appends comments that weren't attached to any node to the end of the generated output.
*/
generate() {
var ast = this.ast;
@@ -120,16 +144,23 @@ class CodeGenerator {
};
}
/**
* Build NodePrinter.
*/
buildPrint(parent) {
return new NodePrinter(this, parent);
}
/**
* [Please add a description.]
*/
catchUp(node, parent, leftParenPrinted) {
// catch up to this nodes newline if we're behind
if (node.loc && this.format.retainLines && this.buffer.buf) {
var needsParens = false;
if (!leftParenPrinted && parent &&
this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
if (!leftParenPrinted && parent && this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
needsParens = true;
this._push("(");
}
@@ -141,6 +172,10 @@ class CodeGenerator {
return false;
}
/**
* [Please add a description.]
*/
_printNewline(leading, node, parent, opts) {
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
return;
@@ -171,6 +206,10 @@ class CodeGenerator {
this.newline(lines);
}
/**
* [Please add a description.]
*/
print(node, parent, opts = {}) {
if (!node) return;
@@ -220,6 +259,10 @@ class CodeGenerator {
}
}
/**
* [Please add a description.]
*/
printJoin(print, nodes, opts = {}) {
if (!nodes || !nodes.length) return;
@@ -249,6 +292,10 @@ class CodeGenerator {
if (opts.indent) this.dedent();
}
/**
* [Please add a description.]
*/
printAndIndentOnComments(print, node) {
var indent = !!node.leadingComments;
if (indent) this.indent();
@@ -256,6 +303,10 @@ class CodeGenerator {
if (indent) this.dedent();
}
/**
* [Please add a description.]
*/
printBlock(print, node) {
if (t.isEmptyStatement(node)) {
this.semicolon();
@@ -265,6 +316,10 @@ class CodeGenerator {
}
}
/**
* [Please add a description.]
*/
generateComment(comment) {
var val = comment.value;
if (comment.type === "CommentLine") {
@@ -275,14 +330,26 @@ class CodeGenerator {
return val;
}
/**
* [Please add a description.]
*/
printTrailingComments(node, parent) {
this._printComments(this.getComments("trailingComments", node, parent));
}
/**
* [Please add a description.]
*/
printLeadingComments(node, parent) {
this._printComments(this.getComments("leadingComments", node, parent));
}
/**
* [Please add a description.]
*/
getComments(key, node, parent) {
if (t.isExpressionStatement(parent)) {
return [];
@@ -302,10 +369,18 @@ class CodeGenerator {
return comments;
}
/**
* [Please add a description.]
*/
_getComments(key, node) {
return (node && node[key]) || [];
}
/**
* [Please add a description.]
*/
_printComments(comments) {
if (this.format.compact) return;
if (!this.format.comments) return;
@@ -344,7 +419,7 @@ class CodeGenerator {
//
if (comment.type === "CommentBlock" && this.format.indent.adjustMultilineComment) {
var offset = comment.loc.start.column;
var offset = comment.loc && comment.loc.start.column;
if (offset) {
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
val = val.replace(newlineRegex, "\n");
@@ -373,16 +448,28 @@ class CodeGenerator {
}
}
/**
* [Please add a description.]
*/
each(Buffer.prototype, function (fn, key) {
CodeGenerator.prototype[key] = function () {
return fn.apply(this.buffer, arguments);
};
});
/**
* [Please add a description.]
*/
each(CodeGenerator.generators, function (generator) {
extend(CodeGenerator.prototype, generator);
});
/**
* [Please add a description.]
*/
module.exports = function (ast, opts, code) {
var gen = new CodeGenerator(ast, opts, code);
return gen.generate();

View File

@@ -4,6 +4,16 @@ import each from "lodash/collection/each";
import some from "lodash/collection/some";
import * as t from "../../types";
/**
* Test if node matches a set of type-matcher pairs.
* @example
* find({
* VariableDeclaration(node, parent) {
* return true;
* }
* }, node, parent);
*/
var find = function (obj, node, parent) {
if (!obj) return;
var result;
@@ -22,16 +32,28 @@ var find = function (obj, node, parent) {
return result;
};
/**
* Whitespace and Parenthesis related methods for nodes.
*/
export default class Node {
constructor(node, parent) {
this.parent = parent;
this.node = node;
}
/**
* Test if `node` can have whitespace set by the user.
*/
static isUserWhitespacable(node) {
return t.isUserWhitespacable(node);
}
/**
* Test if a `node` requires whitespace.
*/
static needsWhitespace(node, parent, type) {
if (!node) return 0;
@@ -54,14 +76,26 @@ export default class Node {
return (linesInfo && linesInfo[type]) || 0;
}
/**
* Test if a `node` requires whitespace before it.
*/
static needsWhitespaceBefore(node, parent) {
return Node.needsWhitespace(node, parent, "before");
}
/**
* Test if a `note` requires whitespace after it.
*/
static needsWhitespaceAfter(node, parent) {
return Node.needsWhitespace(node, parent, "after");
}
/**
* Test if a `node` needs parentheses around it.
*/
static needsParens(node, parent) {
if (!parent) return false;
@@ -77,6 +111,10 @@ export default class Node {
return find(parens, node, parent);
}
/**
* [Please add a description.]
*/
static needsParensNoLineTerminator(node, parent) {
if (!parent) return false;
@@ -89,6 +127,10 @@ export default class Node {
}
}
/**
* Add all static methods from `Node` to `Node.prototype`.
*/
each(Node, function (fn, key) {
Node.prototype[key] = function () {
// Avoid leaking arguments to prevent deoptimization

View File

@@ -1,6 +1,12 @@
import each from "lodash/collection/each";
import * as t from "../../types";
/**
* Create a mapping of operators to precendence.
*
* @example
* { "==": 6, "+": 9 }
*/
const PRECEDENCE = {};
each([
@@ -21,12 +27,24 @@ each([
});
});
/**
* Test if NullableTypeAnnotation needs parentheses.
*/
export function NullableTypeAnnotation(node, parent) {
return t.isArrayTypeAnnotation(parent);
}
/**
* Alias NullableTypeAnnotation test as FunctionTypeAnnotation.
*/
export { NullableTypeAnnotation as FunctionTypeAnnotation };
/**
* Test if UpdateExpression needs parentheses.
*/
export function UpdateExpression(node, parent) {
if (t.isMemberExpression(parent) && parent.object === node) {
// (foo++).test()
@@ -34,6 +52,10 @@ export function UpdateExpression(node, parent) {
}
}
/**
* Test if ObjectExpression needs parentheses.
*/
export function ObjectExpression(node, parent) {
if (t.isExpressionStatement(parent)) {
// ({ foo: "bar" });
@@ -48,6 +70,10 @@ export function ObjectExpression(node, parent) {
return false;
}
/**
* Test if Binary needs parentheses.
*/
export function Binary(node, parent) {
if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) {
return true;
@@ -78,6 +104,10 @@ export function Binary(node, parent) {
}
}
/**
* Test if BinaryExpression needs parentheses.
*/
export function BinaryExpression(node, parent) {
if (node.operator === "in") {
// var i = (1 in []);
@@ -92,6 +122,10 @@ export function BinaryExpression(node, parent) {
}
}
/**
* Test if SequenceExpression needs parentheses.
*/
export function SequenceExpression(node, parent) {
if (t.isForStatement(parent)) {
// Although parentheses wouldn't hurt around sequence
@@ -110,6 +144,10 @@ export function SequenceExpression(node, parent) {
return true;
}
/**
* Test if YieldExpression needs parentheses.
*/
export function YieldExpression(node, parent) {
return t.isBinary(parent) ||
t.isUnaryLike(parent) ||
@@ -120,14 +158,26 @@ export function YieldExpression(node, parent) {
t.isYieldExpression(parent);
}
/**
* Test if ClassExpression needs parentheses.
*/
export function ClassExpression(node, parent) {
return t.isExpressionStatement(parent);
}
/**
* Test if UnaryLike needs parentheses.
*/
export function UnaryLike(node, parent) {
return t.isMemberExpression(parent) && parent.object === node;
}
/**
* Test if FunctionExpression needs parentheses.
*/
export function FunctionExpression(node, parent) {
// function () {};
if (t.isExpressionStatement(parent)) {
@@ -145,6 +195,10 @@ export function FunctionExpression(node, parent) {
}
}
/**
* Test if ConditionalExpression needs parentheses.
*/
export function ConditionalExpression(node, parent) {
if (t.isUnaryLike(parent)) {
return true;
@@ -171,6 +225,10 @@ export function ConditionalExpression(node, parent) {
return false;
}
/**
* Test if AssignmentExpression needs parentheses.
*/
export function AssignmentExpression(node) {
if (t.isObjectPattern(node.left)) {
return true;

View File

@@ -1,31 +1,63 @@
/**
* Printer for nodes, needs a `generator` and a `parent`.
*/
export default class NodePrinter {
constructor(generator, parent) {
this.generator = generator;
this.parent = parent;
}
/**
* Print a plain node.
*/
plain(node, opts) {
return this.generator.print(node, this.parent, opts);
}
/**
* Print a sequence of nodes as statements.
*/
sequence(nodes, opts = {}) {
opts.statement = true;
return this.generator.printJoin(this, nodes, opts);
}
/**
* Print a sequence of nodes as expressions.
*/
join(nodes, opts) {
return this.generator.printJoin(this, nodes, opts);
}
/**
* Print a list of nodes, with a customizable separator (defaults to ",").
*/
list(items, opts = {}) {
if (opts.separator == null) opts.separator = ", ";
if (opts.separator == null) {
opts.separator = ",";
if (!this.generator.format.compact) opts.separator += " ";
}
return this.join(items, opts);
}
/**
* Print a block-like node.
*/
block(node) {
return this.generator.printBlock(this, node);
}
/**
* Print node and indent comments.
*/
indentOnComments(node) {
return this.generator.printAndIndentOnComments(this, node);
}

View File

@@ -3,6 +3,14 @@ import each from "lodash/collection/each";
import map from "lodash/collection/map";
import * as t from "../../types";
/**
* Crawl a node to test if it contains a CallExpression, a Function, or a Helper.
*
* @example
* crawl(node)
* // { hasCall: false, hasFunction: true, hasHelper: false }
*/
function crawl(node, state = {}) {
if (t.isMemberExpression(node)) {
crawl(node.object, state);
@@ -22,6 +30,10 @@ function crawl(node, state = {}) {
return state;
}
/**
* Test if a node is or has a helper.
*/
function isHelper(node) {
if (t.isMemberExpression(node)) {
return isHelper(node.object) || isHelper(node.property);
@@ -36,12 +48,25 @@ function isHelper(node) {
}
}
/**
* [Please add a description.]
*/
function isType(node) {
return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) ||
t.isIdentifier(node) || t.isMemberExpression(node);
}
/**
* Tests for node types that need whitespace.
*/
exports.nodes = {
/**
* Test if AssignmentExpression needs whitespace.
*/
AssignmentExpression(node) {
var state = crawl(node.right);
if ((state.hasCall && state.hasHelper) || state.hasFunction) {
@@ -52,12 +77,20 @@ exports.nodes = {
}
},
/**
* Test if SwitchCase needs whitespace.
*/
SwitchCase(node, parent) {
return {
before: node.consequent.length || parent.cases[0] === node
};
},
/**
* Test if LogicalExpression needs whitespace.
*/
LogicalExpression(node) {
if (t.isFunction(node.left) || t.isFunction(node.right)) {
return {
@@ -66,6 +99,10 @@ exports.nodes = {
}
},
/**
* Test if Literal needs whitespace.
*/
Literal(node) {
if (node.value === "use strict") {
return {
@@ -74,6 +111,10 @@ exports.nodes = {
}
},
/**
* Test if CallExpression needs whitespace.
*/
CallExpression(node) {
if (t.isFunction(node.callee) || isHelper(node)) {
return {
@@ -83,6 +124,10 @@ exports.nodes = {
}
},
/**
* Test if VariableDeclaration needs whitespace.
*/
VariableDeclaration(node) {
for (var i = 0; i < node.declarations.length; i++) {
var declar = node.declarations[i];
@@ -102,6 +147,10 @@ exports.nodes = {
}
},
/**
* Test if IfStatement needs whitespace.
*/
IfStatement(node) {
if (t.isBlockStatement(node.consequent)) {
return {
@@ -112,6 +161,10 @@ exports.nodes = {
}
};
/**
* Test if Property or SpreadProperty needs whitespace.
*/
exports.nodes.Property =
exports.nodes.SpreadProperty = function (node, parent) {
if (parent.properties[0] === node) {
@@ -121,20 +174,41 @@ exports.nodes.SpreadProperty = function (node, parent) {
}
};
/**
* Returns lists from node types that need whitespace.
*/
exports.list = {
/**
* Return VariableDeclaration declarations init properties.
*/
VariableDeclaration(node) {
return map(node.declarations, "init");
},
/**
* Return VariableDeclaration elements.
*/
ArrayExpression(node) {
return node.elements;
},
/**
* Return VariableDeclaration properties.
*/
ObjectExpression(node) {
return node.properties;
}
};
/**
* Add whitespace tests for nodes and their aliases.
*/
each({
Function: true,
Class: true,

View File

@@ -1,9 +1,17 @@
/**
* Track current position in code generation.
*/
export default class Position {
constructor() {
this.line = 1;
this.column = 0;
}
/**
* Push a string to the current position, mantaining the current line and column.
*/
push(str) {
for (var i = 0; i < str.length; i++) {
if (str[i] === "\n") {
@@ -15,6 +23,10 @@ export default class Position {
}
}
/**
* Unshift a string from the current position, mantaining the current line and column.
*/
unshift(str) {
for (var i = 0; i < str.length; i++) {
if (str[i] === "\n") {

View File

@@ -1,6 +1,10 @@
import sourceMap from "source-map";
import * as t from "../types";
/**
* Build a sourcemap.
*/
export default class SourceMap {
constructor(position, opts, code) {
this.position = position;
@@ -18,6 +22,10 @@ export default class SourceMap {
}
}
/**
* Get the sourcemap.
*/
get() {
var map = this.map;
if (map) {
@@ -27,6 +35,10 @@ export default class SourceMap {
}
}
/**
* Mark a node's generated position, and add it to the sourcemap.
*/
mark(node, type) {
var loc = node.loc;
if (!loc) return; // no location info

View File

@@ -18,6 +18,10 @@ function getLookupIndex(i, base, max) {
return i;
}
/**
* Get whitespace around tokens.
*/
export default class Whitespace {
constructor(tokens) {
this.tokens = tokens;
@@ -34,6 +38,10 @@ export default class Whitespace {
this._lastFoundIndex = 0;
}
/**
* Count all the newlines before a node.
*/
getNewlinesBefore(node) {
var startToken;
var endToken;
@@ -57,6 +65,10 @@ export default class Whitespace {
return this.getNewlinesBetween(startToken, endToken);
}
/**
* Count all the newlines after a node.
*/
getNewlinesAfter(node) {
var startToken;
var endToken;
@@ -91,6 +103,10 @@ export default class Whitespace {
}
}
/**
* Count all the newlines between two tokens.
*/
getNewlinesBetween(startToken, endToken) {
if (!endToken || !endToken.loc) return 0;

View File

@@ -0,0 +1,4 @@
## Helpers
Utilities for Babel, which is just another way to say "helpers", but I wrote it
anyways, so deal with it.

View File

@@ -4,6 +4,10 @@ import jsTokens from "js-tokens";
import esutils from "esutils";
import chalk from "chalk";
/**
* Chalk styles for token types.
*/
var defs = {
string: chalk.red,
punctuator: chalk.bold,
@@ -17,8 +21,16 @@ var defs = {
invalid: chalk.inverse
};
/**
* RegExp to test for newlines in terminal.
*/
const NEWLINE = /\r\n|[\n\r\u2028\u2029]/;
/**
* Get the type of token, specifying punctuator type.
*/
function getTokenType(match) {
var token = jsTokens.matchToToken(match);
if (token.type === "name" && esutils.keyword.isReservedWordES6(token.value)) {
@@ -42,6 +54,10 @@ function getTokenType(match) {
return token.type;
}
/**
* Highlight `text`.
*/
function highlight(text) {
return text.replace(jsTokens, function (...args) {
var type = getTokenType(args);
@@ -54,6 +70,10 @@ function highlight(text) {
});
}
/**
* Create a code frame, adding line numbers, code highlighting, and pointing to a given position.
*/
export default function (lines: number, lineNumber: number, colNumber: number, opts = {}): string {
colNumber = Math.max(colNumber, 0);
@@ -79,9 +99,11 @@ export default function (lines: number, lineNumber: number, colNumber: number, o
if (params.number !== lineNumber) {
return;
}
if (colNumber) {
params.line += `\n${params.before}${repeating(" ", params.width)}${params.after}${repeating(" ", colNumber - 1)}^`;
}
params.before = params.before.replace(/^./, ">");
}
}).join("\n");

View File

@@ -1,10 +1,14 @@
import merge from "lodash/object/merge";
/**
* Merge options.
*/
export default function (dest, src) {
if (!dest || !src) return;
return merge(dest, src, function(a, b) {
if (Array.isArray(a)) {
return merge(dest, src, function (a, b) {
if (b && Array.isArray(a)) {
var c = a.slice(0);
for (var v of b) {
if (a.indexOf(v) < 0) {

View File

@@ -1,5 +1,11 @@
import * as t from "../types";
/**
* Normalize an AST.
*
* - Wrap `Program` node with a `File` node.
*/
export default function (ast, comments, tokens) {
if (ast && ast.type === "Program") {
return t.file(ast, comments || [], tokens || []);

View File

@@ -1,3 +1,7 @@
/**
* Create an object with a `null` prototype.
*/
export default function () {
return Object.create(null);
}

View File

@@ -2,6 +2,10 @@ import normalizeAst from "./normalize-ast";
import estraverse from "estraverse";
import * as acorn from "../../acorn";
/**
* Parse `code` with normalized options, collecting tokens and comments.
*/
export default function (code, opts = {}) {
var commentsAndTokens = [];
var comments = [];
@@ -21,11 +25,17 @@ export default function (code, opts = {}) {
ranges: true
};
/**
* Collect all tokens.
*/
parseOpts.onToken = function (token) {
tokens.push(token);
commentsAndTokens.push(token);
};
/**
* Collection all comments.
*/
parseOpts.onComment = function (block, text, start, end, startLoc, endLoc) {
var comment = {
type: block ? "CommentBlock" : "CommentLine",

View File

@@ -1,30 +1,37 @@
import * as util from "util";
/**
* Mapping of messages to be used in Babel.
* Messages can include $0-style placeholders.
*/
export const MESSAGES = {
tailCallReassignmentDeopt: "Function reference has been reassigned so it's probably be dereferenced so we can't optimise this with confidence",
tailCallReassignmentDeopt: "Function reference has been reassigned, so it will probably be dereferenced, therefore 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 exactly one parameter",
settersNoRest: "Setters aren't allowed to have a rest",
noAssignmentsInForHead: "No assignments allowed in for-in/of head",
expectedMemberExpressionOrIdentifier: "Expected type MemeberExpression or Identifier",
expectedMemberExpressionOrIdentifier: "Expected type MemberExpression 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",
didYouMean: "Did you mean $1?",
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
unsupportedOutputType: "Unsupported output type $1",
illegalMethodName: "Illegal method name $1",
lostTrackNodePath: "We lost track of this nodes position, likely because the AST was directly manipulated",
lostTrackNodePath: "We lost track of this node's position, likely because the AST was directly manipulated",
traverseNeedsParent: "Must pass a scope and parentPath unless traversing a Program/File got a $1 node",
modulesIllegalExportName: "Illegal export $1",
modulesDuplicateDeclarations: "Duplicate module declarations with the same source but in different scopes",
undeclaredVariable: "Reference to undeclared variable $1",
undeclaredVariableType: "Referencing a type alias outside of a type annotation",
undeclaredVariableSuggestion: "Reference to undeclared variable $1 - did you mean $2?",
traverseNeedsParent: "You must pass a scope and parentPath unless traversing a Program/File got a $1 node",
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
traverseVerifyNodeType: "You gave us a visitor for the node type $1 but it's not a valid type",
@@ -32,24 +39,44 @@ export const MESSAGES = {
pluginIllegalKind: "Illegal kind $1 for plugin $2",
pluginIllegalPosition: "Illegal position $1 for plugin $2",
pluginKeyCollision: "The plugin $1 collides with another of the same name",
pluginNotTransformer: "The plugin $1 didn't export a Transformer instance",
pluginNotTransformer: "The plugin $1 didn't export a Plugin instance",
pluginUnknown: "Unknown plugin $1",
transformerNotFile: "Transformer $1 is resolving to a different Babel version to what is doing the actual transformation..."
pluginNotFile: "Plugin $1 is resolving to a different Babel version than what is performing the transformation.",
pluginInvalidProperty: "Plugin $1 provided an invalid property of $2.",
pluginInvalidPropertyVisitor: `Define your visitor methods inside a \`visitor\` property like so:
new Plugin("foobar", {
visitor: {
// define your visitor methods here!
}
});
`
};
export function get(key: String, ...args) {
/**
* Get a message with $0 placeholders replaced by arguments.
*/
export function get(key: string, ...args): string {
var msg = MESSAGES[key];
if (!msg) throw new ReferenceError(`Unknown message ${JSON.stringify(key)}`);
// stringify args
args = parseArgs(args);
// replace $0 placeholders with args
return msg.replace(/\$(\d+)/g, function (str, i) {
return args[--i];
});
}
export function parseArgs(args: Array<any>) {
/**
* Stingify arguments to be used inside messages.
*/
export function parseArgs(args: Array<any>): Array<string> {
return args.map(function (val) {
if (val != null && val.inspect) {
return val.inspect();

View File

@@ -1,81 +1,7 @@
import estraverse from "estraverse";
import extend from "lodash/object/extend";
import types from "ast-types";
import * as t from "./types";
// estraverse
extend(estraverse.VisitorKeys, t.VISITOR_KEYS);
// regenerator/ast-types
var def = types.Type.def;
var or = types.Type.or;
//def("File")
// .bases("Node")
// .build("program")
// .field("program", def("Program"));
def("AssignmentPattern")
.bases("Pattern")
.build("left", "right")
.field("left", def("Pattern"))
.field("right", def("Expression"));
def("RestElement")
.bases("Pattern")
.build("argument")
.field("argument", def("expression"));
def("DoExpression")
.bases("Expression")
.build("body")
.field("body", [def("Statement")]);
def("Super")
.bases("Expression");
def("ExportDefaultDeclaration")
.bases("Declaration")
.build("declaration")
.field("declaration", or(
def("Declaration"),
def("Expression"),
null
));
def("ExportNamedDeclaration")
.bases("Declaration")
.build("declaration")
.field("declaration", or(
def("Declaration"),
def("Expression"),
null
))
.field("specifiers", [or(
def("ExportSpecifier")
)])
.field("source", or(def("ModuleSpecifier"), null));
def("ExportNamespaceSpecifier")
.bases("Specifier")
.field("exported", def("Identifier"));
def("ExportDefaultSpecifier")
.bases("Specifier")
.field("exported", def("Identifier"));
def("ExportAllDeclaration")
.bases("Declaration")
.build("exported", "source")
.field("exported", def("Identifier"))
.field("source", def("Literal"));
def("BindExpression")
.bases("Expression")
.build("object", "callee")
.field("object", or(def("Expression"), null))
.field("callee", def("Expression"));
types.finalize();

15
src/babel/tools/README.md Normal file
View File

@@ -0,0 +1,15 @@
## Tools
> This directory is best browsed while listening to
> https://www.youtube.com/watch?v=hglVqACd1C8.
### Protect Babel
The protect script seen here is to throw errors if someone ever tries to
include internal babel files in their script. If you need something to be
exposed, you should ask for it, not try to hack your way into getting it.
### External Helpers
You'll also find the script for building the external helpers file, this is
the Babel "runtime" where all helper functions go instead of the top of a file.

View File

@@ -5,6 +5,10 @@ import File from "../transformation/file";
import each from "lodash/collection/each";
import * as t from "../types";
/**
* [Please add a description.]
*/
function buildGlobal(namespace, builder) {
var body = [];
var container = t.functionExpression(null, [t.identifier("global")], t.blockStatement(body));
@@ -22,6 +26,10 @@ function buildGlobal(namespace, builder) {
return tree;
}
/**
* [Please add a description.]
*/
function buildUmd(namespace, builder) {
var body = [];
body.push(t.variableDeclaration("var", [
@@ -41,6 +49,10 @@ function buildUmd(namespace, builder) {
return t.program([container]);
}
/**
* [Please add a description.]
*/
function buildVar(namespace, builder) {
var body = [];
body.push(t.variableDeclaration("var", [
@@ -50,6 +62,10 @@ function buildVar(namespace, builder) {
return t.program(body);
}
/**
* [Please add a description.]
*/
function buildHelpers(body, namespace, whitelist) {
each(File.helpers, function (name) {
if (whitelist && whitelist.indexOf(name) === -1) return;
@@ -61,6 +77,10 @@ function buildHelpers(body, namespace, whitelist) {
});
}
/**
* [Please add a description.]
*/
export default function (whitelist, outputType = "global") {
var namespace = t.identifier("babelHelpers");

View File

@@ -0,0 +1,14 @@
import path from "path";
var root = path.resolve(__dirname, "../../../");
/**
* Protect Babel internals from being hotlinked by other tools.
* Sorry, not sorry.
*/
export default function (module) {
if (module.parent && module.parent.filename.indexOf(root) !== 0) {
throw new Error("Don't hotlink internal Babel files.");
}
}

View File

@@ -1,59 +0,0 @@
import stripJsonComments from "strip-json-comments";
import merge from "../helpers/merge";
import path from "path";
import fs from "fs";
var cache = {};
var jsons = {};
function exists(filename) {
if (!fs.existsSync) return false;
var cached = cache[filename];
if (cached != null) return cached;
return cache[filename] = fs.existsSync(filename);
}
export default function (loc, opts = {}) {
var rel = ".babelrc";
if (!opts.babelrc) {
opts.babelrc = [];
}
function find(start, rel) {
var file = path.join(start, rel);
if (opts.babelrc.indexOf(file) >= 0) {
return;
}
if (exists(file)) {
var content = fs.readFileSync(file, "utf8");
var json;
try {
json = jsons[content] = jsons[content] || JSON.parse(stripJsonComments(content));
} catch (err) {
err.message = `${file}: ${err.message}`;
throw err;
}
opts.babelrc.push(file);
if (json.breakConfig) return;
merge(opts, json);
}
var up = path.dirname(start);
if (up !== start) { // root
find(up, rel);
}
}
if (opts.babelrc.indexOf(loc) < 0 && opts.breakConfig !== true) {
find(loc, rel);
}
return opts;
}

View File

@@ -0,0 +1,3 @@
## Transformation
This is the Transformation directory.

View File

@@ -0,0 +1,3 @@
## File Transformation
This is the File Transformation directory.

View File

@@ -1,29 +1,28 @@
import convertSourceMap from "convert-source-map";
import * as optionParsers from "./option-parsers";
import moduleFormatters from "../modules";
import OptionManager from "./options/option-manager";
import PluginManager from "./plugin-manager";
import shebangRegex from "shebang-regex";
import NodePath from "../../traversal/path";
import Transformer from "../transformer";
import isFunction from "lodash/lang/isFunction";
import isAbsolute from "path-is-absolute";
import resolveRc from "../../tools/resolve-rc";
import sourceMap from "source-map";
import generate from "../../generation";
import codeFrame from "../../helpers/code-frame";
import defaults from "lodash/object/defaults";
import includes from "lodash/collection/includes";
import traverse from "../../traversal";
import assign from "lodash/object/assign";
import Logger from "./logger";
import Plugin from "../plugin";
import parse from "../../helpers/parse";
import merge from "../../helpers/merge";
import slash from "slash";
import clone from "lodash/lang/clone";
import Hub from "../../traversal/hub";
import * as util from "../../util";
import path from "path";
import * as t from "../../types";
/**
* [Please add a description.]
*/
export default class File {
constructor(opts = {}, pipeline) {
this.transformerDependencies = {};
@@ -35,17 +34,32 @@ export default class File {
this.declarations = {};
this.usedHelpers = {};
this.dynamicData = {};
this.metadata = {};
this.data = {};
this.metadata = {
modules: {
imports: [],
exports: {
exported: [],
specifiers: []
}
}
};
this.pipeline = pipeline;
this.log = new Logger(this, opts.filename || "unknown");
this.opts = this.normalizeOptions(opts);
this.opts = this.initOptions(opts);
this.ast = {};
this.buildTransformers();
this.hub = new Hub(this);
}
/**
* [Please add a description.]
*/
static helpers = [
"inherits",
"defaults",
@@ -80,68 +94,27 @@ export default class File {
"instanceof",
// legacy
"interop-require",
"interop-require"
];
/**
* [Please add a description.]
*/
static soloHelpers = [];
static options = require("./options");
normalizeOptions(opts: Object) {
opts = assign({}, opts);
/**
* [Please add a description.]
*/
if (opts.filename) {
var rcFilename = opts.filename;
if (!isAbsolute(rcFilename)) rcFilename = path.join(process.cwd(), rcFilename);
opts = resolveRc(rcFilename, opts);
}
//
for (let key in opts) {
if (key[0] === "_") continue;
let option = File.options[key];
if (!option) this.log.error(`Unknown option: ${key}`, ReferenceError);
}
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
if (opts.env) merge(opts, opts.env[envKey]);
for (let key in File.options) {
let option = File.options[key];
var val = opts[key];
if (!val && option.optional) continue;
if (val && option.deprecated) {
throw new Error("Deprecated option " + key + ": " + option.deprecated);
}
if (val == null) {
val = clone(option.default);
}
var optionParser = optionParsers[option.type];
if (optionParser) val = optionParser(key, val, this.pipeline);
if (option.alias) {
opts[option.alias] = opts[option.alias] || val;
} else {
opts[key] = val;
}
}
initOptions(opts) {
opts = new OptionManager(this.log, this.pipeline).init(opts);
if (opts.inputSourceMap) {
opts.sourceMaps = true;
}
// normalize windows path separators to unix
opts.filename = slash(opts.filename);
if (opts.sourceRoot) {
opts.sourceRoot = slash(opts.sourceRoot);
}
if (opts.moduleId) {
opts.moduleIds = true;
}
@@ -149,7 +122,8 @@ export default class File {
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
opts.ignore = util.arrayify(opts.ignore, util.regexify);
opts.only = util.arrayify(opts.only, util.regexify);
if (opts.only) opts.only = util.arrayify(opts.only, util.regexify);
defaults(opts, {
moduleRoot: opts.sourceRoot
@@ -175,12 +149,20 @@ export default class File {
}
return opts;
};
}
/**
* [Please add a description.]
*/
isLoose(key: string) {
return includes(this.opts.loose, key);
}
/**
* [Please add a description.]
*/
buildTransformers() {
var file = this;
@@ -226,7 +208,7 @@ export default class File {
// build dependency graph
for (let pass of (stack: Array)) {
for (var dep of (pass.transformer.dependencies: Array)) {
for (var dep of (pass.plugin.dependencies: Array)) {
this.transformerDependencies[dep] = pass.key;
}
}
@@ -235,6 +217,10 @@ export default class File {
this.transformerStack = this.collapseStack(stack);
}
/**
* [Please add a description.]
*/
collapseStack(_stack) {
var stack = [];
var ignore = [];
@@ -243,7 +229,7 @@ export default class File {
// been merged
if (ignore.indexOf(pass) >= 0) continue;
var group = pass.transformer.metadata.group;
var group = pass.plugin.metadata.group;
// can't merge
if (!pass.canTransform() || !group) {
@@ -253,7 +239,7 @@ export default class File {
var mergeStack = [];
for (let pass of (_stack: Array)) {
if (pass.transformer.metadata.group === group) {
if (pass.plugin.metadata.group === group) {
mergeStack.push(pass);
ignore.push(pass);
}
@@ -261,24 +247,36 @@ export default class File {
var visitors = [];
for (let pass of (mergeStack: Array)) {
visitors.push(pass.handlers);
visitors.push(pass.plugin.visitor);
}
var visitor = traverse.visitors.merge(visitors);
var mergeTransformer = new Transformer(group, visitor);
stack.push(mergeTransformer.buildPass(this));
var mergePlugin = new Plugin(group, { visitor });
stack.push(mergePlugin.buildPass(this));
}
return stack;
}
/**
* [Please add a description.]
*/
set(key: string, val): any {
return this.data[key] = val;
};
}
/**
* [Please add a description.]
*/
setDynamic(key: string, fn: Function) {
this.dynamicData[key] = fn;
}
/**
* [Please add a description.]
*/
get(key: string): any {
var data = this.data[key];
if (data) {
@@ -291,12 +289,20 @@ export default class File {
}
}
/**
* [Please add a description.]
*/
resolveModuleSource(source: string): string {
var resolveModuleSource = this.opts.resolveModuleSource;
if (resolveModuleSource) source = resolveModuleSource(source, this.opts.filename);
return source;
}
/**
* [Please add a description.]
*/
addImport(source: string, name?: string, type?: string): Object {
name = name || source;
var id = this.dynamicImportIds[name];
@@ -315,7 +321,7 @@ export default class File {
}
if (this.transformers["es6.modules"].canTransform()) {
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports, this.scope);
this.moduleFormatter.hasLocalImports = true;
} else {
this.dynamicImports.push(declar);
@@ -325,18 +331,36 @@ export default class File {
return id;
}
/**
* [Please add a description.]
*/
attachAuxiliaryComment(node: Object): Object {
var comment = this.opts.auxiliaryComment;
if (comment) {
var beforeComment = this.opts.auxiliaryCommentBefore;
if (beforeComment) {
node.leadingComments = node.leadingComments || [];
node.leadingComments.push({
type: "CommentLine",
value: " " + comment
value: " " + beforeComment
});
}
var afterComment = this.opts.auxiliaryCommentAfter;
if (afterComment) {
node.trailingComments = node.trailingComments || [];
node.trailingComments.push({
type: "CommentLine",
value: " " + afterComment
});
}
return node;
}
/**
* [Please add a description.]
*/
addHelper(name: string): Object {
var isSolo = includes(File.soloHelpers, name);
@@ -383,18 +407,27 @@ export default class File {
return uid;
}
/**
* [Please add a description.]
*/
errorWithNode(node, msg, Error = SyntaxError) {
var err;
if (node.loc) {
if (node && node.loc) {
var loc = node.loc.start;
err = new Error(`Line ${loc.line}: ${msg}`);
err.loc = loc;
} else {
// todo: find errors with nodes inside to at least point to something
err = new Error("There's been an error on a dynamic node. This is almost certainly an internal error. Please report it.");
}
return err;
}
/**
* [Please add a description.]
*/
mergeSourceMap(map: Object) {
var opts = this.opts;
@@ -417,6 +450,9 @@ export default class File {
return map;
}
/**
* [Please add a description.]
*/
getModuleFormatter(type: string) {
if (isFunction(type) || !moduleFormatters[type]) {
@@ -437,6 +473,10 @@ export default class File {
return new ModuleFormatter(this);
}
/**
* [Please add a description.]
*/
parse(code: string) {
var opts = this.opts;
@@ -465,17 +505,26 @@ export default class File {
return tree;
}
/**
* [Please add a description.]
*/
_addAst(ast) {
this.path = NodePath.get({
this.path = NodePath.get({
hub: this.hub,
parentPath: null,
parent: ast,
container: ast,
key: "program"
}).setContext(null, this);
}).setContext();
this.scope = this.path.scope;
this.ast = ast;
}
/**
* [Please add a description.]
*/
addAst(ast) {
this.log.debug("Start set AST");
this._addAst(ast);
@@ -486,14 +535,12 @@ export default class File {
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
modFormatter.init();
}
this.populateModuleMetadata();
this.log.debug("End module formatter init");
}
populateModuleMetadata() {
var modules = {};
this.metadata.modules = modules;
}
/**
* [Please add a description.]
*/
transform() {
this.call("pre");
@@ -505,11 +552,19 @@ export default class File {
return this.generate();
}
/**
* [Please add a description.]
*/
wrap(code, callback) {
code = code + "";
try {
return callback();
if (this.shouldIgnore()) {
return this.makeResult({ code, ignored: true });
} else {
return callback();
}
} catch (err) {
if (err._babel) {
throw err;
@@ -538,29 +593,49 @@ export default class File {
}
}
/**
* [Please add a description.]
*/
addCode(code: string) {
code = (code || "") + "";
code = this.parseInputSourceMap(code);
this.code = code;
}
/**
* [Please add a description.]
*/
parseCode() {
this.parseShebang();
this.addAst(this.parse(this.code));
}
/**
* [Please add a description.]
*/
shouldIgnore() {
var opts = this.opts;
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
}
/**
* [Please add a description.]
*/
call(key: string) {
for (var pass of (this.uncollapsedTransformerStack: Array)) {
var fn = pass.transformer[key];
var fn = pass.plugin[key];
if (fn) fn(this);
}
}
/**
* [Please add a description.]
*/
parseInputSourceMap(code: string) {
var opts = this.opts;
@@ -575,6 +650,10 @@ export default class File {
return code;
}
/**
* [Please add a description.]
*/
parseShebang() {
var shebangMatch = shebangRegex.exec(this.code);
if (shebangMatch) {
@@ -583,6 +662,10 @@ export default class File {
}
}
/**
* [Please add a description.]
*/
makeResult({ code, map = null, ast, ignored }) {
var result = {
metadata: null,
@@ -608,6 +691,10 @@ export default class File {
return result;
}
/**
* [Please add a description.]
*/
generate() {
var opts = this.opts;
var ast = this.ast;

View File

@@ -4,36 +4,82 @@ import buildDebug from "debug/node";
var verboseDebug = buildDebug("babel:verbose");
var generalDebug = buildDebug("babel");
var seenDeprecatedMessages = [];
/**
* [Please add a description.]
*/
export default class Logger {
constructor(file: File, filename: string) {
this.filename = filename;
this.file = file;
}
/**
* [Please add a description.]
*/
_buildMessage(msg: string): string {
var parts = `[BABEL] ${this.filename}`;
if (msg) parts += `: ${msg}`;
return parts;
}
/**
* [Please add a description.]
*/
warn(msg) {
console.warn(this._buildMessage(msg));
}
/**
* [Please add a description.]
*/
error(msg: string, Constructor = Error) {
throw new Constructor(this._buildMessage(msg));
}
/**
* [Please add a description.]
*/
deprecate(msg) {
if (!this.file.opts.suppressDeprecationMessages) {
console.error(this._buildMessage(msg));
}
if (this.file.opts.suppressDeprecationMessages) return;
msg = this._buildMessage(msg);
// already seen this message
if (seenDeprecatedMessages.indexOf(msg) >= 0) return;
// make sure we don't see it again
seenDeprecatedMessages.push(msg);
console.error(msg);
}
/**
* [Please add a description.]
*/
verbose(msg: string) {
if (verboseDebug.enabled) verboseDebug(this._buildMessage(msg));
}
/**
* [Please add a description.]
*/
debug(msg: string) {
if (generalDebug.enabled) generalDebug(this._buildMessage(msg));
}
/**
* [Please add a description.]
*/
deopt(node: Object, msg: string) {
this.debug(msg);
}

View File

@@ -1,27 +0,0 @@
import * as util from "../../util";
export function transformerList(key, val, pipeline) {
val = util.arrayify(val);
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
val = Object.keys(pipeline.transformers);
}
return pipeline._ensureTransformerNames(key, val);
}
export function number(key, val) {
return +val;
}
export function boolean(key, val) {
return !!val;
}
export function booleanString(key, val) {
return util.booleanify(val);
}
export function list(key, val) {
return util.list(val);
}

View File

@@ -0,0 +1,3 @@
## File Options
This is the File Options directory.

View File

@@ -1,6 +1,6 @@
{
"filename": {
"type": "string",
"type": "filename",
"description": "filename to use when reading from stdin - this will be used in source-maps, errors etc",
"default": "unknown",
"shorthand": "f"
@@ -47,7 +47,9 @@
},
"experimental": {
"deprecated": "use `--stage 0`/`{ stage: 0 }` instead"
"type": "boolean",
"description": "allow use of experimental transformers",
"default": false
},
"highlightCode": {
@@ -76,7 +78,8 @@
"blacklist": {
"type": "transformerList",
"description": "blacklist of transformers to NOT use",
"shorthand": "b"
"shorthand": "b",
"default": []
},
"whitelist": {
@@ -88,7 +91,8 @@
"optional": {
"type": "transformerList",
"description": "list of optional transformers to enable"
"description": "list of optional transformers to enable",
"default": []
},
"modules": {
@@ -120,12 +124,14 @@
"plugins": {
"type": "list",
"description": ""
"description": "",
"default": []
},
"ignore": {
"type": "list",
"description": "list of glob paths to **not** compile"
"description": "list of glob paths to **not** compile",
"default": []
},
"only": {
@@ -171,12 +177,23 @@
},
"auxiliaryComment": {
"deprecated": "renamed to auxiliaryCommentBefore",
"shorthand": "a",
"alias": "auxiliaryCommentBefore"
},
"auxiliaryCommentBefore": {
"type": "string",
"default": "",
"shorthand": "a",
"description": "attach a comment before all helper declarations and auxiliary code"
},
"auxiliaryCommentAfter": {
"type": "string",
"default": "",
"description": "attach a comment after all helper declarations and auxiliary code"
},
"externalHelpers": {
"type": "boolean",
"default": false,
@@ -219,12 +236,12 @@
},
"sourceRoot": {
"type": "string",
"type": "filename",
"description": "the root from which all sources are relative"
},
"moduleRoot": {
"type": "string",
"type": "filename",
"description": "optional prefix for the AMD module formatter that will be prepend to the filename on module definitions"
},
@@ -236,7 +253,7 @@
},
"babelrc": {
"hidden": true,
"description": "do not load the same .babelrc file twice"
"description": "Specify a custom list of babelrc files to use",
"type": "list"
}
}

View File

@@ -0,0 +1,39 @@
import * as parsers from "./parsers";
import config from "./config";
export { config };
/**
* Validate an option.
*/
export function validateOption(key, val, pipeline) {
var opt = config[key];
var parser = opt && parsers[opt.type];
if (parser && parser.validate) {
return parser.validate(key, val, pipeline);
} else {
return val;
}
}
/**
* Normalize all options.
*/
export function normaliseOptions(options = {}) {
for (var key in options) {
var val = options[key];
if (val == null) continue;
var opt = config[key];
if (!opt) continue;
var parser = parsers[opt.type];
if (parser) val = parser(val);
options[key] = val;
}
return options;
}

View File

@@ -0,0 +1,170 @@
import { validateOption, normaliseOptions } from "./index";
import stripJsonComments from "strip-json-comments";
import isAbsolute from "path-is-absolute";
import pathExists from "path-exists";
import clone from "lodash/lang/clone";
import merge from "../../../helpers/merge";
import config from "./config";
import path from "path";
import fs from "fs";
var existsCache = {};
var jsonCache = {};
const CONFIG_FILENAME = ".babelrc";
function exists(filename) {
var cached = existsCache[filename];
if (cached != null) {
return cached;
} else {
return existsCache[filename] = pathExists.sync(filename);
}
}
export default class OptionManager {
constructor(log, pipeline) {
this.resolvedConfigs = [];
this.options = OptionManager.createBareOptions();
this.pipeline = pipeline;
this.log = log;
}
/**
* [Please add a description.]
*/
static createBareOptions() {
var opts = {};
for (var key in config) {
var opt = config[key];
opts[key] = clone(opt.default);
}
return opts;
}
/**
* [Please add a description.]
*/
addConfig(loc) {
if (this.resolvedConfigs.indexOf(loc) >= 0) return;
var content = fs.readFileSync(loc, "utf8");
var opts;
try {
opts = jsonCache[content] = jsonCache[content] || JSON.parse(stripJsonComments(content));
} catch (err) {
err.message = `${loc}: ${err.message}`;
throw err;
}
this.mergeOptions(opts, loc);
this.resolvedConfigs.push(loc);
}
/**
* [Please add a description.]
*/
mergeOptions(opts, alias = "foreign") {
if (!opts) return;
for (let key in opts) {
if (key[0] === "_") continue;
let option = config[key];
// check for an unknown option
if (!option) this.log.error(`Unknown option: ${alias}.${key}`, ReferenceError);
}
// normalise options
normaliseOptions(opts);
// merge them into this current files options
merge(this.options, opts);
}
/**
* [Please add a description.]
*/
findConfigs(loc) {
if (!loc) return;
if (!isAbsolute(loc)) {
loc = path.join(process.cwd(), loc);
}
while (loc !== (loc = path.dirname(loc))) {
if (this.options.breakConfig) return;
var configLoc = path.join(loc, CONFIG_FILENAME);
if (exists(configLoc)) this.addConfig(configLoc);
}
}
/**
* [Please add a description.]
*/
normaliseOptions() {
var opts = this.options;
for (let key in config) {
var option = config[key];
var val = opts[key];
// optional
if (!val && option.optional) continue;
// deprecated
if (this.log && val && option.deprecated) {
this.log.deprecate(`Deprecated option ${key}: ${option.deprecated}`);
}
// validate
if (this.pipeline && val) {
val = validateOption(key, val, this.pipeline);
}
// aaliases
if (option.alias) {
opts[option.alias] = opts[option.alias] || val;
} else {
opts[key] = val;
}
}
}
/**
* [Please add a description.]
*/
init(opts) {
this.mergeOptions(opts, "direct");
// babelrc option
if (opts.babelrc) {
for (var loc of (opts.babelrc: Array)) this.addConfig(loc);
}
// resolve all .babelrc files
this.findConfigs(opts.filename);
// merge in env
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
if (this.options.env) {
this.mergeOptions(this.options.env[envKey], `direct.env.${envKey}`);
}
// normalise
this.normaliseOptions(opts);
return this.options;
}
}

View File

@@ -0,0 +1,60 @@
import slash from "slash";
import * as util from "../../../util";
/**
* Get a transformer list from a value.
*/
export function transformerList(val) {
return util.arrayify(val);
}
/**
* Validate transformer list. Maps "all" to all transformer names.
*/
transformerList.validate = function (key, val, pipeline) {
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
val = Object.keys(pipeline.transformers);
}
return pipeline._ensureTransformerNames(key, val);
};
/**
* Cast a value to a number.
*/
export function number(val) {
return +val;
}
/**
* Cast a value to a boolean.
*/
export var filename = slash;
/**
* [Please add a description.]
*/
export function boolean(val) {
return !!val;
}
/**
* Cast a boolean-like string to a boolean.
*/
export function booleanString(val) {
return util.booleanify(val);
}
/**
* Cast a value to an array, splitting strings by ",".
*/
export function list(val) {
return util.list(val);
}

View File

@@ -1,17 +1,48 @@
import * as node from "../../api/node";
import Transformer from "../transformer";
import Plugin from "../plugin";
import * as types from "../../types";
import * as messages from "../../messages";
import traverse from "../../traversal";
import parse from "../../helpers/parse";
/**
* [Please add a description.]
*/
var context = {
messages,
Transformer,
Plugin,
types,
parse,
traverse
};
import * as util from "../../util";
/**
* [Please add a description.]
*/
export default class PluginManager {
/**
* [Please add a description.]
*/
static memoisedPlugins = [];
/**
* [Please add a description.]
*/
static memoisePluginContainer(fn) {
for (var i = 0; i < PluginManager.memoisedPlugins.length; i++) {
var plugin = PluginManager.memoisedPlugins[i];
if (plugin.container === fn) return plugin.transformer;
}
var transformer = fn(node);
var transformer = fn(context);
PluginManager.memoisedPlugins.push({
container: fn,
transformer: transformer
@@ -19,8 +50,16 @@ export default class PluginManager {
return transformer;
}
/**
* [Please add a description.]
*/
static positions = ["before", "after"];
/**
* [Please add a description.]
*/
constructor({ file, transformers, before, after } = { transformers: {}, before: [], after: [] }) {
this.transformers = transformers;
this.file = file;
@@ -28,6 +67,10 @@ export default class PluginManager {
this.after = after;
}
/**
* [Please add a description.]
*/
subnormaliseString(name, position) {
// this is a plugin in the form of "foobar" or "foobar:after"
// where the optional colon is the delimiter for plugin position in the transformer stack
@@ -47,6 +90,10 @@ export default class PluginManager {
}
}
/**
* [Please add a description.]
*/
validate(name, plugin) {
// validate transformer key
var key = plugin.key;
@@ -55,7 +102,7 @@ export default class PluginManager {
}
// validate Transformer instance
if (!plugin.buildPass || plugin.constructor.name !== "Transformer") {
if (!plugin.buildPass || plugin.constructor.name !== "Plugin") {
throw new TypeError(messages.get("pluginNotTransformer", name));
}
@@ -63,6 +110,10 @@ export default class PluginManager {
plugin.metadata.plugin = true;
}
/**
* [Please add a description.]
*/
add(name) {
var position;
var plugin;

View File

@@ -0,0 +1,3 @@
## Transformation Helpers
This is the Transformation Helpers directory.

View File

@@ -1,17 +1,33 @@
import explode from "./explode-assignable-expression";
import * as t from "../../types";
/**
* [Please add a description.]
*/
export default function (opts) {
var exports = {};
/**
* [Please add a description.]
*/
var isAssignment = function (node) {
return node.operator === opts.operator + "=";
};
/**
* [Please add a description.]
*/
var buildAssignment = function (left, right) {
return t.assignmentExpression("=", left, right);
};
/**
* [Please add a description.]
*/
exports.ExpressionStatement = function (node, parent, scope, file) {
// hit the `AssignmentExpression` one below
if (this.isCompletionRecord()) return;
@@ -29,6 +45,10 @@ export default function (opts) {
return nodes;
};
/**
* [Please add a description.]
*/
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!isAssignment(node)) return;
@@ -38,6 +58,10 @@ export default function (opts) {
return nodes;
};
/**
* [Please add a description.]
*/
exports.BinaryExpression = function (node) {
if (node.operator !== opts.operator) return;
return opts.build(node.left, node.right);

View File

@@ -1,5 +1,9 @@
import * as t from "../../types";
/**
* [Please add a description.]
*/
export default function build(node, buildBody) {
var self = node.blocks.shift();
if (!self) return;

View File

@@ -1,11 +1,24 @@
import explode from "./explode-assignable-expression";
import * as t from "../../types";
/**
* [Please add a description.]
*/
export default function (exports, opts) {
/**
* [Please add a description.]
*/
var buildAssignment = function (left, right) {
return t.assignmentExpression("=", left, right);
};
/**
* [Please add a description.]
*/
exports.ExpressionStatement = function (node, parent, scope, file) {
// hit the `AssignmentExpression` one below
if (this.isCompletionRecord()) return;
@@ -25,6 +38,10 @@ export default function (exports, opts) {
return nodes;
};
/**
* [Please add a description.]
*/
exports.AssignmentExpression = function (node, parent, scope, file) {
if (!opts.is(node, file)) return;

View File

@@ -9,8 +9,18 @@ import esutils from "esutils";
import * as react from "./react";
import * as t from "../../types";
export default function (exports, opts) {
exports.JSXIdentifier = function (node) {
/**
* [Please add a description.]
*/
export default function (opts) {
var visitor = {};
/**
* [Please add a description.]
*/
visitor.JSXIdentifier = function (node) {
if (node.name === "this" && this.isReferenced()) {
return t.thisExpression();
} else if (esutils.keyword.isIdentifierNameES6(node.name)) {
@@ -20,22 +30,38 @@ export default function (exports, opts) {
}
};
exports.JSXNamespacedName = function () {
/**
* [Please add a description.]
*/
visitor.JSXNamespacedName = function () {
throw this.errorWithNode(messages.get("JSXNamespacedTags"));
};
exports.JSXMemberExpression = {
/**
* [Please add a description.]
*/
visitor.JSXMemberExpression = {
exit(node) {
node.computed = t.isLiteral(node.property);
node.type = "MemberExpression";
}
};
exports.JSXExpressionContainer = function (node) {
/**
* [Please add a description.]
*/
visitor.JSXExpressionContainer = function (node) {
return node.expression;
};
exports.JSXAttribute = {
/**
* [Please add a description.]
*/
visitor.JSXAttribute = {
enter(node) {
var value = node.value;
if (t.isLiteral(value) && isString(value.value)) {
@@ -49,7 +75,11 @@ export default function (exports, opts) {
}
};
exports.JSXOpeningElement = {
/**
* [Please add a description.]
*/
visitor.JSXOpeningElement = {
exit(node, parent, scope, file) {
parent.children = react.buildChildren(parent);
@@ -139,7 +169,11 @@ export default function (exports, opts) {
return attribs;
};
exports.JSXElement = {
/**
* [Please add a description.]
*/
visitor.JSXElement = {
exit(node) {
var callExpr = node.openingElement;
@@ -153,54 +187,5 @@ export default function (exports, opts) {
}
};
// 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];
var key = t.toComputedKey(prop);
if (t.isLiteral(key, { value: "displayName" })) {
safe = false;
break;
}
}
if (safe) {
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
}
};
exports.ExportDefaultDeclaration = function (node, parent, scope, file) {
if (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);
}
};
return visitor;
}

View File

@@ -1,6 +1,15 @@
import * as t from "../../types";
/**
* [Please add a description.]
*/
var visitor = {
/**
* [Please add a description.]
*/
enter(node, parent, scope, state) {
if (this.isThisExpression() || this.isReferencedIdentifier({ name: "arguments" })) {
state.found = true;
@@ -8,11 +17,19 @@ var visitor = {
}
},
/**
* [Please add a description.]
*/
Function() {
this.skip();
}
};
/**
* [Please add a description.]
*/
export default function (node, scope) {
var container = t.functionExpression(null, [], node.body, node.generator, node.async);

View File

@@ -2,6 +2,10 @@ import each from "lodash/collection/each";
import has from "lodash/object/has";
import * as t from "../../types";
/**
* [Please add a description.]
*/
export function push(mutatorMap, node, kind, file) {
var alias = t.toKeyAlias(node);
@@ -43,6 +47,10 @@ export function push(mutatorMap, node, kind, file) {
return map;
}
/**
* [Please add a description.]
*/
export function hasComputed(mutatorMap) {
for (var key in mutatorMap) {
if (mutatorMap[key]._computed) {
@@ -52,6 +60,10 @@ export function hasComputed(mutatorMap) {
return false;
}
/**
* [Please add a description.]
*/
export function toComputedObjectFromClass(obj) {
var objExpr = t.arrayExpression([]);
@@ -65,6 +77,10 @@ export function toComputedObjectFromClass(obj) {
return objExpr;
}
/**
* [Please add a description.]
*/
export function toClassObject(mutatorMap) {
var objExpr = t.objectExpression([]);
@@ -92,6 +108,10 @@ export function toClassObject(mutatorMap) {
return objExpr;
}
/**
* [Please add a description.]
*/
export function toDefineObject(mutatorMap) {
each(mutatorMap, function (map) {
if (map.value) map.writable = t.literal(true);

View File

@@ -1,5 +1,9 @@
import * as t from "../../types";
/**
* [Please add a description.]
*/
var getObjRef = function (node, nodes, file, scope) {
var ref;
if (t.isIdentifier(node)) {
@@ -33,6 +37,10 @@ var getObjRef = function (node, nodes, file, scope) {
return temp;
};
/**
* [Please add a description.]
*/
var getPropRef = function (node, nodes, file, scope) {
var prop = node.property;
var key = t.toComputedKey(node, prop);
@@ -45,6 +53,10 @@ var getPropRef = function (node, nodes, file, scope) {
return temp;
};
/**
* [Please add a description.]
*/
export default function (node, nodes, file, scope, allowedSingleIdent) {
var obj;
if (t.isIdentifier(node) && allowedSingleIdent) {

View File

@@ -1,9 +1,16 @@
import * as t from "../../types";
/**
* [Please add a description.]
*/
export default function (node) {
var lastNonDefault = 0;
for (var i = 0; i < node.params.length; i++) {
if (!t.isAssignmentPattern(node.params[i])) lastNonDefault = i + 1;
var param = node.params[i];
if (!t.isAssignmentPattern(param) && !t.isRestElement(param)) {
lastNonDefault = i + 1;
}
}
return lastNonDefault;
}

View File

@@ -1,5 +1,9 @@
import * as t from "../../types";
/**
* [Please add a description.]
*/
export default function (decorators, scope) {
for (var i = 0; i < decorators.length; i++) {
var decorator = decorators[i];

View File

@@ -2,6 +2,10 @@ import getFunctionArity from "./get-function-arity";
import * as util from "../../util";
import * as t from "../../types";
/**
* [Please add a description.]
*/
function visitIdentifier(context, node, scope, state) {
// check if this node matches our function id
if (node.name !== state.name) return;
@@ -15,19 +19,33 @@ function visitIdentifier(context, node, scope, state) {
context.stop();
}
/**
* [Please add a description.]
*/
var visitor = {
/**
* [Please add a description.]
*/
ReferencedIdentifier(node, parent, scope, state) {
visitIdentifier(this, node, scope, state);
},
AssignmentExpression(node, parent, scope, state) {
var ids = this.getBindingIdentifiers();
for (var name in ids) {
visitIdentifier(this, ids[name], scope, state);
}
/**
* [Please add a description.]
*/
BindingIdentifier(node, parent, scope, state) {
visitIdentifier(this, node, scope, state);
}
};
/**
* [Please add a description.]
*/
var wrap = function (state, method, id, scope) {
if (state.selfReference) {
if (scope.hasBinding(id.name) && !scope.hasGlobal(id.name)) {
@@ -59,6 +77,10 @@ var wrap = function (state, method, id, scope) {
scope.getProgramParent().references[id.name] = true;
};
/**
* [Please add a description.]
*/
var visit = function (node, name, scope) {
var state = {
selfAssignment: false,
@@ -71,10 +93,10 @@ var visit = function (node, name, scope) {
// check to see if we have a local binding of the id we're setting inside of
// the function, this is important as there are caveats associated
var bindingInfo = scope.getOwnBindingInfo(name);
var binding = scope.getOwnBinding(name);
if (bindingInfo) {
if (bindingInfo.kind === "param") {
if (binding) {
if (binding.kind === "param") {
// safari will blow up in strict mode with code like:
//
// var t = function t(t) {};
@@ -105,17 +127,24 @@ var visit = function (node, name, scope) {
return state;
};
/**
* [Please add a description.]
*/
export function custom(node, id, scope) {
var state = visit(node, id.name, scope);
return wrap(state, node, id, scope);
}
/**
* [Please add a description.]
*/
export function property(node, file, scope) {
var key = t.toComputedKey(node, node.key);
if (!t.isLiteral(key)) return; // we can't set a function id with this
var name = t.toIdentifier(key.value);
if (name === "eval" || name === "arguments") name = "_" + name;
var name = t.toBindingIdentifierName(key.value);
var id = t.identifier(name);
var method = node.value;
@@ -123,6 +152,10 @@ export function property(node, file, scope) {
node.value = wrap(state, method, id, scope) || method;
}
/**
* [Please add a description.]
*/
export function bare(node, parent, scope) {
// has an `id` so we don't need to infer one
if (node.id) return;
@@ -136,8 +169,8 @@ export function bare(node, parent, scope) {
id = parent.id;
if (t.isIdentifier(id)) {
var bindingInfo = scope.parent.getBinding(id.name);
if (bindingInfo && bindingInfo.constant && scope.getBinding(id.name) === bindingInfo) {
var binding = scope.parent.getBinding(id.name);
if (binding && binding.constant && scope.getBinding(id.name) === binding) {
// always going to reference this method
node.id = id;
return;
@@ -156,7 +189,7 @@ export function bare(node, parent, scope) {
return;
}
name = t.toIdentifier(name);
name = t.toBindingIdentifierName(name);
id = t.identifier(name);
var state = visit(node, name, scope);

View File

@@ -1,30 +1,19 @@
import * as t from "../../types";
var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass");
export function isCreateClass(node) {
if (!node || !t.isCallExpression(node)) return false;
// not React.createClass call member object
if (!isCreateClassCallExpression(node.callee)) return false;
// no call arguments
var args = node.arguments;
if (args.length !== 1) return false;
// first node arg is not an object
var first = args[0];
if (!t.isObjectExpression(first)) return false;
return true;
}
export var isReactComponent = t.buildMatchMemberExpression("React.Component");
/**
* [Please add a description.]
*/
export function isCompatTag(tagName) {
return tagName && /^[a-z]|\-/.test(tagName);
}
/**
* [Please add a description.]
*/
function cleanJSXElementLiteralChild(child, args) {
var lines = child.value.split(/\r\n|\n|\r/);
@@ -70,6 +59,10 @@ function cleanJSXElementLiteralChild(child, args) {
if (str) args.push(t.literal(str));
}
/**
* [Please add a description.]
*/
export function buildChildren(node) {
var elems = [];

View File

@@ -1,10 +1,18 @@
import pull from "lodash/array/pull";
import * as t from "../../types";
/**
* [Please add a description.]
*/
export function is(node, flag) {
return t.isLiteral(node) && node.regex && node.regex.flags.indexOf(flag) >= 0;
}
/**
* [Please add a description.]
*/
export function pullFlag(node, flag) {
var flags = node.regex.flags.split("");
if (node.regex.flags.indexOf(flag) < 0) return;

View File

@@ -1,10 +1,23 @@
import * as t from "../../types";
/**
* [Please add a description.]
*/
var awaitVisitor = {
/**
* [Please add a description.]
*/
Function() {
this.skip();
},
/**
* [Please add a description.]
*/
AwaitExpression(node) {
node.type = "YieldExpression";
@@ -16,7 +29,16 @@ var awaitVisitor = {
}
};
/**
* [Please add a description.]
*/
var referenceVisitor = {
/**
* [Please add a description.]
*/
ReferencedIdentifier(node, parent, scope, state) {
var name = state.id.name;
if (node.name === name && scope.bindingIdentifierEquals(name, state.id)) {
@@ -25,11 +47,17 @@ var referenceVisitor = {
}
};
export default function (node, callId, scope) {
/**
* [Please add a description.]
*/
export default function (path, callId) {
var node = path.node;
node.async = false;
node.generator = true;
scope.traverse(node, awaitVisitor, state);
path.traverse(awaitVisitor, state);
var call = t.callExpression(callId, [node]);
@@ -44,11 +72,11 @@ export default function (node, callId, scope) {
return declar;
} else {
if (id) {
var state = { id: id };
scope.traverse(node, referenceVisitor, state);
var state = { id };
path.traverse(referenceVisitor, state);
if (state.ref) {
scope.parent.push({ id: state.ref });
path.scope.parent.push({ id: state.ref });
return t.assignmentExpression("=", state.ref, call);
}
}

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