Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51dff364db | ||
|
|
dc6129eb6a | ||
|
|
5b84b9c867 | ||
|
|
04c3027f4d | ||
|
|
95e2345b19 | ||
|
|
eafb02be31 | ||
|
|
b91997354c | ||
|
|
4b8039a00c | ||
|
|
0a0931dc2e | ||
|
|
372c06eb80 | ||
|
|
b8121ed4d0 | ||
|
|
1f79445ee5 | ||
|
|
cb46ca60af | ||
|
|
24c0c7679f | ||
|
|
d7ec337567 | ||
|
|
845f1ce65e | ||
|
|
88563a0c26 | ||
|
|
ccd7a6560c | ||
|
|
c340597fdb | ||
|
|
e498358125 | ||
|
|
25232d3141 | ||
|
|
5b9878451a | ||
|
|
23d6fb6bb1 | ||
|
|
8d1b5c8ccb | ||
|
|
10bd7d1b91 | ||
|
|
f5d9636353 | ||
|
|
a7f713ef5a | ||
|
|
ba11069b1c | ||
|
|
c13f8a3f50 | ||
|
|
339bd2b6d9 | ||
|
|
a2843a5cb8 | ||
|
|
c31832439a | ||
|
|
b7f19221a9 | ||
|
|
46a37f4672 | ||
|
|
cfe2c19a02 | ||
|
|
649d91ef25 | ||
|
|
4d72bffa30 | ||
|
|
5889233adc | ||
|
|
7bb98352df | ||
|
|
12ebeed7c6 | ||
|
|
7d87e52377 | ||
|
|
2bab285970 | ||
|
|
00651e671e | ||
|
|
37588a6ceb | ||
|
|
a45d6960da | ||
|
|
b13aa41a75 | ||
|
|
20a4ed6140 | ||
|
|
c256e060b3 | ||
|
|
bef315efd6 | ||
|
|
2ec5390b63 | ||
|
|
f4c9dd8768 | ||
|
|
510c7a3e60 | ||
|
|
3ce9508a1c | ||
|
|
717ef280f7 | ||
|
|
8c5e7cf272 | ||
|
|
811a843be9 | ||
|
|
b7c297bb89 | ||
|
|
b7342ef4ea | ||
|
|
1a899f5e77 | ||
|
|
f2eb1643c0 | ||
|
|
9621d1bbeb | ||
|
|
3cf7b2b761 | ||
|
|
ae8b1e242b | ||
|
|
eea48f866d | ||
|
|
84d2d7b7d4 | ||
|
|
ea30a619dd | ||
|
|
87a201db22 | ||
|
|
bcc86c47bc | ||
|
|
b6df9b583b | ||
|
|
52ea7b5f59 | ||
|
|
7bff8239a1 | ||
|
|
04d79c1740 | ||
|
|
e387da7c2b | ||
|
|
53cf453480 | ||
|
|
341528ee4a | ||
|
|
5f6808ba92 | ||
|
|
0b2f1fedcb | ||
|
|
c3c94f0a4a | ||
|
|
f2d60aab9e | ||
|
|
ab6bb35a4f | ||
|
|
e11b943514 | ||
|
|
b44a6eb297 | ||
|
|
f3288ddb1f | ||
|
|
476aa44a90 | ||
|
|
c5589e9336 | ||
|
|
404eb2f972 | ||
|
|
366257915e | ||
|
|
e0cd9bdbe3 | ||
|
|
39854dc088 | ||
|
|
81132aa942 | ||
|
|
5ba2e6254b | ||
|
|
61ea720637 | ||
|
|
55357a331d | ||
|
|
5deaeba3a0 | ||
|
|
a38ae381e2 | ||
|
|
9a2e56f003 | ||
|
|
5bc78b0237 | ||
|
|
c5af8b8694 | ||
|
|
c637575cab | ||
|
|
bc8d49c95c | ||
|
|
59ff0fd9a9 | ||
|
|
b1f794eb84 | ||
|
|
79ab92b5d4 | ||
|
|
f6512b45d5 | ||
|
|
8065c981dc | ||
|
|
7927aa2e18 | ||
|
|
35bd510930 | ||
|
|
74186241f9 | ||
|
|
1effa72a33 | ||
|
|
b03a806d7c | ||
|
|
6220fd9fc3 | ||
|
|
8d92a75190 | ||
|
|
60a7e40140 | ||
|
|
299e462a29 | ||
|
|
62556f6102 | ||
|
|
f2c5accab3 | ||
|
|
15f1978cae | ||
|
|
710ff548cb | ||
|
|
fbb19fc656 | ||
|
|
e87ef80bc5 | ||
|
|
aca750e881 | ||
|
|
672e55082c | ||
|
|
a49f746700 | ||
|
|
83cd3bef92 | ||
|
|
5e4a008a06 | ||
|
|
1594efbc20 | ||
|
|
002be9a05c | ||
|
|
8e06db8f7d | ||
|
|
b1238a1746 | ||
|
|
0874f390ff | ||
|
|
eeff4ac9d1 | ||
|
|
8f0ffc7302 | ||
|
|
bb19649af8 | ||
|
|
692262df1b | ||
|
|
067047da34 | ||
|
|
1c5d169b1e | ||
|
|
3f82b4ec72 | ||
|
|
9c6e632021 | ||
|
|
45553f1fb7 | ||
|
|
f228edbb84 | ||
|
|
64e657e53d | ||
|
|
17e65cc772 |
3
.babelrc
3
.babelrc
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"experimental": true,
|
||||
"playground": true,
|
||||
"loose": true
|
||||
"loose": true,
|
||||
"blacklist": ["es6.tailCall"]
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
|
||||
[*.{js,json}]
|
||||
indent_style = space
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,3 +13,4 @@ dist
|
||||
.package.json
|
||||
packages/babel-runtime/*.js
|
||||
packages/babel-runtime/regenerator/*.js
|
||||
lib
|
||||
|
||||
58
.jscsrc
58
.jscsrc
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"excludeFiles": ["lib/babel/transformation/templates"],
|
||||
"disallowSpacesInNamedFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"requireSpacesInAnonymousFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"requireSpacesInAnonymousFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInFunctionDeclaration": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInsideArrayBrackets": true,
|
||||
"disallowSpacesInsideParentheses": true,
|
||||
"disallowSpaceAfterObjectKeys": true,
|
||||
"disallowSpaceAfterPrefixUnaryOperators": true,
|
||||
"disallowSpaceBeforePostfixUnaryOperators": true,
|
||||
"disallowSpaceBeforeBinaryOperators": [
|
||||
","
|
||||
],
|
||||
"disallowMixedSpacesAndTabs": true,
|
||||
"disallowTrailingWhitespace": true,
|
||||
"disallowYodaConditions": true,
|
||||
"disallowKeywords": [ "with" ],
|
||||
"disallowMultipleLineBreaks": true,
|
||||
"requireSpaceBeforeBlockStatements": true,
|
||||
"requireParenthesesAroundIIFE": true,
|
||||
"requireSpacesInConditionalExpression": true,
|
||||
"requireBlocksOnNewline": 1,
|
||||
"requireCommaBeforeLineBreak": true,
|
||||
"requireSpaceBeforeBinaryOperators": true,
|
||||
"requireSpaceAfterBinaryOperators": true,
|
||||
"requireLineFeedAtFileEnd": true,
|
||||
"requireCapitalizedConstructors": true,
|
||||
"requireSpacesInForStatement": true,
|
||||
"requireCurlyBraces": [
|
||||
"do"
|
||||
],
|
||||
"requireSpaceAfterKeywords": [
|
||||
"if",
|
||||
"else",
|
||||
"for",
|
||||
"while",
|
||||
"do",
|
||||
"switch",
|
||||
"case",
|
||||
"return",
|
||||
"try",
|
||||
"catch",
|
||||
"typeof",
|
||||
"function"
|
||||
],
|
||||
"validateLineBreaks": "LF",
|
||||
"validateQuoteMarks": "\"",
|
||||
"validateIndentation": 2
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
lib/babel/transformation/templates
|
||||
27
.jshintrc
27
.jshintrc
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"esnext": true,
|
||||
"indent": 2,
|
||||
"freeze": true,
|
||||
"validthis": true,
|
||||
"camelcase": true,
|
||||
"unused": true,
|
||||
"eqnull": true,
|
||||
"newcap": true,
|
||||
"supernew": true,
|
||||
"noyield": true,
|
||||
"evil": true,
|
||||
"node": true,
|
||||
"boss": true,
|
||||
"expr": true,
|
||||
"undef": true,
|
||||
"maxparams": 5,
|
||||
"maxdepth": 4,
|
||||
|
||||
"globals": {
|
||||
"window": true,
|
||||
"suite": true,
|
||||
"set": true,
|
||||
"before": true,
|
||||
"bench": true
|
||||
}
|
||||
}
|
||||
@@ -13,3 +13,4 @@ CHANGELOG.md
|
||||
coverage
|
||||
vendor
|
||||
packages
|
||||
src
|
||||
|
||||
94
CHANGELOG.md
94
CHANGELOG.md
@@ -13,6 +13,100 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 4.5.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix whitelisting logic for helper build script.
|
||||
|
||||
## 4.5.2
|
||||
|
||||
* **New Feature**
|
||||
* `returnUsedHelpers` option and add whitelist to `buildHelpers`.
|
||||
* **Bug Fix**
|
||||
* Fix function arity on self referencing inferred named functions.
|
||||
* **Internal**
|
||||
* Bump `acorn-babel`.
|
||||
* Start converting source to ES6...
|
||||
|
||||
## 4.5.1
|
||||
|
||||
**Babel now compiles itself!**
|
||||
|
||||

|
||||
|
||||
## 4.5.0
|
||||
|
||||
* **New Feature**
|
||||
* Add `.babelrc` support.
|
||||
* **Bug Fix**
|
||||
* Move use strict directives to the module formatter bodies.
|
||||
* **Internal**
|
||||
* Make default `bin/babel` behaviour to ignore non-compilable files and add a `--copy-files` flag to revert to the old behaviour.
|
||||
|
||||
## 4.4.6
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix extending a class expression with no methods/only constructor. Thanks [@neVERberleRfellerER](https://github.com/neVERberleRfellerER)!
|
||||
* Allow `MemberExpression` as a valid `left` of `ForOfStatement`.
|
||||
* **Polish**
|
||||
* Throw an error when people try and transpile code with the `@jsx React.DOM` pragma as it conflicts with the custom jsx constructo method detection.
|
||||
* Crawl all comments for `@jsx` pragma.
|
||||
* **Internal**
|
||||
* Upgrade `chalk`.
|
||||
* Upgrade `core-js`.
|
||||
|
||||
## 4.4.5
|
||||
|
||||
* **Internal**
|
||||
* Remove function self reference optimisation.
|
||||
|
||||
## 4.4.4
|
||||
|
||||
* **Bug Fix**
|
||||
* Handle inferred function ids to be reassigned and deopt to a slower but working equivalent.
|
||||
* Don't unpack array patterns that have more elements than their right hand array expression.
|
||||
* **Polish**
|
||||
* Improve syntax highlighting in the code frame. Thanks [@lydell](https://github.com/lydell)!
|
||||
* **Internal**
|
||||
* Upgrade `acorn-babel`.
|
||||
|
||||
## 4.4.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `for...of` iterator break returns being duplicated.
|
||||
* Only call `return` on the iterator if it exists.
|
||||
* **Internal**
|
||||
* Rename `selfContained` transformer to `runtime`.
|
||||
|
||||
## 4.4.2
|
||||
|
||||
* **New Feature**
|
||||
* Add `moduleId` option for specifying a custom module id.
|
||||
|
||||
## 4.4.0
|
||||
|
||||
* **New Feature**
|
||||
* `/*** @jsx NAMESPACE **/` comments are now honored by the `react` transformer.
|
||||
* `getModuleName` option.
|
||||
* Infer function expression names. Thanks [@RReverser](https://github.com/RReverser)!
|
||||
* **Bug Fix**
|
||||
* Add proper control flow for tail recursion optimisation.
|
||||
* **Internal**
|
||||
* Remove useless `format` options and move the `format.compact` option to `format`.
|
||||
* **Polish**
|
||||
* Newline handling of the code generator has been heavily improved.
|
||||
* Code generator now deopts whitespace if the input size is >100KB.
|
||||
|
||||
## 4.3.0
|
||||
|
||||
* **Breaking Change**
|
||||
* Remove `commonStandard` module formatter and make it the default behaviour of all the strict module formatters.
|
||||
|
||||
## 4.2.1
|
||||
|
||||
* **Polish**
|
||||
* Add auxiliary comment to let scoping closure flow control.
|
||||
|
||||
## 4.2.0
|
||||
|
||||
* **Polish**
|
||||
|
||||
@@ -10,6 +10,49 @@ pollutes the git tree.
|
||||
|
||||
## Developing
|
||||
|
||||
#### Setup
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/babel/babel
|
||||
$ cd babel
|
||||
$ make bootstrap
|
||||
```
|
||||
|
||||
Then you need to run:
|
||||
|
||||
```sh
|
||||
$ make watch-core
|
||||
```
|
||||
|
||||
This will compile babel and then sit in the background and on file modification
|
||||
recompile the necessary files.
|
||||
|
||||
#### Running tests
|
||||
|
||||
You can run tests via:
|
||||
|
||||
```sh
|
||||
$ make test
|
||||
```
|
||||
|
||||
This will usually take around two minutes as it's compiling the entire
|
||||
[test262](https://github.com/tc39/test262) test suite and validating it's AST.
|
||||
This is mostly overkill and you can limit the tests to a select few by directly
|
||||
running them with `mocha`:
|
||||
|
||||
```sh
|
||||
$ mocha test/transformation.js
|
||||
```
|
||||
|
||||
#### Linting
|
||||
|
||||
Please follow the correct code style, this ensures that the code is consistent
|
||||
and increases maintainability.
|
||||
|
||||
```sh
|
||||
$ make lint
|
||||
```
|
||||
|
||||
#### Workflow
|
||||
|
||||
* Fork the repository
|
||||
@@ -18,8 +61,7 @@ pollutes the git tree.
|
||||
* Link your forked clone (`npm link`)
|
||||
* Develop your changes ensuring you're fetching updates from upstream often
|
||||
* Ensure the test are passing (`make test`)
|
||||
* Create new pull request explaining your proposed change or reference an issue
|
||||
in your commit message
|
||||
* Create new pull request explaining your proposed change or reference an issue in your commit message
|
||||
|
||||
#### Code Standards
|
||||
|
||||
@@ -43,11 +85,3 @@ pollutes the git tree.
|
||||
* **Declaration**
|
||||
* No unused variables
|
||||
* No pollution of global variables and prototypes
|
||||
|
||||
## Testing
|
||||
|
||||
$ make test
|
||||
|
||||
## Linting
|
||||
|
||||
$ make lint
|
||||
|
||||
20
Makefile
20
Makefile
@@ -4,21 +4,21 @@ UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs
|
||||
#UGLIFY_CMD = node_modules/uglify-js/bin/uglifyjs --mangle sort
|
||||
JSHINT_CMD = node_modules/jshint/bin/jshint
|
||||
MOCHA_CMD = node_modules/mocha/bin/_mocha
|
||||
JSCS_CMD = node_modules/jscs/bin/jscs
|
||||
BABEL_CMD = node_modules/babel/bin/babel
|
||||
|
||||
export NODE_ENV = test
|
||||
|
||||
.PHONY: clean test test-cov test-clean lint test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime build-core watch-core
|
||||
.PHONY: clean test test-cov test-clean test-travis test-simple test-all test-browser publish build bootstrap publish-core publish-runtime build-core watch-core
|
||||
|
||||
build-core:
|
||||
#node $(BABEL_CMD) src --out-dir lib
|
||||
node $(BABEL_CMD) src --out-dir lib --copy-files
|
||||
|
||||
watch-core:
|
||||
#node $(BABEL_CMD) src --out-dir lib --watch
|
||||
node $(BABEL_CMD) src --out-dir lib --watch --copy-files
|
||||
|
||||
build:
|
||||
mkdir -p dist
|
||||
make build-core
|
||||
|
||||
node tools/cache-templates
|
||||
|
||||
@@ -36,14 +36,10 @@ build:
|
||||
clean:
|
||||
rm -rf coverage templates.json test/tmp dist
|
||||
|
||||
lint:
|
||||
$(JSHINT_CMD) --reporter node_modules/jshint-stylish/stylish.js lib bin
|
||||
$(JSCS_CMD) lib bin
|
||||
|
||||
test-clean:
|
||||
rm -rf test/tmp
|
||||
|
||||
test: lint
|
||||
test:
|
||||
$(MOCHA_CMD)
|
||||
make test-clean
|
||||
|
||||
@@ -61,7 +57,7 @@ test-cov:
|
||||
export SIMPLE_BABEL_TESTS=1; \
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
|
||||
|
||||
test-travis: build-core bootstrap
|
||||
test-travis: bootstrap build
|
||||
node $(ISTANBUL_CMD) $(MOCHA_CMD) --
|
||||
if test -n "$$CODECLIMATE_REPO_TOKEN"; then codeclimate < coverage/lcov.info; fi
|
||||
|
||||
@@ -119,5 +115,5 @@ publish-core:
|
||||
bootstrap:
|
||||
npm install
|
||||
git submodule update --init
|
||||
cd vendor/regenerator; npm install
|
||||
cd vendor/compat-table; npm install object-assign
|
||||
cd vendor/regenerator && npm install
|
||||
cd vendor/compat-table && npm install object-assign
|
||||
|
||||
11
README.md
11
README.md
@@ -1,5 +1,7 @@
|
||||
<p align="center">
|
||||
<img alt="babel" src="https://raw.githubusercontent.com/babel/logo/master/logo.png" width="546">
|
||||
<a href="https://babeljs.io/">
|
||||
<img alt="babel" src="https://raw.githubusercontent.com/babel/logo/master/logo.png" width="546">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -7,6 +9,9 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
For more information view the <a href="https://babeljs.io/">documentation</a>. For
|
||||
support visit the <a href="https://gitter.im/babel/babel">gitter room</a>.
|
||||
For questions and support please visit the <a href="https://gitter.im/babel/babel">gitter room</a> before creating an issue.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
For documentation and website issues please visit the <a href="https://github.com/babel/babel.github.io">babel.github.io</a> repo.
|
||||
</p>
|
||||
|
||||
@@ -50,7 +50,10 @@ var _eval = function (code, filename) {
|
||||
experimental: program.experimental,
|
||||
playground: program.playground
|
||||
}).code;
|
||||
return vm.runInThisContext(code, filename);
|
||||
|
||||
return vm.runInThisContext(code, {
|
||||
filename: filename
|
||||
});
|
||||
};
|
||||
|
||||
if (program.eval || program.print) {
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var opts = require("./babel").opts;
|
||||
opts.optional = (opts.optional || []).concat("minification");
|
||||
opts.format = {
|
||||
compact: true
|
||||
};
|
||||
@@ -43,7 +43,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
var src = path.join(dirname, filename);
|
||||
if (util.canCompile(filename)) {
|
||||
write(src, filename);
|
||||
} else {
|
||||
} else if (commander.copyFiles) {
|
||||
outputFileSync(path.join(commander.outDir, filename), fs.readFileSync(src));
|
||||
}
|
||||
});
|
||||
@@ -64,7 +64,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
_.each(["add", "change"], function (type) {
|
||||
watcher.on(type, function (filename) {
|
||||
var relative = path.relative(dirname, filename) || filename;
|
||||
write(filename, relative);
|
||||
if (util.canCompile(filename)) write(filename, relative);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,6 +15,7 @@ commander.option("-r, --external-helpers", "Replace helpers with references to a
|
||||
commander.option("-e, --experimental", "Enable experimental support for proposed ES7 features");
|
||||
commander.option("-p, --playground", "Enable playground support");
|
||||
|
||||
commander.option("-c, --compact [mode]", "When set to \"auto\" compact is `true` when the input size exceeds 100KB. (auto|true|false)", "auto");
|
||||
commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common");
|
||||
commander.option("-l, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
|
||||
commander.option("-b, --blacklist [blacklist]", "Blacklist of transformers to NOT use", util.list);
|
||||
@@ -27,6 +28,7 @@ commander.option("-M, --module-ids", "Insert module id in modules", false);
|
||||
commander.option("-R, --react-compat", "Makes the react transformer produce pre-v0.12 code");
|
||||
commander.option("--keep-module-id-extensions", "Keep extensions when generating module ids", false);
|
||||
commander.option("-a, --auxiliary-comment [comment]", "Comment text to prepend to all auxiliary code");
|
||||
commander.option("-D, --copy-files", "When compiling a directory copy over non-compilable files");
|
||||
|
||||
commander.on("--help", function () {
|
||||
var outKeys = function (title, obj) {
|
||||
@@ -113,20 +115,16 @@ exports.opts = {
|
||||
optional: commander.optional,
|
||||
comments: !commander.removeComments,
|
||||
modules: commander.modules,
|
||||
compact: commander.compact,
|
||||
loose: commander.loose
|
||||
};
|
||||
|
||||
setTimeout(function () {
|
||||
// this is just a hack to give `babel-minify` and other files including this
|
||||
// time to modify `exports.opts`
|
||||
var fn;
|
||||
|
||||
var fn;
|
||||
if (commander.outDir) {
|
||||
fn = require("./dir");
|
||||
} else {
|
||||
fn = require("./file");
|
||||
}
|
||||
|
||||
if (commander.outDir) {
|
||||
fn = require("./dir");
|
||||
} else {
|
||||
fn = require("./file");
|
||||
}
|
||||
|
||||
fn(commander, filenames, exports.opts);
|
||||
}, 0);
|
||||
fn(commander, filenames, exports.opts);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
var readdir = require("fs-readdir-recursive");
|
||||
var index = require("./index");
|
||||
var babel = require("../../lib/babel/api/node");
|
||||
var util = require("../../lib/babel/util");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
var resolveRc = require("../../lib/babel/api/register/resolve-rc");
|
||||
var readdir = require("fs-readdir-recursive");
|
||||
var index = require("./index");
|
||||
var babel = require("../../lib/babel/api/node");
|
||||
var util = require("../../lib/babel/util");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
var _ = require("lodash");
|
||||
|
||||
exports.readdirFilter = function (filename) {
|
||||
return readdir(filename).filter(function (filename) {
|
||||
@@ -23,6 +24,7 @@ exports.addSourceMappingUrl = function (code, loc) {
|
||||
exports.transform = function (filename, code, opts) {
|
||||
opts = _.defaults(opts || {}, index.opts);
|
||||
opts.filename = filename;
|
||||
resolveRc(filename, opts);
|
||||
|
||||
var result;
|
||||
try {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
console.error("`6to5-minify` has been renamed to `babel-minify`");
|
||||
require("../babel-minify");
|
||||
@@ -1 +0,0 @@
|
||||
See [babel.github.io/docs](https://github.com/babel/babel.github.io/tree/master/docs).
|
||||
@@ -1,84 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var each = require("lodash/collection/each");
|
||||
var map = require("lodash/collection/map");
|
||||
var isNumber = require("lodash/lang/isNumber");
|
||||
|
||||
exports.before = {
|
||||
nodes: {
|
||||
Property: function (node, parent) {
|
||||
if (parent.properties[0] === node) {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
||||
SpreadProperty: function (node, parent) {
|
||||
return exports.before.nodes.Property(node, parent);
|
||||
},
|
||||
|
||||
SwitchCase: function (node, parent) {
|
||||
if (parent.cases[0] === node) {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
||||
CallExpression: function (node) {
|
||||
if (t.isFunction(node.callee)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.after = {
|
||||
nodes: {
|
||||
LogicalExpression: function (node) {
|
||||
return t.isFunction(node.left) || t.isFunction(node.right);
|
||||
},
|
||||
|
||||
AssignmentExpression: function (node) {
|
||||
if (t.isFunction(node.right)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
list: {
|
||||
VariableDeclaration: function (node) {
|
||||
return map(node.declarations, "init");
|
||||
},
|
||||
|
||||
ArrayExpression: function (node) {
|
||||
return node.elements;
|
||||
},
|
||||
|
||||
ObjectExpression: function (node) {
|
||||
return node.properties;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
each({
|
||||
Function: 1,
|
||||
Class: 1,
|
||||
For: 1,
|
||||
ArrayExpression: { after: 1 },
|
||||
ObjectExpression: { after: 1 },
|
||||
SwitchStatement: 1,
|
||||
IfStatement: { before: 1 },
|
||||
CallExpression: { after: 1 },
|
||||
Literal: { after: 1 }
|
||||
}, function (amounts, type) {
|
||||
if (isNumber(amounts)) {
|
||||
amounts = { after: amounts, before: amounts };
|
||||
}
|
||||
|
||||
each([type].concat(t.FLIPPED_ALIAS_KEYS[type] || []), function (type) {
|
||||
each(amounts, function (amount, key) {
|
||||
exports[key].nodes[type] = function () {
|
||||
return amount;
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,78 +0,0 @@
|
||||
// syntax highlighting based on https://github.com/dominictarr/ansi-highlight by the fantastic Dominic Tarr
|
||||
|
||||
var repeating = require("repeating");
|
||||
var tokenize = require("js-tokenizer");
|
||||
var chalk = require("chalk");
|
||||
|
||||
var defs = {
|
||||
string1: "red",
|
||||
string2: "red",
|
||||
punct: ["white", "bold"],
|
||||
curly: "green",
|
||||
parens: ["blue", "bold"],
|
||||
square: ["yellow"],
|
||||
name: "white",
|
||||
keyword: ["cyan"],
|
||||
number: "magenta",
|
||||
regexp: "magenta",
|
||||
comment1: "grey",
|
||||
comment2: "grey"
|
||||
};
|
||||
|
||||
var highlight = function (text) {
|
||||
var colorize = function (str, col) {
|
||||
if (!col) return str;
|
||||
|
||||
if (Array.isArray(col)) {
|
||||
col.forEach(function (col) {
|
||||
str = chalk[col](str);
|
||||
});
|
||||
} else {
|
||||
str = chalk[col](str);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
return tokenize(text, true).map(function (str) {
|
||||
var type = tokenize.type(str);
|
||||
return colorize(str, defs[type]);
|
||||
}).join("");
|
||||
};
|
||||
|
||||
module.exports = function (lines, lineNumber, colNumber) {
|
||||
colNumber = Math.max(colNumber, 0);
|
||||
|
||||
if (chalk.supportsColor) {
|
||||
lines = highlight(lines);
|
||||
}
|
||||
|
||||
lines = lines.split(/\r\n|[\n\r\u2028\u2029]/);
|
||||
|
||||
var start = Math.max(lineNumber - 3, 0);
|
||||
var end = Math.min(lines.length, lineNumber + 3);
|
||||
var width = (end + "").length;
|
||||
|
||||
if (!lineNumber && !colNumber) {
|
||||
start = 0;
|
||||
end = lines.length;
|
||||
}
|
||||
|
||||
return "\n" + lines.slice(start, end).map(function (line, i) {
|
||||
var curr = i + start + 1;
|
||||
|
||||
var gutter = curr === lineNumber ? "> " : " ";
|
||||
|
||||
var sep = curr + repeating(" ", width + 1);
|
||||
gutter += sep + "| ";
|
||||
|
||||
var str = gutter + line;
|
||||
|
||||
if (colNumber && curr === lineNumber) {
|
||||
str += "\n";
|
||||
str += repeating(" ", gutter.length - 2);
|
||||
str += "|" + repeating(" ", colNumber) + "^";
|
||||
}
|
||||
|
||||
return str;
|
||||
}).join("\n");
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
// check if this node is an identifier that matches the same as our function id
|
||||
if (!t.isIdentifier(node, { name: state.id })) return;
|
||||
|
||||
// check if this node is the one referenced
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
|
||||
// check that we don't have a local variable declared as that removes the need
|
||||
// for the wrapper
|
||||
var localDeclar = scope.getBindingIdentifier(state.id);
|
||||
if (localDeclar !== state.outerDeclar) return;
|
||||
|
||||
state.selfReference = true;
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
exports.property = function (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
|
||||
|
||||
var id = t.toIdentifier(key.value);
|
||||
key = t.identifier(id);
|
||||
|
||||
var state = {
|
||||
id: id,
|
||||
selfReference: false,
|
||||
outerDeclar: scope.getBindingIdentifier(id),
|
||||
};
|
||||
|
||||
scope.traverse(node, visitor, state);
|
||||
|
||||
var method = node.value;
|
||||
|
||||
if (state.selfReference) {
|
||||
var templateName = "property-method-assignment-wrapper";
|
||||
if (method.generator) templateName += "-generator";
|
||||
node.value = util.template(templateName, {
|
||||
FUNCTION: method,
|
||||
FUNCTION_ID: key,
|
||||
FUNCTION_KEY: scope.generateUidIdentifier(id),
|
||||
WRAPPER_KEY: scope.generateUidIdentifier(id + "Wrapper")
|
||||
});
|
||||
} else {
|
||||
method.id = key;
|
||||
}
|
||||
};
|
||||
@@ -1,13 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = CommonStandardFormatter;
|
||||
|
||||
var CommonStrictFormatter = require("./common-strict");
|
||||
var util = require("../../util");
|
||||
|
||||
function CommonStandardFormatter() {
|
||||
this.noInteropRequireImport = true;
|
||||
CommonStrictFormatter.apply(this, arguments);
|
||||
}
|
||||
|
||||
util.inherits(CommonStandardFormatter, CommonStrictFormatter);
|
||||
@@ -1,11 +0,0 @@
|
||||
module.exports = {
|
||||
commonStandard: require("./common-standard"),
|
||||
commonStrict: require("./common-strict"),
|
||||
amdStrict: require("./amd-strict"),
|
||||
umdStrict: require("./umd-strict"),
|
||||
common: require("./common"),
|
||||
system: require("./system"),
|
||||
ignore: require("./ignore"),
|
||||
amd: require("./amd"),
|
||||
umd: require("./umd")
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"blacklist": ["useStrict"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
FUNCTION_ID:while (true) BLOCK
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
(function () {
|
||||
function Tail(func, args, context) {
|
||||
this.func = func;
|
||||
this.args = args;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
Tail.prototype._isTailDescriptor = true;
|
||||
|
||||
var isRunning = false;
|
||||
|
||||
return function (func, args, context) {
|
||||
var result = new Tail(func, args, context);
|
||||
if (!isRunning) {
|
||||
isRunning = true;
|
||||
do {
|
||||
result = result.func.apply(result.context, result.args);
|
||||
} while (result instanceof Tail || (result && result._isTailDescriptor));
|
||||
isRunning = false;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})()
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1,559 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var traverse = require("../../../traversal");
|
||||
var object = require("../../../helpers/object");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
var values = require("lodash/object/values");
|
||||
var extend = require("lodash/object/extend");
|
||||
|
||||
exports.check = function (node) {
|
||||
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
|
||||
};
|
||||
|
||||
var isLet = function (node, parent) {
|
||||
if (!t.isVariableDeclaration(node)) return false;
|
||||
if (node._let) return true;
|
||||
if (node.kind !== "let") return false;
|
||||
|
||||
// https://github.com/babel/babel/issues/255
|
||||
if (isLetInitable(node, parent)) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var declar = node.declarations[i];
|
||||
declar.init = declar.init || t.identifier("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
node._let = true;
|
||||
node.kind = "var";
|
||||
return true;
|
||||
};
|
||||
|
||||
var isLetInitable = function (node, parent) {
|
||||
return !t.isFor(parent) || t.isFor(parent) && parent.left !== node;
|
||||
};
|
||||
|
||||
var isVar = function (node, parent) {
|
||||
return t.isVariableDeclaration(node, { kind: "var" }) && !isLet(node, parent);
|
||||
};
|
||||
|
||||
var standardizeLets = function (declars) {
|
||||
for (var i = 0; i < declars.length; i++) {
|
||||
delete declars[i]._let;
|
||||
}
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, scope, file) {
|
||||
if (!isLet(node, parent)) return;
|
||||
|
||||
if (isLetInitable(node) && file.transformers["es6.blockScopingTDZ"].canRun()) {
|
||||
var nodes = [node];
|
||||
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var decl = node.declarations[i];
|
||||
if (decl.init) {
|
||||
var assign = t.assignmentExpression("=", decl.id, decl.init);
|
||||
assign._ignoreBlockScopingTDZ = true;
|
||||
nodes.push(t.expressionStatement(assign));
|
||||
}
|
||||
decl.init = file.addHelper("temporal-undefined");
|
||||
}
|
||||
|
||||
node._blockHoist = 2;
|
||||
|
||||
return nodes;
|
||||
}
|
||||
};
|
||||
|
||||
exports.Loop = function (node, parent, scope, file) {
|
||||
var init = node.left || node.init;
|
||||
if (isLet(init, node)) {
|
||||
t.ensureBlock(node);
|
||||
node.body._letDeclarators = [init];
|
||||
}
|
||||
var blockScoping = new BlockScoping(node, node.body, parent, scope, file);
|
||||
blockScoping.run();
|
||||
};
|
||||
|
||||
exports.Program =
|
||||
exports.BlockStatement = function (block, parent, scope, file) {
|
||||
if (!t.isLoop(parent)) {
|
||||
var blockScoping = new BlockScoping(false, block, parent, scope, file);
|
||||
blockScoping.run();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Boolean|Node} loopParent
|
||||
* @param {Node} block
|
||||
* @param {Node} parent
|
||||
* @param {Scope} scope
|
||||
* @param {File} file
|
||||
*/
|
||||
|
||||
function BlockScoping(loopParent, block, parent, scope, file) {
|
||||
this.loopParent = loopParent;
|
||||
this.parent = parent;
|
||||
this.scope = scope;
|
||||
this.block = block;
|
||||
this.file = file;
|
||||
|
||||
this.outsideLetReferences = object();
|
||||
this.hasLetReferences = false;
|
||||
this.letReferences = block._letReferences = object();
|
||||
this.body = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the ball rolling.
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.run = function () {
|
||||
var block = this.block;
|
||||
if (block._letDone) return;
|
||||
block._letDone = true;
|
||||
|
||||
var needsClosure = this.getLetReferences();
|
||||
|
||||
// this is a block within a `Function/Program` so we can safely leave it be
|
||||
if (t.isFunction(this.parent) || t.isProgram(this.block)) return;
|
||||
|
||||
// we can skip everything
|
||||
if (!this.hasLetReferences) return;
|
||||
|
||||
if (needsClosure) {
|
||||
this.wrapClosure();
|
||||
} else {
|
||||
this.remap();
|
||||
}
|
||||
};
|
||||
|
||||
function replace(node, parent, scope, remaps) {
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
var remap = remaps[node.name];
|
||||
if (!remap) return;
|
||||
|
||||
var ownBinding = scope.getBindingIdentifier(node.name);
|
||||
if (ownBinding === remap.binding) {
|
||||
node.name = remap.uid;
|
||||
} else {
|
||||
// scope already has it's own binding that doesn't
|
||||
// match the one we have a stored replacement for
|
||||
if (this) this.skip();
|
||||
}
|
||||
}
|
||||
|
||||
var replaceVisitor = {
|
||||
enter: replace
|
||||
};
|
||||
|
||||
function traverseReplace(node, parent, scope, remaps) {
|
||||
replace(node, parent, scope, remaps);
|
||||
scope.traverse(node, replaceVisitor, remaps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.remap = function () {
|
||||
var hasRemaps = false;
|
||||
var letRefs = this.letReferences;
|
||||
var scope = this.scope;
|
||||
|
||||
// alright, so since we aren't wrapping this block in a closure
|
||||
// we have to check if any of our let variables collide with
|
||||
// those in upper scopes and then if they do, generate a uid
|
||||
// for them and replace all references with it
|
||||
var remaps = object();
|
||||
|
||||
for (var key in letRefs) {
|
||||
// just an Identifier node we collected in `getLetReferences`
|
||||
// this is the defining identifier of a declaration
|
||||
var ref = letRefs[key];
|
||||
|
||||
if (scope.parentHasBinding(key) || scope.hasGlobal(key)) {
|
||||
var uid = scope.generateUidIdentifier(ref.name).name;
|
||||
ref.name = uid;
|
||||
|
||||
hasRemaps = true;
|
||||
remaps[key] = remaps[uid] = {
|
||||
binding: ref,
|
||||
uid: uid
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRemaps) return;
|
||||
|
||||
//
|
||||
|
||||
var loopParent = this.loopParent;
|
||||
if (loopParent) {
|
||||
traverseReplace(loopParent.right, loopParent, scope, remaps);
|
||||
traverseReplace(loopParent.test, loopParent, scope, remaps);
|
||||
traverseReplace(loopParent.update, loopParent, scope, remaps);
|
||||
}
|
||||
|
||||
scope.traverse(this.block, replaceVisitor, remaps);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.wrapClosure = function () {
|
||||
var block = this.block;
|
||||
|
||||
var outsideRefs = this.outsideLetReferences;
|
||||
|
||||
// remap loop heads with colliding variables
|
||||
if (this.loopParent) {
|
||||
for (var name in outsideRefs) {
|
||||
var id = outsideRefs[name];
|
||||
|
||||
if (this.scope.hasGlobal(id.name)) {
|
||||
delete outsideRefs[id.name];
|
||||
delete this.letReferences[id.name];
|
||||
|
||||
this.scope.rename(id.name);
|
||||
|
||||
this.letReferences[id.name] = id;
|
||||
outsideRefs[id.name] = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we're inside of a for loop then we search to see if there are any
|
||||
// `break`s, `continue`s, `return`s etc
|
||||
this.has = this.checkLoop();
|
||||
|
||||
// hoist var references to retain scope
|
||||
this.hoistVarDeclarations();
|
||||
|
||||
// turn outsideLetReferences into an array
|
||||
var params = values(outsideRefs);
|
||||
|
||||
// build the closure that we're going to wrap the block with
|
||||
var fn = t.functionExpression(null, params, t.blockStatement(block.body));
|
||||
fn._aliasFunction = true;
|
||||
|
||||
// replace the current block body with the one we're going to build
|
||||
block.body = this.body;
|
||||
|
||||
// build a call and a unique id that we can assign the return value to
|
||||
var call = t.callExpression(fn, params);
|
||||
var ret = this.scope.generateUidIdentifier("ret");
|
||||
|
||||
// handle generators
|
||||
var hasYield = traverse.hasType(fn.body, this.scope, "YieldExpression", t.FUNCTION_TYPES);
|
||||
if (hasYield) {
|
||||
fn.generator = true;
|
||||
call = t.yieldExpression(call, true);
|
||||
}
|
||||
|
||||
// handlers async functions
|
||||
var hasAsync = traverse.hasType(fn.body, this.scope, "AwaitExpression", t.FUNCTION_TYPES);
|
||||
if (hasAsync) {
|
||||
fn.async = true;
|
||||
call = t.awaitExpression(call, true);
|
||||
}
|
||||
|
||||
this.build(ret, call);
|
||||
};
|
||||
|
||||
var letReferenceFunctionVisitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
// not a direct reference
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
if (scope.hasOwnBinding(node.name)) return;
|
||||
|
||||
// not a part of our scope
|
||||
if (!state.letReferences[node.name]) return;
|
||||
|
||||
state.closurify = true;
|
||||
}
|
||||
};
|
||||
|
||||
var letReferenceBlockVisitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isFunction(node)) {
|
||||
scope.traverse(node, letReferenceFunctionVisitor, state);
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.getLetReferences = function () {
|
||||
var block = this.block;
|
||||
|
||||
var declarators = block._letDeclarators || [];
|
||||
var declar;
|
||||
|
||||
//
|
||||
for (var 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++) {
|
||||
declar = block.body[i];
|
||||
if (isLet(declar, block)) {
|
||||
declarators = declarators.concat(declar.declarations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
for (i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
var keys = t.getBindingIdentifiers(declar);
|
||||
extend(this.letReferences, keys);
|
||||
this.hasLetReferences = true;
|
||||
}
|
||||
|
||||
// no let references so we can just quit
|
||||
if (!this.hasLetReferences) return;
|
||||
|
||||
// set let references to plain var references
|
||||
standardizeLets(declarators);
|
||||
|
||||
var state = {
|
||||
letReferences: this.letReferences,
|
||||
closurify: false
|
||||
};
|
||||
|
||||
// traverse through this block, stopping on functions and checking if they
|
||||
// contain any local let references
|
||||
this.scope.traverse(this.block, letReferenceBlockVisitor, state);
|
||||
|
||||
return state.closurify;
|
||||
};
|
||||
|
||||
var loopNodeTo = function (node) {
|
||||
if (t.isBreakStatement(node)) {
|
||||
return "break";
|
||||
} else if (t.isContinueStatement(node)) {
|
||||
return "continue";
|
||||
}
|
||||
};
|
||||
|
||||
var loopVisitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
var replace;
|
||||
|
||||
if (t.isLoop(node)) {
|
||||
state.ignoreLabeless = true;
|
||||
scope.traverse(node, loopVisitor, state);
|
||||
state.ignoreLabeless = false;
|
||||
}
|
||||
|
||||
if (t.isFunction(node) || t.isLoop(node)) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
var loopText = loopNodeTo(node);
|
||||
|
||||
if (loopText) {
|
||||
if (node.label) {
|
||||
// we shouldn't be transforming this because it exists somewhere inside
|
||||
if (state.innerLabels.indexOf(node.label.name) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
loopText = loopText + "|" + node.label.name;
|
||||
} else {
|
||||
// we shouldn't be transforming these statements because
|
||||
// they don't refer to the actual loop we're scopifying
|
||||
if (state.ignoreLabeless) return;
|
||||
|
||||
// break statements mean something different in this context
|
||||
if (t.isBreakStatement(node) && t.isSwitchCase(parent)) return;
|
||||
}
|
||||
|
||||
state.hasBreakContinue = true;
|
||||
state.map[loopText] = node;
|
||||
replace = t.literal(loopText);
|
||||
}
|
||||
|
||||
if (t.isReturnStatement(node)) {
|
||||
state.hasReturn = true;
|
||||
replace = t.objectExpression([
|
||||
t.property("init", t.identifier("v"), node.argument || t.identifier("undefined"))
|
||||
]);
|
||||
}
|
||||
|
||||
if (replace) {
|
||||
replace = t.returnStatement(replace);
|
||||
return t.inherits(replace, node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var loopLabelVisitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isLabeledStatement(node)) {
|
||||
state.innerLabels.push(node.label.name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If we're inside of a loop then traverse it and check if it has one of
|
||||
* the following node types `ReturnStatement`, `BreakStatement`,
|
||||
* `ContinueStatement` and replace it with a return value that we can track
|
||||
* later on.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.checkLoop = function () {
|
||||
var state = {
|
||||
hasBreakContinue: false,
|
||||
ignoreLabeless: false,
|
||||
innerLabels: [],
|
||||
hasReturn: false,
|
||||
isLoop: !!this.loopParent,
|
||||
map: {}
|
||||
};
|
||||
|
||||
this.scope.traverse(this.block, loopLabelVisitor, state);
|
||||
this.scope.traverse(this.block, loopVisitor, state);
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
var hoistVarDeclarationsVisitor = {
|
||||
enter: function (node, parent, scope, self) {
|
||||
if (t.isForStatement(node)) {
|
||||
if (isVar(node.init, node)) {
|
||||
node.init = t.sequenceExpression(self.pushDeclar(node.init));
|
||||
}
|
||||
} else if (t.isFor(node)) {
|
||||
if (isVar(node.left, node)) {
|
||||
node.left = node.left.declarations[0].id;
|
||||
}
|
||||
} else if (isVar(node, parent)) {
|
||||
return self.pushDeclar(node).map(t.expressionStatement);
|
||||
} else if (t.isFunction(node)) {
|
||||
return this.skip();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hoist all var declarations in this block to before it so they retain scope
|
||||
* once we wrap everything in a closure.
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.hoistVarDeclarations = function () {
|
||||
traverse(this.block, hoistVarDeclarationsVisitor, this.scope, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn a `VariableDeclaration` into an array of `AssignmentExpressions` with
|
||||
* their declarations hoisted to before the closure wrapper.
|
||||
*
|
||||
* @param {Node} node VariableDeclaration
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.pushDeclar = function (node) {
|
||||
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
|
||||
return t.variableDeclarator(declar.id);
|
||||
})));
|
||||
|
||||
var replace = [];
|
||||
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var declar = node.declarations[i];
|
||||
if (!declar.init) continue;
|
||||
|
||||
var expr = t.assignmentExpression("=", declar.id, declar.init);
|
||||
replace.push(t.inherits(expr, declar));
|
||||
}
|
||||
|
||||
return replace;
|
||||
};
|
||||
|
||||
/**
|
||||
* Push the closure to the body.
|
||||
*
|
||||
* @param {Node} ret Identifier
|
||||
* @param {Node} call CallExpression
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.build = function (ret, call) {
|
||||
var has = this.has;
|
||||
if (has.hasReturn || has.hasBreakContinue) {
|
||||
this.buildHas(ret, call);
|
||||
} else {
|
||||
this.body.push(t.expressionStatement(call));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Node} ret Identifier
|
||||
* @param {Node} call CallExpression
|
||||
*/
|
||||
|
||||
BlockScoping.prototype.buildHas = function (ret, call) {
|
||||
var body = this.body;
|
||||
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ret, call)
|
||||
]));
|
||||
|
||||
var loopParent = this.loopParent;
|
||||
var retCheck;
|
||||
var has = this.has;
|
||||
var cases = [];
|
||||
|
||||
if (has.hasReturn) {
|
||||
// typeof ret === "object"
|
||||
retCheck = util.template("let-scoping-return", {
|
||||
RETURN: ret
|
||||
});
|
||||
}
|
||||
|
||||
if (has.hasBreakContinue) {
|
||||
if (!loopParent) {
|
||||
throw new Error("Has no loop parent but we're trying to reassign breaks " +
|
||||
"and continues, something is going wrong here.");
|
||||
}
|
||||
|
||||
for (var key in has.map) {
|
||||
cases.push(t.switchCase(t.literal(key), [has.map[key]]));
|
||||
}
|
||||
|
||||
if (has.hasReturn) {
|
||||
cases.push(t.switchCase(null, [retCheck]));
|
||||
}
|
||||
|
||||
if (cases.length === 1) {
|
||||
var single = cases[0];
|
||||
body.push(t.ifStatement(
|
||||
t.binaryExpression("===", ret, single.test),
|
||||
single.consequent[0]
|
||||
));
|
||||
} else {
|
||||
body.push(t.switchStatement(ret, cases));
|
||||
}
|
||||
} else {
|
||||
if (has.hasReturn) body.push(retCheck);
|
||||
}
|
||||
};
|
||||
@@ -1,296 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var ReplaceSupers = require("../../helpers/replace-supers");
|
||||
var nameMethod = require("../../helpers/name-method");
|
||||
var defineMap = require("../../helpers/define-map");
|
||||
var messages = require("../../../messages");
|
||||
var util = require("../../../util");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isClass;
|
||||
|
||||
exports.ClassDeclaration = function (node, parent, scope, file) {
|
||||
return new ClassTransformer(node, file, scope, true).run();
|
||||
};
|
||||
|
||||
exports.ClassExpression = function (node, parent, scope, file) {
|
||||
if (!node.id) {
|
||||
if (t.isProperty(parent) && parent.value === node && !parent.computed && t.isIdentifier(parent.key)) {
|
||||
// var o = { foo: class {} };
|
||||
node.id = parent.key;
|
||||
}
|
||||
|
||||
if (t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)) {
|
||||
// var foo = class {};
|
||||
node.id = parent.id;
|
||||
}
|
||||
}
|
||||
|
||||
return new ClassTransformer(node, file, scope, false).run();
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {File} file
|
||||
* @param {Scope} scope
|
||||
* @param {Boolean} isStatement
|
||||
*/
|
||||
|
||||
function ClassTransformer(node, file, scope, isStatement) {
|
||||
this.isStatement = isStatement;
|
||||
this.scope = scope;
|
||||
this.node = node;
|
||||
this.file = file;
|
||||
|
||||
this.hasInstanceMutators = false;
|
||||
this.hasStaticMutators = false;
|
||||
|
||||
this.instanceMutatorMap = {};
|
||||
this.staticMutatorMap = {};
|
||||
this.hasConstructor = false;
|
||||
this.className = node.id || scope.generateUidIdentifier("class");
|
||||
this.superName = node.superClass || t.identifier("Function");
|
||||
this.hasSuper = !!node.superClass;
|
||||
this.isLoose = file.isLoose("es6.classes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
|
||||
ClassTransformer.prototype.run = function () {
|
||||
var superName = this.superName;
|
||||
var className = this.className;
|
||||
var file = this.file;
|
||||
|
||||
//
|
||||
|
||||
var body = this.body = [];
|
||||
|
||||
var constructorBody = t.blockStatement([
|
||||
t.expressionStatement(t.callExpression(file.addHelper("class-call-check"), [
|
||||
t.thisExpression(),
|
||||
className
|
||||
]))
|
||||
]);
|
||||
var constructor;
|
||||
|
||||
if (this.node.id) {
|
||||
constructor = t.functionDeclaration(className, [], constructorBody);
|
||||
body.push(constructor);
|
||||
} else {
|
||||
constructor = t.functionExpression(null, [], constructorBody);
|
||||
body.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(className, constructor)
|
||||
]));
|
||||
}
|
||||
this.constructor = constructor;
|
||||
|
||||
var closureParams = [];
|
||||
var closureArgs = [];
|
||||
|
||||
//
|
||||
|
||||
if (this.hasSuper) {
|
||||
closureArgs.push(superName);
|
||||
|
||||
if (!t.isIdentifier(superName)) {
|
||||
superName = this.scope.generateUidBasedOnNode(superName, this.file);
|
||||
}
|
||||
|
||||
closureParams.push(superName);
|
||||
|
||||
this.superName = superName;
|
||||
body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName])));
|
||||
}
|
||||
|
||||
this.buildBody();
|
||||
|
||||
t.inheritsComments(body[0], this.node);
|
||||
|
||||
var init;
|
||||
|
||||
if (body.length === 1) {
|
||||
// only a constructor so no need for a closure container
|
||||
init = t.toExpression(constructor);
|
||||
} else {
|
||||
body.push(t.returnStatement(className));
|
||||
init = t.callExpression(
|
||||
t.functionExpression(null, closureParams, t.blockStatement(body)),
|
||||
closureArgs
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isStatement) {
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(className, init)
|
||||
]);
|
||||
} else {
|
||||
return init;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
ClassTransformer.prototype.buildBody = function () {
|
||||
var constructor = this.constructor;
|
||||
var className = this.className;
|
||||
var superName = this.superName;
|
||||
var classBody = this.node.body.body;
|
||||
var body = this.body;
|
||||
|
||||
for (var i = 0; i < classBody.length; i++) {
|
||||
var node = classBody[i];
|
||||
if (t.isMethodDefinition(node)) {
|
||||
var replaceSupers = new ReplaceSupers({
|
||||
methodNode: node,
|
||||
className: this.className,
|
||||
superName: this.superName,
|
||||
isStatic: node.static,
|
||||
isLoose: this.isLoose,
|
||||
scope: this.scope,
|
||||
file: this.file
|
||||
}, true);
|
||||
replaceSupers.replace();
|
||||
|
||||
if (node.key.name === "constructor") {
|
||||
this.pushConstructor(node);
|
||||
} else {
|
||||
this.pushMethod(node);
|
||||
}
|
||||
} else if (t.isPrivateDeclaration(node)) {
|
||||
this.closure = true;
|
||||
body.unshift(node);
|
||||
} else if (t.isClassProperty(node)) {
|
||||
this.pushProperty(node);
|
||||
}
|
||||
}
|
||||
|
||||
// we have no constructor, we have a super, and the super doesn't appear to be falsy
|
||||
if (!this.hasConstructor && this.hasSuper && !t.isFalsyExpression(superName)) {
|
||||
var helperName = "class-super-constructor-call";
|
||||
if (this.isLoose) helperName += "-loose";
|
||||
constructor.body.body.push(util.template(helperName, {
|
||||
CLASS_NAME: className,
|
||||
SUPER_NAME: this.superName
|
||||
}, true));
|
||||
}
|
||||
|
||||
var instanceProps;
|
||||
var staticProps;
|
||||
|
||||
if (this.hasInstanceMutators) {
|
||||
instanceProps = defineMap.build(this.instanceMutatorMap);
|
||||
}
|
||||
|
||||
if (this.hasStaticMutators) {
|
||||
staticProps = defineMap.build(this.staticMutatorMap);
|
||||
}
|
||||
|
||||
if (instanceProps || staticProps) {
|
||||
staticProps = staticProps || t.literal(null);
|
||||
|
||||
var args = [className, staticProps];
|
||||
if (instanceProps) args.push(instanceProps);
|
||||
|
||||
body.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("prototype-properties"), args)
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Push a method to its respective mutatorMap.
|
||||
*
|
||||
* @param {Node} node MethodDefinition
|
||||
*/
|
||||
|
||||
ClassTransformer.prototype.pushMethod = function (node) {
|
||||
var methodName = node.key;
|
||||
|
||||
var kind = node.kind;
|
||||
|
||||
if (kind === "") {
|
||||
nameMethod.property(node, this.file, this.scope);
|
||||
|
||||
if (this.isLoose) {
|
||||
// use assignments instead of define properties for loose classes
|
||||
|
||||
var className = this.className;
|
||||
if (!node.static) className = t.memberExpression(className, t.identifier("prototype"));
|
||||
methodName = t.memberExpression(className, methodName, node.computed);
|
||||
|
||||
var expr = t.expressionStatement(t.assignmentExpression("=", methodName, node.value));
|
||||
t.inheritsComments(expr, node);
|
||||
this.body.push(expr);
|
||||
return;
|
||||
}
|
||||
|
||||
kind = "value";
|
||||
}
|
||||
|
||||
var mutatorMap = this.instanceMutatorMap;
|
||||
if (node.static) {
|
||||
this.hasStaticMutators = true;
|
||||
mutatorMap = this.staticMutatorMap;
|
||||
} else {
|
||||
this.hasInstanceMutators = true;
|
||||
}
|
||||
|
||||
defineMap.push(mutatorMap, methodName, kind, node.computed, node);
|
||||
defineMap.push(mutatorMap, methodName, "enumerable", node.computed, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Node} node
|
||||
*/
|
||||
|
||||
ClassTransformer.prototype.pushProperty = function (node) {
|
||||
if (!node.value) return;
|
||||
|
||||
var key;
|
||||
|
||||
if (node.static) {
|
||||
key = t.memberExpression(this.className, node.key);
|
||||
this.body.push(
|
||||
t.expressionStatement(t.assignmentExpression("=", key, node.value))
|
||||
);
|
||||
} else {
|
||||
key = t.memberExpression(t.thisExpression(), node.key);
|
||||
this.constructor.body.body.unshift(
|
||||
t.expressionStatement(t.assignmentExpression("=", key, node.value))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace the constructor body of our class.
|
||||
*
|
||||
* @param {Node} method MethodDefinition
|
||||
*/
|
||||
|
||||
ClassTransformer.prototype.pushConstructor = function (method) {
|
||||
if (method.kind) {
|
||||
throw this.file.errorWithNode(method, messages.get("classesIllegalConstructorKind"));
|
||||
}
|
||||
|
||||
var construct = this.constructor;
|
||||
var fn = method.value;
|
||||
|
||||
this.hasConstructor = true;
|
||||
|
||||
t.inherits(construct, fn);
|
||||
t.inheritsComments(construct, method);
|
||||
|
||||
construct._ignoreUserWhitespace = true;
|
||||
construct.params = fn.params;
|
||||
construct.body.body = construct.body.body.concat(fn.body.body);
|
||||
};
|
||||
@@ -1,403 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var messages = require("../../../messages");
|
||||
var t = require("../../../types");
|
||||
|
||||
exports.check = t.isPattern;
|
||||
|
||||
function DestructuringTransformer(opts) {
|
||||
this.blockHoist = opts.blockHoist;
|
||||
this.operator = opts.operator;
|
||||
this.nodes = opts.nodes;
|
||||
this.scope = opts.scope;
|
||||
this.file = opts.file;
|
||||
this.kind = opts.kind;
|
||||
}
|
||||
|
||||
DestructuringTransformer.prototype.buildVariableAssignment = function (id, init) {
|
||||
var op = this.operator;
|
||||
if (t.isMemberExpression(id)) op = "=";
|
||||
|
||||
var node;
|
||||
|
||||
if (op) {
|
||||
node = t.expressionStatement(t.assignmentExpression(op, id, init));
|
||||
} else {
|
||||
node = t.variableDeclaration(this.kind, [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
}
|
||||
|
||||
node._blockHoist = this.blockHoist;
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.buildVariableDeclaration = function (id, init) {
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
declar._blockHoist = this.blockHoist;
|
||||
return declar;
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.push = function (elem, parentId) {
|
||||
if (t.isObjectPattern(elem)) {
|
||||
this.pushObjectPattern(elem, parentId);
|
||||
} else if (t.isArrayPattern(elem)) {
|
||||
this.pushArrayPattern(elem, parentId);
|
||||
} else if (t.isAssignmentPattern(elem)) {
|
||||
this.pushAssignmentPattern(elem, parentId);
|
||||
} else {
|
||||
this.nodes.push(this.buildVariableAssignment(elem, parentId));
|
||||
}
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.pushAssignmentPattern = function (pattern, parentId) {
|
||||
var tempParentId = this.scope.generateUidBasedOnNode(parentId);
|
||||
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(tempParentId, parentId)
|
||||
]);
|
||||
declar._blockHoist = this.blockHoist;
|
||||
this.nodes.push(declar);
|
||||
|
||||
this.nodes.push(this.buildVariableAssignment(
|
||||
pattern.left,
|
||||
t.conditionalExpression(
|
||||
t.binaryExpression("===", tempParentId, t.identifier("undefined")),
|
||||
pattern.right,
|
||||
tempParentId
|
||||
)
|
||||
));
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.pushObjectSpread = function (pattern, parentId, prop, i) {
|
||||
// get all the keys that appear in this object before the current spread
|
||||
var keys = [];
|
||||
for (var i2 = 0; i2 < pattern.properties.length; i2++) {
|
||||
var prop2 = pattern.properties[i2];
|
||||
|
||||
if (i2 >= i) break;
|
||||
if (t.isSpreadProperty(prop2)) continue;
|
||||
|
||||
var key = prop2.key;
|
||||
if (t.isIdentifier(key)) {
|
||||
key = t.literal(prop2.key.name);
|
||||
}
|
||||
keys.push(key);
|
||||
}
|
||||
keys = t.arrayExpression(keys);
|
||||
|
||||
var value = t.callExpression(this.file.addHelper("object-without-properties"), [parentId, keys]);
|
||||
this.nodes.push(this.buildVariableAssignment(prop.argument, value));
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.pushObjectProperty = function (prop, parentId) {
|
||||
if (t.isLiteral(prop.key)) prop.computed = true;
|
||||
|
||||
var pattern2 = prop.value;
|
||||
var patternId2 = t.memberExpression(parentId, prop.key, prop.computed);
|
||||
|
||||
if (t.isPattern(pattern2)) {
|
||||
this.push(pattern2, patternId2);
|
||||
} else {
|
||||
this.nodes.push(this.buildVariableAssignment(pattern2, patternId2));
|
||||
}
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.pushObjectPattern = function (pattern, parentId) {
|
||||
if (!pattern.properties.length) {
|
||||
this.nodes.push(t.expressionStatement(
|
||||
t.callExpression(this.file.addHelper("object-destructuring-empty"), [parentId])
|
||||
));
|
||||
}
|
||||
|
||||
if (pattern.properties.length > 1 && t.isMemberExpression(parentId)) {
|
||||
var temp = this.scope.generateUidBasedOnNode(parentId, this.file);
|
||||
this.nodes.push(this.buildVariableDeclaration(temp, parentId));
|
||||
parentId = temp;
|
||||
}
|
||||
|
||||
for (var i = 0; i < pattern.properties.length; i++) {
|
||||
var prop = pattern.properties[i];
|
||||
if (t.isSpreadProperty(prop)) {
|
||||
this.pushObjectSpread(pattern, parentId, prop, i);
|
||||
} else {
|
||||
this.pushObjectProperty(prop, parentId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var hasRest = function (pattern) {
|
||||
for (var i = 0; i < pattern.elements.length; i++) {
|
||||
if (t.isRestElement(pattern.elements[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.pushArrayPattern = function (pattern, parentId) {
|
||||
if (!pattern.elements) return;
|
||||
|
||||
// if we have a rest then we need all the elements
|
||||
var count = !hasRest(pattern) && pattern.elements.length;
|
||||
|
||||
var toArray = this.scope.toArray(parentId, count);
|
||||
|
||||
var _parentId = this.scope.generateUidBasedOnNode(parentId);
|
||||
this.nodes.push(this.buildVariableDeclaration(_parentId, toArray));
|
||||
parentId = _parentId;
|
||||
|
||||
this.scope.assignTypeGeneric(parentId.name, "Array");
|
||||
|
||||
for (var i = 0; i < pattern.elements.length; i++) {
|
||||
var elem = pattern.elements[i];
|
||||
|
||||
// hole
|
||||
if (!elem) continue;
|
||||
|
||||
var newPatternId;
|
||||
|
||||
if (t.isRestElement(elem)) {
|
||||
newPatternId = this.scope.toArray(parentId);
|
||||
|
||||
if (i > 0) {
|
||||
newPatternId = t.callExpression(t.memberExpression(newPatternId, t.identifier("slice")), [t.literal(i)]);
|
||||
}
|
||||
|
||||
elem = elem.argument;
|
||||
} else {
|
||||
newPatternId = t.memberExpression(parentId, t.literal(i), true);
|
||||
}
|
||||
|
||||
this.push(elem, newPatternId);
|
||||
}
|
||||
};
|
||||
|
||||
DestructuringTransformer.prototype.init = function (pattern, parentId) {
|
||||
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
var key = this.scope.generateUidBasedOnNode(parentId);
|
||||
this.nodes.push(this.buildVariableDeclaration(key, parentId));
|
||||
parentId = key;
|
||||
}
|
||||
|
||||
this.push(pattern, parentId);
|
||||
};
|
||||
|
||||
exports.ForInStatement =
|
||||
exports.ForOfStatement = function (node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
|
||||
if (t.isPattern(left)) {
|
||||
// for ({ length: k } in { abc: 3 });
|
||||
|
||||
var temp = scope.generateUidIdentifier("ref");
|
||||
|
||||
node.left = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp)
|
||||
]);
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
node.body.body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(left, temp)
|
||||
]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!t.isVariableDeclaration(left)) return;
|
||||
|
||||
var pattern = left.declarations[0].id;
|
||||
if (!t.isPattern(pattern)) return;
|
||||
|
||||
var key = scope.generateUidIdentifier("ref");
|
||||
node.left = t.variableDeclaration(left.kind, [
|
||||
t.variableDeclarator(key, null)
|
||||
]);
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
kind: left.kind,
|
||||
file: file,
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
|
||||
destructuring.init(pattern, key);
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuringTransformer = false;
|
||||
|
||||
node.params = node.params.map(function (pattern, i) {
|
||||
if (!t.isPattern(pattern)) return pattern;
|
||||
|
||||
hasDestructuringTransformer = true;
|
||||
var parentId = scope.generateUidIdentifier("ref");
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
blockHoist: node.params.length - i,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
file: file,
|
||||
kind: "var",
|
||||
});
|
||||
destructuring.init(pattern, parentId);
|
||||
|
||||
return parentId;
|
||||
});
|
||||
|
||||
if (!hasDestructuringTransformer) return;
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
};
|
||||
|
||||
exports.CatchClause = function (node, parent, scope, file) {
|
||||
var pattern = node.param;
|
||||
if (!t.isPattern(pattern)) return;
|
||||
|
||||
var ref = scope.generateUidIdentifier("ref");
|
||||
node.param = ref;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
kind: "let",
|
||||
file: file,
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
destructuring.init(pattern, ref);
|
||||
|
||||
node.body.body = nodes.concat(node.body.body);
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
var expr = node.expression;
|
||||
if (expr.type !== "AssignmentExpression") return;
|
||||
if (!t.isPattern(expr.left)) return;
|
||||
if (file.isConsequenceExpressionStatement(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
var ref = scope.generateUidIdentifier("ref");
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(ref, expr.right)
|
||||
]));
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
operator: expr.operator,
|
||||
file: file,
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
destructuring.init(expr.left, ref);
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
||||
exports.AssignmentExpression = function (node, parent, scope, file) {
|
||||
if (!t.isPattern(node.left)) return;
|
||||
|
||||
var ref = scope.generateUidIdentifier("temp");
|
||||
scope.push({
|
||||
key: ref.name,
|
||||
id: ref
|
||||
});
|
||||
|
||||
var nodes = [];
|
||||
nodes.push(t.assignmentExpression("=", ref, node.right));
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
operator: node.operator,
|
||||
file: file,
|
||||
scope: scope,
|
||||
nodes: nodes
|
||||
});
|
||||
destructuring.init(node.left, ref);
|
||||
|
||||
nodes.push(ref);
|
||||
|
||||
return t.toSequenceExpression(nodes, scope);
|
||||
};
|
||||
|
||||
var variableDeclarationhasPattern = function (node) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
if (t.isPattern(node.declarations[i].id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.VariableDeclaration = function (node, parent, scope, file) {
|
||||
if (t.isForInStatement(parent) || t.isForOfStatement(parent)) return;
|
||||
if (!variableDeclarationhasPattern(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
var declar;
|
||||
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
declar = node.declarations[i];
|
||||
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
kind: node.kind,
|
||||
file: file
|
||||
});
|
||||
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
destructuring.init(pattern, patternId);
|
||||
|
||||
if (+i !== node.declarations.length - 1) {
|
||||
// we aren't the last declarator so let's just make the
|
||||
// last transformed node inherit from us
|
||||
t.inherits(nodes[nodes.length - 1], declar);
|
||||
}
|
||||
} else {
|
||||
nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar));
|
||||
}
|
||||
}
|
||||
|
||||
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
|
||||
// https://github.com/babel/babel/issues/113
|
||||
// for (let [x] = [0]; false;) {}
|
||||
|
||||
declar = null;
|
||||
|
||||
for (i = 0; i < nodes.length; i++) {
|
||||
node = nodes[i];
|
||||
declar = declar || t.variableDeclaration(node.kind, []);
|
||||
|
||||
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
|
||||
throw file.errorWithNode(node, messages.get("invalidParentForThisNode"));
|
||||
}
|
||||
|
||||
declar.declarations = declar.declarations.concat(node.declarations);
|
||||
}
|
||||
|
||||
return declar;
|
||||
}
|
||||
|
||||
return nodes;
|
||||
};
|
||||
@@ -1,367 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var reduceRight = require("lodash/collection/reduceRight");
|
||||
var messages = require("../../../messages");
|
||||
var flatten = require("lodash/array/flatten");
|
||||
var util = require("../../../util");
|
||||
var map = require("lodash/collection/map");
|
||||
var t = require("../../../types");
|
||||
|
||||
function returnBlock(expr) {
|
||||
return t.blockStatement([t.returnStatement(expr)]);
|
||||
}
|
||||
|
||||
function TailCallTransformer(node, scope, file) {
|
||||
this.hasTailRecursion = false;
|
||||
this.needsArguments = false;
|
||||
this.setsArguments = false;
|
||||
this.needsThis = false;
|
||||
this.ownerId = node.id;
|
||||
this.vars = [];
|
||||
|
||||
this.scope = scope;
|
||||
this.file = file;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
TailCallTransformer.prototype.getArgumentsId = function () {
|
||||
return this.argumentsId = this.argumentsId || this.scope.generateUidIdentifier("arguments");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getThisId = function () {
|
||||
return this.thisId = this.thisId || this.scope.generateUidIdentifier("this");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getLeftId = function () {
|
||||
return this.leftId = this.leftId || this.scope.generateUidIdentifier("left");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getFunctionId = function () {
|
||||
return this.functionId = this.functionId || this.scope.generateUidIdentifier("function");
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.getParams = function () {
|
||||
var params = this.params;
|
||||
|
||||
if (!params) {
|
||||
params = this.node.params;
|
||||
this.paramDecls = [];
|
||||
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var param = params[i];
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
this.paramDecls.push(t.variableDeclarator(
|
||||
param,
|
||||
params[i] = this.scope.generateUidIdentifier("x")
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.params = params;
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.hasDeopt = function () {
|
||||
// check if the ownerId has been reassigned, if it has then it's not safe to
|
||||
// perform optimisations
|
||||
var ownerIdInfo = this.scope.getBindingInfo(this.ownerId.name);
|
||||
return ownerIdInfo && ownerIdInfo.reassigned;
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.run = function () {
|
||||
var scope = this.scope;
|
||||
var node = this.node;
|
||||
|
||||
// only tail recursion can be optimized as for now, so we can skip anonymous
|
||||
// functions entirely
|
||||
var ownerId = this.ownerId;
|
||||
if (!ownerId) return;
|
||||
|
||||
// traverse the function and look for tail recursion
|
||||
scope.traverse(node, firstPass, this);
|
||||
|
||||
if (!this.hasTailRecursion) return;
|
||||
|
||||
if (this.hasDeopt()) {
|
||||
this.file.logDeopt(node, messages.get("tailCallReassignmentDeopt"));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
scope.traverse(node, secondPass, this);
|
||||
|
||||
if (!this.needsThis || !this.needsArguments) {
|
||||
scope.traverse(node, thirdPass, this);
|
||||
}
|
||||
|
||||
var body = t.ensureBlock(node).body;
|
||||
|
||||
if (this.vars.length > 0) {
|
||||
var declarations = flatten(map(this.vars, function (decl) {
|
||||
return decl.declarations;
|
||||
}, this));
|
||||
var statement = reduceRight(declarations, function (expr, decl) {
|
||||
return t.assignmentExpression("=", decl.id, expr);
|
||||
}, t.identifier("undefined"));
|
||||
body.unshift(t.expressionStatement(statement));
|
||||
}
|
||||
|
||||
var paramDecls = this.paramDecls;
|
||||
if (paramDecls.length > 0) {
|
||||
body.unshift(t.variableDeclaration("var", paramDecls));
|
||||
}
|
||||
|
||||
node.body = util.template("tail-call-body", {
|
||||
THIS_ID: this.thisId,
|
||||
ARGUMENTS_ID: this.argumentsId,
|
||||
FUNCTION_ID: this.getFunctionId(),
|
||||
BLOCK: node.body
|
||||
});
|
||||
|
||||
var topVars = [];
|
||||
|
||||
if (this.needsThis) {
|
||||
topVars.push(t.variableDeclarator(this.getThisId(), t.thisExpression()));
|
||||
}
|
||||
|
||||
if (this.needsArguments || this.setsArguments) {
|
||||
var decl = t.variableDeclarator(this.getArgumentsId());
|
||||
if (this.needsArguments) {
|
||||
decl.init = t.identifier("arguments");
|
||||
}
|
||||
topVars.push(decl);
|
||||
}
|
||||
|
||||
var leftId = this.leftId;
|
||||
if (leftId) {
|
||||
topVars.push(t.variableDeclarator(leftId));
|
||||
}
|
||||
|
||||
if (topVars.length > 0) {
|
||||
node.body.body.unshift(t.variableDeclaration("var", topVars));
|
||||
}
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransform = function (node) {
|
||||
if (!node) return;
|
||||
|
||||
var handler = this["subTransform" + node.type];
|
||||
if (handler) return handler.call(this, node);
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformConditionalExpression = function (node) {
|
||||
var callConsequent = this.subTransform(node.consequent);
|
||||
var callAlternate = this.subTransform(node.alternate);
|
||||
if (!callConsequent && !callAlternate) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if ternary operator had tail recursion in value, convert to optimized if-statement
|
||||
node.type = "IfStatement";
|
||||
node.consequent = callConsequent ? t.toBlock(callConsequent) : returnBlock(node.consequent);
|
||||
|
||||
if (callAlternate) {
|
||||
node.alternate = t.isIfStatement(callAlternate) ? callAlternate : t.toBlock(callAlternate);
|
||||
} else {
|
||||
node.alternate = returnBlock(node.alternate);
|
||||
}
|
||||
|
||||
return [node];
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformLogicalExpression = function (node) {
|
||||
// only call in right-value of can be optimized
|
||||
var callRight = this.subTransform(node.right);
|
||||
if (!callRight) return;
|
||||
|
||||
// cache left value as it might have side-effects
|
||||
var leftId = this.getLeftId();
|
||||
var testExpr = t.assignmentExpression(
|
||||
"=",
|
||||
leftId,
|
||||
node.left
|
||||
);
|
||||
|
||||
if (node.operator === "&&") {
|
||||
testExpr = t.unaryExpression("!", testExpr);
|
||||
}
|
||||
|
||||
return [t.ifStatement(testExpr, returnBlock(leftId))].concat(callRight);
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformSequenceExpression = function (node) {
|
||||
var seq = node.expressions;
|
||||
|
||||
// only last element can be optimized
|
||||
var lastCall = this.subTransform(seq[seq.length - 1]);
|
||||
if (!lastCall) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove converted expression from sequence
|
||||
// and convert to regular expression if needed
|
||||
if (--seq.length === 1) {
|
||||
node = seq[0];
|
||||
}
|
||||
|
||||
return [t.expressionStatement(node)].concat(lastCall);
|
||||
};
|
||||
|
||||
TailCallTransformer.prototype.subTransformCallExpression = function (node) {
|
||||
var callee = node.callee, thisBinding, args;
|
||||
|
||||
if (t.isMemberExpression(callee, { computed: false }) && t.isIdentifier(callee.property)) {
|
||||
switch (callee.property.name) {
|
||||
case "call":
|
||||
args = t.arrayExpression(node.arguments.slice(1));
|
||||
break;
|
||||
|
||||
case "apply":
|
||||
args = node.arguments[1] || t.identifier("undefined");
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
thisBinding = node.arguments[0];
|
||||
callee = callee.object;
|
||||
}
|
||||
|
||||
// only tail recursion can be optimized as for now
|
||||
if (!t.isIdentifier(callee) || !this.scope.bindingIdentifierEquals(callee.name, this.ownerId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hasTailRecursion = true;
|
||||
|
||||
if (this.hasDeopt()) return;
|
||||
|
||||
var body = [];
|
||||
|
||||
if (!t.isThisExpression(thisBinding)) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
this.getThisId(),
|
||||
thisBinding || t.identifier("undefined")
|
||||
)));
|
||||
}
|
||||
|
||||
if (!args) {
|
||||
args = t.arrayExpression(node.arguments);
|
||||
}
|
||||
|
||||
var argumentsId = this.getArgumentsId();
|
||||
var params = this.getParams();
|
||||
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
argumentsId,
|
||||
args
|
||||
)));
|
||||
|
||||
var i, param;
|
||||
|
||||
if (t.isArrayExpression(args)) {
|
||||
var elems = args.elements;
|
||||
for (i = 0; i < elems.length && i < params.length; i++) {
|
||||
param = params[i];
|
||||
var elem = elems[i] || (elems[i] = t.identifier("undefined"));
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
elems[i] = t.assignmentExpression("=", param, elem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.setsArguments = true;
|
||||
for (i = 0; i < params.length; i++) {
|
||||
param = params[i];
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
param,
|
||||
t.memberExpression(argumentsId, t.literal(i), true)
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
body.push(t.continueStatement(this.getFunctionId()));
|
||||
|
||||
return body;
|
||||
};
|
||||
|
||||
// looks for and replaces tail recursion calls
|
||||
var firstPass = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isIfStatement(node)) {
|
||||
if (t.isReturnStatement(node.alternate)) {
|
||||
t.ensureBlock(node, "alternate");
|
||||
}
|
||||
|
||||
if (t.isReturnStatement(node.consequent)) {
|
||||
t.ensureBlock(node, "consequent");
|
||||
}
|
||||
} else if (t.isReturnStatement(node)) {
|
||||
this.skip();
|
||||
return state.subTransform(node.argument);
|
||||
} else if (t.isTryStatement(parent)) {
|
||||
if (node === parent.block) {
|
||||
this.skip();
|
||||
} else if (parent.finalizer && node !== parent.finalizer) {
|
||||
this.skip();
|
||||
}
|
||||
} else if (t.isFunction(node)) {
|
||||
this.skip();
|
||||
} else if (t.isVariableDeclaration(node)) {
|
||||
this.skip();
|
||||
state.vars.push(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// hoists up function declarations, replaces `this` and `arguments` and marks
|
||||
// them as needed
|
||||
var secondPass = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (t.isThisExpression(node)) {
|
||||
state.needsThis = true;
|
||||
return state.getThisId();
|
||||
} else if (t.isReferencedIdentifier(node, parent, { name: "arguments" })) {
|
||||
state.needsArguments = true;
|
||||
return state.getArgumentsId();
|
||||
} else if (t.isFunction(node)) {
|
||||
this.skip();
|
||||
if (t.isFunctionDeclaration(node)) {
|
||||
node = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(node.id, t.toExpression(node))
|
||||
]);
|
||||
node._blockHoist = 2;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// optimizes recursion by removing `this` and `arguments` if they aren't used
|
||||
var thirdPass = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
if (!t.isExpressionStatement(node)) return;
|
||||
|
||||
var expr = node.expression;
|
||||
if (!t.isAssignmentExpression(expr)) return;
|
||||
|
||||
if (!state.needsThis && expr.left === state.getThisId()) {
|
||||
this.remove();
|
||||
} else if (!state.needsArguments && expr.left === state.getArgumentsId() && t.isArrayExpression(expr.right)) {
|
||||
return map(expr.right.elements, function (elem) {
|
||||
return t.expressionStatement(elem);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
var tailCall = new TailCallTransformer(node, scope, file);
|
||||
tailCall.run();
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var useStrict = require("../../helpers/use-strict");
|
||||
var groupBy = require("lodash/collection/groupBy");
|
||||
var flatten = require("lodash/array/flatten");
|
||||
var values = require("lodash/object/values");
|
||||
|
||||
// Priority:
|
||||
//
|
||||
// - 0 We want this to be at the **very** bottom
|
||||
// - 1 Default node position
|
||||
// - 2 Priority over normal nodes
|
||||
// - 3 We want this to be at the **very** top
|
||||
|
||||
exports.BlockStatement =
|
||||
exports.Program = {
|
||||
exit: function (node) {
|
||||
var hasChange = false;
|
||||
for (var i = 0; i < node.body.length; i++) {
|
||||
var bodyNode = node.body[i];
|
||||
if (bodyNode && bodyNode._blockHoist != null) hasChange = true;
|
||||
}
|
||||
if (!hasChange) return;
|
||||
|
||||
useStrict.wrap(node, function () {
|
||||
var nodePriorities = groupBy(node.body, function (bodyNode) {
|
||||
var priority = bodyNode._blockHoist;
|
||||
if (priority == null) priority = 1;
|
||||
if (priority === true) priority = 2;
|
||||
return priority;
|
||||
});
|
||||
|
||||
node.body = flatten(values(nodePriorities).reverse());
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var react = require("../../helpers/react");
|
||||
var t = require("../../../types");
|
||||
|
||||
require("../../helpers/build-react-transformer")(exports, {
|
||||
pre: function (state) {
|
||||
var tagName = state.tagName;
|
||||
var args = state.args;
|
||||
if (react.isCompatTag(tagName)) {
|
||||
args.push(t.literal(tagName));
|
||||
} else {
|
||||
args.push(state.tagExpr);
|
||||
}
|
||||
},
|
||||
|
||||
post: function (state) {
|
||||
state.callee = t.memberExpression(t.identifier("React"), t.identifier("createElement"));
|
||||
}
|
||||
});
|
||||
19
package.json
19
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "4.2.0",
|
||||
"version": "4.5.4",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"repository": "babel/babel",
|
||||
@@ -12,11 +12,9 @@
|
||||
},
|
||||
"bin": {
|
||||
"6to5": "./bin/deprecated/6to5",
|
||||
"6to5-minify": "./bin/deprecated/6to5-minify",
|
||||
"6to5-node": "./bin/deprecated/6to5-node",
|
||||
"6to5-runtime": "./bin/deprecated/6to5-runtime",
|
||||
"babel": "./bin/babel/index.js",
|
||||
"babel-minify": "./bin/babel-minify",
|
||||
"babel-node": "./bin/babel-node",
|
||||
"babel-external-helpers": "./bin/babel-external-helpers"
|
||||
},
|
||||
@@ -38,12 +36,12 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-babel": "0.11.1-33",
|
||||
"acorn-babel": "0.11.1-35",
|
||||
"ast-types": "~0.6.1",
|
||||
"chalk": "^0.5.1",
|
||||
"chalk": "^1.0.0",
|
||||
"chokidar": "^0.12.6",
|
||||
"commander": "^2.6.0",
|
||||
"core-js": "^0.5.4",
|
||||
"core-js": "^0.6.1",
|
||||
"debug": "^2.1.1",
|
||||
"detect-indent": "^3.0.0",
|
||||
"estraverse": "^1.9.1",
|
||||
@@ -51,13 +49,14 @@
|
||||
"fs-readdir-recursive": "^0.1.0",
|
||||
"globals": "^6.2.0",
|
||||
"is-integer": "^1.0.4",
|
||||
"js-tokenizer": "^1.3.3",
|
||||
"js-tokens": "0.4.1",
|
||||
"leven": "^1.0.1",
|
||||
"line-numbers": "0.2.0",
|
||||
"lodash": "^3.2.0",
|
||||
"output-file-sync": "^1.1.0",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"private": "^0.1.6",
|
||||
"regenerator-babel": "0.8.10-2",
|
||||
"regenerator-babel": "0.8.13-1",
|
||||
"regexpu": "^1.1.1",
|
||||
"repeating": "^1.1.2",
|
||||
"shebang-regex": "^1.0.0",
|
||||
@@ -68,13 +67,11 @@
|
||||
"trim-right": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "4.5.1",
|
||||
"browserify": "^8.1.3",
|
||||
"chai": "^2.0.0",
|
||||
"esvalid": "^1.1.0",
|
||||
"istanbul": "^0.3.5",
|
||||
"jscs": "^1.11.3",
|
||||
"jshint": "^2.6.0",
|
||||
"jshint-stylish": "^1.0.0",
|
||||
"matcha": "^0.6.0",
|
||||
"mocha": "^2.1.0",
|
||||
"rimraf": "^2.2.8",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel-runtime",
|
||||
"description": "babel selfContained runtime",
|
||||
"version": "4.1.1",
|
||||
"version": "4.5.3",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>"
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var transform = module.exports = require("../transformation");
|
||||
|
||||
transform.version = require("../../../package").version;
|
||||
@@ -7,14 +5,14 @@ transform.version = require("../../../package").version;
|
||||
transform.transform = transform;
|
||||
|
||||
transform.run = function (code, opts) {
|
||||
opts = opts || {};
|
||||
opts ||= {};
|
||||
opts.sourceMap = "inline";
|
||||
return new Function(transform(code, opts).code)();
|
||||
};
|
||||
|
||||
transform.load = function (url, callback, opts, hold) {
|
||||
opts = opts || {};
|
||||
opts.filename = opts.filename || url;
|
||||
opts ||= {};
|
||||
opts.filename ||= url;
|
||||
|
||||
var xhr = global.ActiveXObject ? new global.ActiveXObject("Microsoft.XMLHTTP") : new global.XMLHttpRequest();
|
||||
xhr.open("GET", url, true);
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var isFunction = require("lodash/lang/isFunction");
|
||||
var transform = require("../transformation");
|
||||
var util = require("../util");
|
||||
@@ -52,7 +50,7 @@ exports.transformFile = function (filename, opts, callback) {
|
||||
};
|
||||
|
||||
exports.transformFileSync = function (filename, opts) {
|
||||
opts = opts || {};
|
||||
opts ||= {};
|
||||
opts.filename = filename;
|
||||
return transform(fs.readFileSync(filename), opts);
|
||||
};
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
// required to safely use babel/register within a browserify codebase
|
||||
|
||||
module.exports = function () {};
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var path = require("path");
|
||||
var os = require("os");
|
||||
var fs = require("fs");
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
require("../../polyfill");
|
||||
|
||||
var sourceMapSupport = require("source-map-support");
|
||||
var registerCache = require("./cache");
|
||||
var resolveRc = require("./resolve-rc");
|
||||
var extend = require("lodash/object/extend");
|
||||
var babel = require("../node");
|
||||
var each = require("lodash/collection/each");
|
||||
@@ -11,7 +10,7 @@ var util = require("../../util");
|
||||
var fs = require("fs");
|
||||
|
||||
sourceMapSupport.install({
|
||||
retrieveSourceMap: function (source) {
|
||||
retrieveSourceMap(source) {
|
||||
var map = maps && maps[source];
|
||||
if (map) {
|
||||
return {
|
||||
@@ -44,7 +43,10 @@ var mtime = function (filename) {
|
||||
var compile = function (filename) {
|
||||
var result;
|
||||
|
||||
var cacheKey = filename + ":" + JSON.stringify(transformOpts);
|
||||
var opts = extend({}, transformOpts);
|
||||
resolveRc(filename, opts);
|
||||
|
||||
var cacheKey = filename + ":" + JSON.stringify(opts);
|
||||
|
||||
if (cache) {
|
||||
var cached = cache[cacheKey];
|
||||
@@ -54,10 +56,10 @@ var compile = function (filename) {
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = babel.transformFileSync(filename, extend({
|
||||
result = babel.transformFileSync(filename, extend(opts, {
|
||||
sourceMap: true,
|
||||
ast: false
|
||||
}, transformOpts));
|
||||
}));
|
||||
}
|
||||
|
||||
if (cache) {
|
||||
@@ -134,7 +136,7 @@ hookExtensions(util.canCompile.EXTENSIONS);
|
||||
|
||||
module.exports = function (opts) {
|
||||
// normalize options
|
||||
opts = opts || {};
|
||||
opts ||= {};
|
||||
|
||||
if (opts.only != null) onlyRegex = util.regexify(opts.only);
|
||||
if (opts.ignore != null) ignoreRegex = util.regexify(opts.ignore);
|
||||
48
src/babel/api/register/resolve-rc.js
Normal file
48
src/babel/api/register/resolve-rc.js
Normal file
@@ -0,0 +1,48 @@
|
||||
var merge = require("lodash/object/merge");
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
|
||||
var cache = {};
|
||||
|
||||
function exists(filename) {
|
||||
var cached = cache[filename];
|
||||
if (cached != null) return cached;
|
||||
return cache[filename] = fs.existsSync(filename);
|
||||
}
|
||||
|
||||
module.exports = function (loc, opts) {
|
||||
var rel = ".babelrc";
|
||||
opts ||= {};
|
||||
|
||||
function find(start, rel) {
|
||||
var file = path.join(start, rel);
|
||||
|
||||
if (exists(file)) {
|
||||
var content = fs.readFileSync(file, "utf8");
|
||||
var json;
|
||||
|
||||
try {
|
||||
json = JSON.parse(content);
|
||||
} catch (err) {
|
||||
err.message = file + ": " + err.message;
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (json.breakConfig) return;
|
||||
merge(opts, json, function(a, b) {
|
||||
if (Array.isArray(a)) {
|
||||
return a.concat(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var up = path.dirname(start);
|
||||
if (up !== start) { // root
|
||||
find(up, rel);
|
||||
}
|
||||
}
|
||||
|
||||
find(loc, rel);
|
||||
|
||||
return opts;
|
||||
};
|
||||
@@ -1,11 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var buildHelpers = require("./build-helpers");
|
||||
var generator = require("./generation");
|
||||
var util = require("./util");
|
||||
var t = require("./types");
|
||||
|
||||
module.exports = function () {
|
||||
module.exports = function (whitelist) {
|
||||
var namespace = t.identifier("babelHelpers");
|
||||
|
||||
var body = [];
|
||||
@@ -19,7 +17,7 @@ module.exports = function () {
|
||||
)
|
||||
]));
|
||||
|
||||
buildHelpers(body, namespace);
|
||||
buildHelpers(body, namespace, whitelist);
|
||||
|
||||
return generator(tree).code;
|
||||
};
|
||||
@@ -3,8 +3,10 @@ var util = require("./util");
|
||||
var each = require("lodash/collection/each");
|
||||
var t = require("./types");
|
||||
|
||||
module.exports = function (body, namespace) {
|
||||
module.exports = function (body, namespace, whitelist = []) {
|
||||
each(File.helpers, function (name) {
|
||||
if (whitelist.length && whitelist.indexOf(name) == -1) return;
|
||||
|
||||
var key = t.identifier(t.toIdentifier(name));
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", t.memberExpression(namespace, key), util.template(name))
|
||||
@@ -15,7 +15,7 @@ function detect(ast) {
|
||||
};
|
||||
|
||||
traverse(ast, {
|
||||
enter: function (node, parent) {
|
||||
enter(node, parent) {
|
||||
if (SYNTAX_KEYS[node.type]) {
|
||||
detectedSyntax(SYNTAX_KEYS[node.type]);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Buffer;
|
||||
|
||||
var repeating = require("repeating");
|
||||
@@ -59,13 +57,13 @@ Buffer.prototype.keyword = function (name) {
|
||||
|
||||
Buffer.prototype.space = function () {
|
||||
if (this.format.compact) return;
|
||||
|
||||
if (this.buf && !this.isLast([" ", "\n"])) {
|
||||
if (this.buf && !this.isLast(" ") && !this.isLast("\n")) {
|
||||
this.push(" ");
|
||||
}
|
||||
};
|
||||
|
||||
Buffer.prototype.removeLast = function (cha) {
|
||||
if (this.format.compact) return;
|
||||
if (!this.isLast(cha)) return;
|
||||
|
||||
this.buf = this.buf.substr(0, this.buf.length - 1);
|
||||
@@ -73,19 +71,24 @@ Buffer.prototype.removeLast = function (cha) {
|
||||
};
|
||||
|
||||
Buffer.prototype.newline = function (i, removeLast) {
|
||||
if (this.format.compact || this.format.concise) {
|
||||
if (this.format.compact) return;
|
||||
|
||||
if (this.format.concise) {
|
||||
this.space();
|
||||
return;
|
||||
}
|
||||
|
||||
removeLast = removeLast || false;
|
||||
removeLast ||= false;
|
||||
|
||||
if (isNumber(i)) {
|
||||
if (this.endsWith("{\n")) i--;
|
||||
if (this.endsWith(repeating("\n", i > 0 ? i : 0))) return;
|
||||
i = Math.min(2, i);
|
||||
|
||||
while (i--) {
|
||||
if (this.endsWith("{\n") || this.endsWith(":\n")) i--;
|
||||
if (i <= 0) return;
|
||||
|
||||
while (i > 0) {
|
||||
this._newline(removeLast);
|
||||
i--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -98,11 +101,13 @@ Buffer.prototype.newline = function (i, removeLast) {
|
||||
};
|
||||
|
||||
Buffer.prototype._newline = function (removeLast) {
|
||||
// never allow more than two lines
|
||||
if (this.endsWith("\n\n")) return;
|
||||
|
||||
// remove the last newline
|
||||
if (removeLast && this.isLast("\n")) this.removeLast("\n");
|
||||
|
||||
this.removeLast(" ");
|
||||
|
||||
// remove whitespace if last character was a newline
|
||||
this._removeSpacesAfterLastNewline();
|
||||
this._push("\n");
|
||||
};
|
||||
@@ -110,6 +115,7 @@ Buffer.prototype._newline = function (removeLast) {
|
||||
/**
|
||||
* If buffer ends with a newline and some spaces after it, trim those spaces.
|
||||
*/
|
||||
|
||||
Buffer.prototype._removeSpacesAfterLastNewline = function () {
|
||||
var lastNewlineIndex = this.buf.lastIndexOf("\n");
|
||||
if (lastNewlineIndex === -1)
|
||||
@@ -130,7 +136,7 @@ Buffer.prototype._removeSpacesAfterLastNewline = function () {
|
||||
};
|
||||
|
||||
Buffer.prototype.push = function (str, noIndent) {
|
||||
if (this._indent && !noIndent && str !== "\n") {
|
||||
if (!this.format.compact && this._indent && !noIndent && str !== "\n") {
|
||||
// we have an indent level and we aren't pushing a newline
|
||||
var indent = this.getIndent();
|
||||
|
||||
@@ -138,7 +144,7 @@ Buffer.prototype.push = function (str, noIndent) {
|
||||
str = str.replace(/\n/g, "\n" + indent);
|
||||
|
||||
// we've got a newline before us so prepend on the indentation
|
||||
if (this.isLast("\n")) str = indent + str;
|
||||
if (this.isLast("\n")) this._push(indent);
|
||||
}
|
||||
|
||||
this._push(str);
|
||||
@@ -150,13 +156,13 @@ Buffer.prototype._push = function (str) {
|
||||
};
|
||||
|
||||
Buffer.prototype.endsWith = function (str) {
|
||||
var d = this.buf.length - str.length;
|
||||
return d >= 0 && this.buf.lastIndexOf(str) === d;
|
||||
return this.buf.slice(-str.length) === str;
|
||||
};
|
||||
|
||||
Buffer.prototype.isLast = function (cha, shouldTrimRight) {
|
||||
Buffer.prototype.isLast = function (cha) {
|
||||
if (this.format.compact) return false;
|
||||
|
||||
var buf = this.buf;
|
||||
if (shouldTrimRight) buf = trimRight(buf);
|
||||
var last = buf[buf.length - 1];
|
||||
|
||||
if (Array.isArray(cha)) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
exports.File = function (node, print) {
|
||||
print(node.program);
|
||||
};
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
exports.ClassExpression =
|
||||
exports.ClassDeclaration = function (node, print) {
|
||||
this.push("class");
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
exports.ComprehensionBlock = function (node, print) {
|
||||
this.keyword("for");
|
||||
this.push("(");
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var isInteger = require("is-integer");
|
||||
var isNumber = require("lodash/lang/isNumber");
|
||||
var t = require("../../types");
|
||||
@@ -46,11 +44,9 @@ exports.ConditionalExpression = function (node, print) {
|
||||
exports.NewExpression = function (node, print) {
|
||||
this.push("new ");
|
||||
print(node.callee);
|
||||
if (node.arguments.length || this.format.parentheses) {
|
||||
this.push("(");
|
||||
print.list(node.arguments);
|
||||
this.push(")");
|
||||
}
|
||||
this.push("(");
|
||||
print.list(node.arguments);
|
||||
this.push(")");
|
||||
};
|
||||
|
||||
exports.SequenceExpression = function (node, print) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
exports.AnyTypeAnnotation =
|
||||
exports.ArrayTypeAnnotation =
|
||||
exports.BooleanTypeAnnotation =
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
@@ -40,16 +38,14 @@ exports.JSXExpressionContainer = function (node, print) {
|
||||
};
|
||||
|
||||
exports.JSXElement = function (node, print) {
|
||||
var self = this;
|
||||
|
||||
var open = node.openingElement;
|
||||
print(open);
|
||||
if (open.selfClosing) return;
|
||||
|
||||
this.indent();
|
||||
each(node.children, function (child) {
|
||||
each(node.children, (child) => {
|
||||
if (t.isLiteral(child)) {
|
||||
self.push(child.value);
|
||||
this.push(child.value);
|
||||
} else {
|
||||
print(child);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports._params = function (node, print) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
@@ -58,24 +56,26 @@ exports.ExportDeclaration = function (node, print) {
|
||||
};
|
||||
|
||||
exports.ImportDeclaration = function (node, print) {
|
||||
var self = this;
|
||||
|
||||
this.push("import ");
|
||||
|
||||
if (node.isType) {
|
||||
this.push("type ");
|
||||
}
|
||||
|
||||
var specfiers = node.specifiers;
|
||||
if (specfiers && specfiers.length) {
|
||||
var foundImportSpecifier = false;
|
||||
|
||||
each(node.specifiers, function (spec, i) {
|
||||
each(node.specifiers, (spec, i) => {
|
||||
if (+i > 0) {
|
||||
self.push(", ");
|
||||
this.push(", ");
|
||||
}
|
||||
|
||||
var isDefault = t.isSpecifierDefault(spec);
|
||||
|
||||
if (!isDefault && spec.type !== "ImportBatchSpecifier" && !foundImportSpecifier) {
|
||||
foundImportSpecifier = true;
|
||||
self.push("{ ");
|
||||
this.push("{ ");
|
||||
}
|
||||
|
||||
print(spec);
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
each(["BindMemberExpression", "BindFunctionExpression"], function (type) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var repeating = require("repeating");
|
||||
var t = require("../../types");
|
||||
|
||||
@@ -22,12 +20,7 @@ exports.IfStatement = function (node, print) {
|
||||
|
||||
if (node.alternate) {
|
||||
if (this.isLast("}")) this.space();
|
||||
this.keyword("else");
|
||||
|
||||
if (this.format.format && !t.isBlockStatement(node.alternate)) {
|
||||
this.push(" ");
|
||||
}
|
||||
|
||||
this.push("else ");
|
||||
print.indentOnComments(node.alternate);
|
||||
}
|
||||
};
|
||||
@@ -153,7 +146,14 @@ exports.SwitchStatement = function (node, print) {
|
||||
this.push(")");
|
||||
this.space();
|
||||
this.push("{");
|
||||
print.sequence(node.cases, { indent: true });
|
||||
|
||||
print.sequence(node.cases, {
|
||||
indent: true,
|
||||
addNewlines(leading, cas) {
|
||||
if (!leading && node.cases[node.cases.length - 1] === cas) return -1;
|
||||
}
|
||||
});
|
||||
|
||||
this.push("}");
|
||||
};
|
||||
|
||||
@@ -166,8 +166,10 @@ exports.SwitchCase = function (node, print) {
|
||||
this.push("default:");
|
||||
}
|
||||
|
||||
this.newline();
|
||||
print.sequence(node.consequent, { indent: true });
|
||||
if (node.consequent.length) {
|
||||
this.newline();
|
||||
print.sequence(node.consequent, { indent: true });
|
||||
}
|
||||
};
|
||||
|
||||
exports.DebuggerStatement = function () {
|
||||
@@ -189,7 +191,7 @@ exports.VariableDeclaration = function (node, print, parent) {
|
||||
}
|
||||
|
||||
var sep = ",";
|
||||
if (hasInits) {
|
||||
if (!this.format.compact && hasInits) {
|
||||
sep += "\n" + repeating(" ", node.kind.length + 1);
|
||||
} else {
|
||||
sep += " ";
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
exports.TaggedTemplateExpression = function (node, print) {
|
||||
@@ -15,16 +13,15 @@ exports.TemplateLiteral = function (node, print) {
|
||||
this.push("`");
|
||||
|
||||
var quasis = node.quasis;
|
||||
var self = this;
|
||||
var len = quasis.length;
|
||||
|
||||
each(quasis, function (quasi, i) {
|
||||
each(quasis, (quasi, i) => {
|
||||
print(quasi);
|
||||
|
||||
if (i + 1 < len) {
|
||||
self.push("${ ");
|
||||
this.push("${ ");
|
||||
print(node.expressions[i]);
|
||||
self.push(" }");
|
||||
this.push(" }");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
exports.Identifier = function (node) {
|
||||
@@ -58,23 +56,22 @@ exports.Property = function (node, print) {
|
||||
exports.ArrayExpression =
|
||||
exports.ArrayPattern = function (node, print) {
|
||||
var elems = node.elements;
|
||||
var self = this;
|
||||
var len = elems.length;
|
||||
|
||||
this.push("[");
|
||||
|
||||
each(elems, function (elem, i) {
|
||||
each(elems, (elem, i) => {
|
||||
if (!elem) {
|
||||
// If the array expression ends with a hole, that hole
|
||||
// will be ignored by the interpreter, but if it ends with
|
||||
// two (or more) holes, we need to write out two (or more)
|
||||
// commas so that the resulting code is interpreted with
|
||||
// both (all) of the holes.
|
||||
self.push(",");
|
||||
this.push(",");
|
||||
} else {
|
||||
if (i > 0 && !self.format.compact) self.push(" ");
|
||||
if (i > 0) this.push(" ");
|
||||
print(elem);
|
||||
if (i < len - 1) self.push(",");
|
||||
if (i < len - 1) this.push(",");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function (ast, opts, code) {
|
||||
var gen = new CodeGenerator(ast, opts, code);
|
||||
return gen.generate();
|
||||
@@ -12,15 +10,15 @@ var Whitespace = require("./whitespace");
|
||||
var repeating = require("repeating");
|
||||
var SourceMap = require("./source-map");
|
||||
var Position = require("./position");
|
||||
var messages = require("../messages");
|
||||
var Buffer = require("./buffer");
|
||||
var extend = require("lodash/object/extend");
|
||||
var merge = require("lodash/object/merge");
|
||||
var each = require("lodash/collection/each");
|
||||
var n = require("./node");
|
||||
var t = require("../types");
|
||||
|
||||
function CodeGenerator(ast, opts, code) {
|
||||
opts = opts || {};
|
||||
opts ||= {};
|
||||
|
||||
this.comments = ast.comments || [];
|
||||
this.tokens = ast.tokens || [];
|
||||
@@ -28,7 +26,7 @@ function CodeGenerator(ast, opts, code) {
|
||||
this.opts = opts;
|
||||
this.ast = ast;
|
||||
|
||||
this.whitespace = new Whitespace(this.tokens, this.comments);
|
||||
this.whitespace = new Whitespace(this.tokens, this.comments, this.format);
|
||||
this.position = new Position;
|
||||
this.map = new SourceMap(this.position, opts, code);
|
||||
this.buffer = new Buffer(this.position, this.format);
|
||||
@@ -47,17 +45,25 @@ CodeGenerator.normalizeOptions = function (code, opts) {
|
||||
if (indent && indent !== " ") style = indent;
|
||||
}
|
||||
|
||||
return merge({
|
||||
parentheses: true,
|
||||
var format = {
|
||||
comments: opts.comments == null || opts.comments,
|
||||
compact: false,
|
||||
concise: false,
|
||||
compact: opts.compact,
|
||||
indent: {
|
||||
adjustMultilineComment: true,
|
||||
style: style,
|
||||
base: 0
|
||||
}
|
||||
}, opts.format || {});
|
||||
};
|
||||
|
||||
if (format.compact === "auto") {
|
||||
format.compact = code.length > 100000; // 100KB
|
||||
|
||||
if (format.compact) {
|
||||
console.error(messages.get("codeGeneratorDeopt", opts.filename, "100KB"));
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
};
|
||||
|
||||
CodeGenerator.generators = {
|
||||
@@ -97,38 +103,32 @@ CodeGenerator.prototype.generate = function () {
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.buildPrint = function (parent) {
|
||||
var self = this;
|
||||
|
||||
var print = function (node, opts) {
|
||||
return self.print(node, parent, opts);
|
||||
var print = (node, opts) => {
|
||||
return this.print(node, parent, opts);
|
||||
};
|
||||
|
||||
print.sequence = function (nodes, opts) {
|
||||
opts = opts || {};
|
||||
print.sequence = (nodes, opts) => {
|
||||
opts ||= {};
|
||||
opts.statement = true;
|
||||
return self.printJoin(print, nodes, opts);
|
||||
return this.printJoin(print, nodes, opts);
|
||||
};
|
||||
|
||||
print.join = function (nodes, opts) {
|
||||
return self.printJoin(print, nodes, opts);
|
||||
print.join = (nodes, opts) => {
|
||||
return this.printJoin(print, nodes, opts);
|
||||
};
|
||||
|
||||
print.list = function (items, opts) {
|
||||
opts = opts || {};
|
||||
|
||||
var sep = opts.separator || ", ";
|
||||
if (self.format.compact) sep = ",";
|
||||
opts.separator = sep;
|
||||
|
||||
opts ||= {};
|
||||
opts.separator ||= ", ";
|
||||
print.join(items, opts);
|
||||
};
|
||||
|
||||
print.block = function (node) {
|
||||
return self.printBlock(print, node);
|
||||
print.block = (node) => {
|
||||
return this.printBlock(print, node);
|
||||
};
|
||||
|
||||
print.indentOnComments = function (node) {
|
||||
return self.printAndIndentOnComments(print, node);
|
||||
print.indentOnComments = (node) => {
|
||||
return this.printAndIndentOnComments(print, node);
|
||||
};
|
||||
|
||||
return print;
|
||||
@@ -146,11 +146,9 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
this.format.concise = true;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
opts ||= {};
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
var newline = function (leading) {
|
||||
var newline = (leading) => {
|
||||
if (!opts.statement && !n.isUserWhitespacable(node, parent)) {
|
||||
return;
|
||||
}
|
||||
@@ -160,23 +158,24 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
if (node.start != null && !node._ignoreUserWhitespace) {
|
||||
// user node
|
||||
if (leading) {
|
||||
lines = self.whitespace.getNewlinesBefore(node);
|
||||
lines = this.whitespace.getNewlinesBefore(node);
|
||||
} else {
|
||||
lines = self.whitespace.getNewlinesAfter(node);
|
||||
lines = this.whitespace.getNewlinesAfter(node);
|
||||
}
|
||||
} else {
|
||||
// generated node
|
||||
if (!leading) lines++; // always include at least a single line after
|
||||
if (opts.addNewlines) lines += opts.addNewlines(leading, node) || 0;
|
||||
|
||||
var needs = n.needsWhitespaceAfter;
|
||||
if (leading) needs = n.needsWhitespaceBefore;
|
||||
lines += needs(node, parent);
|
||||
if (needs(node, parent)) lines++;
|
||||
|
||||
// generated nodes can't add starting file whitespace
|
||||
if (!self.buffer.get()) lines = 0;
|
||||
if (!this.buffer.buf) lines = 0;
|
||||
}
|
||||
|
||||
self.newline(lines);
|
||||
this.newline(lines);
|
||||
};
|
||||
|
||||
if (this[node.type]) {
|
||||
@@ -217,29 +216,29 @@ CodeGenerator.prototype.print = function (node, parent, opts) {
|
||||
CodeGenerator.prototype.printJoin = function (print, nodes, opts) {
|
||||
if (!nodes || !nodes.length) return;
|
||||
|
||||
opts = opts || {};
|
||||
opts ||= {};
|
||||
|
||||
var self = this;
|
||||
var len = nodes.length;
|
||||
var len = nodes.length;
|
||||
|
||||
if (opts.indent) self.indent();
|
||||
if (opts.indent) this.indent();
|
||||
|
||||
each(nodes, function (node, i) {
|
||||
each(nodes, (node, i) => {
|
||||
print(node, {
|
||||
statement: opts.statement,
|
||||
after: function () {
|
||||
addNewlines: opts.addNewlines,
|
||||
after: () => {
|
||||
if (opts.iterator) {
|
||||
opts.iterator(node, i);
|
||||
}
|
||||
|
||||
if (opts.separator && i < len - 1) {
|
||||
self.push(opts.separator);
|
||||
this.push(opts.separator);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (opts.indent) self.dedent();
|
||||
if (opts.indent) this.dedent();
|
||||
};
|
||||
|
||||
CodeGenerator.prototype.printAndIndentOnComments = function (print, node) {
|
||||
@@ -283,14 +282,13 @@ CodeGenerator.prototype.getComments = function (key, node, parent) {
|
||||
|
||||
var comments = [];
|
||||
var nodes = [node];
|
||||
var self = this;
|
||||
|
||||
if (t.isExpressionStatement(node)) {
|
||||
nodes.push(node.argument);
|
||||
}
|
||||
|
||||
each(nodes, function (node) {
|
||||
comments = comments.concat(self._getComments(key, node));
|
||||
each(nodes, (node) => {
|
||||
comments = comments.concat(this._getComments(key, node));
|
||||
});
|
||||
|
||||
return comments;
|
||||
@@ -302,16 +300,15 @@ CodeGenerator.prototype._getComments = function (key, node) {
|
||||
|
||||
CodeGenerator.prototype._printComments = function (comments) {
|
||||
if (this.format.compact) return;
|
||||
|
||||
if (!this.format.comments) return;
|
||||
if (!comments || !comments.length) return;
|
||||
|
||||
var self = this;
|
||||
|
||||
each(comments, function (comment) {
|
||||
each(comments, (comment) => {
|
||||
var skip = false;
|
||||
|
||||
// find the original comment in the ast and set it as displayed
|
||||
each(self.ast.comments, function (origComment) {
|
||||
each(this.ast.comments, function (origComment) {
|
||||
if (origComment.start === comment.start) {
|
||||
// comment has already been output
|
||||
if (origComment._displayed) skip = true;
|
||||
@@ -324,38 +321,38 @@ CodeGenerator.prototype._printComments = function (comments) {
|
||||
if (skip) return;
|
||||
|
||||
// whitespace before
|
||||
self.newline(self.whitespace.getNewlinesBefore(comment));
|
||||
this.newline(this.whitespace.getNewlinesBefore(comment));
|
||||
|
||||
var column = self.position.column;
|
||||
var val = self.generateComment(comment);
|
||||
var column = this.position.column;
|
||||
var val = this.generateComment(comment);
|
||||
|
||||
if (column && !self.isLast(["\n", " ", "[", "{"])) {
|
||||
self._push(" ");
|
||||
if (column && !this.isLast(["\n", " ", "[", "{"])) {
|
||||
this._push(" ");
|
||||
column++;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if (comment.type === "Block" && self.format.indent.adjustMultilineComment) {
|
||||
if (comment.type === "Block" && this.format.indent.adjustMultilineComment) {
|
||||
var offset = comment.loc.start.column;
|
||||
if (offset) {
|
||||
var newlineRegex = new RegExp("\\n\\s{1," + offset + "}", "g");
|
||||
val = val.replace(newlineRegex, "\n");
|
||||
}
|
||||
|
||||
var indent = Math.max(self.indentSize(), column);
|
||||
var indent = Math.max(this.indentSize(), column);
|
||||
val = val.replace(/\n/g, "\n" + repeating(" ", indent));
|
||||
}
|
||||
|
||||
if (column === 0) {
|
||||
val = self.getIndent() + val;
|
||||
val = this.getIndent() + val;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
self._push(val);
|
||||
this._push(val);
|
||||
|
||||
// whitespace after
|
||||
self.newline(self.whitespace.getNewlinesAfter(comment));
|
||||
this.newline(this.whitespace.getNewlinesAfter(comment));
|
||||
});
|
||||
};
|
||||
@@ -1,12 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Node;
|
||||
|
||||
var whitespace = require("./whitespace");
|
||||
var parens = require("./parentheses");
|
||||
var t = require("../../types");
|
||||
var each = require("lodash/collection/each");
|
||||
var some = require("lodash/collection/some");
|
||||
var t = require("../../types");
|
||||
|
||||
var find = function (obj, node, parent) {
|
||||
if (!obj) return;
|
||||
@@ -42,14 +40,19 @@ Node.needsWhitespace = function (node, parent, type) {
|
||||
node = node.expression;
|
||||
}
|
||||
|
||||
var lines = find(whitespace[type].nodes, node, parent);
|
||||
if (lines) return lines;
|
||||
var linesInfo = find(whitespace.nodes, node, parent);
|
||||
|
||||
each(find(whitespace[type].list, node, parent), function (expr) {
|
||||
lines = Node.needsWhitespace(expr, node, type);
|
||||
if (lines) return false;
|
||||
});
|
||||
return lines || 0;
|
||||
if (!linesInfo) {
|
||||
var items = find(whitespace.list, node, parent);
|
||||
if (items) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
linesInfo = Node.needsWhitespace(items[i], node, type);
|
||||
if (linesInfo) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (linesInfo && linesInfo[type]) || 0;
|
||||
};
|
||||
|
||||
Node.needsWhitespaceBefore = function (node, parent) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
var each = require("lodash/collection/each");
|
||||
|
||||
157
src/babel/generation/node/whitespace.js
Normal file
157
src/babel/generation/node/whitespace.js
Normal file
@@ -0,0 +1,157 @@
|
||||
var isBoolean = require("lodash/lang/isBoolean");
|
||||
var each = require("lodash/collection/each");
|
||||
var map = require("lodash/collection/map");
|
||||
var t = require("../../types");
|
||||
|
||||
var crawl = function (node, state) {
|
||||
state ||= {};
|
||||
|
||||
if (t.isMemberExpression(node)) {
|
||||
crawl(node.object, state);
|
||||
if (node.computed) crawl(node.property, state);
|
||||
} else if (t.isBinary(node) || t.isAssignmentExpression(node)) {
|
||||
crawl(node.left, state);
|
||||
crawl(node.right, state);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
state.hasCall = true;
|
||||
crawl(node.callee, state);
|
||||
} else if (t.isFunction(node)) {
|
||||
state.hasFunction = true;
|
||||
} else if (t.isIdentifier(node)) {
|
||||
state.hasHelper ||= isHelper(node.callee);
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
var isHelper = function (node) {
|
||||
if (t.isMemberExpression(node)) {
|
||||
return isHelper(node.object) || isHelper(node.property);
|
||||
} else if (t.isIdentifier(node)) {
|
||||
return node.name === "require" || node.name[0] === "_";
|
||||
} else if (t.isCallExpression(node)) {
|
||||
return isHelper(node.callee);
|
||||
} else if (t.isBinary(node) || t.isAssignmentExpression(node)) {
|
||||
return (t.isIdentifier(node.left) && isHelper(node.left)) || isHelper(node.right);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
var isType = function (node) {
|
||||
return t.isLiteral(node) || t.isObjectExpression(node) || t.isArrayExpression(node) ||
|
||||
t.isIdentifier(node) || t.isMemberExpression(node);
|
||||
};
|
||||
|
||||
exports.nodes = {
|
||||
AssignmentExpression(node) {
|
||||
var state = crawl(node.right);
|
||||
if ((state.hasCall && state.hasHelper) || state.hasFunction) {
|
||||
return {
|
||||
before: state.hasFunction,
|
||||
after: true
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
SwitchCase(node, parent) {
|
||||
return {
|
||||
before: node.consequent.length || parent.cases[0] === node
|
||||
};
|
||||
},
|
||||
|
||||
LogicalExpression(node) {
|
||||
if (t.isFunction(node.left) || t.isFunction(node.right)) {
|
||||
return {
|
||||
after: true
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
Literal(node) {
|
||||
if (node.value === "use strict") {
|
||||
return {
|
||||
after: true
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
CallExpression(node) {
|
||||
if (t.isFunction(node.callee) || isHelper(node)) {
|
||||
return {
|
||||
before: true,
|
||||
after: true
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
VariableDeclaration(node) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
var declar = node.declarations[i];
|
||||
|
||||
var enabled = isHelper(declar.id) && !isType(declar.init);
|
||||
if (!enabled) {
|
||||
var state = crawl(declar.init);
|
||||
enabled = (isHelper(declar.init) && state.hasCall) || state.hasFunction;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
return {
|
||||
before: true,
|
||||
after: true
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
IfStatement(node) {
|
||||
if (t.isBlockStatement(node.consequent)) {
|
||||
return {
|
||||
before: true,
|
||||
after: true
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.nodes.Property =
|
||||
exports.nodes.SpreadProperty = function (node, parent) {
|
||||
if (parent.properties[0] === node) {
|
||||
return {
|
||||
before: true
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
exports.list = {
|
||||
VariableDeclaration(node) {
|
||||
return map(node.declarations, "init");
|
||||
},
|
||||
|
||||
ArrayExpression(node) {
|
||||
return node.elements;
|
||||
},
|
||||
|
||||
ObjectExpression(node) {
|
||||
return node.properties;
|
||||
}
|
||||
};
|
||||
|
||||
each({
|
||||
Function: true,
|
||||
Class: true,
|
||||
Loop: true,
|
||||
LabeledStatement: true,
|
||||
SwitchStatement: true,
|
||||
TryStatement: true
|
||||
}, function (amounts, type) {
|
||||
if (isBoolean(amounts)) {
|
||||
amounts = { after: amounts, before: amounts };
|
||||
}
|
||||
|
||||
each([type].concat(t.FLIPPED_ALIAS_KEYS[type] || []), function (type) {
|
||||
exports.nodes[type] = function () {
|
||||
return amounts;
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Position;
|
||||
|
||||
function Position() {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = SourceMap;
|
||||
|
||||
var sourceMap = require("source-map");
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = Whitespace;
|
||||
|
||||
var sortBy = require("lodash/collection/sortBy");
|
||||
@@ -13,11 +11,13 @@ var sortBy = require("lodash/collection/sortBy");
|
||||
* @param {Number} max Array length
|
||||
* @returns {Number} shiftedIndex
|
||||
*/
|
||||
|
||||
function getLookupIndex(i, base, max) {
|
||||
i += base;
|
||||
|
||||
if (i >= max)
|
||||
if (i >= max) {
|
||||
i -= max;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
91
src/babel/helpers/code-frame.js
Normal file
91
src/babel/helpers/code-frame.js
Normal file
@@ -0,0 +1,91 @@
|
||||
var lineNumbers = require("line-numbers");
|
||||
var repeating = require("repeating");
|
||||
var jsTokens = require("js-tokens");
|
||||
var esutils = require("esutils");
|
||||
var chalk = require("chalk");
|
||||
var ary = require("lodash/function/ary");
|
||||
|
||||
var defs = {
|
||||
string: chalk.red,
|
||||
punctuation: chalk.white.bold,
|
||||
operator: chalk.white.bold,
|
||||
curly: chalk.green,
|
||||
parens: chalk.blue.bold,
|
||||
square: chalk.yellow,
|
||||
name: chalk.white,
|
||||
keyword: chalk.cyan,
|
||||
number: chalk.magenta,
|
||||
regex: chalk.magenta,
|
||||
comment: chalk.grey,
|
||||
invalid: chalk.inverse
|
||||
};
|
||||
|
||||
var newline = /\r\n|[\n\r\u2028\u2029]/;
|
||||
|
||||
var highlight = function (text) {
|
||||
var tokenType = function (match) {
|
||||
var token = jsTokens.matchToToken(match);
|
||||
if (token.type === "name" && esutils.keyword.isKeywordES6(token.value)) {
|
||||
return "keyword";
|
||||
}
|
||||
|
||||
if (token.type === "punctuation") {
|
||||
switch (token.value) {
|
||||
case "{":
|
||||
case "}":
|
||||
return "curly";
|
||||
case "(":
|
||||
case ")":
|
||||
return "parens";
|
||||
case "[":
|
||||
case "]":
|
||||
return "square";
|
||||
}
|
||||
}
|
||||
|
||||
return token.type;
|
||||
};
|
||||
|
||||
return text.replace(jsTokens, function (match) {
|
||||
var type = tokenType(arguments);
|
||||
if (type in defs) {
|
||||
var colorize = ary(defs[type], 1);
|
||||
return match.split(newline).map(colorize).join("\n");
|
||||
}
|
||||
return match;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = function (lines, lineNumber, colNumber) {
|
||||
colNumber = Math.max(colNumber, 0);
|
||||
|
||||
if (chalk.supportsColor) {
|
||||
lines = highlight(lines);
|
||||
}
|
||||
|
||||
lines = lines.split(newline);
|
||||
|
||||
var start = Math.max(lineNumber - 3, 0);
|
||||
var end = Math.min(lines.length, lineNumber + 3);
|
||||
|
||||
if (!lineNumber && !colNumber) {
|
||||
start = 0;
|
||||
end = lines.length;
|
||||
}
|
||||
|
||||
return "\n" + lineNumbers(lines.slice(start, end), {
|
||||
start: start + 1,
|
||||
before: " ",
|
||||
after: " | ",
|
||||
transform(params) {
|
||||
if (params.number !== lineNumber) {
|
||||
return;
|
||||
}
|
||||
if (colNumber) {
|
||||
params.line += "\n" + params.before + repeating(" ", params.width) +
|
||||
params.after + repeating(" ", colNumber - 1) + "^";
|
||||
}
|
||||
params.before = params.before.replace(/^./, ">");
|
||||
}
|
||||
}).join("\n");
|
||||
};
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = function () {
|
||||
return Object.create(null);
|
||||
};
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A trick from Bluebird to force V8 to use fast properties for an object.
|
||||
* Read more: http://stackoverflow.com/questions/24987896/
|
||||
@@ -17,7 +17,8 @@ exports.messages = {
|
||||
modulesIllegalExportName: "Illegal export $1",
|
||||
unknownForHead: "Unknown node type $1 in ForStatement",
|
||||
didYouMean: "Did you mean $1?",
|
||||
evalInStrictMode: "eval is not allowed in strict mode"
|
||||
evalInStrictMode: "eval is not allowed in strict mode",
|
||||
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2."
|
||||
};
|
||||
|
||||
exports.get = function (key) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var extend = require("lodash/object/extend");
|
||||
var t = require("./types");
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
if (global._babelPolyfill) {
|
||||
throw new Error("only one instance of babel/polyfill is allowed");
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = File;
|
||||
|
||||
var sourceMapToComment = require("source-map-to-comment");
|
||||
@@ -24,12 +22,13 @@ function File(opts) {
|
||||
this.dynamicImported = [];
|
||||
this.dynamicImports = [];
|
||||
|
||||
this.dynamicData = {};
|
||||
this.data = {};
|
||||
this.usedHelpers = {};
|
||||
this.dynamicData = {};
|
||||
this.data = {};
|
||||
|
||||
this.lastStatements = [];
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.ast = {};
|
||||
this.lastStatements = [];
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.ast = {};
|
||||
|
||||
this.buildTransformers();
|
||||
}
|
||||
@@ -60,7 +59,7 @@ File.helpers = [
|
||||
"object-destructuring-empty",
|
||||
"temporal-undefined",
|
||||
"temporal-assert-defined",
|
||||
"tail-call"
|
||||
"self-global"
|
||||
];
|
||||
|
||||
File.validOptions = [
|
||||
@@ -82,12 +81,18 @@ File.validOptions = [
|
||||
"keepModuleIdExtensions",
|
||||
"code",
|
||||
"ast",
|
||||
"format",
|
||||
"playground",
|
||||
"experimental",
|
||||
"resolveModuleSource",
|
||||
"externalHelpers",
|
||||
"auxiliaryComment",
|
||||
"compact",
|
||||
"returnUsedHelpers",
|
||||
|
||||
"resolveModuleSource",
|
||||
"moduleId",
|
||||
|
||||
// legacy
|
||||
"format",
|
||||
|
||||
// these are used by plugins
|
||||
"ignore",
|
||||
@@ -108,12 +113,12 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
defaults(opts, {
|
||||
keepModuleIdExtensions: false,
|
||||
resolveModuleSource: null,
|
||||
returnUsedHelpers: false,
|
||||
externalHelpers: false,
|
||||
auxilaryComment: "",
|
||||
experimental: false,
|
||||
reactCompat: false,
|
||||
playground: false,
|
||||
whitespace: true,
|
||||
moduleIds: false,
|
||||
blacklist: [],
|
||||
whitelist: [],
|
||||
@@ -122,6 +127,7 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
comments: true,
|
||||
filename: "unknown",
|
||||
modules: "common",
|
||||
compact: "auto",
|
||||
loose: [],
|
||||
code: true,
|
||||
ast: true
|
||||
@@ -133,11 +139,16 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
opts.sourceRoot = slash(opts.sourceRoot);
|
||||
}
|
||||
|
||||
if (opts.moduleId) {
|
||||
opts.moduleIds = true;
|
||||
}
|
||||
|
||||
opts.basename = path.basename(opts.filename, path.extname(opts.filename));
|
||||
|
||||
opts.blacklist = util.arrayify(opts.blacklist);
|
||||
opts.whitelist = util.arrayify(opts.whitelist);
|
||||
opts.optional = util.arrayify(opts.optional);
|
||||
opts.compact = util.booleanify(opts.compact);
|
||||
opts.loose = util.arrayify(opts.loose);
|
||||
|
||||
if (includes(opts.loose, "all") || includes(opts.loose, true)) {
|
||||
@@ -166,7 +177,7 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
}
|
||||
|
||||
if (opts.externalHelpers) {
|
||||
this.set("runtimeIdentifier", t.identifier("babelHelpers"));
|
||||
this.set("helpersNamespace", t.identifier("babelHelpers"));
|
||||
}
|
||||
|
||||
opts.blacklist = transform._ensureTransformerNames("blacklist", opts.blacklist);
|
||||
@@ -176,8 +187,7 @@ File.prototype.normalizeOptions = function (opts) {
|
||||
|
||||
if (opts.reactCompat) {
|
||||
opts.optional.push("reactCompat");
|
||||
console.error("The reactCompat option has been moved into the optional transformer " +
|
||||
"`reactCompat` - backwards compatibility will be removed in v4.0.0");
|
||||
console.error("The reactCompat option has been moved into the optional transformer `reactCompat`");
|
||||
}
|
||||
|
||||
var ensureEnabled = function (key) {
|
||||
@@ -279,7 +289,7 @@ File.prototype.get = function (key) {
|
||||
};
|
||||
|
||||
File.prototype.addImport = function (source, name, noDefault) {
|
||||
name = name || source;
|
||||
name ||= source;
|
||||
var id = this.dynamicImportIds[name];
|
||||
|
||||
if (!id) {
|
||||
@@ -305,7 +315,7 @@ File.prototype.isConsequenceExpressionStatement = function (node) {
|
||||
File.prototype.attachAuxiliaryComment = function (node) {
|
||||
var comment = this.opts.auxiliaryComment;
|
||||
if (comment) {
|
||||
node.leadingComments = node.leadingComments || [];
|
||||
node.leadingComments ||= [];
|
||||
node.leadingComments.push({
|
||||
type: "Line",
|
||||
value: " " + comment
|
||||
@@ -324,7 +334,9 @@ File.prototype.addHelper = function (name) {
|
||||
var declar = program._declarations && program._declarations[name];
|
||||
if (declar) return declar.id;
|
||||
|
||||
var runtime = this.get("runtimeIdentifier");
|
||||
this.usedHelpers[name] = true;
|
||||
|
||||
var runtime = this.get("helpersNamespace");
|
||||
if (runtime) {
|
||||
name = t.identifier(t.toIdentifier(name));
|
||||
return t.memberExpression(runtime, name);
|
||||
@@ -346,7 +358,7 @@ File.prototype.logDeopt = function () {
|
||||
};
|
||||
|
||||
File.prototype.errorWithNode = function (node, msg, Error) {
|
||||
Error = Error || SyntaxError;
|
||||
Error ||= SyntaxError;
|
||||
|
||||
var loc = node.loc.start;
|
||||
var err = new Error("Line " + loc.line + ": " + msg);
|
||||
@@ -361,8 +373,6 @@ File.prototype.addCode = function (code) {
|
||||
};
|
||||
|
||||
File.prototype.parse = function (code) {
|
||||
var self = this;
|
||||
|
||||
code = this.addCode(code);
|
||||
|
||||
var opts = this.opts;
|
||||
@@ -370,9 +380,9 @@ File.prototype.parse = function (code) {
|
||||
opts.allowImportExportEverywhere = this.isLoose("es6.modules");
|
||||
opts.strictMode = this.transformers.useStrict.canRun();
|
||||
|
||||
return parse(opts, code, function (tree) {
|
||||
self.transform(tree);
|
||||
return self.generate();
|
||||
return parse(opts, code, (tree) => {
|
||||
this.transform(tree);
|
||||
return this.generate();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -410,7 +420,7 @@ File.prototype.call = function (key) {
|
||||
};
|
||||
|
||||
var checkTransformerVisitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
enter(node, parent, scope, state) {
|
||||
checkNode(state.stack, node, scope);
|
||||
}
|
||||
};
|
||||
@@ -424,7 +434,7 @@ var checkNode = function (stack, node, scope) {
|
||||
|
||||
File.prototype.checkNode = function (node, scope) {
|
||||
var stack = this.transformerStack;
|
||||
scope = scope || this.scope;
|
||||
scope ||= this.scope;
|
||||
|
||||
checkNode(stack, node, scope);
|
||||
|
||||
@@ -443,6 +453,10 @@ File.prototype.generate = function () {
|
||||
ast: null
|
||||
};
|
||||
|
||||
if (this.opts.returnUsedHelpers) {
|
||||
result.usedHelpers = Object.keys(this.usedHelpers);
|
||||
}
|
||||
|
||||
if (opts.ast) result.ast = ast;
|
||||
if (!opts.code) return result;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var explode = require("./explode-assignable-expression");
|
||||
var t = require("../../types");
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function build(node, buildBody) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var explode = require("./explode-assignable-expression");
|
||||
var t = require("../../types");
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
// Based upon the excellent jsx-transpiler by Ingvar Stepanyan (RReverser)
|
||||
// https://github.com/RReverser/jsx-transpiler
|
||||
|
||||
@@ -33,7 +31,7 @@ module.exports = function (exports, opts) {
|
||||
};
|
||||
|
||||
exports.JSXMemberExpression = {
|
||||
exit: function (node) {
|
||||
exit(node) {
|
||||
node.computed = t.isLiteral(node.property);
|
||||
node.type = "MemberExpression";
|
||||
}
|
||||
@@ -44,18 +42,21 @@ module.exports = function (exports, opts) {
|
||||
};
|
||||
|
||||
exports.JSXAttribute = {
|
||||
exit: function (node) {
|
||||
var value = node.value || t.literal(true);
|
||||
|
||||
enter(node) {
|
||||
var value = node.value;
|
||||
if (t.isLiteral(value) && isString(value.value)) {
|
||||
value.value = value.value.replace(/\n\s+/g, " ");
|
||||
}
|
||||
},
|
||||
|
||||
exit(node) {
|
||||
var value = node.value || t.literal(true);
|
||||
return t.inherits(t.property("init", node.name, value), node);
|
||||
}
|
||||
};
|
||||
|
||||
exports.JSXOpeningElement = {
|
||||
exit: function (node, parent, scope, file) {
|
||||
exit(node, parent, scope, file) {
|
||||
var tagExpr = node.name;
|
||||
var args = [];
|
||||
|
||||
@@ -73,7 +74,7 @@ module.exports = function (exports, opts) {
|
||||
};
|
||||
|
||||
if (opts.pre) {
|
||||
opts.pre(state);
|
||||
opts.pre(state, file);
|
||||
}
|
||||
|
||||
var attribs = node.attributes;
|
||||
@@ -86,7 +87,7 @@ module.exports = function (exports, opts) {
|
||||
args.push(attribs);
|
||||
|
||||
if (opts.post) {
|
||||
opts.post(state);
|
||||
opts.post(state, file);
|
||||
}
|
||||
|
||||
return state.call || t.callExpression(state.callee, args);
|
||||
@@ -143,7 +144,7 @@ module.exports = function (exports, opts) {
|
||||
};
|
||||
|
||||
exports.JSXElement = {
|
||||
exit: function (node) {
|
||||
exit(node) {
|
||||
var callExpr = node.openingElement;
|
||||
|
||||
for (var i = 0; i < node.children.length; i++) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
var getObjRef = function (node, nodes, file, scope) {
|
||||
9
src/babel/transformation/helpers/get-function-arity.js
Normal file
9
src/babel/transformation/helpers/get-function-arity.js
Normal file
@@ -0,0 +1,9 @@
|
||||
var t = require("../../types");
|
||||
|
||||
module.exports = function (node) {
|
||||
var lastNonDefault = 0;
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
if (!t.isAssignmentPattern(node.params[i])) lastNonDefault = i + 1;
|
||||
}
|
||||
return lastNonDefault;
|
||||
};
|
||||
126
src/babel/transformation/helpers/name-method.js
Normal file
126
src/babel/transformation/helpers/name-method.js
Normal file
@@ -0,0 +1,126 @@
|
||||
var getFunctionArity = require("./get-function-arity");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
|
||||
var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
// check if this node is a referenced identifier that matches the same as our
|
||||
// function id
|
||||
if (!t.isReferencedIdentifier(node, parent, { name: state.name })) return;
|
||||
|
||||
// check that we don't have a local variable declared as that removes the need
|
||||
// for the wrapper
|
||||
var localDeclar = scope.getBindingIdentifier(state.name);
|
||||
if (localDeclar !== state.outerDeclar) return;
|
||||
|
||||
state.selfReference = true;
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
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),
|
||||
WRAPPER_KEY: scope.generateUidIdentifier(id.name + "Wrapper")
|
||||
});
|
||||
|
||||
// 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].declarations[0].init.params;
|
||||
for (var i = 0, len = getFunctionArity(method); i < len; i++) {
|
||||
params.push(scope.generateUidIdentifier("x"));
|
||||
}
|
||||
|
||||
return template;
|
||||
} else {
|
||||
method.id = id;
|
||||
return method;
|
||||
}
|
||||
};
|
||||
|
||||
var visit = function (node, name, scope) {
|
||||
var state = {
|
||||
selfAssignment: false,
|
||||
selfReference: false,
|
||||
outerDeclar: scope.getBindingIdentifier(name),
|
||||
references: [],
|
||||
name: name,
|
||||
};
|
||||
|
||||
// check to see if we have a local binding of the id we're setting inside of
|
||||
// the function, this is important as there are caveats associated
|
||||
|
||||
var bindingInfo = null; // todo: proper scope not being passed in es6/classes // scope.getOwnBindingInfo(name);
|
||||
|
||||
if (bindingInfo) {
|
||||
if (bindingInfo.kind === "param") {
|
||||
// safari will blow up in strict mode with code like:
|
||||
//
|
||||
// var t = function t(t) {};
|
||||
//
|
||||
// with the error:
|
||||
//
|
||||
// Cannot declare a parameter named 't' as it shadows the name of a
|
||||
// strict mode function.
|
||||
//
|
||||
// this isn't to the spec and they've invented this behaviour which is
|
||||
// **extremely** annoying so we avoid setting the name if it has a param
|
||||
// with the same id
|
||||
state.selfReference = true;
|
||||
} else {
|
||||
// otherwise it's defined somewhere in scope like:
|
||||
//
|
||||
// var t = function () {
|
||||
// var t = 2;
|
||||
// };
|
||||
//
|
||||
// so we can safely just set the id and move along as it shadows the
|
||||
// bound function id
|
||||
}
|
||||
} else {
|
||||
scope.traverse(node, visitor, state);
|
||||
}
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
exports.property = function (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
|
||||
|
||||
var name = t.toIdentifier(key.value);
|
||||
var id = t.identifier(name);
|
||||
|
||||
var method = node.value;
|
||||
var state = visit(method, name, scope);
|
||||
node.value = wrap(state, method, id, scope);
|
||||
};
|
||||
|
||||
exports.bare = function (node, parent, scope) {
|
||||
// has an `id` so we don't need to infer one
|
||||
if (node.id) return;
|
||||
|
||||
var id;
|
||||
if (t.isProperty(parent) && parent.kind === "init" && !parent.computed) {
|
||||
// { foo() {} };
|
||||
id = parent.key;
|
||||
} else if (t.isVariableDeclarator(parent)) {
|
||||
// var foo = function () {};
|
||||
id = parent.id;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!t.isIdentifier(id)) return;
|
||||
|
||||
var name = t.toIdentifier(id.name);
|
||||
id = t.identifier(name);
|
||||
|
||||
var state = visit(node, name, scope);
|
||||
return wrap(state, node, id, scope);
|
||||
};
|
||||
@@ -1,9 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
var visitor = {
|
||||
enter: function (node) {
|
||||
enter(node) {
|
||||
if (t.isFunction(node)) this.skip();
|
||||
|
||||
if (t.isAwaitExpression(node)) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = ReplaceSupers;
|
||||
|
||||
var messages = require("../../messages");
|
||||
@@ -96,7 +94,7 @@ ReplaceSupers.prototype.replace = function () {
|
||||
};
|
||||
|
||||
var visitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
enter(node, parent, scope, state) {
|
||||
var topLevel = state.topLevel;
|
||||
var self = state.self;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
var t = require("../../types");
|
||||
|
||||
exports.has = function (node) {
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = transform;
|
||||
|
||||
var normalizeAst = require("../helpers/normalize-ast");
|
||||
@@ -60,7 +58,7 @@ var rawTransformers = require("./transformers");
|
||||
each(rawTransformers, function (transformer, key) {
|
||||
var namespace = key.split(".")[0];
|
||||
|
||||
transform.namespaces[namespace] = transform.namespaces[namespace] || [];
|
||||
transform.namespaces[namespace] ||= [];
|
||||
transform.namespaces[namespace].push(key);
|
||||
transform.transformerNamespaces[key] = namespace;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = DefaultFormatter;
|
||||
|
||||
var messages = require("../../messages");
|
||||
@@ -35,12 +33,12 @@ DefaultFormatter.prototype.doDefaultExportInterop = function (node) {
|
||||
DefaultFormatter.prototype.bumpImportOccurences = function (node) {
|
||||
var source = node.source.value;
|
||||
var occurs = this.localImportOccurences;
|
||||
occurs[source] = occurs[source] || 0;
|
||||
occurs[source] ||= 0;
|
||||
occurs[source] += node.specifiers.length;
|
||||
};
|
||||
|
||||
var exportsVisitor = {
|
||||
enter: function (node, parent, scope, formatter) {
|
||||
enter(node, parent, scope, formatter) {
|
||||
var declar = node && node.declaration;
|
||||
if (t.isExportDeclaration(node)) {
|
||||
formatter.hasLocalImports = true;
|
||||
@@ -65,7 +63,7 @@ DefaultFormatter.prototype.getLocalExports = function () {
|
||||
};
|
||||
|
||||
var importsVisitor = {
|
||||
enter: function (node, parent, scope, formatter) {
|
||||
enter(node, parent, scope, formatter) {
|
||||
if (t.isImportDeclaration(node)) {
|
||||
formatter.hasLocalImports = true;
|
||||
extend(formatter.localImports, t.getBindingIdentifiers(node));
|
||||
@@ -79,7 +77,7 @@ DefaultFormatter.prototype.getLocalImports = function () {
|
||||
};
|
||||
|
||||
var remapVisitor = {
|
||||
enter: function (node, parent, scope, formatter) {
|
||||
enter(node, parent, scope, formatter) {
|
||||
if (t.isUpdateExpression(node) && formatter.isLocalReference(node.argument, scope)) {
|
||||
this.skip();
|
||||
|
||||
@@ -146,6 +144,8 @@ DefaultFormatter.prototype.isLocalReference = function (node, scope) {
|
||||
|
||||
DefaultFormatter.prototype.getModuleName = function () {
|
||||
var opts = this.file.opts;
|
||||
if (opts.moduleId) return opts.moduleId;
|
||||
|
||||
var filenameRelative = opts.filenameRelative;
|
||||
var moduleName = "";
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var util = require("../../util");
|
||||
|
||||
module.exports = function (Parent) {
|
||||
var Constructor = function () {
|
||||
this.noInteropRequireImport = true;
|
||||
this.noInteropRequireExport = true;
|
||||
Parent.apply(this, arguments);
|
||||
};
|
||||
@@ -1,3 +1 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = require("./_strict")(require("./amd"));
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = AMDFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
@@ -1,3 +1 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = require("./_strict")(require("./common"));
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = CommonJSFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = IgnoreFormatter;
|
||||
|
||||
var t = require("../../types");
|
||||
10
src/babel/transformation/modules/index.js
Normal file
10
src/babel/transformation/modules/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
commonStrict: require("./common-strict"),
|
||||
amdStrict: require("./amd-strict"),
|
||||
umdStrict: require("./umd-strict"),
|
||||
common: require("./common"),
|
||||
system: require("./system"),
|
||||
ignore: require("./ignore"),
|
||||
amd: require("./amd"),
|
||||
umd: require("./umd")
|
||||
};
|
||||
@@ -1,15 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = SystemFormatter;
|
||||
|
||||
var DefaultFormatter = require("./_default");
|
||||
var AMDFormatter = require("./amd");
|
||||
var useStrict = require("../helpers/use-strict");
|
||||
var util = require("../../util");
|
||||
var t = require("../../types");
|
||||
var last = require("lodash/array/last");
|
||||
var each = require("lodash/collection/each");
|
||||
var map = require("lodash/collection/map");
|
||||
var t = require("../../types");
|
||||
|
||||
function SystemFormatter(file) {
|
||||
this.exportIdentifier = file.scope.generateUidIdentifier("export");
|
||||
@@ -69,7 +66,7 @@ SystemFormatter.prototype.importSpecifier = function (specifier, node, nodes) {
|
||||
};
|
||||
|
||||
var runnerSettersVisitor = {
|
||||
enter: function (node, parent, scope, state) {
|
||||
enter(node, parent, scope, state) {
|
||||
if (node._importSource === state.source) {
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
each(node.declarations, function (declar) {
|
||||
@@ -104,7 +101,7 @@ SystemFormatter.prototype.buildRunnerSetters = function (block, hoistDeclarators
|
||||
};
|
||||
|
||||
var hoistVariablesVisitor = {
|
||||
enter: function (node, parent, scope, hoistDeclarators) {
|
||||
enter(node, parent, scope, hoistDeclarators) {
|
||||
if (t.isFunction(node)) {
|
||||
// nothing inside is accessible
|
||||
return this.skip();
|
||||
@@ -149,7 +146,7 @@ var hoistVariablesVisitor = {
|
||||
};
|
||||
|
||||
var hoistFunctionsVisitor = {
|
||||
enter: function (node, parent, scope, handlerBody) {
|
||||
enter(node, parent, scope, handlerBody) {
|
||||
if (t.isFunction(node)) this.skip();
|
||||
|
||||
if (t.isFunctionDeclaration(node) || node._blockHoist) {
|
||||
@@ -193,9 +190,5 @@ SystemFormatter.prototype.transform = function (program) {
|
||||
|
||||
handlerBody.push(returnStatement);
|
||||
|
||||
if (useStrict.has(block)) {
|
||||
handlerBody.unshift(block.body.shift());
|
||||
}
|
||||
|
||||
program.body = [runner];
|
||||
};
|
||||
@@ -1,3 +1 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = require("./_strict")(require("./umd"));
|
||||
@@ -1,5 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = UMDFormatter;
|
||||
|
||||
var AMDFormatter = require("./amd");
|
||||
3
src/babel/transformation/templates/.babelrc
Normal file
3
src/babel/transformation/templates/.babelrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"blacklist": ["useStrict", "es6.blockScoping"]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user