Compare commits
212 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
e080fe547d | ||
|
|
b967ecf063 | ||
|
|
365b7285d2 | ||
|
|
a40d532b0e | ||
|
|
0487bf911d | ||
|
|
57c72d1cd0 | ||
|
|
335bdffec2 | ||
|
|
e1d76a1dfe | ||
|
|
a4845323a2 | ||
|
|
792951b489 | ||
|
|
5adda836af | ||
|
|
4c2c3098c3 | ||
|
|
087c714098 | ||
|
|
5a33e4fe05 | ||
|
|
5f8667eaa7 | ||
|
|
31b4468514 | ||
|
|
2be9678bbe | ||
|
|
b5210877cf | ||
|
|
658dde768e | ||
|
|
8df1d81ca4 | ||
|
|
a505e4a121 | ||
|
|
71eafdcac7 | ||
|
|
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"
|
||||
|
||||
135
CHANGELOG.md
135
CHANGELOG.md
@@ -13,6 +13,141 @@ _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.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**
|
||||
* Add `getIterator` and `isIterable` to `babel-runtime` build script.
|
||||
|
||||
## 5.1.1
|
||||
|
||||
* **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
|
||||
|
||||
13
Makefile
13
Makefile
@@ -9,17 +9,20 @@ 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 +117,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
|
||||
|
||||
12
package.json
12
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel-core",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.1.1",
|
||||
"version": "5.2.4",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"repository": "babel/babel",
|
||||
@@ -28,9 +28,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"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 +47,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 +61,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",
|
||||
|
||||
@@ -8,6 +8,7 @@ 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;
|
||||
@@ -69,7 +70,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.0",
|
||||
"version": "5.2.3",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"repository": "babel/babel",
|
||||
"preferGlobal": true,
|
||||
"dependencies": {
|
||||
"babel-core": "^5.1.0",
|
||||
"babel-core": "^5.2.3",
|
||||
"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.0",
|
||||
"version": "5.2.3",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"dependencies": {
|
||||
"core-js": "^0.8.0"
|
||||
"core-js": "^0.9.0"
|
||||
}
|
||||
}
|
||||
@@ -70,14 +70,14 @@ 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")));
|
||||
|
||||
//
|
||||
|
||||
var coreDefinitions = require("../lib/babel/transformation/transformers/other/runtime/definitions");
|
||||
|
||||
var paths = [];
|
||||
var paths = ["is-iterable", "get-iterator"];
|
||||
|
||||
each(coreDefinitions.builtins, function (path) {
|
||||
paths.push(path);
|
||||
|
||||
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");
|
||||
|
||||
3
src/acorn/index.js
Normal file
3
src/acorn/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./src/index";
|
||||
import "./plugins/flow";
|
||||
import "./plugins/jsx";
|
||||
@@ -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,4 +1,4 @@
|
||||
var acorn = require("..")
|
||||
var acorn = require("../src/index")
|
||||
|
||||
var tt = acorn.tokTypes;
|
||||
var tc = acorn.tokContexts;
|
||||
|
||||
@@ -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 Pipeline } 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;
|
||||
}
|
||||
@@ -54,3 +55,19 @@ export function transformFileSync(filename: string, opts?: Object = {}) {
|
||||
opts.filename = filename;
|
||||
return transform(fs.readFileSync(filename), opts);
|
||||
}
|
||||
|
||||
export function parse(code, opts = {}) {
|
||||
opts.sourceType = "module";
|
||||
opts.ecmaVersion = Infinity;
|
||||
opts.plugins = {
|
||||
flow: true,
|
||||
jsx: true
|
||||
};
|
||||
opts.features = {};
|
||||
|
||||
for (var key in transform.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,7 +78,11 @@ 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 = {};
|
||||
@@ -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,7 +227,7 @@ 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();
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
@@ -16,39 +18,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 +64,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 +78,7 @@ export default class File {
|
||||
"define-property",
|
||||
"async-to-generator",
|
||||
"interop-require-wildcard",
|
||||
"interop-require-default",
|
||||
"typeof",
|
||||
"extends",
|
||||
"get",
|
||||
@@ -82,10 +88,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 +130,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 +202,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 +221,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);
|
||||
|
||||
@@ -216,7 +237,7 @@ export default class File {
|
||||
}
|
||||
|
||||
getModuleFormatter(type: string) {
|
||||
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
|
||||
var ModuleFormatter = isFunction(type) ? type : moduleFormatters[type];
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
var loc = util.resolveRelative(type);
|
||||
@@ -230,57 +251,6 @@ export default class File {
|
||||
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;
|
||||
|
||||
@@ -334,8 +304,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 +315,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 +332,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 +353,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;
|
||||
|
||||
@@ -401,11 +371,11 @@ export default class File {
|
||||
|
||||
var ref = util.template("helper-" + name);
|
||||
ref._compact = true;
|
||||
var uid = this.scope.generateUidIdentifier(name);
|
||||
var uid = this.declarations[name] = this.scope.generateUidIdentifier(name);
|
||||
this.scope.push({
|
||||
key: name,
|
||||
id: uid,
|
||||
init: ref
|
||||
init: ref,
|
||||
unique: true
|
||||
});
|
||||
return uid;
|
||||
}
|
||||
@@ -462,9 +432,12 @@ export default class File {
|
||||
parseOpts.strictMode = features.strict;
|
||||
parseOpts.sourceType = "module";
|
||||
|
||||
this.log.debug("Parse start");
|
||||
|
||||
//
|
||||
|
||||
return parse(parseOpts, code, (tree) => {
|
||||
this.log.debug("Parse stop");
|
||||
this.transform(tree);
|
||||
return this.generate();
|
||||
});
|
||||
@@ -487,25 +460,25 @@ export default class File {
|
||||
}
|
||||
|
||||
transform(ast) {
|
||||
this.log.debug();
|
||||
|
||||
this.log.debug("Start set AST");
|
||||
this.setAst(ast);
|
||||
this.log.debug("End set AST");
|
||||
|
||||
this.lastStatements = t.getLastStatements(ast.program);
|
||||
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.checkNode(ast);
|
||||
this.log.debug("End module formatter init");
|
||||
|
||||
this.call("pre");
|
||||
|
||||
each(this.transformerStack, function (pass) {
|
||||
pass.transform();
|
||||
});
|
||||
|
||||
this.call("post");
|
||||
}
|
||||
|
||||
@@ -518,20 +491,19 @@ export default class File {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
@@ -581,10 +553,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,23 @@
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
"extra": {
|
||||
"hidden": true,
|
||||
"default": {}
|
||||
},
|
||||
|
||||
"moduleId": {
|
||||
"description": "specify a custom name for module ids",
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
"retainLines": {
|
||||
"hidden": true,
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "retain line numbers - will result in really ugly code"
|
||||
},
|
||||
|
||||
"nonStandard": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
@@ -152,7 +164,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 +213,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.addDeprecated(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;
|
||||
|
||||
@@ -49,11 +49,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 +124,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 +166,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: []
|
||||
};
|
||||
|
||||
@@ -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,6 +107,7 @@ export default class AMDFormatter extends DefaultFormatter {
|
||||
|
||||
exportSpecifier(specifier, node, nodes) {
|
||||
if (this.doDefaultExportInterop(specifier)) {
|
||||
this.passModuleArg = true;
|
||||
nodes.push(util.template("exports-default-assign", {
|
||||
VALUE: specifier.local
|
||||
}, true));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
100
src/babel/transformation/transformer-pipeline.js
Normal file
100
src/babel/transformation/transformer-pipeline.js
Normal file
@@ -0,0 +1,100 @@
|
||||
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.parse(code);
|
||||
}
|
||||
|
||||
transformFromAst(ast, code, opts) {
|
||||
ast = normalizeAst(ast);
|
||||
|
||||
var file = new File(opts, this);
|
||||
file.addCode(code);
|
||||
file.transform(ast);
|
||||
return file.generate();
|
||||
}
|
||||
|
||||
_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(`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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -228,7 +245,7 @@ class ClassTransformer {
|
||||
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 +309,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);
|
||||
@@ -326,7 +347,7 @@ class ClassTransformer {
|
||||
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));
|
||||
}
|
||||
@@ -529,34 +550,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,6 +605,10 @@ class ClassTransformer {
|
||||
fnPath.scope.rename(this.classRef.name);
|
||||
}
|
||||
|
||||
if (this.isNativeSuper) {
|
||||
fnPath.traverse(constructorVisitor, this.nativeSuperRef);
|
||||
}
|
||||
|
||||
var construct = this.constructor;
|
||||
var fn = method.value;
|
||||
|
||||
|
||||
@@ -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);
|
||||
return node;
|
||||
};
|
||||
|
||||
export function CatchClause(node, parent, scope, file) {
|
||||
@@ -111,7 +111,7 @@ 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);
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
@@ -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,7 +96,7 @@ exports.Function = function (node, parent, scope, file) {
|
||||
candidate.replaceWith(argsId);
|
||||
optimizeMemberExpression(candidate.parent, node.params.length);
|
||||
}
|
||||
return;
|
||||
return node;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -138,4 +137,5 @@ exports.Function = function (node, parent, scope, file) {
|
||||
});
|
||||
loop._blockHoist = node.params.length + 1;
|
||||
node.body.body.unshift(loop);
|
||||
return node;
|
||||
};
|
||||
|
||||
@@ -84,7 +84,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,13 @@ 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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
@@ -100,23 +101,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;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import memoiseDecorators from "../../helpers/memoise-decorators";
|
||||
import * as defineMap from "../../helpers/define-map";
|
||||
import * as t from "../../../types";
|
||||
|
||||
@@ -6,7 +7,7 @@ export var metadata = {
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return !!node.decorators;
|
||||
}
|
||||
|
||||
@@ -24,7 +25,18 @@ export function ObjectExpression(node, parent, scope, file) {
|
||||
var mutatorMap = {};
|
||||
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
defineMap.push(mutatorMap, node.properties[i], null, file);
|
||||
var prop = node.properties[i];
|
||||
if (prop.decorators) memoiseDecorators(prop.decorators, scope);
|
||||
|
||||
|
||||
if (prop.kind === "init") {
|
||||
prop.kind = "";
|
||||
prop.value = t.functionExpression(null, [], t.blockStatement([
|
||||
t.returnStatement(prop.value)
|
||||
]));
|
||||
}
|
||||
|
||||
defineMap.push(mutatorMap, prop, "initializer", file);
|
||||
}
|
||||
|
||||
var obj = defineMap.toClassObject(mutatorMap);
|
||||
|
||||
@@ -5,7 +5,7 @@ export var metadata = {
|
||||
stage: 0
|
||||
};
|
||||
|
||||
export var check = t.isDoExpression;
|
||||
export var shouldVisit = t.isDoExpression;
|
||||
|
||||
export function DoExpression(node) {
|
||||
var body = node.body.body;
|
||||
|
||||
@@ -6,7 +6,7 @@ export var metadata = {
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function check(node) {
|
||||
export function shouldVisit(node) {
|
||||
return t.isExportDefaultSpecifier(node) || t.isExportNamespaceSpecifier(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,6 @@ export var metadata = {
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function check() {
|
||||
export function shouldVisit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
24
src/babel/transformation/transformers/filters.js
Normal file
24
src/babel/transformation/transformers/filters.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import includes from "lodash/collection/includes";
|
||||
|
||||
export function internal(transformer, opts) {
|
||||
if (transformer.key[0] === "_") return true;
|
||||
}
|
||||
|
||||
export function blacklist(transformer, opts) {
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && includes(blacklist, transformer.key)) return false;
|
||||
}
|
||||
|
||||
export function whitelist(transformer, opts) {
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist) return includes(whitelist, transformer.key);
|
||||
}
|
||||
|
||||
export function stage(transformer, opts) {
|
||||
var stage = transformer.metadata.stage;
|
||||
if (stage != null && stage >= opts.stage) return true;
|
||||
}
|
||||
|
||||
export function optional(transformer, opts) {
|
||||
if (transformer.metadata.optional && !includes(opts.optional, transformer.key)) return false;
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
export default {
|
||||
_modules: require("./internal/modules"),
|
||||
|
||||
"es7.classProperties": require("./es7/class-properties"),
|
||||
"es7.trailingFunctionCommas": require("./es7/trailing-function-commas"),
|
||||
"es7.asyncFunctions": require("./es7/async-functions"),
|
||||
@@ -24,8 +26,6 @@ export default {
|
||||
reactCompat: require("./other/react-compat"),
|
||||
react: require("./other/react"),
|
||||
|
||||
_modules: require("./internal/modules"),
|
||||
|
||||
// needs to be before `regenerator` due to generator comprehensions
|
||||
// needs to be before `_shadowFunctions`
|
||||
"es7.comprehensions": require("./es7/comprehensions"),
|
||||
@@ -94,8 +94,6 @@ export default {
|
||||
|
||||
"spec.protoToAssign": require("./spec/proto-to-assign"),
|
||||
|
||||
_declarations: require("./internal/declarations"),
|
||||
|
||||
_shadowFunctions: require("./internal/shadow-functions"),
|
||||
|
||||
"es7.doExpressions": require("./es7/do-expressions"),
|
||||
@@ -117,6 +115,6 @@ export default {
|
||||
"utility.inlineExpressions": require("./utility/inline-expressions"),
|
||||
"utility.deadCodeElimination": require("./utility/dead-code-elimination"),
|
||||
|
||||
flow: require("./other/flow"),
|
||||
_cleanUp: require("./internal/cleanup")
|
||||
jscript: require("./other/jscript"),
|
||||
flow: require("./other/flow")
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user