Compare commits
267 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8565e2b4e5 | ||
|
|
4317a46a3e | ||
|
|
81ca29adc3 | ||
|
|
c1a6ff7f44 | ||
|
|
7e6e5d4746 | ||
|
|
12d650e195 | ||
|
|
8fb58492df | ||
|
|
2c0c2f12df | ||
|
|
01e5354fd9 | ||
|
|
0b100c4273 | ||
|
|
340e75eb59 | ||
|
|
53808a6d45 | ||
|
|
e6326332b6 | ||
|
|
9e0cf84505 | ||
|
|
b7eea7b08c | ||
|
|
92dd67856e | ||
|
|
a2bb587e24 | ||
|
|
0c570cb599 | ||
|
|
db6fab2c8f | ||
|
|
d92deb52b6 | ||
|
|
b8b70f2f4a | ||
|
|
a8a3f6d34d | ||
|
|
9847d226e1 | ||
|
|
3d48a16305 | ||
|
|
3d24cc9ae5 | ||
|
|
5acc58dd68 | ||
|
|
34f02f06a6 | ||
|
|
6d3fe5b85c | ||
|
|
3878bd812c | ||
|
|
0717eaddce | ||
|
|
102cbbe493 | ||
|
|
d981b30194 | ||
|
|
0fc02f2cf0 | ||
|
|
f24b5164d4 | ||
|
|
4be27ee72c | ||
|
|
f0070e4828 | ||
|
|
ce8beec22c | ||
|
|
b30bdf2294 | ||
|
|
63b44a3e6e | ||
|
|
74aaf848ed | ||
|
|
95de5400e6 | ||
|
|
fe7079802b | ||
|
|
61ddb14e25 | ||
|
|
ca7a93cd64 | ||
|
|
90a1c81d30 | ||
|
|
5e9089d104 | ||
|
|
1a716943bc | ||
|
|
c28415c38a | ||
|
|
e1491de6b8 | ||
|
|
253ea8cd18 | ||
|
|
d37bad3149 | ||
|
|
a2b912bc77 | ||
|
|
f1bfbe44e2 | ||
|
|
dbdd07d0b8 | ||
|
|
166909998e | ||
|
|
a8ec4c965c | ||
|
|
d2aff67c6c | ||
|
|
3353de225d | ||
|
|
203ebeef20 | ||
|
|
032cf990c3 | ||
|
|
16cdb43c67 | ||
|
|
6f622033c5 | ||
|
|
531d4f1937 | ||
|
|
f155bc249c | ||
|
|
452d0ef30e | ||
|
|
005754ba98 | ||
|
|
c3c4cf17e3 | ||
|
|
0866e5a403 | ||
|
|
15f5e658fc | ||
|
|
574e6da132 | ||
|
|
da6d27ed16 | ||
|
|
4e87809ff9 | ||
|
|
f4267aaab0 | ||
|
|
4f255d103a | ||
|
|
502cc13aed | ||
|
|
0a1154e6fd | ||
|
|
f5b3d72730 | ||
|
|
e9bcccffbd | ||
|
|
aaf4cbf06f | ||
|
|
5080534974 | ||
|
|
02cb397873 | ||
|
|
d9169a87ad | ||
|
|
f3b6f2fc61 | ||
|
|
04cc24ee82 | ||
|
|
f32079ef42 | ||
|
|
d1b69656ae | ||
|
|
09453a490b | ||
|
|
e2e7627f0f | ||
|
|
4fe24a9a3b | ||
|
|
d26e7ad577 | ||
|
|
571cb4928f | ||
|
|
c12e8122f8 | ||
|
|
92e7a01d14 | ||
|
|
b9ca9d42dc | ||
|
|
479c3e477a | ||
|
|
2c3d3d8105 | ||
|
|
ea03f67505 | ||
|
|
ee0c88a070 | ||
|
|
98206df864 | ||
|
|
1066a42fb2 | ||
|
|
062175586c | ||
|
|
0dc6b582a6 | ||
|
|
d8d70ba137 | ||
|
|
f23c916520 | ||
|
|
8ae4601177 | ||
|
|
9a466d3ef9 | ||
|
|
713845d14c | ||
|
|
471d60e5cd | ||
|
|
43864e0686 | ||
|
|
4c2ae5dd19 | ||
|
|
a540cbe801 | ||
|
|
34cc577fa2 | ||
|
|
c855b55133 | ||
|
|
16c86c25b7 | ||
|
|
4345f7945b | ||
|
|
f44c93add2 | ||
|
|
09e45c51a4 | ||
|
|
1a42b72b15 | ||
|
|
d30415d74a | ||
|
|
616ef8d840 | ||
|
|
56437f94bc | ||
|
|
881fa6430b | ||
|
|
b7971690f3 | ||
|
|
c01d0abbd3 | ||
|
|
7043119346 | ||
|
|
b5325df57f | ||
|
|
0fc958e0fc | ||
|
|
9cb16711dd | ||
|
|
04766b13f5 | ||
|
|
433d704739 | ||
|
|
30204d2ee6 | ||
|
|
374b7cca2c | ||
|
|
152ae388f0 | ||
|
|
04344026bb | ||
|
|
cfffaf6cdb | ||
|
|
2952d94e60 | ||
|
|
0276c3ae81 | ||
|
|
c00f8dce3f | ||
|
|
4e24ae39cf | ||
|
|
12bd6494b7 | ||
|
|
e35c7550fe | ||
|
|
e7046abe72 | ||
|
|
affa7f0c6f | ||
|
|
be650ffc61 | ||
|
|
3078d48178 | ||
|
|
0be93563dd | ||
|
|
3e55980145 | ||
|
|
470ebf3a46 | ||
|
|
b695369126 | ||
|
|
f4611469b4 | ||
|
|
68bfafe745 | ||
|
|
f72782b71c | ||
|
|
0f1f5e3565 | ||
|
|
dfe126f3d4 | ||
|
|
4c9cb957a9 | ||
|
|
8f997f8825 | ||
|
|
d789a6e7aa | ||
|
|
4007148d9f | ||
|
|
998f1d544e | ||
|
|
deed48a3db | ||
|
|
00c0a958db | ||
|
|
1511dcbd73 | ||
|
|
12fef25803 | ||
|
|
fd30eb1839 | ||
|
|
63344eb0a4 | ||
|
|
6e4e11a365 | ||
|
|
e330efe058 | ||
|
|
ce86eca8b0 | ||
|
|
03dbaa3e0e | ||
|
|
2bd35fac6e | ||
|
|
cdca4e50d9 | ||
|
|
bb041c1bd6 | ||
|
|
a36c1b4a92 | ||
|
|
b760daca21 | ||
|
|
ff63d8f60c | ||
|
|
74f04ed6a1 | ||
|
|
74d880bf18 | ||
|
|
5ce38cacaa | ||
|
|
829f642ad8 | ||
|
|
80a4b95da4 | ||
|
|
dc2a20dbcd | ||
|
|
f6278e43ce | ||
|
|
30bc80000b | ||
|
|
ef56042c93 | ||
|
|
b6498103db | ||
|
|
7af4302d07 | ||
|
|
543770960c | ||
|
|
a2975a72cc | ||
|
|
beb3fd51d8 | ||
|
|
9360860601 | ||
|
|
7d4ecea8fb | ||
|
|
a44831b3fa | ||
|
|
8357f3900f | ||
|
|
6b1c5bc358 | ||
|
|
3564309a77 | ||
|
|
c9518bb60d | ||
|
|
0f1215e33e | ||
|
|
d7b0b5bec0 | ||
|
|
3e5af404ab | ||
|
|
1818094577 | ||
|
|
6d712b3d14 | ||
|
|
11389fe165 | ||
|
|
0ee9531db3 | ||
|
|
1622d2498d | ||
|
|
b76e6f8e5b | ||
|
|
beac006832 | ||
|
|
20d7603c0b | ||
|
|
24b13c5e49 | ||
|
|
9e21074e88 | ||
|
|
9a825bced7 | ||
|
|
fcb78436c6 | ||
|
|
bb30a64f8d | ||
|
|
b483c16fe2 | ||
|
|
569f046045 | ||
|
|
4e969d3d92 | ||
|
|
0bca1de285 | ||
|
|
3a5bd06a7e | ||
|
|
66a908aaa7 | ||
|
|
cd0ed08237 | ||
|
|
dd84b554e6 | ||
|
|
b51411f090 | ||
|
|
4cc843ded3 | ||
|
|
47d253c732 | ||
|
|
09901274ab | ||
|
|
35196e20c7 | ||
|
|
35af771a29 | ||
|
|
dee80caa09 | ||
|
|
46b7cc0a72 | ||
|
|
3b189e22b7 | ||
|
|
6ca565d7fb | ||
|
|
64f5480f96 | ||
|
|
828fdc8769 | ||
|
|
6763c4415e | ||
|
|
fb30e79e03 | ||
|
|
85fb4304b0 | ||
|
|
c2da77d7ec | ||
|
|
c54c3d3c15 | ||
|
|
2a7c954155 | ||
|
|
3fb7f7c7cc | ||
|
|
c4b2818336 | ||
|
|
061561bfd8 | ||
|
|
d4944d606b | ||
|
|
736b689c3b | ||
|
|
e12b377014 | ||
|
|
5fd5b815ab | ||
|
|
92db8312f6 | ||
|
|
1f2f4ce4f3 | ||
|
|
e080fe547d | ||
|
|
b967ecf063 | ||
|
|
365b7285d2 | ||
|
|
a40d532b0e | ||
|
|
0487bf911d | ||
|
|
57c72d1cd0 | ||
|
|
335bdffec2 | ||
|
|
e1d76a1dfe | ||
|
|
a4845323a2 | ||
|
|
792951b489 | ||
|
|
5adda836af | ||
|
|
4c2c3098c3 | ||
|
|
087c714098 | ||
|
|
5a33e4fe05 | ||
|
|
5f8667eaa7 | ||
|
|
31b4468514 | ||
|
|
2be9678bbe | ||
|
|
b5210877cf | ||
|
|
a8702be756 | ||
|
|
0995cc3f4e |
8
.babelrc
8
.babelrc
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"experimental": true,
|
||||
"playground": true,
|
||||
"loose": true,
|
||||
"blacklist": ["es6.tailCall"]
|
||||
"stage": 0,
|
||||
"loose": ["all"],
|
||||
"blacklist": ["es6.tailCall"],
|
||||
"optional": ["optimisation.flow.forOf"]
|
||||
}
|
||||
|
||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,12 +1,6 @@
|
||||
[submodule "vendor/traceur"]
|
||||
path = vendor/traceur
|
||||
url = https://github.com/google/traceur-compiler
|
||||
[submodule "vendor/regenerator"]
|
||||
path = vendor/regenerator
|
||||
url = https://github.com/babel/regenerator-babel
|
||||
[submodule "vendor/test262"]
|
||||
path = vendor/test262
|
||||
url = https://github.com/tc39/test262
|
||||
[submodule "vendor/compat-table"]
|
||||
path = vendor/compat-table
|
||||
url = https://github.com/kangax/compat-table
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
sudo: false
|
||||
#sudo: false
|
||||
language: node_js
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
node_js:
|
||||
- "0.12"
|
||||
- "iojs"
|
||||
|
||||
171
CHANGELOG.md
171
CHANGELOG.md
@@ -13,6 +13,177 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 5.2.11
|
||||
|
||||
* **Internal**
|
||||
* Rename `getModuleName` option to `getModuleId`, doh.
|
||||
|
||||
## 5.2.10
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix numerous issues in `replaceWithSourceString`. Thanks [@pangratz](https://github.com/pangratz)!
|
||||
* **New Feature**
|
||||
* Add `getModuleName` option. Thanks [@jayphelps](https://github.com/jayphelps)!
|
||||
|
||||
## 5.2.9
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `_blockHoist` transformer incorrectly sorting nodes on shitty environments that aren't spec compliant in their key order.
|
||||
* Fix broken `parse` API method reference to an undeclared import.
|
||||
|
||||
## 5.2.7
|
||||
|
||||
* **Bug Fix**
|
||||
* Move `utility.deadCodeElimination` transformer up to avoid race conditions.
|
||||
* Fix shorthand property scope binding renaming.
|
||||
* **Polish**
|
||||
* Turn helper variable declarations into function declarations if possible.
|
||||
* **Internal**
|
||||
* Removed native inheritance support from classes.
|
||||
* Added `replaceWithSourceString` path API.
|
||||
* Split up `es3.propertyLiterals` and `es3.memberExpressionLiterals` transformers to `minfication.propertyLiterals` and `es3.memberExpressionLiterals`.
|
||||
|
||||
## 5.2.6
|
||||
|
||||
* **Internal**
|
||||
* Fix transformer aliases being accidently set as deprecated ones.
|
||||
* Expose `Pipeline` as `TransformerPipeline` instead.
|
||||
|
||||
## 5.2.5
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `parse` API not adding all the correct pipeline transformers.
|
||||
|
||||
## 5.2.4
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix race condition with the Node API being loaded awkwardly and not being able to initialise itself when used in the browser.
|
||||
* **Internal**
|
||||
* Expose `transform.pipeline`.
|
||||
|
||||
## 5.2.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix plugin containers being called with an undefined import. Thanks [@timbur](https://github.com/timbur)!
|
||||
* Allow Flow object separators to be commas. Thanks [@monsanto](https://github.com/monsanto)!
|
||||
* Add missing `Statement` and `Declaration` node aliases to flow types.
|
||||
|
||||
## 5.2.2
|
||||
|
||||
* **Internal**
|
||||
* Allow `util.arrayify` to take arbitrary types and coerce it into an array.
|
||||
|
||||
## 5.2.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix regression in `node/register` that caused `node_modules` to not be ignored.
|
||||
|
||||
## 5.2.0
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix plugin strings splitting arbitrarily on `:` which caused full paths on Windows to fail as they include `:` after the drive letter.
|
||||
* Call class property `initializer`s with their target instead of their descriptor.
|
||||
* Fix `ignore` and `only` not properly working on Windows path separators. Thanks [@stagas](https://github.com/stagas)!
|
||||
* Fix `resolveRc` running on files twice causing issues. Thanks [@lukescott](https://github.com/lukescott)!
|
||||
* Fix shorthand properties not correctly being target for `isReferenced` checks. Thanks [@monsanto](https://github.com/monsanto)!
|
||||
* **Polish**
|
||||
* Allow passing an array of globs to `babel/register` `only` and `ignore` options. Thanks [@Mark-Simulacrum](https://github.com/Mark-Simulacrum)!
|
||||
* When inferring function names that collide with upper bindings, instead of doing the wrapper, instead rename them.
|
||||
* Consider constant-like variable declaration functions to always refer to themselves so TOC can be performed.
|
||||
* Process globs manually when using `$ babel` as some shells such as Windows don't explode them. Thanks [@jden](https://github.com/jden)!
|
||||
* Add alternative way to execute plugins via a closure that's called with the current Babel instance.
|
||||
* **Internal**
|
||||
* Remove multiple internal transformers in favor of directly doing things when we need to. Previously, declarations such as `_ref` that we needed to create in specific scopes were done at the very end via the `_declarations` transformer. Now, they're done and added to the scope **right** when they're needed. This gets rid of the crappy `_declarations` property on scope nodes and fixes the crappy regenerator bug where it was creating a new `BlockStatement` so the declarations were being lost.
|
||||
* Rework transformer traversal optimisation. Turns out that calling a `check` function for **every single node** in the AST is ridiculously expensive. 300,000 nodes timesed by ~30 transformers meant that it took tens of seconds to perform while it's quicker to just do the unnecessary traversal. Seems obvious in hindsight.
|
||||
* **New Feature**
|
||||
* Add `jscript` transformer that turns named function expressions into function declarations to get around [JScript's horribly broken function expression semantics](https://kangax.github.io/nfe/#jscript-bugs). Thanks [@kondi](https://github.com/kondi)!
|
||||
* Add `@@hasInstance` support to objects when using the `es6.spec.symbols` transformer.
|
||||
* Add `retainLines` option that retains the line (but not the columns!) of the input code.
|
||||
|
||||
## 5.1.13
|
||||
|
||||
* **Polish**
|
||||
* Remove symbol check from `defineProperty` helper.
|
||||
|
||||
## 5.1.12
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `resolveModuleSource` not being ran on `ExportAllDeclaration`s.
|
||||
* Fix `.babelrc` being resolved multiple times when using the require hook.
|
||||
* Fix parse error on spread properties in assignment position.
|
||||
* Fix `externalHelpers` option being incorrectly listed as type `string`.
|
||||
* **Internal**
|
||||
* Upgrade `core-js` to `0.9.0`.
|
||||
* **Spec Compliancy**
|
||||
* Fix object decorators not using the `initializer` pattern.
|
||||
* Remove property initializer descriptor reflection.
|
||||
|
||||
## 5.1.11
|
||||
|
||||
* **Bug Fix**
|
||||
* Memoise and bind member expression decorators.
|
||||
* Move JSX children cleaning to opening element visitor. Fixes elements not being cleaned in certain scenarios.
|
||||
* Consider `SwitchStatement`s to be `Scopable`.
|
||||
* Fix `bluebirdCoroutines` calling `interopRequireWildcard` before it's defined.
|
||||
* Add space to `do...while` code generation.
|
||||
* Validate `super` use before `this` on `super` exit rather than entrance.
|
||||
* **Polish**
|
||||
* Add Babel name to logger.
|
||||
|
||||
## 5.1.10
|
||||
|
||||
* **Bug Fix**
|
||||
* Remove `makePredicate` from acorn in favor of an `indexOf`.
|
||||
* Remove statements to expression explosion when inserting a block statement.
|
||||
* **Internal**
|
||||
* Remove runtime compatibility check.
|
||||
|
||||
## 5.1.9
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix class property initializers with `undefined` values not being correctly writable.
|
||||
* Fix self inferring generators incorrectly causing a stack error.
|
||||
* Fix default export specifiers not triggering AMD `module` argument inclusion.
|
||||
* Fix assignments not having their module references properly remapped.
|
||||
* **Internal**
|
||||
* Upgrade to latest `acorn`.
|
||||
* **Polish**
|
||||
* Make invalid LHS pattern error messages nicer.
|
||||
|
||||
## 5.1.8
|
||||
|
||||
* **Bug Fix**
|
||||
* Only make parenthesized object pattern LHS illegal.
|
||||
|
||||
## 5.1.7
|
||||
|
||||
* **Internal**
|
||||
* Add `parse` node API.
|
||||
|
||||
## 5.1.6
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `runtime` built-in catchall not properly checking for local variables.
|
||||
|
||||
## 5.1.5
|
||||
|
||||
* **Internal**
|
||||
* Bump `core-js` version.
|
||||
|
||||
## 5.1.4
|
||||
|
||||
* **Polish**
|
||||
* Add missing `Reflect` methods to runtime transformer.
|
||||
|
||||
## 5.1.3
|
||||
|
||||
* **Internal**
|
||||
* Switch entirely to vanilla regenerator.
|
||||
* Clean up and make the parsing of decorators stateless.
|
||||
* **Bug Fix**
|
||||
* Don't do TCO on generators and async functions.
|
||||
* Add missing `core-js` runtime definitions.
|
||||
|
||||
## 5.1.2
|
||||
|
||||
* **Bug Fix**
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
<p align="center">
|
||||
<strong><a href="#setup">Setup</a></strong>
|
||||
|
|
||||
<strong><a href="#running-tests">Running tests</a></strong>
|
||||
|
|
||||
<strong><a href="#workflow">Workflow</a></strong>
|
||||
|
|
||||
<strong><a href="#dependencies">Dependencies</a></strong>
|
||||
|
|
||||
<strong><a href="#code-standards">Code Standards</a></strong>
|
||||
</p>
|
||||
|
||||
----
|
||||
|
||||
# Contributing
|
||||
|
||||
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
|
||||
|
||||
#### Setup
|
||||
@@ -14,14 +29,19 @@ $ cd babel
|
||||
$ make bootstrap
|
||||
```
|
||||
|
||||
Then you need to run:
|
||||
Then you can either run:
|
||||
|
||||
```sh
|
||||
$ make build-core
|
||||
```
|
||||
|
||||
to build Babel **once** or:
|
||||
|
||||
```sh
|
||||
$ make watch-core
|
||||
```
|
||||
|
||||
This will compile Babel and then sit in the background and on file modification
|
||||
recompile the necessary files.
|
||||
to have Babel build itself then incrementally build files on change.
|
||||
|
||||
#### Running tests
|
||||
|
||||
@@ -44,6 +64,11 @@ Use mocha's `--grep` option to run a subset of tests by name:
|
||||
$ mocha test/core/transformation.js --grep es7
|
||||
```
|
||||
|
||||
If you don't have `mocha` installed globally, you can still use it from Babel's
|
||||
dependencies in `node_modules`, but make sure `node_modules/.bin` is added to
|
||||
your [`$PATH`](http://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path) environment variable.
|
||||
|
||||
|
||||
#### Workflow
|
||||
|
||||
* Fork the repository
|
||||
@@ -54,24 +79,91 @@ $ mocha test/core/transformation.js --grep es7
|
||||
* Ensure the test are passing (`make test`)
|
||||
* Create new pull request explaining your proposed change or reference an issue in your commit message
|
||||
|
||||
|
||||
#### Dependencies
|
||||
|
||||
+ [ast-types](http://ghub.io/ast-types) This is required to monkeypatch regenerators AST definitions. Could be improved in the future.
|
||||
|
||||
+ [chalk](http://ghub.io/chalk) This is used for terminal color highlighting for syntax errors.
|
||||
|
||||
+ [convert-source-map](http://ghub.io/convert-source-map) Turns a source map object into a comment etc.
|
||||
|
||||
+ [core-js](http://ghub.io/core-js) Used for the polyfill.
|
||||
|
||||
+ [debug](http://ghub.io/debug) Used to output debugging information when NODE_DEBUG is set to babel.
|
||||
|
||||
+ [detect-indent](http://ghub.io/detect-indent) This is used in the code generator so it can infer indentation.
|
||||
|
||||
+ [estraverse](http://ghub.io/estraverse) The only method on this is attachComments. I'd like to implement our own comment attachment algorithm eventually though.
|
||||
|
||||
+ [esutils](http://ghub.io/esutils) Various ES related utilities. Check whether something is a keyword etc.
|
||||
|
||||
+ [fs-readdir-recursive](http://ghub.io/fs-readdir-recursive) Recursively search a directory for.
|
||||
|
||||
+ [globals](http://ghub.io/globals) A list of JavaScript global variables. This is used by the scope tracking to check for colliding variables.
|
||||
|
||||
+ [is-integer](http://ghub.io/is-integer) Checks if something is an integer.
|
||||
|
||||
+ [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.
|
||||
|
||||
+ [minimatch](http://ghub.io/minimatch) This is used to match glob-style ignore/only filters.
|
||||
|
||||
+ [output-file-sync](http://ghub.io/output-file-sync) Synchronously writes a file and create its ancestor directories if needed.
|
||||
|
||||
+ [path-is-absolute](http://ghub.io/path-is-absolute) Checks if a path is absolute. C:\foo and \foo are considered absolute.
|
||||
|
||||
+ [regenerator](http://ghub.io/regenerator) This is used to transform generators/async functions.
|
||||
|
||||
+ [regexpu](http://ghub.io/regexpu) Used to transform unicode regex patterns.
|
||||
|
||||
+ [repeating](http://ghub.io/repeating) Repeats a string.
|
||||
|
||||
+ [shebang-regex](http://ghub.io/shebang-regex) Literally just a regex that matches shebangs.
|
||||
|
||||
+ [slash](http://ghub.io/slash) Normalises path separators.
|
||||
|
||||
+ [source-map](http://ghub.io/source-map) Generates sourcemaps.
|
||||
|
||||
+ [source-map-support](http://ghub.io/source-map-support) Adds source map support to babel-node/babel/register.
|
||||
|
||||
+ [strip-json-comments](http://ghub.io/strip-json-comments) Remove comments from a JSON string. This is used for .babelrc files.
|
||||
|
||||
+ [to-fast-properties](http://ghub.io/to-fast-properties) A V8 trick to put an object into fast properties mode.
|
||||
|
||||
+ [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.
|
||||
|
||||
|
||||
#### Code Standards
|
||||
|
||||
* **General**
|
||||
* Max of five arguments for functions
|
||||
* Max depth of four nested blocks
|
||||
* 2-spaced soft tabs
|
||||
|
||||
* **Naming**
|
||||
* CamelCase all class names
|
||||
* camelBack all variable names
|
||||
|
||||
* **Spacing**
|
||||
* Spaces after all keywords
|
||||
* Spaces before all left curly braces
|
||||
|
||||
* **Comments**
|
||||
* Use JSDoc-style comments for methods
|
||||
* Single-line comments for ambiguous code
|
||||
|
||||
* **Quotes**
|
||||
* Always use double quotes
|
||||
* Only use single quotes when the string contains a double quote
|
||||
|
||||
* **Declaration**
|
||||
* No unused variables
|
||||
* No pollution of global variables and prototypes
|
||||
|
||||
14
Makefile
14
Makefile
@@ -3,23 +3,25 @@ BROWSERIFY_CMD = node_modules/browserify/bin/cmd.js
|
||||
ISTANBUL_CMD = node_modules/istanbul/lib/cli.js cover
|
||||
UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
|
||||
#UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs --mangle sort
|
||||
JSHINT_CMD = node_modules/jshint/bin/jshint
|
||||
MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
BABEL_CMD = node_modules/babel/bin/babel
|
||||
|
||||
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
|
||||
.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
|
||||
|
||||
build-core:
|
||||
build-core: clean-core
|
||||
node $(BABEL_CMD) src --out-dir lib --copy-files
|
||||
|
||||
build-core-test:
|
||||
build-core-test: clean-core
|
||||
node $(BABEL_CMD) src --out-dir lib --copy-files --auxiliary-comment "istanbul ignore next"
|
||||
|
||||
watch-core:
|
||||
watch-core: clean-core
|
||||
node $(BABEL_CMD) src --out-dir lib --watch --copy-files
|
||||
|
||||
clean-core:
|
||||
rm -rf lib
|
||||
|
||||
build:
|
||||
mkdir -p dist
|
||||
make build-core
|
||||
@@ -114,5 +116,5 @@ bootstrap:
|
||||
npm link
|
||||
cd packages/babel-cli && npm install && npm link && npm link babel-core
|
||||
git submodule update --init
|
||||
cd vendor/regenerator && npm install
|
||||
cd vendor/compat-table && npm install object-assign
|
||||
make build
|
||||
|
||||
13
package.json
13
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel-core",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.1.2",
|
||||
"version": "5.2.11",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"repository": "babel/babel",
|
||||
@@ -27,10 +27,12 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-jsx": "^1.0.0",
|
||||
"ast-types": "~0.7.0",
|
||||
"bluebird": "^2.9.25",
|
||||
"chalk": "^1.0.0",
|
||||
"convert-source-map": "^1.0.0",
|
||||
"core-js": "^0.8.1",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"core-js": "^0.9.0",
|
||||
"debug": "^2.1.1",
|
||||
"detect-indent": "^3.0.0",
|
||||
"estraverse": "^3.0.0",
|
||||
@@ -46,9 +48,10 @@
|
||||
"output-file-sync": "^1.1.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"private": "^0.1.6",
|
||||
"regenerator": "https://github.com/sebmck/regenerator/archive/block-hoist.tar.gz",
|
||||
"regenerator": "^0.8.20",
|
||||
"regexpu": "^1.1.2",
|
||||
"repeating": "^1.1.2",
|
||||
"resolve": "^1.1.6",
|
||||
"shebang-regex": "^1.0.0",
|
||||
"slash": "^1.0.0",
|
||||
"source-map": "^0.4.0",
|
||||
@@ -59,7 +62,7 @@
|
||||
"user-home": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "4.7.13",
|
||||
"babel": "5.1.13",
|
||||
"browserify": "^9.0.8",
|
||||
"chai": "^2.2.0",
|
||||
"eslint": "^0.18.0",
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
var handleFile = function (src, filename) {
|
||||
if (util.shouldIgnore(src)) return;
|
||||
|
||||
if (util.canCompile(filename)) {
|
||||
if (util.canCompile(filename, commander.extensions)) {
|
||||
write(src, filename);
|
||||
} else if (commander.copyFiles) {
|
||||
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
|
||||
|
||||
@@ -27,9 +27,14 @@ module.exports = function (commander, filenames, opts) {
|
||||
|
||||
if (result.map) {
|
||||
var consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||
var sourceFilename = filename;
|
||||
|
||||
map._sources.add(filename);
|
||||
map.setSourceContent(filename, result.actual);
|
||||
if (commander.outFile) {
|
||||
sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
|
||||
}
|
||||
|
||||
map._sources.add(sourceFilename);
|
||||
map.setSourceContent(sourceFilename, result.actual);
|
||||
|
||||
consumer.eachMapping(function (mapping) {
|
||||
map._mappings.add({
|
||||
@@ -37,7 +42,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
generatedColumn: mapping.generatedColumn,
|
||||
originalLine: mapping.originalLine,
|
||||
originalColumn: mapping.originalColumn,
|
||||
source: filename
|
||||
source: sourceFilename
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
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 each = require("lodash/collection/each");
|
||||
var keys = require("lodash/object/keys");
|
||||
var fs = require("fs");
|
||||
var moduleFormatters = require("babel-core/lib/babel/transformation/modules");
|
||||
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 each = require("lodash/collection/each");
|
||||
var keys = require("lodash/object/keys");
|
||||
var fs = require("fs");
|
||||
var glob = require("glob");
|
||||
|
||||
each(options, function (option, key) {
|
||||
if (option.hidden) return;
|
||||
@@ -35,6 +37,7 @@ each(options, function (option, key) {
|
||||
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");
|
||||
@@ -56,8 +59,8 @@ commander.on("--help", function () {
|
||||
console.log();
|
||||
};
|
||||
|
||||
outKeys("Transformers", transform.transformers);
|
||||
outKeys("Module formatters", transform.moduleFormatters);
|
||||
outKeys("Transformers", transform.pipeline.transformers);
|
||||
outKeys("Module formatters", moduleFormatters);
|
||||
});
|
||||
|
||||
var pkg = require("../../package.json");
|
||||
@@ -69,7 +72,9 @@ commander.parse(process.argv);
|
||||
|
||||
var errors = [];
|
||||
|
||||
var filenames = commander.args;
|
||||
var filenames = commander.args.reduce(function (globbed, input) {
|
||||
return globbed.concat(glob.sync(input));
|
||||
}, []);
|
||||
|
||||
each(filenames, function (filename) {
|
||||
if (!fs.existsSync(filename)) {
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
{
|
||||
"name": "babel",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.1.1",
|
||||
"version": "5.2.10",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"repository": "babel/babel",
|
||||
"preferGlobal": true,
|
||||
"dependencies": {
|
||||
"babel-core": "^5.1.1",
|
||||
"babel-core": "^5.2.10",
|
||||
"chokidar": "^1.0.0",
|
||||
"commander": "^2.6.0",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"fs-readdir-recursive": "^0.1.0",
|
||||
"output-file-sync": "^1.1.0",
|
||||
"glob": "^5.0.5",
|
||||
"lodash": "^3.2.0",
|
||||
"convert-source-map": "^0.5.0",
|
||||
"source-map": "^0.4.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
"output-file-sync": "^1.1.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"source-map": "^0.4.0"
|
||||
},
|
||||
"bin": {
|
||||
"babel": "./bin/babel/index.js",
|
||||
|
||||
1
packages/babel-cli/register-without-polyfill.js
Normal file
1
packages/babel-cli/register-without-polyfill.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("babel-core/register-without-polyfill");
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "babel-runtime",
|
||||
"description": "babel selfContained runtime",
|
||||
"version": "5.1.1",
|
||||
"version": "5.2.10",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"dependencies": {
|
||||
"core-js": "^0.8.0"
|
||||
"core-js": "^0.9.0"
|
||||
}
|
||||
}
|
||||
@@ -70,8 +70,8 @@ each(File.helpers, function (helperName) {
|
||||
writeFile("helpers/" + helperName + ".js", buildHelper(helperName));
|
||||
});
|
||||
|
||||
writeFile("regenerator/index.js", readFile("regenerator-babel/runtime-module", true));
|
||||
writeFile("regenerator/runtime.js", selfContainify(readFile("regenerator-babel/runtime")));
|
||||
writeFile("regenerator/index.js", readFile("regenerator/runtime-module", true));
|
||||
writeFile("regenerator/runtime.js", selfContainify(readFile("regenerator/runtime")));
|
||||
|
||||
//
|
||||
|
||||
|
||||
1
register-without-polyfill.js
Normal file
1
register-without-polyfill.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require("./lib/babel/api/register/node");
|
||||
@@ -1 +1 @@
|
||||
module.exports = require("./lib/babel/api/register/node");
|
||||
module.exports = require("./lib/babel/api/register/node-polyfill");
|
||||
|
||||
6
src/acorn/index.js
Normal file
6
src/acorn/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export * from "./src/index";
|
||||
import "./plugins/flow";
|
||||
|
||||
import inject from "acorn-jsx/inject";
|
||||
import * as acorn from "./src/index";
|
||||
inject(acorn);
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "acorn",
|
||||
"description": "ECMAScript parser",
|
||||
"homepage": "https://github.com/marijnh/acorn",
|
||||
"main": "src/index.js",
|
||||
"main": "index.js",
|
||||
"version": "1.0.0",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var acorn = require("..")
|
||||
var acorn = require("../src/index")
|
||||
|
||||
var pp = acorn.Parser.prototype
|
||||
var tt = acorn.tokTypes
|
||||
@@ -322,7 +322,7 @@ pp.flow_parseObjectType = function (allowStatic) {
|
||||
}
|
||||
|
||||
pp.flow_objectTypeSemicolon = function () {
|
||||
if (!this.eat(tt.semi) && this.type !== tt.braceR) {
|
||||
if (!this.eat(tt.semi) && !this.eat(tt.comma) && this.type !== tt.braceR) {
|
||||
this.unexpected()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,658 +0,0 @@
|
||||
var acorn = require("..")
|
||||
|
||||
var tt = acorn.tokTypes;
|
||||
var tc = acorn.tokContexts;
|
||||
|
||||
tc.j_oTag = new acorn.TokContext("<tag", false);
|
||||
tc.j_cTag = new acorn.TokContext("</tag", false);
|
||||
tc.j_expr = new acorn.TokContext("<tag>...</tag>", true, true);
|
||||
|
||||
tt.jsxName = new acorn.TokenType("jsxName");
|
||||
tt.jsxText = new acorn.TokenType("jsxText", {beforeExpr: true});
|
||||
tt.jsxTagStart = new acorn.TokenType("jsxTagStart");
|
||||
tt.jsxTagEnd = new acorn.TokenType("jsxTagEnd");
|
||||
|
||||
tt.jsxTagStart.updateContext = function() {
|
||||
this.context.push(tc.j_expr); // treat as beginning of JSX expression
|
||||
this.context.push(tc.j_oTag); // start opening tag context
|
||||
this.exprAllowed = false;
|
||||
};
|
||||
tt.jsxTagEnd.updateContext = function(prevType) {
|
||||
var out = this.context.pop();
|
||||
if (out === tc.j_oTag && prevType === tt.slash || out === tc.j_cTag) {
|
||||
this.context.pop();
|
||||
this.exprAllowed = this.curContext() === tc.j_expr;
|
||||
} else {
|
||||
this.exprAllowed = true;
|
||||
}
|
||||
};
|
||||
|
||||
var pp = acorn.Parser.prototype;
|
||||
|
||||
// Reads inline JSX contents token.
|
||||
|
||||
pp.jsx_readToken = function() {
|
||||
var out = "", chunkStart = this.pos;
|
||||
for (;;) {
|
||||
if (this.pos >= this.input.length)
|
||||
this.raise(this.start, "Unterminated JSX contents");
|
||||
var ch = this.input.charCodeAt(this.pos);
|
||||
|
||||
switch (ch) {
|
||||
case 60: // '<'
|
||||
case 123: // '{'
|
||||
if (this.pos === this.start) {
|
||||
if (ch === 60 && this.exprAllowed) {
|
||||
++this.pos;
|
||||
return this.finishToken(tt.jsxTagStart);
|
||||
}
|
||||
return this.getTokenFromCode(ch);
|
||||
}
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
return this.finishToken(tt.jsxText, out);
|
||||
|
||||
case 38: // '&'
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
out += this.jsx_readEntity();
|
||||
chunkStart = this.pos;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (acorn.isNewLine(ch)) {
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
++this.pos;
|
||||
if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
|
||||
++this.pos;
|
||||
out += "\n";
|
||||
} else {
|
||||
out += String.fromCharCode(ch);
|
||||
}
|
||||
if (this.options.locations) {
|
||||
++this.curLine;
|
||||
this.lineStart = this.pos;
|
||||
}
|
||||
chunkStart = this.pos;
|
||||
} else {
|
||||
++this.pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pp.jsx_readString = function(quote) {
|
||||
var out = "", chunkStart = ++this.pos;
|
||||
for (;;) {
|
||||
if (this.pos >= this.input.length)
|
||||
this.raise(this.start, "Unterminated string constant");
|
||||
var ch = this.input.charCodeAt(this.pos);
|
||||
if (ch === quote) break;
|
||||
if (ch === 38) { // '&'
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
out += this.jsx_readEntity();
|
||||
chunkStart = this.pos;
|
||||
} else {
|
||||
++this.pos;
|
||||
}
|
||||
}
|
||||
out += this.input.slice(chunkStart, this.pos++);
|
||||
return this.finishToken(tt.string, out);
|
||||
};
|
||||
|
||||
var XHTMLEntities = {
|
||||
quot: '\u0022',
|
||||
amp: '&',
|
||||
apos: '\u0027',
|
||||
lt: '<',
|
||||
gt: '>',
|
||||
nbsp: '\u00A0',
|
||||
iexcl: '\u00A1',
|
||||
cent: '\u00A2',
|
||||
pound: '\u00A3',
|
||||
curren: '\u00A4',
|
||||
yen: '\u00A5',
|
||||
brvbar: '\u00A6',
|
||||
sect: '\u00A7',
|
||||
uml: '\u00A8',
|
||||
copy: '\u00A9',
|
||||
ordf: '\u00AA',
|
||||
laquo: '\u00AB',
|
||||
not: '\u00AC',
|
||||
shy: '\u00AD',
|
||||
reg: '\u00AE',
|
||||
macr: '\u00AF',
|
||||
deg: '\u00B0',
|
||||
plusmn: '\u00B1',
|
||||
sup2: '\u00B2',
|
||||
sup3: '\u00B3',
|
||||
acute: '\u00B4',
|
||||
micro: '\u00B5',
|
||||
para: '\u00B6',
|
||||
middot: '\u00B7',
|
||||
cedil: '\u00B8',
|
||||
sup1: '\u00B9',
|
||||
ordm: '\u00BA',
|
||||
raquo: '\u00BB',
|
||||
frac14: '\u00BC',
|
||||
frac12: '\u00BD',
|
||||
frac34: '\u00BE',
|
||||
iquest: '\u00BF',
|
||||
Agrave: '\u00C0',
|
||||
Aacute: '\u00C1',
|
||||
Acirc: '\u00C2',
|
||||
Atilde: '\u00C3',
|
||||
Auml: '\u00C4',
|
||||
Aring: '\u00C5',
|
||||
AElig: '\u00C6',
|
||||
Ccedil: '\u00C7',
|
||||
Egrave: '\u00C8',
|
||||
Eacute: '\u00C9',
|
||||
Ecirc: '\u00CA',
|
||||
Euml: '\u00CB',
|
||||
Igrave: '\u00CC',
|
||||
Iacute: '\u00CD',
|
||||
Icirc: '\u00CE',
|
||||
Iuml: '\u00CF',
|
||||
ETH: '\u00D0',
|
||||
Ntilde: '\u00D1',
|
||||
Ograve: '\u00D2',
|
||||
Oacute: '\u00D3',
|
||||
Ocirc: '\u00D4',
|
||||
Otilde: '\u00D5',
|
||||
Ouml: '\u00D6',
|
||||
times: '\u00D7',
|
||||
Oslash: '\u00D8',
|
||||
Ugrave: '\u00D9',
|
||||
Uacute: '\u00DA',
|
||||
Ucirc: '\u00DB',
|
||||
Uuml: '\u00DC',
|
||||
Yacute: '\u00DD',
|
||||
THORN: '\u00DE',
|
||||
szlig: '\u00DF',
|
||||
agrave: '\u00E0',
|
||||
aacute: '\u00E1',
|
||||
acirc: '\u00E2',
|
||||
atilde: '\u00E3',
|
||||
auml: '\u00E4',
|
||||
aring: '\u00E5',
|
||||
aelig: '\u00E6',
|
||||
ccedil: '\u00E7',
|
||||
egrave: '\u00E8',
|
||||
eacute: '\u00E9',
|
||||
ecirc: '\u00EA',
|
||||
euml: '\u00EB',
|
||||
igrave: '\u00EC',
|
||||
iacute: '\u00ED',
|
||||
icirc: '\u00EE',
|
||||
iuml: '\u00EF',
|
||||
eth: '\u00F0',
|
||||
ntilde: '\u00F1',
|
||||
ograve: '\u00F2',
|
||||
oacute: '\u00F3',
|
||||
ocirc: '\u00F4',
|
||||
otilde: '\u00F5',
|
||||
ouml: '\u00F6',
|
||||
divide: '\u00F7',
|
||||
oslash: '\u00F8',
|
||||
ugrave: '\u00F9',
|
||||
uacute: '\u00FA',
|
||||
ucirc: '\u00FB',
|
||||
uuml: '\u00FC',
|
||||
yacute: '\u00FD',
|
||||
thorn: '\u00FE',
|
||||
yuml: '\u00FF',
|
||||
OElig: '\u0152',
|
||||
oelig: '\u0153',
|
||||
Scaron: '\u0160',
|
||||
scaron: '\u0161',
|
||||
Yuml: '\u0178',
|
||||
fnof: '\u0192',
|
||||
circ: '\u02C6',
|
||||
tilde: '\u02DC',
|
||||
Alpha: '\u0391',
|
||||
Beta: '\u0392',
|
||||
Gamma: '\u0393',
|
||||
Delta: '\u0394',
|
||||
Epsilon: '\u0395',
|
||||
Zeta: '\u0396',
|
||||
Eta: '\u0397',
|
||||
Theta: '\u0398',
|
||||
Iota: '\u0399',
|
||||
Kappa: '\u039A',
|
||||
Lambda: '\u039B',
|
||||
Mu: '\u039C',
|
||||
Nu: '\u039D',
|
||||
Xi: '\u039E',
|
||||
Omicron: '\u039F',
|
||||
Pi: '\u03A0',
|
||||
Rho: '\u03A1',
|
||||
Sigma: '\u03A3',
|
||||
Tau: '\u03A4',
|
||||
Upsilon: '\u03A5',
|
||||
Phi: '\u03A6',
|
||||
Chi: '\u03A7',
|
||||
Psi: '\u03A8',
|
||||
Omega: '\u03A9',
|
||||
alpha: '\u03B1',
|
||||
beta: '\u03B2',
|
||||
gamma: '\u03B3',
|
||||
delta: '\u03B4',
|
||||
epsilon: '\u03B5',
|
||||
zeta: '\u03B6',
|
||||
eta: '\u03B7',
|
||||
theta: '\u03B8',
|
||||
iota: '\u03B9',
|
||||
kappa: '\u03BA',
|
||||
lambda: '\u03BB',
|
||||
mu: '\u03BC',
|
||||
nu: '\u03BD',
|
||||
xi: '\u03BE',
|
||||
omicron: '\u03BF',
|
||||
pi: '\u03C0',
|
||||
rho: '\u03C1',
|
||||
sigmaf: '\u03C2',
|
||||
sigma: '\u03C3',
|
||||
tau: '\u03C4',
|
||||
upsilon: '\u03C5',
|
||||
phi: '\u03C6',
|
||||
chi: '\u03C7',
|
||||
psi: '\u03C8',
|
||||
omega: '\u03C9',
|
||||
thetasym: '\u03D1',
|
||||
upsih: '\u03D2',
|
||||
piv: '\u03D6',
|
||||
ensp: '\u2002',
|
||||
emsp: '\u2003',
|
||||
thinsp: '\u2009',
|
||||
zwnj: '\u200C',
|
||||
zwj: '\u200D',
|
||||
lrm: '\u200E',
|
||||
rlm: '\u200F',
|
||||
ndash: '\u2013',
|
||||
mdash: '\u2014',
|
||||
lsquo: '\u2018',
|
||||
rsquo: '\u2019',
|
||||
sbquo: '\u201A',
|
||||
ldquo: '\u201C',
|
||||
rdquo: '\u201D',
|
||||
bdquo: '\u201E',
|
||||
dagger: '\u2020',
|
||||
Dagger: '\u2021',
|
||||
bull: '\u2022',
|
||||
hellip: '\u2026',
|
||||
permil: '\u2030',
|
||||
prime: '\u2032',
|
||||
Prime: '\u2033',
|
||||
lsaquo: '\u2039',
|
||||
rsaquo: '\u203A',
|
||||
oline: '\u203E',
|
||||
frasl: '\u2044',
|
||||
euro: '\u20AC',
|
||||
image: '\u2111',
|
||||
weierp: '\u2118',
|
||||
real: '\u211C',
|
||||
trade: '\u2122',
|
||||
alefsym: '\u2135',
|
||||
larr: '\u2190',
|
||||
uarr: '\u2191',
|
||||
rarr: '\u2192',
|
||||
darr: '\u2193',
|
||||
harr: '\u2194',
|
||||
crarr: '\u21B5',
|
||||
lArr: '\u21D0',
|
||||
uArr: '\u21D1',
|
||||
rArr: '\u21D2',
|
||||
dArr: '\u21D3',
|
||||
hArr: '\u21D4',
|
||||
forall: '\u2200',
|
||||
part: '\u2202',
|
||||
exist: '\u2203',
|
||||
empty: '\u2205',
|
||||
nabla: '\u2207',
|
||||
isin: '\u2208',
|
||||
notin: '\u2209',
|
||||
ni: '\u220B',
|
||||
prod: '\u220F',
|
||||
sum: '\u2211',
|
||||
minus: '\u2212',
|
||||
lowast: '\u2217',
|
||||
radic: '\u221A',
|
||||
prop: '\u221D',
|
||||
infin: '\u221E',
|
||||
ang: '\u2220',
|
||||
and: '\u2227',
|
||||
or: '\u2228',
|
||||
cap: '\u2229',
|
||||
cup: '\u222A',
|
||||
'int': '\u222B',
|
||||
there4: '\u2234',
|
||||
sim: '\u223C',
|
||||
cong: '\u2245',
|
||||
asymp: '\u2248',
|
||||
ne: '\u2260',
|
||||
equiv: '\u2261',
|
||||
le: '\u2264',
|
||||
ge: '\u2265',
|
||||
sub: '\u2282',
|
||||
sup: '\u2283',
|
||||
nsub: '\u2284',
|
||||
sube: '\u2286',
|
||||
supe: '\u2287',
|
||||
oplus: '\u2295',
|
||||
otimes: '\u2297',
|
||||
perp: '\u22A5',
|
||||
sdot: '\u22C5',
|
||||
lceil: '\u2308',
|
||||
rceil: '\u2309',
|
||||
lfloor: '\u230A',
|
||||
rfloor: '\u230B',
|
||||
lang: '\u2329',
|
||||
rang: '\u232A',
|
||||
loz: '\u25CA',
|
||||
spades: '\u2660',
|
||||
clubs: '\u2663',
|
||||
hearts: '\u2665',
|
||||
diams: '\u2666'
|
||||
};
|
||||
|
||||
var hexNumber = /^[\da-fA-F]+$/;
|
||||
var decimalNumber = /^\d+$/;
|
||||
|
||||
pp.jsx_readEntity = function() {
|
||||
var str = "", count = 0, entity;
|
||||
var ch = this.input[this.pos];
|
||||
if (ch !== "&")
|
||||
this.raise(this.pos, "Entity must start with an ampersand");
|
||||
var startPos = ++this.pos;
|
||||
while (this.pos < this.input.length && count++ < 10) {
|
||||
ch = this.input[this.pos++];
|
||||
if (ch === ";") {
|
||||
if (str[0] === "#") {
|
||||
if (str[1] === "x") {
|
||||
str = str.substr(2);
|
||||
if (hexNumber.test(str))
|
||||
entity = String.fromCharCode(parseInt(str, 16));
|
||||
} else {
|
||||
str = str.substr(1);
|
||||
if (decimalNumber.test(str))
|
||||
entity = String.fromCharCode(parseInt(str, 10));
|
||||
}
|
||||
} else {
|
||||
entity = XHTMLEntities[str];
|
||||
}
|
||||
break;
|
||||
}
|
||||
str += ch;
|
||||
}
|
||||
if (!entity) {
|
||||
this.pos = startPos;
|
||||
return "&";
|
||||
}
|
||||
return entity;
|
||||
};
|
||||
|
||||
|
||||
// Read a JSX identifier (valid tag or attribute name).
|
||||
//
|
||||
// Optimized version since JSX identifiers can't contain
|
||||
// escape characters and so can be read as single slice.
|
||||
// Also assumes that first character was already checked
|
||||
// by isIdentifierStart in readToken.
|
||||
|
||||
pp.jsx_readWord = function() {
|
||||
var ch, start = this.pos;
|
||||
do {
|
||||
ch = this.input.charCodeAt(++this.pos);
|
||||
} while (acorn.isIdentifierChar(ch) || ch === 45); // '-'
|
||||
return this.finishToken(tt.jsxName, this.input.slice(start, this.pos));
|
||||
};
|
||||
|
||||
// Transforms JSX element name to string.
|
||||
|
||||
function getQualifiedJSXName(object) {
|
||||
if (object.type === "JSXIdentifier")
|
||||
return object.name;
|
||||
|
||||
if (object.type === "JSXNamespacedName")
|
||||
return object.namespace.name + ':' + object.name.name;
|
||||
|
||||
if (object.type === "JSXMemberExpression")
|
||||
return getQualifiedJSXName(object.object) + '.' +
|
||||
getQualifiedJSXName(object.property);
|
||||
}
|
||||
|
||||
// Parse next token as JSX identifier
|
||||
|
||||
pp.jsx_parseIdentifier = function() {
|
||||
var node = this.startNode();
|
||||
if (this.type === tt.jsxName)
|
||||
node.name = this.value;
|
||||
else if (this.type.keyword)
|
||||
node.name = this.type.keyword;
|
||||
else
|
||||
this.unexpected();
|
||||
this.next();
|
||||
return this.finishNode(node, "JSXIdentifier");
|
||||
};
|
||||
|
||||
// Parse namespaced identifier.
|
||||
|
||||
pp.jsx_parseNamespacedName = function() {
|
||||
var start = this.markPosition();
|
||||
var name = this.jsx_parseIdentifier();
|
||||
if (!this.eat(tt.colon)) return name;
|
||||
var node = this.startNodeAt(start);
|
||||
node.namespace = name;
|
||||
node.name = this.jsx_parseIdentifier();
|
||||
return this.finishNode(node, "JSXNamespacedName");
|
||||
};
|
||||
|
||||
// Parses element name in any form - namespaced, member
|
||||
// or single identifier.
|
||||
|
||||
pp.jsx_parseElementName = function() {
|
||||
var start = this.markPosition();
|
||||
var node = this.jsx_parseNamespacedName();
|
||||
while (this.eat(tt.dot)) {
|
||||
var newNode = this.startNodeAt(start);
|
||||
newNode.object = node;
|
||||
newNode.property = this.jsx_parseIdentifier();
|
||||
node = this.finishNode(newNode, "JSXMemberExpression");
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
// Parses any type of JSX attribute value.
|
||||
|
||||
pp.jsx_parseAttributeValue = function() {
|
||||
switch (this.type) {
|
||||
case tt.braceL:
|
||||
var node = this.jsx_parseExpressionContainer();
|
||||
if (node.expression.type === "JSXEmptyExpression")
|
||||
this.raise(node.start, "JSX attributes must only be assigned a non-empty expression");
|
||||
return node;
|
||||
|
||||
case tt.jsxTagStart:
|
||||
case tt.string:
|
||||
return this.parseExprAtom();
|
||||
|
||||
default:
|
||||
this.raise(this.start, "JSX value should be either an expression or a quoted JSX text");
|
||||
}
|
||||
};
|
||||
|
||||
// JSXEmptyExpression is unique type since it doesn't actually parse anything,
|
||||
// and so it should start at the end of last read token (left brace) and finish
|
||||
// at the beginning of the next one (right brace).
|
||||
|
||||
pp.jsx_parseEmptyExpression = function() {
|
||||
var tmp = this.start;
|
||||
this.start = this.lastTokEnd;
|
||||
this.lastTokEnd = tmp;
|
||||
|
||||
tmp = this.startLoc;
|
||||
this.startLoc = this.lastTokEndLoc;
|
||||
this.lastTokEndLoc = tmp;
|
||||
|
||||
return this.finishNode(this.startNode(), "JSXEmptyExpression");
|
||||
};
|
||||
|
||||
// Parses JSX expression enclosed into curly brackets.
|
||||
|
||||
|
||||
pp.jsx_parseExpressionContainer = function() {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
node.expression = this.type === tt.braceR
|
||||
? this.jsx_parseEmptyExpression()
|
||||
: this.parseExpression();
|
||||
this.expect(tt.braceR);
|
||||
return this.finishNode(node, "JSXExpressionContainer");
|
||||
};
|
||||
|
||||
// Parses following JSX attribute name-value pair.
|
||||
|
||||
pp.jsx_parseAttribute = function() {
|
||||
var node = this.startNode();
|
||||
if (this.eat(tt.braceL)) {
|
||||
this.expect(tt.ellipsis);
|
||||
node.argument = this.parseMaybeAssign();
|
||||
this.expect(tt.braceR);
|
||||
return this.finishNode(node, "JSXSpreadAttribute");
|
||||
}
|
||||
node.name = this.jsx_parseNamespacedName();
|
||||
node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null;
|
||||
return this.finishNode(node, "JSXAttribute");
|
||||
};
|
||||
|
||||
// Parses JSX opening tag starting after '<'.
|
||||
|
||||
pp.jsx_parseOpeningElementAt = function(start) {
|
||||
var node = this.startNodeAt(start);
|
||||
node.attributes = [];
|
||||
node.name = this.jsx_parseElementName();
|
||||
while (this.type !== tt.slash && this.type !== tt.jsxTagEnd)
|
||||
node.attributes.push(this.jsx_parseAttribute());
|
||||
node.selfClosing = this.eat(tt.slash);
|
||||
this.expect(tt.jsxTagEnd);
|
||||
return this.finishNode(node, "JSXOpeningElement");
|
||||
};
|
||||
|
||||
// Parses JSX closing tag starting after '</'.
|
||||
|
||||
pp.jsx_parseClosingElementAt = function(start) {
|
||||
var node = this.startNodeAt(start);
|
||||
node.name = this.jsx_parseElementName();
|
||||
this.expect(tt.jsxTagEnd);
|
||||
return this.finishNode(node, "JSXClosingElement");
|
||||
};
|
||||
|
||||
// Parses entire JSX element, including it's opening tag
|
||||
// (starting after '<'), attributes, contents and closing tag.
|
||||
|
||||
pp.jsx_parseElementAt = function(start) {
|
||||
var node = this.startNodeAt(start);
|
||||
var children = [];
|
||||
var openingElement = this.jsx_parseOpeningElementAt(start);
|
||||
var closingElement = null;
|
||||
|
||||
if (!openingElement.selfClosing) {
|
||||
contents: for (;;) {
|
||||
switch (this.type) {
|
||||
case tt.jsxTagStart:
|
||||
start = this.markPosition();
|
||||
this.next();
|
||||
if (this.eat(tt.slash)) {
|
||||
closingElement = this.jsx_parseClosingElementAt(start);
|
||||
break contents;
|
||||
}
|
||||
children.push(this.jsx_parseElementAt(start));
|
||||
break;
|
||||
|
||||
case tt.jsxText:
|
||||
children.push(this.parseExprAtom());
|
||||
break;
|
||||
|
||||
case tt.braceL:
|
||||
children.push(this.jsx_parseExpressionContainer());
|
||||
break;
|
||||
|
||||
default:
|
||||
this.unexpected();
|
||||
}
|
||||
}
|
||||
if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name))
|
||||
this.raise(
|
||||
closingElement.start,
|
||||
"Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">");
|
||||
}
|
||||
|
||||
node.openingElement = openingElement;
|
||||
node.closingElement = closingElement;
|
||||
node.children = children;
|
||||
return this.finishNode(node, "JSXElement");
|
||||
};
|
||||
|
||||
// Parses entire JSX element from current position.
|
||||
|
||||
pp.jsx_parseElement = function() {
|
||||
var start = this.markPosition();
|
||||
this.next();
|
||||
return this.jsx_parseElementAt(start);
|
||||
};
|
||||
|
||||
acorn.plugins.jsx = function(instance) {
|
||||
instance.extend("parseExprAtom", function(inner) {
|
||||
return function(refShortHandDefaultPos) {
|
||||
if (this.type === tt.jsxText)
|
||||
return this.parseLiteral(this.value);
|
||||
else if (this.type === tt.jsxTagStart)
|
||||
return this.jsx_parseElement();
|
||||
else
|
||||
return inner.call(this, refShortHandDefaultPos);
|
||||
};
|
||||
});
|
||||
|
||||
instance.extend("readToken", function(inner) {
|
||||
return function(code) {
|
||||
var context = this.curContext();
|
||||
|
||||
if (context === tc.j_expr) return this.jsx_readToken();
|
||||
|
||||
if (context === tc.j_oTag || context === tc.j_cTag) {
|
||||
if (acorn.isIdentifierStart(code)) return this.jsx_readWord();
|
||||
|
||||
if (code == 62) {
|
||||
++this.pos;
|
||||
return this.finishToken(tt.jsxTagEnd);
|
||||
}
|
||||
|
||||
if ((code === 34 || code === 39) && context == tc.j_oTag)
|
||||
return this.jsx_readString(code);
|
||||
}
|
||||
|
||||
if (code === 60 && this.exprAllowed) {
|
||||
++this.pos;
|
||||
return this.finishToken(tt.jsxTagStart);
|
||||
}
|
||||
return inner.call(this, code);
|
||||
};
|
||||
});
|
||||
|
||||
instance.extend("updateContext", function(inner) {
|
||||
return function(prevType) {
|
||||
if (this.type == tt.braceL) {
|
||||
var curContext = this.curContext();
|
||||
if (curContext == tc.j_oTag) this.context.push(tc.b_expr);
|
||||
else if (curContext == tc.j_expr) this.context.push(tc.b_tmpl);
|
||||
else inner.call(this, prevType);
|
||||
this.exprAllowed = true;
|
||||
} else if (this.type === tt.slash && prevType === tt.jsxTagStart) {
|
||||
this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
|
||||
this.context.push(tc.j_cTag); // reconsider as closing tag context
|
||||
this.exprAllowed = false;
|
||||
} else {
|
||||
return inner.call(this, prevType);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -104,10 +104,14 @@ pp.parseMaybeAssign = function(noIn, refShorthandDefaultPos, afterLeftParse) {
|
||||
refShorthandDefaultPos.start = 0 // reset because shorthand default was used correctly
|
||||
this.checkLVal(left)
|
||||
if (left.parenthesizedExpression) {
|
||||
let errorMsg
|
||||
if (left.type === "ObjectPattern") {
|
||||
this.raise(left.start, "You're trying to assign to a parenthesized expression, instead of `({ foo }) = {}` use `({ foo } = {})`");
|
||||
} else {
|
||||
this.raise(left.start, "Parenthesized left hand expressions are illegal");
|
||||
errorMsg = "`({a}) = 0` use `({a} = 0)`"
|
||||
} else if (left.type === "ArrayPattern") {
|
||||
errorMsg = "`([a]) = 0` use `([a] = 0)`"
|
||||
}
|
||||
if (errorMsg) {
|
||||
this.raise(left.start, `You're trying to assign to a parenthesized expression, eg. instead of ${errorMsg}`)
|
||||
}
|
||||
}
|
||||
this.next()
|
||||
@@ -509,22 +513,24 @@ pp.parseTemplate = function() {
|
||||
pp.parseObj = function(isPattern, refShorthandDefaultPos) {
|
||||
let node = this.startNode(), first = true, propHash = {}
|
||||
node.properties = []
|
||||
let decorators = []
|
||||
this.next()
|
||||
while (!this.eat(tt.braceR)) {
|
||||
if (!first) {
|
||||
this.expect(tt.comma)
|
||||
if (this.afterTrailingComma(tt.braceR)) break
|
||||
} else first = false
|
||||
|
||||
while (this.type === tt.at) {
|
||||
this.decorators.push(this.parseDecorator())
|
||||
decorators.push(this.parseDecorator())
|
||||
}
|
||||
|
||||
let prop = this.startNode(), isGenerator = false, isAsync = false, start
|
||||
if (decorators.length) {
|
||||
prop.decorators = decorators
|
||||
decorators = []
|
||||
}
|
||||
if (this.options.features["es7.objectRestSpread"] && this.type === tt.ellipsis) {
|
||||
prop = this.parseSpread()
|
||||
prop.type = "SpreadProperty"
|
||||
this.takeDecorators(prop)
|
||||
node.properties.push(prop)
|
||||
continue
|
||||
}
|
||||
@@ -550,10 +556,9 @@ pp.parseObj = function(isPattern, refShorthandDefaultPos) {
|
||||
}
|
||||
this.parseObjPropValue(prop, start, isGenerator, isAsync, isPattern, refShorthandDefaultPos);
|
||||
this.checkPropClash(prop, propHash)
|
||||
this.takeDecorators(prop)
|
||||
node.properties.push(this.finishNode(prop, "Property"))
|
||||
}
|
||||
if (this.decorators.length) {
|
||||
if (decorators.length) {
|
||||
this.raise(this.start, "You have trailing decorators with no property");
|
||||
}
|
||||
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
|
||||
|
||||
@@ -9,41 +9,9 @@
|
||||
|
||||
function makePredicate(words) {
|
||||
words = words.split(" ")
|
||||
let f = "", cats = []
|
||||
out: for (let i = 0; i < words.length; ++i) {
|
||||
for (let j = 0; j < cats.length; ++j)
|
||||
if (cats[j][0].length == words[i].length) {
|
||||
cats[j].push(words[i])
|
||||
continue out
|
||||
}
|
||||
cats.push([words[i]])
|
||||
return function(str) {
|
||||
return words.indexOf(str) >= 0
|
||||
}
|
||||
function compareTo(arr) {
|
||||
if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";"
|
||||
f += "switch(str){"
|
||||
for (let i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":"
|
||||
f += "return true}return false;"
|
||||
}
|
||||
|
||||
// When there are more than three length categories, an outer
|
||||
// switch first dispatches on the lengths, to save on comparisons.
|
||||
|
||||
if (cats.length > 3) {
|
||||
cats.sort((a, b) => b.length - a.length)
|
||||
f += "switch(str.length){"
|
||||
for (let i = 0; i < cats.length; ++i) {
|
||||
let cat = cats[i]
|
||||
f += "case " + cat[0].length + ":"
|
||||
compareTo(cat)
|
||||
}
|
||||
f += "}"
|
||||
|
||||
// Otherwise, simply generate a flat `switch` statement.
|
||||
|
||||
} else {
|
||||
compareTo(words)
|
||||
}
|
||||
return new Function("str", f)
|
||||
}
|
||||
|
||||
// Reserved word lists for various dialects of the language
|
||||
|
||||
@@ -38,9 +38,6 @@ export {isIdentifierChar, isIdentifierStart} from "./identifier"
|
||||
export {Token} from "./tokenize"
|
||||
export {isNewLine, lineBreak, lineBreakG} from "./whitespace"
|
||||
|
||||
import "../plugins/flow";
|
||||
import "../plugins/jsx";
|
||||
|
||||
export const version = "1.0.0"
|
||||
|
||||
// The main exported interface (under `self.acorn` when in the
|
||||
|
||||
@@ -21,6 +21,7 @@ pp.toAssignable = function(node, isBinding) {
|
||||
node.type = "ObjectPattern"
|
||||
for (let i = 0; i < node.properties.length; i++) {
|
||||
let prop = node.properties[i]
|
||||
if (prop.type === "SpreadProperty") continue;
|
||||
if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter")
|
||||
this.toAssignable(prop.value, isBinding)
|
||||
}
|
||||
|
||||
@@ -471,14 +471,18 @@ pp.parseClass = function(node, isStatement) {
|
||||
var classBody = this.startNode()
|
||||
classBody.body = []
|
||||
this.expect(tt.braceL)
|
||||
let decorators = []
|
||||
while (!this.eat(tt.braceR)) {
|
||||
if (this.eat(tt.semi)) continue
|
||||
if (this.type === tt.at) {
|
||||
this.decorators.push(this.parseDecorator())
|
||||
decorators.push(this.parseDecorator())
|
||||
continue
|
||||
}
|
||||
var method = this.startNode()
|
||||
this.takeDecorators(method)
|
||||
if (decorators.length) {
|
||||
method.decorators = decorators
|
||||
decorators = []
|
||||
}
|
||||
var isGenerator = this.eat(tt.star), isAsync = false
|
||||
this.parsePropertyName(method)
|
||||
if (this.type !== tt.parenL && !method.computed && method.key.type === "Identifier" &&
|
||||
@@ -517,7 +521,7 @@ pp.parseClass = function(node, isStatement) {
|
||||
}
|
||||
this.parseClassMethod(classBody, method, isGenerator, isAsync)
|
||||
}
|
||||
if (this.decorators.length) {
|
||||
if (decorators.length) {
|
||||
this.raise(this.start, "You have trailing decorators with no method");
|
||||
}
|
||||
node.body = this.finishNode(classBody, "ClassBody")
|
||||
@@ -687,7 +691,6 @@ pp.parseImport = function(node) {
|
||||
if (this.type === tt.string) {
|
||||
node.specifiers = empty
|
||||
node.source = this.parseExprAtom()
|
||||
node.kind = ""
|
||||
} else {
|
||||
node.specifiers = []
|
||||
this.parseImportSpecifiers(node)
|
||||
|
||||
@@ -116,7 +116,7 @@ kw("do", {isLoop: true})
|
||||
kw("else", beforeExpr)
|
||||
kw("finally")
|
||||
kw("for", {isLoop: true})
|
||||
kw("function")
|
||||
kw("function", startsExpr)
|
||||
kw("if")
|
||||
kw("return", beforeExpr)
|
||||
kw("switch")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
require("./node");
|
||||
var transform = module.exports = require("../transformation");
|
||||
|
||||
transform.options = require("../transformation/file/options");
|
||||
@@ -11,7 +12,7 @@ transform.run = function (code, opts = {}) {
|
||||
};
|
||||
|
||||
transform.load = function (url, callback, opts = {}, hold) {
|
||||
opts.filename ||= url;
|
||||
opts.filename = opts.filename || url;
|
||||
|
||||
var xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest();
|
||||
xhr.open("GET", url, true);
|
||||
|
||||
@@ -4,12 +4,13 @@ import * as acorn from "../../acorn";
|
||||
import * as util from "../util";
|
||||
import fs from "fs";
|
||||
|
||||
export { util, acorn };
|
||||
export { util, acorn, transform };
|
||||
export { pipeline } from "../transformation";
|
||||
export { canCompile } from "../util";
|
||||
|
||||
export { default as options } from "../transformation/file/options";
|
||||
export { default as Transformer } from "../transformation/transformer";
|
||||
export { default as transform } from "../transformation";
|
||||
export { default as TransformerPipeline } from "../transformation/transformer-pipeline";
|
||||
export { default as traverse } from "../traversal";
|
||||
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
|
||||
export { version } from "../../../package";
|
||||
@@ -18,7 +19,7 @@ import * as t from "../types";
|
||||
export { t as types };
|
||||
|
||||
export function register(opts?: Object) {
|
||||
var callback = require("./register/node");
|
||||
var callback = require("./register/node-polyfill");
|
||||
if (opts != null) callback(opts);
|
||||
return callback;
|
||||
}
|
||||
@@ -52,5 +53,22 @@ export function transformFile(filename: string, opts?: Object, callback: Functio
|
||||
|
||||
export function transformFileSync(filename: string, opts?: Object = {}) {
|
||||
opts.filename = filename;
|
||||
return transform(fs.readFileSync(filename), opts);
|
||||
return transform(fs.readFileSync(filename, "utf8"), opts);
|
||||
}
|
||||
|
||||
export function parse(code, opts = {}) {
|
||||
opts.allowHashBang = true;
|
||||
opts.sourceType = "module";
|
||||
opts.ecmaVersion = Infinity;
|
||||
opts.plugins = {
|
||||
flow: true,
|
||||
jsx: true
|
||||
};
|
||||
opts.features = {};
|
||||
|
||||
for (var key in transform.pipeline.transformers) {
|
||||
opts.features[key] = true;
|
||||
}
|
||||
|
||||
return acorn.parse(code, opts);
|
||||
}
|
||||
|
||||
2
src/babel/api/register/node-polyfill.js
Normal file
2
src/babel/api/register/node-polyfill.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import "../../polyfill";
|
||||
export { default } from "./node";
|
||||
@@ -1,4 +1,3 @@
|
||||
import "../../polyfill";
|
||||
import sourceMapSupport from "source-map-support";
|
||||
import * as registerCache from "./cache";
|
||||
import resolveRc from "../../tools/resolve-rc";
|
||||
@@ -7,6 +6,7 @@ import * as babel from "../node";
|
||||
import each from "lodash/collection/each";
|
||||
import * as util from "../../util";
|
||||
import fs from "fs";
|
||||
import slash from "slash";
|
||||
|
||||
sourceMapSupport.install({
|
||||
handleUncaughtExceptions: false,
|
||||
@@ -31,8 +31,10 @@ var cache = registerCache.get();
|
||||
//
|
||||
|
||||
var transformOpts = {};
|
||||
var ignoreRegex = /node_modules/;
|
||||
var onlyRegex;
|
||||
|
||||
var ignore;
|
||||
var only;
|
||||
|
||||
var oldHandlers = {};
|
||||
var maps = {};
|
||||
|
||||
@@ -76,12 +78,16 @@ var compile = function (filename) {
|
||||
};
|
||||
|
||||
var shouldIgnore = function (filename) {
|
||||
return (ignoreRegex && ignoreRegex.test(filename)) || (onlyRegex && !onlyRegex.test(filename));
|
||||
if (!ignore && !only) {
|
||||
return /node_modules/.test(filename);
|
||||
} else {
|
||||
return util.shouldIgnore(filename, ignore || [], only || []);
|
||||
}
|
||||
};
|
||||
|
||||
var istanbulMonkey = {};
|
||||
|
||||
if (process.env.running_under_istanbul) { // jshint ignore:line
|
||||
if (process.env.running_under_istanbul) {
|
||||
// we need to monkey patch fs.readFileSync so we can hook into
|
||||
// what istanbul gets, it's extremely dirty but it's the only way
|
||||
var _readFileSync = fs.readFileSync;
|
||||
@@ -111,7 +117,7 @@ var registerExtension = function (ext) {
|
||||
var old = oldHandlers[ext] || oldHandlers[".js"];
|
||||
|
||||
var loader = normalLoader;
|
||||
if (process.env.running_under_istanbul) loader = istanbulLoader; // jshint ignore:line
|
||||
if (process.env.running_under_istanbul) loader = istanbulLoader;
|
||||
|
||||
require.extensions[ext] = function (m, filename) {
|
||||
if (shouldIgnore(filename)) {
|
||||
@@ -142,8 +148,8 @@ var hookExtensions = function (_exts) {
|
||||
hookExtensions(util.canCompile.EXTENSIONS);
|
||||
|
||||
export default function (opts = {}) {
|
||||
if (opts.only != null) onlyRegex = util.regexify(opts.only);
|
||||
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
|
||||
if (opts.only != null) only = util.arrayify(opts.only, util.regexify);
|
||||
if (opts.ignore != null) ignore = util.arrayify(opts.ignore, util.regexify);
|
||||
|
||||
if (opts.extensions) hookExtensions(util.arrayify(opts.extensions));
|
||||
|
||||
@@ -156,16 +162,3 @@ export default function (opts = {}) {
|
||||
|
||||
extend(transformOpts, opts);
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
try {
|
||||
var runtimePackage = require("babel-runtime/package");
|
||||
var version = require("../../../../package").version;
|
||||
if (runtimePackage.version !== version) {
|
||||
throw new ReferenceError(`The verison of babel-runtime of ${runtimePackage.runtime} that you have installed does not match the babel verison of ${version}`);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code !== "MODULE_NOT_FOUND") throw err;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,14 +70,14 @@ export default class Buffer {
|
||||
}
|
||||
|
||||
newline(i, removeLast) {
|
||||
if (this.format.compact) return;
|
||||
if (this.format.compact || this.format.retainLines) return;
|
||||
|
||||
if (this.format.concise) {
|
||||
this.space();
|
||||
return;
|
||||
}
|
||||
|
||||
removeLast ||= false;
|
||||
removeLast = removeLast || false;
|
||||
|
||||
if (isNumber(i)) {
|
||||
i = Math.min(2, i);
|
||||
|
||||
@@ -13,7 +13,7 @@ export function BlockStatement(node, print) {
|
||||
this.push("{");
|
||||
this.newline();
|
||||
print.sequence(node.body, { indent: true });
|
||||
this.removeLast("\n");
|
||||
if (!this.format.retainLines) this.removeLast("\n");
|
||||
this.rightBrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ export function JSXElement(node, print) {
|
||||
this.indent();
|
||||
each(node.children, (child) => {
|
||||
if (t.isLiteral(child)) {
|
||||
this.push(child.value);
|
||||
this.push(child.value, true);
|
||||
} else {
|
||||
print(child);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ export var ForInStatement = buildForXStatement("in");
|
||||
export var ForOfStatement = buildForXStatement("of");
|
||||
|
||||
export function DoWhileStatement(node, print) {
|
||||
this.keyword("do");
|
||||
this.push("do ");
|
||||
print(node.body);
|
||||
this.space();
|
||||
this.keyword("while");
|
||||
|
||||
@@ -12,7 +12,7 @@ import * as t from "../types";
|
||||
|
||||
class CodeGenerator {
|
||||
constructor(ast, opts, code) {
|
||||
opts ||= {};
|
||||
opts = opts || {};
|
||||
|
||||
this.comments = ast.comments || [];
|
||||
this.tokens = ast.tokens || [];
|
||||
@@ -34,9 +34,10 @@ class CodeGenerator {
|
||||
}
|
||||
|
||||
var format = {
|
||||
retainLines: opts.retainLines,
|
||||
comments: opts.comments == null || opts.comments,
|
||||
compact: opts.compact,
|
||||
quotes: CodeGenerator.findCommonStringDelimeter(code, tokens),
|
||||
quotes: CodeGenerator.findCommonStringDelimiter(code, tokens),
|
||||
indent: {
|
||||
adjustMultilineComment: true,
|
||||
style: style,
|
||||
@@ -48,14 +49,14 @@ class CodeGenerator {
|
||||
format.compact = code.length > 100000; // 100KB
|
||||
|
||||
if (format.compact) {
|
||||
console.error(messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
|
||||
console.error("[BABEL] " + messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static findCommonStringDelimeter(code, tokens) {
|
||||
static findCommonStringDelimiter(code, tokens) {
|
||||
var occurences = {
|
||||
single: 0,
|
||||
double: 0
|
||||
@@ -146,6 +147,22 @@ class CodeGenerator {
|
||||
return print;
|
||||
}
|
||||
|
||||
catchUp(node, parent) {
|
||||
// catch up to this nodes newline if we're behind
|
||||
if (node.loc && this.format.retainLines && this.buffer.buf) {
|
||||
var needsParens = false;
|
||||
if (parent && this.position.line < node.loc.start.line && t.isTerminatorless(parent)) {
|
||||
needsParens = true;
|
||||
this._push("(");
|
||||
}
|
||||
while (this.position.line < node.loc.start.line) {
|
||||
this._push("\n");
|
||||
}
|
||||
return needsParens;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
print(node, parent, opts = {}) {
|
||||
if (!node) return;
|
||||
|
||||
@@ -197,6 +214,8 @@ class CodeGenerator {
|
||||
|
||||
this.printLeadingComments(node, parent);
|
||||
|
||||
var needsParensFromCatchup = this.catchUp(node, parent);
|
||||
|
||||
newline(true);
|
||||
|
||||
if (opts.before) opts.before();
|
||||
@@ -208,19 +227,19 @@ class CodeGenerator {
|
||||
this.newline();
|
||||
this.dedent();
|
||||
}
|
||||
if (needsParens) this.push(")");
|
||||
if (needsParens || needsParensFromCatchup) this.push(")");
|
||||
|
||||
this.map.mark(node, "end");
|
||||
if (opts.after) opts.after();
|
||||
|
||||
this.format.concise = oldConcise;
|
||||
|
||||
newline(false);
|
||||
|
||||
this.printTrailingComments(node, parent);
|
||||
} else {
|
||||
throw new ReferenceError(`unknown node of type ${JSON.stringify(node.type)} with constructor ${JSON.stringify(node && node.constructor.name)}`);
|
||||
}
|
||||
|
||||
this.format.concise = oldConcise;
|
||||
}
|
||||
|
||||
printJoin(print, nodes, opts = {}) {
|
||||
@@ -328,6 +347,8 @@ class CodeGenerator {
|
||||
|
||||
if (skip) return;
|
||||
|
||||
this.catchUp(comment);
|
||||
|
||||
// whitespace before
|
||||
this.newline(this.whitespace.getNewlinesBefore(comment));
|
||||
|
||||
@@ -340,7 +361,6 @@ class CodeGenerator {
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if (comment.type === "Block" && this.format.indent.adjustMultilineComment) {
|
||||
var offset = comment.loc.start.column;
|
||||
if (offset) {
|
||||
@@ -356,8 +376,13 @@ class CodeGenerator {
|
||||
val = this.getIndent() + val;
|
||||
}
|
||||
|
||||
//
|
||||
// force a newline for line comments when retainLines is set in case the next printed node
|
||||
// doesn't catch up
|
||||
if (this.format.retainLines && comment.type === "Line") {
|
||||
val += "\n";
|
||||
}
|
||||
|
||||
//
|
||||
this._push(val);
|
||||
|
||||
// whitespace after
|
||||
|
||||
@@ -85,16 +85,7 @@ export default class Node {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isYieldExpression(parent) || t.isAwaitExpression(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isContinueStatement(parent) || t.isBreakStatement(parent) ||
|
||||
t.isReturnStatement(parent) || t.isThrowStatement(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return t.isTerminatorless(parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -171,4 +171,10 @@ export function ConditionalExpression(node, parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
export { ConditionalExpression as AssignmentExpression };
|
||||
export function AssignmentExpression(node) {
|
||||
if (t.isObjectPattern(node.left)) {
|
||||
return true;
|
||||
} else {
|
||||
return ConditionalExpression(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ function crawl(node, state = {}) {
|
||||
} else if (t.isFunction(node)) {
|
||||
state.hasFunction = true;
|
||||
} else if (t.isIdentifier(node)) {
|
||||
state.hasHelper ||= isHelper(node.callee);
|
||||
state.hasHelper = state.hasHelper || isHelper(node.callee);
|
||||
}
|
||||
|
||||
return state;
|
||||
|
||||
@@ -1,65 +1,34 @@
|
||||
import normalizeAst from "./normalize-ast";
|
||||
import estraverse from "estraverse";
|
||||
import codeFrame from "./code-frame";
|
||||
import * as acorn from "../../acorn";
|
||||
|
||||
export default function (opts, code, callback) {
|
||||
try {
|
||||
var comments = [];
|
||||
var tokens = [];
|
||||
export default function (code, opts = {}) {
|
||||
var comments = [];
|
||||
var tokens = [];
|
||||
|
||||
var parseOpts = {
|
||||
allowImportExportEverywhere: opts.looseModules,
|
||||
allowReturnOutsideFunction: opts.looseModules,
|
||||
ecmaVersion: 6,
|
||||
strictMode: opts.strictMode,
|
||||
sourceType: opts.sourceType,
|
||||
onComment: comments,
|
||||
locations: true,
|
||||
features: opts.features || {},
|
||||
plugins: opts.plugins || {},
|
||||
onToken: tokens,
|
||||
ranges: true
|
||||
};
|
||||
var parseOpts = {
|
||||
allowImportExportEverywhere: opts.looseModules,
|
||||
allowReturnOutsideFunction: opts.looseModules,
|
||||
allowHashBang: true,
|
||||
ecmaVersion: 6,
|
||||
strictMode: opts.strictMode,
|
||||
sourceType: opts.sourceType,
|
||||
locations: true,
|
||||
onComment: comments,
|
||||
features: opts.features || {},
|
||||
plugins: opts.plugins || {},
|
||||
onToken: tokens,
|
||||
ranges: true
|
||||
};
|
||||
|
||||
if (opts.nonStandard) {
|
||||
parseOpts.plugins.jsx = true;
|
||||
parseOpts.plugins.flow = true;
|
||||
}
|
||||
|
||||
var ast = acorn.parse(code, parseOpts);
|
||||
|
||||
estraverse.attachComments(ast, comments, tokens);
|
||||
|
||||
ast = normalizeAst(ast, comments, tokens);
|
||||
|
||||
if (callback) {
|
||||
return callback(ast);
|
||||
} else {
|
||||
return ast;
|
||||
}
|
||||
} catch (err) {
|
||||
if (!err._babel) {
|
||||
err._babel = true;
|
||||
|
||||
var message = err.message = `${opts.filename}: ${err.message}`;
|
||||
|
||||
var loc = err.loc;
|
||||
if (loc) {
|
||||
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, opts);
|
||||
message += "\n" + err.codeFrame;
|
||||
}
|
||||
|
||||
if (err.stack) {
|
||||
var newStack = err.stack.replace(err.message, message);
|
||||
try {
|
||||
err.stack = newStack;
|
||||
} catch (e) {
|
||||
// `err.stack` may be a readonly property in some environments
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw err;
|
||||
if (opts.nonStandard) {
|
||||
parseOpts.plugins.jsx = true;
|
||||
parseOpts.plugins.flow = true;
|
||||
}
|
||||
};
|
||||
|
||||
var ast = acorn.parse(code, parseOpts);
|
||||
|
||||
estraverse.attachComments(ast, comments, tokens);
|
||||
ast = normalizeAst(ast, comments, tokens);
|
||||
return ast;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,19 @@ export const MESSAGES = {
|
||||
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"
|
||||
illegalMethodName: "Illegal method name $1",
|
||||
traverseNeedsParent: "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 }`?",
|
||||
traverseVerifyVisitorFunction: "Hey! You passed \`traverse()\` a visitor object with the key $1 that's a straight up `Function` instead of `{ enter: Function }`. You need to normalise it with `traverse.explode(visitor)`.",
|
||||
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
||||
|
||||
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",
|
||||
pluginUnknown: "Unknown plugin $1",
|
||||
|
||||
transformerNotFile: "Transformer $1 is resolving to a different Babel version to what is doing the actual transformation..."
|
||||
};
|
||||
|
||||
export function get(key: String, ...args) {
|
||||
|
||||
@@ -55,4 +55,18 @@ def("ExportNamedDeclaration")
|
||||
)])
|
||||
.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"));
|
||||
|
||||
types.finalize();
|
||||
|
||||
@@ -17,24 +17,40 @@ function exists(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] ||= JSON.parse(stripJsonComments(content));
|
||||
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, function(a, b) {
|
||||
if (Array.isArray(a)) {
|
||||
return a.concat(b);
|
||||
var c = a.slice(0);
|
||||
for (var v of b) {
|
||||
if (a.indexOf(v) < 0) {
|
||||
c.push(v);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -44,11 +60,10 @@ export default function (loc, opts = {}) {
|
||||
find(up, rel);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.breakConfig !== true) {
|
||||
|
||||
if (opts.babelrc.indexOf(loc) < 0 && opts.breakConfig !== true) {
|
||||
find(loc, rel);
|
||||
}
|
||||
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import * as optionParsers from "./option-parsers";
|
||||
import moduleFormatters from "../modules";
|
||||
import PluginManager from "./plugin-manager";
|
||||
import shebangRegex from "shebang-regex";
|
||||
import TraversalPath from "../../traversal/path";
|
||||
import isFunction from "lodash/lang/isFunction";
|
||||
@@ -8,6 +10,7 @@ import resolveRc from "../../tools/resolve-rc";
|
||||
import sourceMap from "source-map";
|
||||
import transform from "./../index";
|
||||
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";
|
||||
@@ -16,39 +19,42 @@ import Logger from "./logger";
|
||||
import parse from "../../helpers/parse";
|
||||
import Scope from "../../traversal/scope";
|
||||
import slash from "slash";
|
||||
import clone from "lodash/lang/clone";
|
||||
import * as util from "../../util";
|
||||
import * as api from "../../api/node";
|
||||
import path from "path";
|
||||
import each from "lodash/collection/each";
|
||||
import * as t from "../../types";
|
||||
|
||||
var checkTransformerVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
checkNode(state.stack, node, scope);
|
||||
exit(node, parent, scope, state) {
|
||||
checkPath(state.stack, this);
|
||||
}
|
||||
};
|
||||
|
||||
function checkNode(stack, node, scope) {
|
||||
function checkPath(stack, path) {
|
||||
each(stack, function (pass) {
|
||||
if (pass.shouldRun || pass.ran) return;
|
||||
pass.checkNode(node, scope);
|
||||
pass.checkPath(path);
|
||||
});
|
||||
}
|
||||
|
||||
export default class File {
|
||||
constructor(opts = {}) {
|
||||
this.dynamicImportAbsoluteDefaults = [];
|
||||
this.dynamicImportIds = {};
|
||||
this.dynamicImports = [];
|
||||
constructor(opts = {}, pipeline) {
|
||||
this.dynamicImportTypes = {};
|
||||
this.dynamicImportIds = {};
|
||||
this.dynamicImports = [];
|
||||
|
||||
this.usedHelpers = {};
|
||||
this.dynamicData = {};
|
||||
this.data = {};
|
||||
this.uids = {};
|
||||
this.declarations = {};
|
||||
this.usedHelpers = {};
|
||||
this.dynamicData = {};
|
||||
this.data = {};
|
||||
this.uids = {};
|
||||
|
||||
this.lastStatements = [];
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.ast = {};
|
||||
this.pipeline = pipeline;
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.ast = {};
|
||||
|
||||
this.buildTransformers();
|
||||
}
|
||||
@@ -59,9 +65,9 @@ export default class File {
|
||||
"create-class",
|
||||
"create-decorated-class",
|
||||
"create-decorated-object",
|
||||
"define-decorated-property-descriptor",
|
||||
"tagged-template-literal",
|
||||
"tagged-template-literal-loose",
|
||||
"interop-require",
|
||||
"to-array",
|
||||
"to-consumable-array",
|
||||
"sliced-to-array",
|
||||
@@ -73,6 +79,7 @@ export default class File {
|
||||
"define-property",
|
||||
"async-to-generator",
|
||||
"interop-require-wildcard",
|
||||
"interop-require-default",
|
||||
"typeof",
|
||||
"extends",
|
||||
"get",
|
||||
@@ -82,10 +89,17 @@ export default class File {
|
||||
"temporal-undefined",
|
||||
"temporal-assert-defined",
|
||||
"self-global",
|
||||
"default-props"
|
||||
"default-props",
|
||||
"instanceof",
|
||||
|
||||
// legacy
|
||||
"interop-require",
|
||||
];
|
||||
|
||||
static soloHelpers = [];
|
||||
static soloHelpers = [
|
||||
"ludicrous-proxy-create",
|
||||
"ludicrous-proxy-directory"
|
||||
];
|
||||
|
||||
static options = require("./options");
|
||||
|
||||
@@ -117,13 +131,15 @@ export default class File {
|
||||
throw new Error("Deprecated option " + key + ": " + option.deprecated);
|
||||
}
|
||||
|
||||
if (val == null) val = option.default || val;
|
||||
if (val == null) {
|
||||
val = clone(option.default);
|
||||
}
|
||||
|
||||
var optionParser = optionParsers[option.type];
|
||||
if (optionParser) val = optionParser(key, val);
|
||||
if (optionParser) val = optionParser(key, val, this.pipeline);
|
||||
|
||||
if (option.alias) {
|
||||
opts[option.alias] ||= val;
|
||||
opts[option.alias] = opts[option.alias] || val;
|
||||
} else {
|
||||
opts[key] = val;
|
||||
}
|
||||
@@ -187,7 +203,7 @@ export default class File {
|
||||
var stack = [];
|
||||
|
||||
// build internal transformers
|
||||
each(transform.transformers, function (transformer, key) {
|
||||
each(this.pipeline.transformers, function (transformer, key) {
|
||||
var pass = transformers[key] = transformer.buildPass(file);
|
||||
|
||||
if (pass.canTransform()) {
|
||||
@@ -206,8 +222,14 @@ export default class File {
|
||||
// init plugins!
|
||||
var beforePlugins = [];
|
||||
var afterPlugins = [];
|
||||
var pluginManager = new PluginManager({
|
||||
file: this,
|
||||
transformers: this.transformers,
|
||||
before: beforePlugins,
|
||||
after: afterPlugins
|
||||
});
|
||||
for (var i = 0; i < file.opts.plugins.length; i++) {
|
||||
this.addPlugin(file.opts.plugins[i], beforePlugins, afterPlugins);
|
||||
pluginManager.add(file.opts.plugins[i]);
|
||||
}
|
||||
stack = beforePlugins.concat(stack, afterPlugins);
|
||||
|
||||
@@ -215,99 +237,6 @@ export default class File {
|
||||
this.transformerStack = stack.concat(secondaryStack);
|
||||
}
|
||||
|
||||
getModuleFormatter(type: string) {
|
||||
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
var loc = util.resolveRelative(type);
|
||||
if (loc) ModuleFormatter = require(loc);
|
||||
}
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
throw new ReferenceError(`Unknown module formatter type ${JSON.stringify(type)}`);
|
||||
}
|
||||
|
||||
return new ModuleFormatter(this);
|
||||
}
|
||||
|
||||
addPlugin(name, before, after) {
|
||||
var position = "before";
|
||||
var plugin;
|
||||
|
||||
if (name) {
|
||||
if (typeof name === "string") {
|
||||
// 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
|
||||
|
||||
[name, position = "before"] = name.split(":");
|
||||
|
||||
var loc = util.resolveRelative(name) || util.resolveRelative(`babel-plugin-${name}`);
|
||||
if (loc) {
|
||||
plugin = require(loc)
|
||||
} else {
|
||||
throw new ReferenceError(`Unknown plugin ${JSON.stringify(name)}`);
|
||||
}
|
||||
} else {
|
||||
// not a string so we'll just assume that it's a direct Transformer instance, if not then
|
||||
// the checks later on will complain
|
||||
plugin = name;
|
||||
}
|
||||
} else {
|
||||
throw new TypeError(`Ilegal kind ${typeof name} for plugin name ${JSON.stringify(name)}`);
|
||||
}
|
||||
|
||||
// validate position
|
||||
if (position !== "before" && position !== "after") {
|
||||
throw new TypeError(`Plugin ${JSON.stringify(name)} has an illegal position of ${JSON.stringify(position)}`);
|
||||
}
|
||||
|
||||
// validate transformer key
|
||||
var key = plugin.key;
|
||||
if (this.transformers[key]) {
|
||||
throw new ReferenceError(`The key for plugin ${JSON.stringify(name)} of ${key} collides with an existing plugin`);
|
||||
}
|
||||
|
||||
// validate Transformer instance
|
||||
if (!plugin.buildPass || plugin.constructor.name !== "Transformer") {
|
||||
throw new TypeError(`Plugin ${JSON.stringify(name)} didn't export a default Transformer instance`);
|
||||
}
|
||||
|
||||
// build!
|
||||
var pass = this.transformers[key] = plugin.buildPass(this);
|
||||
if (pass.canTransform()) {
|
||||
var stack = before;
|
||||
if (position === "after") stack = after;
|
||||
stack.push(pass);
|
||||
}
|
||||
}
|
||||
|
||||
parseInputSourceMap(code: string) {
|
||||
var opts = this.opts;
|
||||
|
||||
if (opts.inputSourceMap !== false) {
|
||||
var inputMap = convertSourceMap.fromSource(code);
|
||||
if (inputMap) {
|
||||
opts.inputSourceMap = inputMap.toObject();
|
||||
code = convertSourceMap.removeComments(code);
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
parseShebang(code: string) {
|
||||
var shebangMatch = shebangRegex.exec(code);
|
||||
|
||||
if (shebangMatch) {
|
||||
this.shebang = shebangMatch[0];
|
||||
|
||||
// remove shebang
|
||||
code = code.replace(shebangRegex, "");
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
set(key: string, val): any {
|
||||
return this.data[key] = val;
|
||||
};
|
||||
@@ -334,8 +263,8 @@ export default class File {
|
||||
return source;
|
||||
}
|
||||
|
||||
addImport(source: string, name?: string, absoluteDefault?: boolean): Object {
|
||||
name ||= source;
|
||||
addImport(source: string, name?: string, type?: string): Object {
|
||||
name = name || source;
|
||||
var id = this.dynamicImportIds[name];
|
||||
|
||||
if (!id) {
|
||||
@@ -345,7 +274,11 @@ export default class File {
|
||||
var specifiers = [t.importDefaultSpecifier(id)];
|
||||
var declar = t.importDeclaration(specifiers, t.literal(source));
|
||||
declar._blockHoist = 3;
|
||||
if (absoluteDefault) this.dynamicImportAbsoluteDefaults.push(declar);
|
||||
|
||||
if (type) {
|
||||
var modules = this.dynamicImportTypes[type] = this.dynamicImportTypes[type] || [];
|
||||
modules.push(declar);
|
||||
}
|
||||
|
||||
if (this.transformers["es6.modules"].canTransform()) {
|
||||
this.moduleFormatter.importSpecifier(specifiers[0], declar, this.dynamicImports);
|
||||
@@ -358,14 +291,10 @@ export default class File {
|
||||
return id;
|
||||
}
|
||||
|
||||
isConsequenceExpressionStatement(node: Object): boolean {
|
||||
return t.isExpressionStatement(node) && this.lastStatements.indexOf(node) >= 0;
|
||||
}
|
||||
|
||||
attachAuxiliaryComment(node: Object): Object {
|
||||
var comment = this.opts.auxiliaryComment;
|
||||
if (comment) {
|
||||
node.leadingComments ||= [];
|
||||
node.leadingComments = node.leadingComments || [];
|
||||
node.leadingComments.push({
|
||||
type: "Line",
|
||||
value: " " + comment
|
||||
@@ -383,8 +312,8 @@ export default class File {
|
||||
|
||||
var program = this.ast.program;
|
||||
|
||||
var declar = program._declarations && program._declarations[name];
|
||||
if (declar) return declar.id;
|
||||
var declar = this.declarations[name];
|
||||
if (declar) return declar;
|
||||
|
||||
this.usedHelpers[name] = true;
|
||||
|
||||
@@ -400,13 +329,24 @@ export default class File {
|
||||
}
|
||||
|
||||
var ref = util.template("helper-" + name);
|
||||
ref._compact = true;
|
||||
var uid = this.scope.generateUidIdentifier(name);
|
||||
this.scope.push({
|
||||
key: name,
|
||||
id: uid,
|
||||
init: ref
|
||||
});
|
||||
|
||||
var uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
|
||||
|
||||
if (t.isFunctionExpression(ref) && !ref.id) {
|
||||
ref.body._compact = true;
|
||||
ref._generated = true;
|
||||
ref.id = uid;
|
||||
ref.type = "FunctionDeclaration";
|
||||
this.path.unshiftContainer("body", ref);
|
||||
} else {
|
||||
ref._compact = true;
|
||||
this.scope.push({
|
||||
id: uid,
|
||||
init: ref,
|
||||
unique: true
|
||||
});
|
||||
}
|
||||
|
||||
return uid;
|
||||
}
|
||||
|
||||
@@ -417,121 +357,19 @@ export default class File {
|
||||
return err;
|
||||
}
|
||||
|
||||
addCode(code: string) {
|
||||
code = (code || "") + "";
|
||||
code = this.parseInputSourceMap(code);
|
||||
this.code = code;
|
||||
return this.parseShebang(code);
|
||||
}
|
||||
|
||||
shouldIgnore() {
|
||||
var opts = this.opts;
|
||||
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
|
||||
}
|
||||
|
||||
parse(code: string) {
|
||||
if (this.shouldIgnore()) {
|
||||
return {
|
||||
metadata: {},
|
||||
code: code,
|
||||
map: null,
|
||||
ast: null
|
||||
};
|
||||
}
|
||||
|
||||
code = this.addCode(code);
|
||||
|
||||
var opts = this.opts;
|
||||
|
||||
//
|
||||
|
||||
var parseOpts = {
|
||||
highlightCode: opts.highlightCode,
|
||||
nonStandard: opts.nonStandard,
|
||||
filename: opts.filename,
|
||||
plugins: {}
|
||||
};
|
||||
|
||||
var features = parseOpts.features = {};
|
||||
for (var key in this.transformers) {
|
||||
var transformer = this.transformers[key];
|
||||
features[key] = transformer.canTransform();
|
||||
}
|
||||
|
||||
parseOpts.looseModules = this.isLoose("es6.modules");
|
||||
parseOpts.strictMode = features.strict;
|
||||
parseOpts.sourceType = "module";
|
||||
|
||||
//
|
||||
|
||||
return parse(parseOpts, code, (tree) => {
|
||||
this.transform(tree);
|
||||
return this.generate();
|
||||
});
|
||||
}
|
||||
|
||||
setAst(ast) {
|
||||
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
|
||||
this.scope = this.path.scope;
|
||||
this.ast = ast;
|
||||
|
||||
this.path.traverse({
|
||||
enter(node, parent, scope) {
|
||||
if (this.isScope()) {
|
||||
for (var key in scope.bindings) {
|
||||
scope.bindings[key].setTypeAnnotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
transform(ast) {
|
||||
this.log.debug();
|
||||
|
||||
this.setAst(ast);
|
||||
|
||||
this.lastStatements = t.getLastStatements(ast.program);
|
||||
|
||||
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
|
||||
modFormatter.init();
|
||||
}
|
||||
|
||||
this.checkNode(ast);
|
||||
|
||||
this.call("pre");
|
||||
|
||||
each(this.transformerStack, function (pass) {
|
||||
pass.transform();
|
||||
});
|
||||
|
||||
this.call("post");
|
||||
}
|
||||
|
||||
call(key: string) {
|
||||
var stack = this.transformerStack;
|
||||
for (var i = 0; i < stack.length; i++) {
|
||||
var transformer = stack[i].transformer;
|
||||
var fn = transformer[key];
|
||||
if (fn) fn(this);
|
||||
}
|
||||
}
|
||||
|
||||
checkNode(node, scope) {
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
this.checkNode(node[i], scope);
|
||||
checkPath(path) {
|
||||
if (Array.isArray(path)) {
|
||||
for (var i = 0; i < path.length; i++) {
|
||||
this.checkPath(path[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = this.transformerStack;
|
||||
scope ||= this.scope;
|
||||
|
||||
checkNode(stack, node, scope);
|
||||
checkPath(stack, path);
|
||||
|
||||
scope.traverse(node, checkTransformerVisitor, {
|
||||
path.traverse(checkTransformerVisitor, {
|
||||
stack: stack
|
||||
});
|
||||
}
|
||||
@@ -558,6 +396,180 @@ export default class File {
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
getModuleFormatter(type: string) {
|
||||
var ModuleFormatter = isFunction(type) ? type : moduleFormatters[type];
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
var loc = util.resolveRelative(type);
|
||||
if (loc) ModuleFormatter = require(loc);
|
||||
}
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
throw new ReferenceError(`Unknown module formatter type ${JSON.stringify(type)}`);
|
||||
}
|
||||
|
||||
return new ModuleFormatter(this);
|
||||
}
|
||||
|
||||
parse(code: string) {
|
||||
var opts = this.opts;
|
||||
|
||||
//
|
||||
|
||||
var parseOpts = {
|
||||
highlightCode: opts.highlightCode,
|
||||
nonStandard: opts.nonStandard,
|
||||
filename: opts.filename,
|
||||
plugins: {}
|
||||
};
|
||||
|
||||
var features = parseOpts.features = {};
|
||||
for (var key in this.transformers) {
|
||||
var transformer = this.transformers[key];
|
||||
features[key] = transformer.canTransform();
|
||||
}
|
||||
|
||||
parseOpts.looseModules = this.isLoose("es6.modules");
|
||||
parseOpts.strictMode = features.strict;
|
||||
parseOpts.sourceType = "module";
|
||||
|
||||
this.log.debug("Parse start");
|
||||
var tree = parse(code, parseOpts);
|
||||
this.log.debug("Parse stop");
|
||||
return tree;
|
||||
}
|
||||
|
||||
_addAst(ast) {
|
||||
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
|
||||
this.scope = this.path.scope;
|
||||
this.ast = ast;
|
||||
|
||||
this.path.traverse({
|
||||
enter(node, parent, scope) {
|
||||
if (this.isScope()) {
|
||||
for (var key in scope.bindings) {
|
||||
scope.bindings[key].setTypeAnnotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addAst(ast) {
|
||||
this.log.debug("Start set AST");
|
||||
this._addAst(ast);
|
||||
this.log.debug("End set AST");
|
||||
|
||||
this.log.debug("Start prepass");
|
||||
this.checkPath(this.path);
|
||||
this.log.debug("End prepass");
|
||||
|
||||
this.log.debug("Start module formatter init");
|
||||
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
|
||||
modFormatter.init();
|
||||
}
|
||||
this.log.debug("End module formatter init");
|
||||
|
||||
this.call("pre");
|
||||
each(this.transformerStack, function (pass) {
|
||||
pass.transform();
|
||||
});
|
||||
this.call("post");
|
||||
}
|
||||
|
||||
wrap(code, callback) {
|
||||
code = code + "";
|
||||
|
||||
try {
|
||||
if (this.shouldIgnore()) {
|
||||
return {
|
||||
metadata: {},
|
||||
code: code,
|
||||
map: null,
|
||||
ast: null
|
||||
};
|
||||
}
|
||||
|
||||
callback();
|
||||
|
||||
return this.generate();
|
||||
} catch (err) {
|
||||
if (err._babel) {
|
||||
throw err;
|
||||
} else {
|
||||
err._babel = true;
|
||||
}
|
||||
|
||||
var message = err.message = `${this.opts.filename}: ${err.message}`;
|
||||
|
||||
var loc = err.loc;
|
||||
if (loc) {
|
||||
err.codeFrame = codeFrame(code, loc.line, loc.column + 1, this.opts);
|
||||
message += "\n" + err.codeFrame;
|
||||
}
|
||||
|
||||
if (err.stack) {
|
||||
var newStack = err.stack.replace(err.message, message);
|
||||
try {
|
||||
err.stack = newStack;
|
||||
} catch (e) {
|
||||
// `err.stack` may be a readonly property in some environments
|
||||
}
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
addCode(code: string, parseCode?) {
|
||||
code = (code || "") + "";
|
||||
code = this.parseInputSourceMap(code);
|
||||
this.code = code;
|
||||
|
||||
if (parseCode) {
|
||||
this.parseShebang();
|
||||
this.addAst(this.parse(this.code));
|
||||
}
|
||||
}
|
||||
|
||||
shouldIgnore() {
|
||||
var opts = this.opts;
|
||||
return util.shouldIgnore(opts.filename, opts.ignore, opts.only);
|
||||
}
|
||||
|
||||
call(key: string) {
|
||||
var stack = this.transformerStack;
|
||||
for (var i = 0; i < stack.length; i++) {
|
||||
var transformer = stack[i].transformer;
|
||||
var fn = transformer[key];
|
||||
if (fn) fn(this);
|
||||
}
|
||||
}
|
||||
|
||||
parseInputSourceMap(code: string) {
|
||||
var opts = this.opts;
|
||||
|
||||
if (opts.inputSourceMap !== false) {
|
||||
var inputMap = convertSourceMap.fromSource(code);
|
||||
if (inputMap) {
|
||||
opts.inputSourceMap = inputMap.toObject();
|
||||
code = convertSourceMap.removeComments(code);
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
parseShebang() {
|
||||
var shebangMatch = shebangRegex.exec(this.code);
|
||||
if (shebangMatch) {
|
||||
this.shebang = shebangMatch[0];
|
||||
this.code = this.code.replace(shebangRegex, "");
|
||||
}
|
||||
}
|
||||
|
||||
generate(): {
|
||||
usedHelpers?: Array<string>;
|
||||
code: string;
|
||||
@@ -581,10 +593,14 @@ export default class File {
|
||||
if (opts.ast) result.ast = ast;
|
||||
if (!opts.code) return result;
|
||||
|
||||
this.log.debug("Generation start");
|
||||
|
||||
var _result = generate(ast, opts, this.code);
|
||||
result.code = _result.code;
|
||||
result.map = _result.map;
|
||||
|
||||
this.log.debug("Generation end");
|
||||
|
||||
if (this.shebang) {
|
||||
// add back shebang
|
||||
result.code = `${this.shebang}\n${result.code}`;
|
||||
|
||||
@@ -7,7 +7,7 @@ export default class Logger {
|
||||
}
|
||||
|
||||
_buildMessage(msg: string): string {
|
||||
var parts = this.filename;
|
||||
var parts = `[BABEL] ${this.filename}`;
|
||||
if (msg) parts += `: ${msg}`;
|
||||
return parts;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export default class Logger {
|
||||
|
||||
deprecate(msg) {
|
||||
if (!this.file.opts.suppressDeprecationMessages) {
|
||||
console.error(msg);
|
||||
console.error(this._buildMessage(msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import transform from "./../index";
|
||||
import * as util from "../../util";
|
||||
|
||||
export function transformerList(key, val) {
|
||||
export function transformerList(key, val, pipeline) {
|
||||
val = util.arrayify(val);
|
||||
|
||||
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
|
||||
val = Object.keys(transform.transformers);
|
||||
val = Object.keys(pipeline.transformers);
|
||||
}
|
||||
|
||||
return transform._ensureTransformerNames(key, val);
|
||||
return pipeline._ensureTransformerNames(key, val);
|
||||
}
|
||||
|
||||
export function number(key, val) {
|
||||
|
||||
@@ -15,11 +15,27 @@
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
"extra": {
|
||||
"hidden": true,
|
||||
"default": {}
|
||||
},
|
||||
|
||||
"moduleId": {
|
||||
"description": "specify a custom name for module ids",
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
"getModuleId": {
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
"retainLines": {
|
||||
"hidden": true,
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "retain line numbers - will result in really ugly code"
|
||||
},
|
||||
|
||||
"nonStandard": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
@@ -152,7 +168,7 @@
|
||||
},
|
||||
|
||||
"externalHelpers": {
|
||||
"type": "string",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"shorthand": "r",
|
||||
"description": "uses a reference to `babelHelpers` instead of placing helpers at the top of your code."
|
||||
@@ -201,6 +217,10 @@
|
||||
"default": false,
|
||||
"hidden": true,
|
||||
"description": "stop trying to load .babelrc files"
|
||||
}
|
||||
},
|
||||
|
||||
"babelrc": {
|
||||
"hidden": true,
|
||||
"description": "do not load the same .babelrc file twice"
|
||||
}
|
||||
}
|
||||
|
||||
105
src/babel/transformation/file/plugin-manager.js
Normal file
105
src/babel/transformation/file/plugin-manager.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import * as node from "../../api/node";
|
||||
import * as messages from "../../messages";
|
||||
import * as util from "../../util";
|
||||
|
||||
export default class PluginManager {
|
||||
static memoisedPlugins = [];
|
||||
|
||||
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);
|
||||
PluginManager.memoisedPlugins.push({
|
||||
container: fn,
|
||||
transformer: transformer
|
||||
});
|
||||
return transformer;
|
||||
}
|
||||
|
||||
static positions = ["before", "after"];
|
||||
|
||||
constructor({ file, transformers, before, after } = { transformers: {}, before: [], after: [] }) {
|
||||
this.transformers = transformers;
|
||||
this.file = file;
|
||||
this.before = before;
|
||||
this.after = after;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
var match = name.match(/^(.*?):(after|before)$/);
|
||||
if (match) [, name, position] = match;
|
||||
|
||||
var loc = util.resolveRelative(name) || util.resolveRelative(`babel-plugin-${name}`);
|
||||
if (loc) {
|
||||
return {
|
||||
position: position,
|
||||
plugin: require(loc)
|
||||
};
|
||||
} else {
|
||||
throw new ReferenceError(messages.get("pluginUnknown", name));
|
||||
}
|
||||
}
|
||||
|
||||
validate(name, plugin) {
|
||||
// validate transformer key
|
||||
var key = plugin.key;
|
||||
if (this.transformers[key]) {
|
||||
throw new ReferenceError(messages.get("pluginKeyCollision", key));
|
||||
}
|
||||
|
||||
// validate Transformer instance
|
||||
if (!plugin.buildPass || plugin.constructor.name !== "Transformer") {
|
||||
throw new TypeError(messages.get("pluginNotTransformer", name));
|
||||
}
|
||||
}
|
||||
|
||||
add(name) {
|
||||
var position;
|
||||
var plugin;
|
||||
|
||||
if (name) {
|
||||
if (typeof name === "object" && name.transformer) {
|
||||
({ plugin: name, position } = name);
|
||||
} else if (typeof name !== "string") {
|
||||
// not a string so we'll just assume that it's a direct Transformer instance, if not then
|
||||
// the checks later on will complain
|
||||
plugin = name;
|
||||
}
|
||||
|
||||
if (typeof name === "string") {
|
||||
({ plugin, position } = this.subnormaliseString(name, position));
|
||||
}
|
||||
} else {
|
||||
throw new TypeError(messages.get("pluginIllegalKind", typeof name, name));
|
||||
}
|
||||
|
||||
// default position
|
||||
position = position || "before";
|
||||
|
||||
// validate position
|
||||
if (PluginManager.positions.indexOf(position) < 0) {
|
||||
throw new TypeError(messages.get("pluginIllegalPosition", position, name));
|
||||
}
|
||||
|
||||
// allow plugin containers to be specified so they don't have to manually require
|
||||
if (typeof plugin === "function") {
|
||||
plugin = PluginManager.memoisePluginContainer(plugin);
|
||||
}
|
||||
|
||||
//
|
||||
this.validate(name, plugin);
|
||||
|
||||
// build!
|
||||
var pass = this.transformers[plugin.key] = plugin.buildPass(this.file);
|
||||
if (pass.canTransform()) {
|
||||
var stack = position === "before" ? this.before : this.after;
|
||||
stack.push(pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,13 @@ export default function (exports, opts) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
exports.shouldVisit = function (node) {
|
||||
return node.operator && (node.operator === opts.operator || node.operator === opts.operator + "=");
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (file.isConsequenceExpressionStatement(node)) return;
|
||||
if (this.isCompletionRecord()) return;
|
||||
|
||||
var expr = node.expression;
|
||||
if (!isAssignment(expr)) return;
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function (exports, opts) {
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (file.isConsequenceExpressionStatement(node)) return;
|
||||
if (this.isCompletionRecord()) return;
|
||||
|
||||
var expr = node.expression;
|
||||
if (!opts.is(expr, file)) return;
|
||||
|
||||
@@ -57,6 +57,8 @@ export default function (exports, opts) {
|
||||
|
||||
exports.JSXOpeningElement = {
|
||||
exit(node, parent, scope, file) {
|
||||
parent.children = react.buildChildren(parent);
|
||||
|
||||
var tagExpr = node.name;
|
||||
var args = [];
|
||||
|
||||
@@ -144,10 +146,6 @@ export default function (exports, opts) {
|
||||
};
|
||||
|
||||
exports.JSXElement = {
|
||||
enter(node) {
|
||||
node.children = react.buildChildren(node);
|
||||
},
|
||||
|
||||
exit(node) {
|
||||
var callExpr = node.openingElement;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export function push(mutatorMap, node, kind, file) {
|
||||
|
||||
//
|
||||
|
||||
map._inherits ||= [];
|
||||
map._inherits = map._inherits || [];
|
||||
map._inherits.push(node);
|
||||
|
||||
map._key = node.key;
|
||||
@@ -25,7 +25,7 @@ export function push(mutatorMap, node, kind, file) {
|
||||
}
|
||||
|
||||
if (node.decorators) {
|
||||
var decorators = map.decorators ||= t.arrayExpression([]);
|
||||
var decorators = map.decorators = map.decorators || t.arrayExpression([]);
|
||||
decorators.elements = decorators.elements.concat(node.decorators.map(dec => dec.expression));
|
||||
}
|
||||
|
||||
|
||||
37
src/babel/transformation/helpers/memoise-decorators.js
Normal file
37
src/babel/transformation/helpers/memoise-decorators.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as t from "../../types";
|
||||
|
||||
export default function (decorators, scope) {
|
||||
for (var i = 0; i < decorators.length; i++) {
|
||||
var decorator = decorators[i];
|
||||
var expression = decorator.expression;
|
||||
if (!t.isMemberExpression(expression)) continue;
|
||||
|
||||
var temp = scope.generateMemoisedReference(expression.object);
|
||||
var ref;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
if (temp) {
|
||||
ref = temp;
|
||||
nodes.push(t.assignmentExpression("=", temp, expression.object));
|
||||
} else {
|
||||
ref = expression.object;
|
||||
}
|
||||
|
||||
nodes.push(t.callExpression(
|
||||
t.memberExpression(
|
||||
t.memberExpression(ref, expression.property, expression.computed),
|
||||
t.identifier("bind")
|
||||
),
|
||||
[ref]
|
||||
));
|
||||
|
||||
if (nodes.length === 1) {
|
||||
decorator.expression = nodes[0];
|
||||
} else {
|
||||
decorator.expression = t.sequenceExpression(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
return decorators;
|
||||
}
|
||||
@@ -20,27 +20,32 @@ var visitor = {
|
||||
|
||||
var wrap = function (state, method, id, scope) {
|
||||
if (state.selfReference) {
|
||||
var templateName = "property-method-assignment-wrapper";
|
||||
if (method.generator) templateName += "-generator";
|
||||
var template = util.template(templateName, {
|
||||
FUNCTION: method,
|
||||
FUNCTION_ID: id,
|
||||
FUNCTION_KEY: scope.generateUidIdentifier(id.name)
|
||||
});
|
||||
template.callee._skipModulesRemap = true;
|
||||
if (scope.hasBinding(id.name)) {
|
||||
// we can just munge the local binding
|
||||
scope.rename(id.name);
|
||||
} else {
|
||||
// need to add a wrapper since we can't change the references
|
||||
var templateName = "property-method-assignment-wrapper";
|
||||
if (method.generator) templateName += "-generator";
|
||||
var template = util.template(templateName, {
|
||||
FUNCTION: method,
|
||||
FUNCTION_ID: id,
|
||||
FUNCTION_KEY: scope.generateUidIdentifier(id.name)
|
||||
});
|
||||
template.callee._skipModulesRemap = true;
|
||||
|
||||
// shim in dummy params to retain function arity, if you try to read the
|
||||
// source then you'll get the original since it's proxied so it's all good
|
||||
var params = template.callee.body.body[0].params;
|
||||
for (var i = 0, len = getFunctionArity(method); i < len; i++) {
|
||||
params.push(scope.generateUidIdentifier("x"));
|
||||
// shim in dummy params to retain function arity, if you try to read the
|
||||
// source then you'll get the original since it's proxied so it's all good
|
||||
var params = template.callee.body.body[0].params;
|
||||
for (var i = 0, len = getFunctionArity(method); i < len; i++) {
|
||||
params.push(scope.generateUidIdentifier("x"));
|
||||
}
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
return template;
|
||||
} else {
|
||||
method.id = id;
|
||||
return method;
|
||||
}
|
||||
|
||||
method.id = id;
|
||||
};
|
||||
|
||||
var visit = function (node, name, scope) {
|
||||
@@ -82,7 +87,7 @@ var visit = function (node, name, scope) {
|
||||
// so we can safely just set the id and move along as it shadows the
|
||||
// bound function id
|
||||
}
|
||||
} else {
|
||||
} else if (state.outerDeclar || scope.hasGlobal(name)) {
|
||||
scope.traverse(node, visitor, state);
|
||||
}
|
||||
|
||||
@@ -96,7 +101,7 @@ export function custom(node, id, scope) {
|
||||
|
||||
export function property(node, file, scope) {
|
||||
var key = t.toComputedKey(node, node.key);
|
||||
if (!t.isLiteral(key)) return node; // we can't set a function id with this
|
||||
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;
|
||||
@@ -104,12 +109,12 @@ export function property(node, file, scope) {
|
||||
|
||||
var method = node.value;
|
||||
var state = visit(method, name, scope);
|
||||
node.value = wrap(state, method, id, scope);
|
||||
node.value = wrap(state, method, id, scope) || method;
|
||||
}
|
||||
|
||||
export function bare(node, parent, scope) {
|
||||
// has an `id` so we don't need to infer one
|
||||
if (node.id) return node;
|
||||
if (node.id) return;
|
||||
|
||||
var id;
|
||||
if (t.isProperty(parent) && parent.kind === "init" && (!parent.computed || t.isLiteral(parent.key))) {
|
||||
@@ -118,8 +123,17 @@ export function bare(node, parent, scope) {
|
||||
} else if (t.isVariableDeclarator(parent)) {
|
||||
// var foo = function () {};
|
||||
id = parent.id;
|
||||
|
||||
if (t.isIdentifier(id)) {
|
||||
var bindingInfo = scope.parent.getBinding(id.name);
|
||||
if (bindingInfo && bindingInfo.constant && scope.getBinding(id.name) === bindingInfo) {
|
||||
// always going to reference this method
|
||||
node.id = id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return node;
|
||||
return;
|
||||
}
|
||||
|
||||
var name;
|
||||
|
||||
5
src/babel/transformation/helpers/react.js
vendored
5
src/babel/transformation/helpers/react.js
vendored
@@ -34,9 +34,8 @@ function cleanJSXElementLiteralChild(child, args) {
|
||||
var lines = child.value.split(/\r\n|\n|\r/);
|
||||
|
||||
var lastNonEmptyLine = 0;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].match(/[^ \t]/)) {
|
||||
lastNonEmptyLine = i;
|
||||
}
|
||||
@@ -44,7 +43,7 @@ function cleanJSXElementLiteralChild(child, args) {
|
||||
|
||||
var str = "";
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
|
||||
var isFirstLine = i === 0;
|
||||
|
||||
@@ -20,7 +20,7 @@ var referenceVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
var name = state.id.name;
|
||||
if (t.isReferencedIdentifier(node, parent, { name: name }) && scope.bindingIdentifierEquals(name, state.id)) {
|
||||
return state.ref ||= scope.generateUidIdentifier(name);
|
||||
return state.ref = state.ref || scope.generateUidIdentifier(name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -218,7 +218,7 @@ export default class ReplaceSupers {
|
||||
return this.setSuperProperty(node.left.property, node.right, node.left.computed, getThisReference());
|
||||
} else {
|
||||
// super.age += 2; -> var _ref = super.age; super.age = _ref + 2;
|
||||
ref ||= path.scope.generateUidIdentifier("ref");
|
||||
ref = ref || path.scope.generateUidIdentifier("ref");
|
||||
return [
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, node.left)
|
||||
|
||||
@@ -1,68 +1,34 @@
|
||||
import normalizeAst from "../helpers/normalize-ast";
|
||||
import Transformer from "./transformer";
|
||||
import object from "../helpers/object";
|
||||
import File from "./file";
|
||||
import each from "lodash/collection/each";
|
||||
import Pipeline from "./transformer-pipeline";
|
||||
|
||||
export default function transform(code: string, opts?: Object) {
|
||||
var file = new File(opts);
|
||||
return file.parse(code);
|
||||
}
|
||||
var pipeline = new Pipeline;
|
||||
|
||||
transform.fromAst = function (ast, code, opts) {
|
||||
ast = normalizeAst(ast);
|
||||
//
|
||||
|
||||
var file = new File(opts);
|
||||
file.addCode(code);
|
||||
file.transform(ast);
|
||||
return file.generate();
|
||||
};
|
||||
import transformers from "./transformers";
|
||||
pipeline.addTransformers(transformers);
|
||||
|
||||
transform._ensureTransformerNames = function (type: string, rawKeys: Array<string>) {
|
||||
var keys = [];
|
||||
//
|
||||
|
||||
for (var i = 0; i < rawKeys.length; i++) {
|
||||
var key = rawKeys[i];
|
||||
import deprecated from "./transformers/deprecated";
|
||||
pipeline.addDeprecated(deprecated);
|
||||
|
||||
var deprecatedKey = transform.deprecatedTransformerMap[key];
|
||||
var aliasKey = transform.aliasTransformerMap[key];
|
||||
if (aliasKey) {
|
||||
keys.push(aliasKey);
|
||||
} else if (deprecatedKey) {
|
||||
// deprecated key, remap it to the new one
|
||||
console.error(`The transformer ${key} has been renamed to ${deprecatedKey}`);
|
||||
rawKeys.push(deprecatedKey);
|
||||
} else if (transform.transformers[key]) {
|
||||
// valid key
|
||||
keys.push(key);
|
||||
} else if (transform.namespaces[key]) {
|
||||
// namespace, append all transformers within this namespace
|
||||
keys = keys.concat(transform.namespaces[key]);
|
||||
} else {
|
||||
// invalid key
|
||||
throw new ReferenceError(`Unknown transformer ${key} specified in ${type}`);
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
return keys;
|
||||
};
|
||||
import aliases from "./transformers/aliases";
|
||||
pipeline.addAliases(aliases);
|
||||
|
||||
transform.transformerNamespaces = object();
|
||||
transform.transformers = object();
|
||||
transform.namespaces = object();
|
||||
//
|
||||
|
||||
transform.deprecatedTransformerMap = require("./transformers/deprecated");
|
||||
transform.aliasTransformerMap = require("./transformers/aliases");
|
||||
transform.moduleFormatters = require("./modules");
|
||||
import * as filters from "./transformers/filters";
|
||||
pipeline.addFilter(filters.internal);
|
||||
pipeline.addFilter(filters.blacklist);
|
||||
pipeline.addFilter(filters.whitelist);
|
||||
pipeline.addFilter(filters.stage);
|
||||
pipeline.addFilter(filters.optional);
|
||||
|
||||
import rawTransformers from "./transformers";
|
||||
//
|
||||
|
||||
each(rawTransformers, function (transformer, key) {
|
||||
var namespace = key.split(".")[0];
|
||||
|
||||
transform.namespaces[namespace] ||= [];
|
||||
transform.namespaces[namespace].push(key);
|
||||
transform.transformerNamespaces[key] = namespace;
|
||||
|
||||
transform.transformers[key] = new Transformer(key, transformer);
|
||||
});
|
||||
var transform = pipeline.transform.bind(pipeline);
|
||||
transform.fromAst = pipeline.transformFromAst.bind(pipeline);
|
||||
transform.pipeline = pipeline;
|
||||
export default transform;
|
||||
|
||||
@@ -8,7 +8,8 @@ import * as t from "../../types";
|
||||
var remapVisitor = {
|
||||
enter(node, parent, scope, formatter) {
|
||||
var remap = formatter.internalRemap[node.name];
|
||||
if (this.isReferencedIdentifier() && remap) {
|
||||
|
||||
if (this.isReferencedIdentifier() && remap && node !== remap) {
|
||||
if (!scope.hasBinding(node.name) || scope.bindingIdentifierEquals(node.name, formatter.localImports[node.name])) {
|
||||
return remap;
|
||||
}
|
||||
@@ -49,11 +50,12 @@ var remapVisitor = {
|
||||
if (node._skipModulesRemap) {
|
||||
return this.skip();
|
||||
}
|
||||
},
|
||||
|
||||
exit(node, parent, scope, formatter) {
|
||||
if (t.isAssignmentExpression(node) && !node._ignoreModulesRemap) {
|
||||
var exported = formatter.getExport(node.left, scope);
|
||||
if (exported) {
|
||||
this.skip();
|
||||
return formatter.remapExportAssignment(node, exported);
|
||||
}
|
||||
}
|
||||
@@ -123,6 +125,11 @@ export default class DefaultFormatter {
|
||||
this.getLocalImports();
|
||||
}
|
||||
|
||||
isModuleType(node, type) {
|
||||
var modules = this.file.dynamicImportTypes[type];
|
||||
return modules && modules.indexOf(node) >= 0;
|
||||
}
|
||||
|
||||
transform() {
|
||||
this.remapAssignments();
|
||||
}
|
||||
@@ -160,7 +167,7 @@ export default class DefaultFormatter {
|
||||
}
|
||||
|
||||
_addExport(name, exported) {
|
||||
var info = this.localExports[name] ||= {
|
||||
var info = this.localExports[name] = this.localExports[name] || {
|
||||
binding: this.scope.getBindingIdentifier(name),
|
||||
exported: []
|
||||
};
|
||||
@@ -178,7 +185,10 @@ export default class DefaultFormatter {
|
||||
|
||||
getModuleName() {
|
||||
var opts = this.file.opts;
|
||||
if (opts.moduleId) return opts.moduleId;
|
||||
// moduleId is n/a if a `getModuleId()` is provided
|
||||
if (opts.moduleId && !opts.getModuleId) {
|
||||
return opts.moduleId;
|
||||
}
|
||||
|
||||
var filenameRelative = opts.filenameRelative;
|
||||
var moduleName = "";
|
||||
@@ -207,7 +217,12 @@ export default class DefaultFormatter {
|
||||
// normalize path separators
|
||||
moduleName = moduleName.replace(/\\/g, "/");
|
||||
|
||||
return moduleName;
|
||||
if (opts.getModuleId) {
|
||||
// If return is falsy, assume they want us to use our generated default name
|
||||
return opts.getModuleId(moduleName) || moduleName;
|
||||
} else {
|
||||
return moduleName;
|
||||
}
|
||||
}
|
||||
|
||||
_pushStatement(ref, nodes) {
|
||||
|
||||
@@ -23,7 +23,7 @@ export default class AMDFormatter extends DefaultFormatter {
|
||||
*/
|
||||
|
||||
transform(program) {
|
||||
DefaultFormatter.prototype.transform.apply(this, arguments);
|
||||
CommonFormatter.prototype.transform.apply(this, arguments);
|
||||
|
||||
var body = program.body;
|
||||
|
||||
@@ -80,7 +80,9 @@ export default class AMDFormatter extends DefaultFormatter {
|
||||
this.defaultIds[key] = specifier.local;
|
||||
}
|
||||
|
||||
if (includes(this.file.dynamicImportAbsoluteDefaults, node)) {
|
||||
if (this.isModuleType(node, "absolute")) {
|
||||
// absolute module reference
|
||||
} else if (this.isModuleType(node, "absoluteDefault")) {
|
||||
// prevent unnecessary renaming of dynamic imports
|
||||
this.ids[node.source.value] = ref;
|
||||
ref = t.memberExpression(ref, t.identifier("default"));
|
||||
@@ -105,12 +107,17 @@ export default class AMDFormatter extends DefaultFormatter {
|
||||
|
||||
exportSpecifier(specifier, node, nodes) {
|
||||
if (this.doDefaultExportInterop(specifier)) {
|
||||
nodes.push(util.template("exports-default-assign", {
|
||||
VALUE: specifier.local
|
||||
}, true));
|
||||
} else {
|
||||
CommonFormatter.prototype.exportSpecifier.apply(this, arguments);
|
||||
this.passModuleArg = true;
|
||||
|
||||
if (specifier.exported !== specifier.local && !node.source) {
|
||||
nodes.push(util.template("exports-default-assign", {
|
||||
VALUE: specifier.local
|
||||
}, true));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CommonFormatter.prototype.exportSpecifier.apply(this, arguments);
|
||||
}
|
||||
|
||||
exportDeclaration(node, nodes) {
|
||||
|
||||
@@ -20,7 +20,7 @@ export default class CommonJSFormatter extends DefaultFormatter {
|
||||
if (this.file.isLoose("es6.modules")) templateName += "-loose";
|
||||
var declar = util.template(templateName, true);
|
||||
declar._blockHoist = 3;
|
||||
file.ast.program.body.unshift(declar);
|
||||
file.path.unshiftContainer("body", [declar]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,9 @@ export default class CommonJSFormatter extends DefaultFormatter {
|
||||
|
||||
// import foo from "foo";
|
||||
if (t.isSpecifierDefault(specifier)) {
|
||||
if (includes(this.file.dynamicImportAbsoluteDefaults, node)) {
|
||||
if (this.isModuleType(node, "absolute")) {
|
||||
// absolute module reference
|
||||
} else if (this.isModuleType(node, "absoluteDefault")) {
|
||||
this.internalRemap[variableName.name] = ref;
|
||||
} else if (this.noInteropRequireImport) {
|
||||
this.internalRemap[variableName.name] = t.memberExpression(ref, t.identifier("default"));
|
||||
@@ -53,7 +55,7 @@ export default class CommonJSFormatter extends DefaultFormatter {
|
||||
var uid = this.scope.generateUidBasedOnNode(node, "import");
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(uid, t.callExpression(this.file.addHelper("interop-require-wildcard"), [ref]))
|
||||
t.variableDeclarator(uid, t.callExpression(this.file.addHelper("interop-require-default"), [ref]))
|
||||
]));
|
||||
|
||||
this.internalRemap[variableName.name] = t.memberExpression(uid, t.identifier("default"));
|
||||
@@ -104,13 +106,16 @@ export default class CommonJSFormatter extends DefaultFormatter {
|
||||
var call = t.callExpression(t.identifier("require"), [node.source]);
|
||||
var uid;
|
||||
|
||||
if (includes(this.file.dynamicImportAbsoluteDefaults, node)) {
|
||||
if (this.isModuleType(node, "absolute")) {
|
||||
// absolute module reference
|
||||
} else if (this.isModuleType(node, "absoluteDefault")) {
|
||||
call = t.memberExpression(call, t.identifier("default"));
|
||||
uid = node.specifiers[0].local;
|
||||
} else {
|
||||
uid = this.scope.generateUidBasedOnNode(node, "import");
|
||||
}
|
||||
|
||||
uid = uid || node.specifiers[0].local;
|
||||
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(uid, call)
|
||||
]);
|
||||
|
||||
@@ -77,11 +77,11 @@ var runnerSettersVisitor = {
|
||||
|
||||
export default class SystemFormatter extends AMDFormatter {
|
||||
constructor(file) {
|
||||
super(file);
|
||||
|
||||
this.exportIdentifier = file.scope.generateUidIdentifier("export");
|
||||
this.noInteropRequireExport = true;
|
||||
this.noInteropRequireImport = true;
|
||||
|
||||
DefaultFormatter.apply(this, arguments);
|
||||
}
|
||||
|
||||
_addImportSource(node, exportNode) {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
this.KEY = INITIALIZERS.KEY.call(this);
|
||||
@@ -1 +0,0 @@
|
||||
CONSTRUCTOR.KEY = INITIALIZERS.KEY.call(CONSTRUCTOR);
|
||||
@@ -23,7 +23,11 @@
|
||||
throw new TypeError("The decorator for method " + descriptor.key + " is of the invalid type " + typeof decorator);
|
||||
}
|
||||
}
|
||||
if (initializers) initializers[key] = descriptor.initializer;
|
||||
|
||||
if (descriptor.initializer !== undefined) {
|
||||
initializers[key] = descriptor;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
descriptor.enumerable = true;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
descriptor.writable = true;
|
||||
|
||||
if (decorators) {
|
||||
for (var f = 0; f < decorators.length; f++) {
|
||||
@@ -26,7 +26,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
if (descriptor.initializer) {
|
||||
descriptor.value = descriptor.initializer.call(target);
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
(function (target, key, descriptors) {
|
||||
var _descriptor = descriptors[key];
|
||||
|
||||
// clone it
|
||||
var descriptor = {};
|
||||
for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
|
||||
|
||||
// initialize it
|
||||
if (!descriptor.initializer) return;
|
||||
descriptor.value = descriptor.initializer.call(target);
|
||||
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
})
|
||||
@@ -1,7 +1,7 @@
|
||||
(function (obj, key, value) {
|
||||
return Object.defineProperty(obj, key, {
|
||||
value: value,
|
||||
enumerable: key == null || typeof Symbol == "undefined" || key.constructor !== Symbol,
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
|
||||
7
src/babel/transformation/templates/helper-instanceof.js
Normal file
7
src/babel/transformation/templates/helper-instanceof.js
Normal file
@@ -0,0 +1,7 @@
|
||||
(function (left, right) {
|
||||
if (right != null && right[Symbol.hasInstance]) {
|
||||
return right[Symbol.hasInstance](left);
|
||||
} else {
|
||||
return left instanceof right;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
(function (obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
})
|
||||
@@ -1,3 +1,14 @@
|
||||
(function (obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
if (obj && obj.__esModule) {
|
||||
return obj;
|
||||
} else {
|
||||
var newObj = {};
|
||||
if (obj != null) {
|
||||
for (var key in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
|
||||
}
|
||||
}
|
||||
newObj.default = obj;
|
||||
return newObj;
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
(function (proxy, directory) {
|
||||
directory.push(proxy);
|
||||
return proxy;
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
[];
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (FUNCTION_KEY) {
|
||||
function* FUNCTION_ID() {
|
||||
return yield* FUNCTION_ID.apply(this, arguments);
|
||||
return yield* FUNCTION_KEY.apply(this, arguments);
|
||||
}
|
||||
|
||||
FUNCTION_ID.toString = function () {
|
||||
|
||||
@@ -8,58 +8,35 @@ import traverse from "../traversal";
|
||||
|
||||
export default class TransformerPass {
|
||||
constructor(file: File, transformer: Transformer) {
|
||||
this.transformer = transformer;
|
||||
this.shouldRun = !transformer.check;
|
||||
this.handlers = transformer.handlers;
|
||||
this.file = file;
|
||||
this.ran = false;
|
||||
this.shouldTransform = !transformer.shouldVisit;
|
||||
this.transformer = transformer;
|
||||
this.handlers = transformer.handlers;
|
||||
this.skipKey = transformer.skipKey;
|
||||
this.file = file;
|
||||
this.ran = false;
|
||||
}
|
||||
|
||||
canTransform(): boolean {
|
||||
var transformer = this.transformer;
|
||||
|
||||
var opts = this.file.opts;
|
||||
var key = transformer.key;
|
||||
|
||||
// internal
|
||||
if (key[0] === "_") return true;
|
||||
|
||||
// blacklist
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && includes(blacklist, key)) return false;
|
||||
|
||||
// whitelist
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist) return includes(whitelist, key);
|
||||
|
||||
// stage
|
||||
var stage = transformer.metadata.stage;
|
||||
if (stage != null && stage >= opts.stage) return true;
|
||||
|
||||
// optional
|
||||
if (transformer.metadata.optional && !includes(opts.optional, key)) return false;
|
||||
|
||||
return true;
|
||||
return this.file.pipeline.canTransform(this.transformer, this.file.opts);
|
||||
}
|
||||
|
||||
checkNode(node: Object): boolean {
|
||||
var check = this.transformer.check;
|
||||
if (check) {
|
||||
return this.shouldRun = check(node);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
checkPath(path: TraversalPath): boolean {
|
||||
if (this.shouldTransform || this.ran) return;
|
||||
|
||||
this.shouldTransform = this.transformer.shouldVisit(path.node);
|
||||
}
|
||||
|
||||
transform() {
|
||||
if (!this.shouldRun) return;
|
||||
if (!this.shouldTransform) return;
|
||||
|
||||
var file = this.file;
|
||||
|
||||
file.log.debug(`Running transformer ${this.transformer.key}`);
|
||||
file.log.debug(`Start transformer ${this.transformer.key}`);
|
||||
|
||||
traverse(file.ast, this.handlers, file.scope, file);
|
||||
|
||||
file.log.debug(`Finish transformer ${this.transformer.key}`);
|
||||
|
||||
this.ran = true;
|
||||
}
|
||||
}
|
||||
|
||||
103
src/babel/transformation/transformer-pipeline.js
Normal file
103
src/babel/transformation/transformer-pipeline.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import Transformer from "./transformer";
|
||||
import normalizeAst from "../helpers/normalize-ast";
|
||||
import assign from "lodash/object/assign";
|
||||
import object from "../helpers/object";
|
||||
import File from "./file";
|
||||
|
||||
export default class TransformerPipeline {
|
||||
constructor() {
|
||||
this.transformers = object();
|
||||
this.namespaces = object();
|
||||
this.deprecated = object();
|
||||
this.aliases = object();
|
||||
this.filters = [];
|
||||
}
|
||||
|
||||
addTransformers(transformers) {
|
||||
for (var key in transformers) {
|
||||
this.addTransformer(key, transformers[key]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
addTransformer(key, transformer) {
|
||||
if (this.transformers[key]) throw new Error(); // todo: error
|
||||
|
||||
var namespace = key.split(".")[0];
|
||||
this.namespaces[namespace] = this.namespaces[namespace] || [];
|
||||
this.namespaces[namespace].push(key);
|
||||
this.namespaces[key] = namespace;
|
||||
|
||||
this.transformers[key] = new Transformer(key, transformer);
|
||||
}
|
||||
|
||||
addAliases(names) {
|
||||
assign(this.aliases, names);
|
||||
return this;
|
||||
}
|
||||
|
||||
addDeprecated(names) {
|
||||
assign(this.deprecated, names);
|
||||
return this;
|
||||
}
|
||||
|
||||
addFilter(filter: Function) {
|
||||
this.filters.push(filter);
|
||||
return this;
|
||||
}
|
||||
|
||||
canTransform(transformer, fileOpts) {
|
||||
for (var filter of (this.filters: Array)) {
|
||||
var result = filter(transformer, fileOpts);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
transform(code: string, opts?: Object) {
|
||||
var file = new File(opts, this);
|
||||
return file.wrap(code, function () {
|
||||
file.addCode(code, true);
|
||||
});
|
||||
}
|
||||
|
||||
transformFromAst(ast, code, opts) {
|
||||
ast = normalizeAst(ast);
|
||||
|
||||
var file = new File(opts, this);
|
||||
return file.wrap(code, function () {
|
||||
file.addCode(code);
|
||||
file.addAst(ast);
|
||||
});
|
||||
}
|
||||
|
||||
_ensureTransformerNames(type: string, rawKeys: Array<string>) {
|
||||
var keys = [];
|
||||
|
||||
for (var i = 0; i < rawKeys.length; i++) {
|
||||
var key = rawKeys[i];
|
||||
|
||||
var deprecatedKey = this.deprecated[key];
|
||||
var aliasKey = this.aliases[key];
|
||||
if (aliasKey) {
|
||||
keys.push(aliasKey);
|
||||
} else if (deprecatedKey) {
|
||||
// deprecated key, remap it to the new one
|
||||
console.error(`[BABEL] The transformer ${key} has been renamed to ${deprecatedKey}`);
|
||||
rawKeys.push(deprecatedKey);
|
||||
} else if (this.transformers[key]) {
|
||||
// valid key
|
||||
keys.push(key);
|
||||
} else if (this.namespaces[key]) {
|
||||
// namespace, append all transformers within this namespace
|
||||
keys = keys.concat(this.namespaces[key]);
|
||||
} else {
|
||||
// invalid key
|
||||
throw new ReferenceError(`Unknown transformer ${key} specified in ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import TransformerPass from "./transformer-pass";
|
||||
import * as messages from "../messages";
|
||||
import isFunction from "lodash/lang/isFunction";
|
||||
import traverse from "../traversal";
|
||||
import isObject from "lodash/lang/isObject";
|
||||
@@ -14,7 +15,7 @@ import each from "lodash/collection/each";
|
||||
*/
|
||||
|
||||
export default class Transformer {
|
||||
constructor(transformerKey: key, transformer: Object, opts: Object) {
|
||||
constructor(transformerKey: string, transformer: Object) {
|
||||
transformer = assign({}, transformer);
|
||||
|
||||
var take = function (key) {
|
||||
@@ -24,19 +25,34 @@ export default class Transformer {
|
||||
};
|
||||
|
||||
this.manipulateOptions = take("manipulateOptions");
|
||||
this.shouldVisit = take("shouldVisit");
|
||||
this.metadata = take("metadata") || {};
|
||||
this.parser = take("parser");
|
||||
this.check = take("check");
|
||||
this.post = take("post");
|
||||
this.pre = take("pre");
|
||||
|
||||
//
|
||||
|
||||
if (this.metadata.stage != null) {
|
||||
this.metadata.optional = true;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
this.handlers = this.normalize(transformer);
|
||||
this.opts ||= {};
|
||||
this.key = transformerKey;
|
||||
|
||||
//
|
||||
|
||||
if (!this.shouldVisit) {
|
||||
var types = Object.keys(this.handlers);
|
||||
this.shouldVisit = function (node) {
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
if (node.type === types[i]) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
normalize(transformer: Object): Object {
|
||||
@@ -71,7 +87,7 @@ export default class Transformer {
|
||||
buildPass(file: File): TransformerPass {
|
||||
// validate Transformer instance
|
||||
if (!(file instanceof File)) {
|
||||
throw new TypeError(`Transformer ${this.key} is resolving to a different Babel version to what is doing the actual transformation...`);
|
||||
throw new TypeError(messages.get("transformerNotFile", this.key));
|
||||
}
|
||||
|
||||
return new TransformerPass(file, this);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"es6.symbols": "es6.spec.symbols",
|
||||
"es6.blockScopingTDZ": "es6.spec.blockScoping",
|
||||
|
||||
"minification.deadCodeElimination": "utility.deadCodeElimination",
|
||||
"utility.deadCodeElimination": "minification.deadCodeElimination",
|
||||
"minification.removeConsoleCalls": "utility.removeConsole",
|
||||
"minification.removeDebugger": "utility.removeDebugger"
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@ import * as t from "../../../types";
|
||||
|
||||
export function MemberExpression(node) {
|
||||
var prop = node.property;
|
||||
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
|
||||
// foo["bar"] => foo.bar
|
||||
node.property = t.identifier(prop.value);
|
||||
node.computed = false;
|
||||
} else if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
// foo.default -> foo["default"]
|
||||
node.property = t.literal(prop.name);
|
||||
node.computed = true;
|
||||
|
||||
@@ -2,11 +2,7 @@ import * as t from "../../../types";
|
||||
|
||||
export function Property(node) {
|
||||
var key = node.key;
|
||||
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
|
||||
// "foo": "bar" -> foo: "bar"
|
||||
node.key = t.identifier(key.value);
|
||||
node.computed = false;
|
||||
} else if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
// default: "bar" -> "default": "bar"
|
||||
node.key = t.literal(key.name);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as defineMap from "../../helpers/define-map";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isProperty(node) && (node.kind === "get" || node.kind === "set");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var check = t.isArrowFunctionExpression;
|
||||
export var shouldVisit = t.isArrowFunctionExpression;
|
||||
|
||||
export function ArrowFunctionExpression(node) {
|
||||
t.ensureBlock(node);
|
||||
@@ -8,6 +8,4 @@ export function ArrowFunctionExpression(node) {
|
||||
node.expression = false;
|
||||
node.type = "FunctionExpression";
|
||||
node.shadow = true;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ function isLet(node, parent) {
|
||||
if (isLetInitable(node, parent)) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var declar = node.declarations[i];
|
||||
declar.init ||= t.identifier("undefined");
|
||||
declar.init = declar.init || t.identifier("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ function standardizeLets(declars) {
|
||||
}
|
||||
}
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
|
||||
}
|
||||
|
||||
@@ -139,7 +139,12 @@ var hoistVarDeclarationsVisitor = {
|
||||
enter(node, parent, scope, self) {
|
||||
if (this.isForStatement()) {
|
||||
if (isVar(node.init, node)) {
|
||||
node.init = t.sequenceExpression(self.pushDeclar(node.init));
|
||||
var nodes = self.pushDeclar(node.init);
|
||||
if (nodes.length === 1) {
|
||||
node.init = nodes[0];
|
||||
} else {
|
||||
node.init = t.sequenceExpression(nodes);
|
||||
}
|
||||
}
|
||||
} else if (this.isFor()) {
|
||||
if (isVar(node.left, node)) {
|
||||
@@ -465,14 +470,14 @@ class BlockScoping {
|
||||
var declar;
|
||||
|
||||
//
|
||||
for (var i = 0; i < declarators.length; i++) {
|
||||
for (let i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
extend(this.outsideLetReferences, t.getBindingIdentifiers(declar));
|
||||
}
|
||||
|
||||
//
|
||||
if (block.body) {
|
||||
for (i = 0; i < block.body.length; i++) {
|
||||
for (let i = 0; i < block.body.length; i++) {
|
||||
declar = block.body[i];
|
||||
if (isLet(declar, block)) {
|
||||
declarators = declarators.concat(declar.declarations);
|
||||
@@ -481,7 +486,7 @@ class BlockScoping {
|
||||
}
|
||||
|
||||
//
|
||||
for (i = 0; i < declarators.length; i++) {
|
||||
for (let i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
var keys = t.getBindingIdentifiers(declar);
|
||||
extend(this.letReferences, keys);
|
||||
@@ -606,7 +611,7 @@ class BlockScoping {
|
||||
for (var i = 0; i < cases.length; i++) {
|
||||
var caseConsequent = cases[i].consequent[0];
|
||||
if (t.isBreakStatement(caseConsequent) && !caseConsequent.label) {
|
||||
caseConsequent.label = this.loopLabel ||= this.file.scope.generateUidIdentifier("loop");
|
||||
caseConsequent.label = this.loopLabel = this.loopLabel || this.file.scope.generateUidIdentifier("loop");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import memoiseDecorators from "../../helpers/memoise-decorators";
|
||||
import ReplaceSupers from "../../helpers/replace-supers";
|
||||
import * as nameMethod from "../../helpers/name-method";
|
||||
import * as defineMap from "../../helpers/define-map";
|
||||
@@ -10,7 +11,7 @@ import * as t from "../../../types";
|
||||
|
||||
const PROPERTY_COLLISION_METHOD_NAME = "__initializeProperties";
|
||||
|
||||
export var check = t.isClass;
|
||||
export var shouldVisit = t.isClass;
|
||||
|
||||
export function ClassDeclaration(node, parent, scope, file) {
|
||||
return t.variableDeclaration("let", [
|
||||
@@ -36,6 +37,22 @@ var collectPropertyReferencesVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
var constructorVisitor = traverse.explode({
|
||||
ThisExpression: {
|
||||
enter(node, parent, scope, ref) {
|
||||
return ref;
|
||||
}
|
||||
},
|
||||
|
||||
Function: {
|
||||
enter(node) {
|
||||
if (!node.shadow) {
|
||||
this.skip();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var verifyConstructorVisitor = traverse.explode({
|
||||
MethodDefinition: {
|
||||
enter() {
|
||||
@@ -50,7 +67,7 @@ var verifyConstructorVisitor = traverse.explode({
|
||||
},
|
||||
|
||||
CallExpression: {
|
||||
enter(node, parent, scope, state) {
|
||||
exit(node, parent, scope, state) {
|
||||
if (this.get("callee").isSuper()) {
|
||||
state.hasBareSuper = true;
|
||||
state.bareSuper = this;
|
||||
@@ -79,10 +96,6 @@ var verifyConstructorVisitor = traverse.explode({
|
||||
if (state.hasSuper && !state.hasBareSuper) {
|
||||
throw this.errorWithNode("'this' is not allowed before super()");
|
||||
}
|
||||
|
||||
if (state.isNativeSuper) {
|
||||
return state.nativeSuperRef;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -137,15 +150,6 @@ class ClassTransformer {
|
||||
|
||||
//
|
||||
|
||||
var superClass = this.node.superClass;
|
||||
this.isNativeSuper = superClass && t.isIdentifier(superClass) && t.NATIVE_TYPE_NAMES.indexOf(superClass.name) >= 0;
|
||||
|
||||
if (this.isNativeSuper) {
|
||||
this.nativeSuperRef = this.scope.generateUidIdentifier("this");
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var body = this.body;
|
||||
|
||||
//
|
||||
@@ -217,18 +221,12 @@ class ClassTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isNativeSuper) {
|
||||
// we've determined this is inheriting from a native class so return the constructed
|
||||
// instance
|
||||
constructorBody.body.push(t.returnStatement(this.nativeSuperRef));
|
||||
}
|
||||
|
||||
if (this.className) {
|
||||
// named class with only a constructor
|
||||
if (body.length === 1) return t.toExpression(body[0]);
|
||||
} else {
|
||||
// infer class name if this is a nameless class expression
|
||||
constructor = nameMethod.bare(constructor, this.parent, this.scope);
|
||||
constructor = nameMethod.bare(constructor, this.parent, this.scope) || constructor;
|
||||
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(classRef, constructor)
|
||||
@@ -292,6 +290,10 @@ class ClassTransformer {
|
||||
var node = classBody[i];
|
||||
var path = classBodyPaths[i];
|
||||
|
||||
if (node.decorators) {
|
||||
memoiseDecorators(node.decorators, this.scope);
|
||||
}
|
||||
|
||||
if (t.isMethodDefinition(node)) {
|
||||
var isConstructor = node.kind === "constructor";
|
||||
if (isConstructor) this.verifyConstructor(path);
|
||||
@@ -323,10 +325,8 @@ class ClassTransformer {
|
||||
if (!this.hasConstructor && this.hasSuper) {
|
||||
var helperName = "class-super-constructor-call";
|
||||
if (this.isLoose) helperName += "-loose";
|
||||
if (this.isNativeSuper) helperName = "class-super-native-constructor-call";
|
||||
constructorBody.body.push(util.template(helperName, {
|
||||
NATIVE_REF: this.nativeSuperRef,
|
||||
CLASS_NAME: className,
|
||||
CLASS_NAME: this.classRef,
|
||||
SUPER_NAME: this.superName
|
||||
}, true));
|
||||
}
|
||||
@@ -454,12 +454,10 @@ class ClassTransformer {
|
||||
|
||||
verifyConstructor(path: TraversalPath) {
|
||||
var state = {
|
||||
nativeSuperRef: this.nativeSuperRef,
|
||||
isNativeSuper: this.isNativeSuper,
|
||||
hasBareSuper: false,
|
||||
bareSuper: null,
|
||||
hasSuper: this.hasSuper,
|
||||
file: this.file
|
||||
hasBareSuper: false,
|
||||
bareSuper: null,
|
||||
hasSuper: this.hasSuper,
|
||||
file: this.file
|
||||
};
|
||||
|
||||
path.get("value").traverse(verifyConstructorVisitor, state);
|
||||
@@ -469,22 +467,7 @@ class ClassTransformer {
|
||||
if (!state.hasBareSuper && this.hasSuper) {
|
||||
throw path.errorWithNode("Derived constructor must call super()");
|
||||
}
|
||||
|
||||
if (this.isNativeSuper && this.bareSuper) {
|
||||
this.bareSuper.replaceWithMultiple([
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(this.nativeSuperRef, t.newExpression(this.superName, this.bareSuper.node.arguments))
|
||||
]),
|
||||
|
||||
t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(this.nativeSuperRef, t.identifier("__proto__")),
|
||||
t.memberExpression(this.classRef, t.identifier("prototype"))
|
||||
)),
|
||||
t.expressionStatement(this.nativeSuperRef)
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a method to its respective mutatorMap.
|
||||
@@ -529,34 +512,47 @@ class ClassTransformer {
|
||||
|
||||
if (node.decorators) {
|
||||
var body = [];
|
||||
if (node.value) body.push(t.returnStatement(node.value));
|
||||
node.value = t.functionExpression(null, [], t.blockStatement(body));
|
||||
if (node.value) {
|
||||
body.push(t.returnStatement(node.value));
|
||||
node.value = t.functionExpression(null, [], t.blockStatement(body));
|
||||
} else {
|
||||
node.value = t.literal(null);
|
||||
}
|
||||
this.pushToMap(node, true, "initializer");
|
||||
|
||||
var initializers;
|
||||
var body;
|
||||
var target;
|
||||
if (node.static) {
|
||||
this.staticPropBody.push(util.template("call-static-decorator", {
|
||||
INITIALIZERS: this.staticInitializersId ||= this.scope.generateUidIdentifier("staticInitializers"),
|
||||
CONSTRUCTOR: this.classRef,
|
||||
KEY: node.key,
|
||||
}, true));
|
||||
initializers = this.staticInitializersId = this.staticInitializersId || this.scope.generateUidIdentifier("staticInitializers");
|
||||
body = this.staticPropBody;
|
||||
target = this.classRef;
|
||||
} else {
|
||||
this.instancePropBody.push(util.template("call-instance-decorator", {
|
||||
INITIALIZERS: this.instanceInitializersId ||= this.scope.generateUidIdentifier("instanceInitializers"),
|
||||
KEY: node.key
|
||||
}, true));
|
||||
initializers = this.instanceInitializersId = this.instanceInitializersId || this.scope.generateUidIdentifier("instanceInitializers");
|
||||
body = this.instancePropBody;
|
||||
target = t.thisExpression();
|
||||
}
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("define-decorated-property-descriptor"), [
|
||||
target,
|
||||
t.literal(node.key.name),
|
||||
initializers
|
||||
])
|
||||
));
|
||||
} else {
|
||||
if (!node.static && node.value) {
|
||||
if (!node.value && !node.decorators) return;
|
||||
|
||||
if (node.static) {
|
||||
// can just be added to the static map
|
||||
this.pushToMap(node, true);
|
||||
} else if (node.value) {
|
||||
// add this to the instancePropBody which will be added after the super call in a derived constructor
|
||||
// or at the start of a constructor for a non-derived constructor
|
||||
this.instancePropBody.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", t.memberExpression(t.thisExpression(), node.key), node.value)
|
||||
));
|
||||
node.value = t.identifier("undefined");
|
||||
}
|
||||
|
||||
// can just be added to the static map
|
||||
this.pushToMap(node, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as messages from "../../../messages";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isVariableDeclaration(node, { kind: "const" }) || t.isImportDeclaration(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as messages from "../../../messages";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var check = t.isPattern;
|
||||
export var shouldVisit = t.isPattern;
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
@@ -78,11 +78,11 @@ exports.Function = function (node, parent, scope, file) {
|
||||
|
||||
if (!hasDestructuring) return;
|
||||
|
||||
file.checkNode(nodes);
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
this.checkSelf();
|
||||
};
|
||||
|
||||
export function CatchClause(node, parent, scope, file) {
|
||||
@@ -104,14 +104,14 @@ export function CatchClause(node, parent, scope, file) {
|
||||
|
||||
node.body.body = nodes.concat(node.body.body);
|
||||
|
||||
return node;
|
||||
this.checkSelf();
|
||||
}
|
||||
|
||||
export function ExpressionStatement(node, parent, scope, file) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
if (!t.isPattern(expr.left)) return;
|
||||
if (file.isConsequenceExpressionStatement(node)) return;
|
||||
if (this.isCompletionRecord()) return;
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
operator: expr.operator,
|
||||
@@ -200,7 +200,7 @@ export function VariableDeclaration(node, parent, scope, file) {
|
||||
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
node = nodes[i];
|
||||
declar ||= t.variableDeclaration(node.kind, []);
|
||||
declar = declar || t.variableDeclaration(node.kind, []);
|
||||
|
||||
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
|
||||
throw file.errorWithNode(node, messages.get("invalidParentForThisNode"));
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as messages from "../../../messages";
|
||||
import * as util from "../../../util";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var check = t.isForOfStatement;
|
||||
export var shouldVisit = t.isForOfStatement;
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
if (this.get("right").isArrayExpression()) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ReplaceSupers from "../../helpers/replace-supers";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var check = t.isSuper;
|
||||
export var shouldVisit = t.isSuper;
|
||||
|
||||
function Property(path, node, scope, getObjectRef, file) {
|
||||
if (!node.method) return;
|
||||
@@ -32,7 +32,7 @@ function Property(path, node, scope, getObjectRef, file) {
|
||||
|
||||
export function ObjectExpression(node, parent, scope, file) {
|
||||
var objectRef;
|
||||
var getObjectRef = () => objectRef ||= scope.generateUidIdentifier("obj");
|
||||
var getObjectRef = () => objectRef = objectRef || scope.generateUidIdentifier("obj");
|
||||
|
||||
var propPaths = this.get("properties");
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import callDelegate from "../../helpers/call-delegate";
|
||||
import * as util from "../../../util";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isFunction(node) && hasDefaults(node);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ exports.Function = function (node, parent, scope, file) {
|
||||
ARGUMENT_KEY: t.literal(i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true);
|
||||
file.checkNode(defNode);
|
||||
defNode._blockHoist = node.params.length - i;
|
||||
body.push(defNode);
|
||||
};
|
||||
@@ -97,4 +96,6 @@ exports.Function = function (node, parent, scope, file) {
|
||||
} else {
|
||||
node.body.body = body.concat(node.body.body);
|
||||
}
|
||||
|
||||
this.checkSelf();
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import isNumber from "lodash/lang/isNumber";
|
||||
import * as util from "../../../util";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var check = t.isRestElement;
|
||||
export var shouldVisit = t.isRestElement;
|
||||
|
||||
var memberExpressionOptimisationVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
@@ -74,7 +74,6 @@ exports.Function = function (node, parent, scope, file) {
|
||||
var accessExpr = t.memberExpression(rest, t.literal(index), true);
|
||||
return t.variableDeclarator(elem, accessExpr);
|
||||
}));
|
||||
file.checkNode(declar);
|
||||
node.body.body.unshift(declar);
|
||||
}
|
||||
|
||||
@@ -97,6 +96,7 @@ exports.Function = function (node, parent, scope, file) {
|
||||
candidate.replaceWith(argsId);
|
||||
optimizeMemberExpression(candidate.parent, node.params.length);
|
||||
}
|
||||
this.checkSelf();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -138,4 +138,5 @@ exports.Function = function (node, parent, scope, file) {
|
||||
});
|
||||
loop._blockHoist = node.params.length + 1;
|
||||
node.body.body.unshift(loop);
|
||||
this.checkSelf();
|
||||
};
|
||||
|
||||
@@ -16,27 +16,13 @@ function loose(node, body, objId) {
|
||||
|
||||
function spec(node, body, objId, initProps, file) {
|
||||
var props = node.properties;
|
||||
var prop, key;
|
||||
|
||||
// normalize key
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
if (prop.kind !== "init") continue;
|
||||
|
||||
key = prop.key;
|
||||
|
||||
if (!prop.computed && t.isIdentifier(key)) {
|
||||
prop.key = t.literal(key.name);
|
||||
}
|
||||
}
|
||||
|
||||
// add all non-computed properties and `__proto__` properties to the initializer
|
||||
|
||||
var broken = false;
|
||||
|
||||
for (i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
let prop = props[i];
|
||||
|
||||
if (prop.computed) {
|
||||
broken = true;
|
||||
@@ -51,24 +37,17 @@ function spec(node, body, objId, initProps, file) {
|
||||
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
|
||||
// otherwise use Object.defineProperty
|
||||
|
||||
for (i = 0; i < props.length; i++) {
|
||||
prop = props[i];
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
let prop = props[i];
|
||||
if (!prop) continue;
|
||||
|
||||
key = prop.key;
|
||||
var bodyNode;
|
||||
|
||||
if (prop.computed && t.isMemberExpression(key) && t.isIdentifier(key.object, { name: "Symbol" })) {
|
||||
// { [Symbol.iterator]: "foo" }
|
||||
bodyNode = t.assignmentExpression(
|
||||
"=",
|
||||
t.memberExpression(objId, key, true),
|
||||
prop.value
|
||||
);
|
||||
} else {
|
||||
bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
|
||||
let key = prop.key;
|
||||
if (t.isIdentifier(key) && !prop.computed) {
|
||||
key = t.literal(key.name);
|
||||
}
|
||||
|
||||
var bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
|
||||
|
||||
body.push(t.expressionStatement(bodyNode));
|
||||
}
|
||||
|
||||
@@ -84,7 +63,7 @@ function spec(node, body, objId, initProps, file) {
|
||||
}
|
||||
}
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isProperty(node) && node.computed;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isProperty(node) && (node.method || node.shorthand);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as regex from "../../helpers/regex";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return regex.is(node, "y");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import rewritePattern from "regexpu/rewrite-pattern";
|
||||
import * as regex from "../../helpers/regex";
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return regex.is(node, "u");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,16 @@ export var metadata = {
|
||||
};
|
||||
|
||||
export function UnaryExpression(node, parent, scope, file) {
|
||||
this.skip();
|
||||
if (node._ignoreSpecSymbols) return;
|
||||
|
||||
if (node.operator === "typeof") {
|
||||
var call = t.callExpression(file.addHelper("typeof"), [node.argument]);
|
||||
if (this.get("argument").isIdentifier()) {
|
||||
var undefLiteral = t.literal("undefined");
|
||||
var unary = t.unaryExpression("typeof", node.argument);
|
||||
unary._ignoreSpecSymbols = true;
|
||||
return t.conditionalExpression(
|
||||
t.binaryExpression("===", t.unaryExpression("typeof", node.argument), undefLiteral),
|
||||
t.binaryExpression("===", unary, undefLiteral),
|
||||
undefLiteral,
|
||||
call
|
||||
);
|
||||
@@ -21,3 +23,15 @@ export function UnaryExpression(node, parent, scope, file) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function BinaryExpression(node, parent, scope, file) {
|
||||
if (node.operator === "instanceof") {
|
||||
return t.callExpression(file.addHelper("instanceof"), [node.left, node.right]);
|
||||
}
|
||||
}
|
||||
|
||||
export function VariableDeclaration(node) {
|
||||
if (node._generated) this.skip();
|
||||
}
|
||||
|
||||
export { VariableDeclaration as FunctionDeclaration };
|
||||
|
||||
@@ -44,7 +44,7 @@ function build(props, scope) {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
export var check = t.isSpreadElement;
|
||||
export var shouldVisit = t.isSpreadElement;
|
||||
|
||||
export function ArrayExpression(node, parent, scope) {
|
||||
var elements = node.elements;
|
||||
|
||||
@@ -6,6 +6,7 @@ import map from "lodash/collection/map";
|
||||
import * as t from "../../../types";
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
if (node.generator || node.async) return;
|
||||
var tailCall = new TailCallTransformer(this, scope, file);
|
||||
tailCall.run();
|
||||
};
|
||||
@@ -17,15 +18,7 @@ function returnBlock(expr) {
|
||||
// looks for and replaces tail recursion calls
|
||||
var firstPass = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isIfStatement()) {
|
||||
if (this.get("alternate").isReturnStatement()) {
|
||||
t.ensureBlock(node, "alternate");
|
||||
}
|
||||
|
||||
if (this.get("consequent").isReturnStatement()) {
|
||||
t.ensureBlock(node, "consequent");
|
||||
}
|
||||
} else if (this.isReturnStatement()) {
|
||||
if (this.isReturnStatement()) {
|
||||
this.skip();
|
||||
return state.subTransform(node.argument);
|
||||
} else if (t.isTryStatement(parent)) {
|
||||
@@ -100,23 +93,23 @@ class TailCallTransformer {
|
||||
}
|
||||
|
||||
getArgumentsId() {
|
||||
return this.argumentsId ||= this.scope.generateUidIdentifier("arguments");
|
||||
return this.argumentsId = this.argumentsId || this.scope.generateUidIdentifier("arguments");
|
||||
}
|
||||
|
||||
getThisId() {
|
||||
return this.thisId ||= this.scope.generateUidIdentifier("this");
|
||||
return this.thisId = this.thisId || this.scope.generateUidIdentifier("this");
|
||||
}
|
||||
|
||||
getLeftId() {
|
||||
return this.leftId ||= this.scope.generateUidIdentifier("left");
|
||||
return this.leftId = this.leftId || this.scope.generateUidIdentifier("left");
|
||||
}
|
||||
|
||||
getFunctionId() {
|
||||
return this.functionId ||= this.scope.generateUidIdentifier("function");
|
||||
return this.functionId = this.functionId || this.scope.generateUidIdentifier("function");
|
||||
}
|
||||
|
||||
getAgainId() {
|
||||
return this.againId ||= this.scope.generateUidIdentifier("again");
|
||||
return this.againId = this.againId || this.scope.generateUidIdentifier("again");
|
||||
}
|
||||
|
||||
getParams() {
|
||||
|
||||
@@ -4,7 +4,7 @@ var buildBinaryExpression = function (left, right) {
|
||||
return t.binaryExpression("+", left, right);
|
||||
};
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@ export var metadata = {
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function check() {
|
||||
export function shouldVisit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ export var metadata = {
|
||||
stage: 0
|
||||
};
|
||||
|
||||
export function check() {
|
||||
export function shouldVisit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user