Compare commits
180 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d12f4d0bc8 | ||
|
|
97680e9dfd | ||
|
|
51341ca6c3 | ||
|
|
ab54bfa50e | ||
|
|
60aa933fb6 | ||
|
|
b0317f9bab | ||
|
|
be2dfaf081 | ||
|
|
2c8437ae92 | ||
|
|
2a0bcfd086 | ||
|
|
2cf41afac3 | ||
|
|
e318f5f3be | ||
|
|
939decb86c | ||
|
|
1baa0df948 | ||
|
|
e8956a8c44 | ||
|
|
2f0fdbbc26 | ||
|
|
5f931525bc | ||
|
|
b86545a320 | ||
|
|
06e75c42bf | ||
|
|
05dd65244d | ||
|
|
c4ebfeb0fa | ||
|
|
1aa0bbfac9 | ||
|
|
58f1e6cbc6 | ||
|
|
83e0be3038 | ||
|
|
5fc242e4ec | ||
|
|
dc101adad3 | ||
|
|
faade72787 | ||
|
|
2a78ae9889 | ||
|
|
9840639843 | ||
|
|
82c21a901e | ||
|
|
e1c83144c1 | ||
|
|
ef2ac73215 | ||
|
|
735d8955bf | ||
|
|
3abee0a4fa | ||
|
|
b6f18b4f2b | ||
|
|
85cd0465fa | ||
|
|
0452e0fdd2 | ||
|
|
462ff572b3 | ||
|
|
d11099bb2b | ||
|
|
f5c4684d3e | ||
|
|
876a22578b | ||
|
|
9f5e8b296b | ||
|
|
d9deb02edc | ||
|
|
a402d0cdeb | ||
|
|
683fb62505 | ||
|
|
941474983d | ||
|
|
2b42773e01 | ||
|
|
8277a532f4 | ||
|
|
539784b640 | ||
|
|
f373f8f003 | ||
|
|
8605e835eb | ||
|
|
b4ace2043a | ||
|
|
444a64e934 | ||
|
|
8ea2ae924d | ||
|
|
4ceb1d6f5e | ||
|
|
3c81899ca7 | ||
|
|
ab59fd08e5 | ||
|
|
19b05b5e61 | ||
|
|
65a44a1e13 | ||
|
|
d38f18af40 | ||
|
|
2744b9f31f | ||
|
|
4deed35212 | ||
|
|
bc9ae5ea8b | ||
|
|
87d879e236 | ||
|
|
f657598c72 | ||
|
|
2a5cb9d21b | ||
|
|
cf7d6b655e | ||
|
|
6d2723eec5 | ||
|
|
6834cc5b46 | ||
|
|
9b949e574f | ||
|
|
a75af0a5d2 | ||
|
|
080b26769c | ||
|
|
e037ae7bc9 | ||
|
|
c60ad89937 | ||
|
|
4194857086 | ||
|
|
1179c44c5b | ||
|
|
f6d9b270c9 | ||
|
|
1be0159b01 | ||
|
|
61ba8ad997 | ||
|
|
89e31085d2 | ||
|
|
920c84a1f2 | ||
|
|
ed56fecd04 | ||
|
|
f0bfdfb699 | ||
|
|
b02a1112bc | ||
|
|
590a165776 | ||
|
|
2fd1b2a484 | ||
|
|
8f9d02d689 | ||
|
|
b376b6b33b | ||
|
|
8292d6d8ad | ||
|
|
d6a5c39079 | ||
|
|
2a9a59f784 | ||
|
|
abf4a5495a | ||
|
|
f8b8723bef | ||
|
|
6b9686f2dd | ||
|
|
4a439d8c8e | ||
|
|
c526a3eb04 | ||
|
|
ba516901af | ||
|
|
8f52229a86 | ||
|
|
5b793f8882 | ||
|
|
b31c14c52a | ||
|
|
78b72512cb | ||
|
|
2fbb3cad9f | ||
|
|
2621081a13 | ||
|
|
8daf95bf59 | ||
|
|
6e8ab16b25 | ||
|
|
a5cda5caa7 | ||
|
|
13a6c69668 | ||
|
|
380293d030 | ||
|
|
0b15a97013 | ||
|
|
11af066956 | ||
|
|
d7b4d342c3 | ||
|
|
77aeebe2a8 | ||
|
|
c3a08d413f | ||
|
|
23ac2319af | ||
|
|
a1bc0704ab | ||
|
|
0bbfd427af | ||
|
|
f17b268a71 | ||
|
|
9ffc265bea | ||
|
|
6f664ca64e | ||
|
|
8a4a76000d | ||
|
|
e83daf87d4 | ||
|
|
8ed90d3af2 | ||
|
|
0bb311f8ce | ||
|
|
53f0f0302b | ||
|
|
c25a5d2480 | ||
|
|
fc8540d88a | ||
|
|
31a4195c81 | ||
|
|
bf0e4ede00 | ||
|
|
3757bc6b9a | ||
|
|
2e01f220da | ||
|
|
8ae4e1fdf2 | ||
|
|
f6219ec15a | ||
|
|
6a82eb5a5c | ||
|
|
a241300ff1 | ||
|
|
d5548a6ff9 | ||
|
|
ba6cb112c3 | ||
|
|
8f1bb84930 | ||
|
|
235726eee6 | ||
|
|
08183ef490 | ||
|
|
dc6fc3b30a | ||
|
|
76f2eb5684 | ||
|
|
4f33687957 | ||
|
|
74f37fe0a3 | ||
|
|
cc5e4bce52 | ||
|
|
f441a7cae8 | ||
|
|
fc2be81c43 | ||
|
|
1277a8f67f | ||
|
|
86c6d4e769 | ||
|
|
bf2d527cfe | ||
|
|
6b59ea8eac | ||
|
|
72e3cb9243 | ||
|
|
5e5ede6058 | ||
|
|
d25944ea1f | ||
|
|
fce2aa8fa3 | ||
|
|
0112c63779 | ||
|
|
6a4e93bf0f | ||
|
|
4328e920d2 | ||
|
|
bbbf0a895d | ||
|
|
3289b33806 | ||
|
|
f4b9faa6b3 | ||
|
|
239b77816f | ||
|
|
8565e2b4e5 | ||
|
|
4317a46a3e | ||
|
|
81ca29adc3 | ||
|
|
c1a6ff7f44 | ||
|
|
7e6e5d4746 | ||
|
|
12d650e195 | ||
|
|
8fb58492df | ||
|
|
2c0c2f12df | ||
|
|
01e5354fd9 | ||
|
|
0b100c4273 | ||
|
|
340e75eb59 | ||
|
|
53808a6d45 | ||
|
|
e6326332b6 | ||
|
|
9e0cf84505 | ||
|
|
b7eea7b08c | ||
|
|
92dd67856e | ||
|
|
a2bb587e24 | ||
|
|
0c570cb599 | ||
|
|
db6fab2c8f | ||
|
|
6491018c21 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "vendor/traceur"]
|
||||
path = vendor/traceur
|
||||
url = https://github.com/google/traceur-compiler
|
||||
[submodule "vendor/compat-table"]
|
||||
path = vendor/compat-table
|
||||
url = https://github.com/kangax/compat-table
|
||||
|
||||
99
CHANGELOG.md
99
CHANGELOG.md
@@ -13,6 +13,105 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 5.3.2
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix patterns not being considered when hoisting variables in the `es6.blockScoping` transformer.
|
||||
|
||||
## 5.3.1
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix unique export specifiers not being cloned when exploding class and function exports,
|
||||
* **Polish**
|
||||
* Turn import remaps to sequence expressions to remove their context and improve performance.
|
||||
|
||||
## 5.3.0
|
||||
|
||||
**Speeeeeeed**
|
||||
|
||||

|
||||
|
||||
* **Spec Compliancy**
|
||||
* Allow trailing param commas for methods when using the `es7.trailingCommas` transformer.
|
||||
* **Bug Fix**
|
||||
* Fix `es6.blockScoping` transformer not properly ignoring `break` in `SwitchCase`.
|
||||
* Fix lookahead context saving to avoid weird tokenizer state.
|
||||
* Explode duplicate identifiers in export/import specifiers and property shorthand to create unique objects.
|
||||
* Skip loose mode for class methods when they have decorators.
|
||||
* When removing nodes, share their comments with their siblings.
|
||||
* Properly hoist temp param declarations when doing TCO.
|
||||
* **Internal**
|
||||
* Add `--harmony_generators` flag to `$ babel-node`.
|
||||
* **Polish**
|
||||
* Move many `utility` transformers to `minification`.
|
||||
|
||||
## 5.2.17
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix auxiliary comments not properly being attached to function declaration helpers.
|
||||
* Add `Super` node type to `ast-types` patch.
|
||||
* Ignore parameter bindings when attempting to inline them in the `minification.deadCodeElimination` transformer.
|
||||
* Correct `extensions` arguments when using the Babel CLI.
|
||||
|
||||
## 5.2.16
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix plugins being disabled when using the whitelist.
|
||||
* Fix correct function scope being passed to `nameMethod.property` when inferring the function name for class methods.
|
||||
* Fix incorrect extensions reference causing weird issues when using the Babel CLI.
|
||||
* Fix destructuring param reference replacements not inheriting from their original param.
|
||||
* **Spec Compliancy**
|
||||
* Fix order that method decorators are ran in.
|
||||
|
||||
## 5.2.15
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix initializer descriptor add attempt if it doesn't exist.
|
||||
|
||||
## 5.2.14
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix bug with initializer decorators where the descriptors weren't being defined if there was no `initializer` property.
|
||||
* **Internal**
|
||||
* Expose `retainLines` option to CLI.
|
||||
* Fix `retainLines` option not being taken into consideration when doing multiple variable declaration declarators generation.
|
||||
* Expose minified and unminified copies of dist scripts.
|
||||
|
||||
## 5.2.13
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `ExportDeclaration`s being incorrectly removed when using the `utility.deadCodeElimination` transformer.
|
||||
* Fix position of `utility` transformers.
|
||||
* **New Feature**
|
||||
* Add built-in `esquery` support.
|
||||
* **Internal**
|
||||
* Consolidate notion of "virtual types".
|
||||
|
||||
## 5.2.12
|
||||
|
||||
* **Polish**
|
||||
* Make UID generation based on module declarations **much** nicer.
|
||||
* **Internal**
|
||||
* Remove internal check for traversal path replacement of self. This is a pattern that **could** come up in the wild and it could lead to pretty nasty code and may lead to internal regressions as the test coverage isn't 100% :( Instead, just put it in the fast path.
|
||||
|
||||
## 5.2.11
|
||||
|
||||
* **Internal**
|
||||
* Rename `getModuleName` option to `getModuleId`, doh.
|
||||
|
||||
## 5.2.10
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix numerous issues in `replaceWithSourceString`. Thanks [@pangratz](https://github.com/pangratz)!
|
||||
* **New Feature**
|
||||
* Add `getModuleName` option. Thanks [@jayphelps](https://github.com/jayphelps)!
|
||||
|
||||
## 5.2.9
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `_blockHoist` transformer incorrectly sorting nodes on shitty environments that aren't spec compliant in their key order.
|
||||
* Fix broken `parse` API method reference to an undeclared import.
|
||||
|
||||
## 5.2.7
|
||||
|
||||
* **Bug Fix**
|
||||
|
||||
15
Makefile
15
Makefile
@@ -82,9 +82,15 @@ publish:
|
||||
npm version $$version --message "v%s"
|
||||
|
||||
make build
|
||||
cp dist/babel.min.js browser.js
|
||||
cp dist/polyfill.min.js browser-polyfill.js
|
||||
cp dist/external-helpers.min.js external-helpers.js
|
||||
|
||||
cp dist/babel.js browser.js
|
||||
cp dist/babel.min.js browser.min.js
|
||||
|
||||
cp dist/polyfill.js browser-polyfill.js
|
||||
cp dist/polyfill.min.js browser-polyfill.min.js
|
||||
|
||||
cp dist/external-helpers.js external-helpers.js
|
||||
cp dist/external-helpers.min.js external-helpers.min.js
|
||||
|
||||
node tools/cache-templates
|
||||
test -f templates.json
|
||||
@@ -96,7 +102,7 @@ publish:
|
||||
make publish-cli
|
||||
make publish-runtime
|
||||
|
||||
rm -rf templates.json browser.js browser-polyfill.js external-helpers.js
|
||||
rm -rf templates.json browser.js browser.min.js browser-polyfill.js browser-polyfill.min.js external-helpers.js external-helpers.min.js
|
||||
|
||||
publish-runtime:
|
||||
cd packages; \
|
||||
@@ -116,5 +122,4 @@ bootstrap:
|
||||
npm link
|
||||
cd packages/babel-cli && npm install && npm link && npm link babel-core
|
||||
git submodule update --init
|
||||
cd vendor/compat-table && npm install object-assign
|
||||
make build
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"name": "babel-core",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.2.8",
|
||||
"version": "5.3.2",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"main": "lib/babel/api/node.js",
|
||||
"browser": {
|
||||
@@ -27,6 +28,7 @@
|
||||
"test": "make test"
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn-jsx": "^1.0.0",
|
||||
"ast-types": "~0.7.0",
|
||||
"bluebird": "^2.9.25",
|
||||
"chalk": "^1.0.0",
|
||||
@@ -34,7 +36,8 @@
|
||||
"core-js": "^0.9.0",
|
||||
"debug": "^2.1.1",
|
||||
"detect-indent": "^3.0.0",
|
||||
"estraverse": "^3.0.0",
|
||||
"esquery": "^0.4.0",
|
||||
"estraverse": "^4.0.0",
|
||||
"esutils": "^2.0.0",
|
||||
"fs-readdir-recursive": "^0.1.0",
|
||||
"globals": "^6.4.0",
|
||||
@@ -61,7 +64,7 @@
|
||||
"user-home": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "5.1.13",
|
||||
"babel": "5.3.1",
|
||||
"browserify": "^9.0.8",
|
||||
"chai": "^2.2.0",
|
||||
"eslint": "^0.18.0",
|
||||
|
||||
@@ -55,6 +55,8 @@ babelArgs.forEach(function(arg){
|
||||
case "--harmony_classes":
|
||||
case "--harmony_object_literals":
|
||||
case "--harmony_templates":
|
||||
case "--harmony_rest_parameters":
|
||||
case "--harmony_generators":
|
||||
case "--compiled_keyed_generic_loads":
|
||||
case "--pretenuring_call_new":
|
||||
case "--allocation_site_pretenuring":
|
||||
|
||||
@@ -70,6 +70,12 @@ commander.parse(process.argv);
|
||||
|
||||
//
|
||||
|
||||
if (commander.extensions) {
|
||||
commander.extensions = util.arrayify(commander.extensions);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
var errors = [];
|
||||
|
||||
var filenames = commander.args.reduce(function (globbed, input) {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{
|
||||
"name": "babel",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.2.7",
|
||||
"version": "5.3.1",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"preferGlobal": true,
|
||||
"dependencies": {
|
||||
"babel-core": "^5.2.7",
|
||||
"babel-core": "^5.3.1",
|
||||
"chokidar": "^1.0.0",
|
||||
"commander": "^2.6.0",
|
||||
"convert-source-map": "^1.1.0",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "babel-runtime",
|
||||
"description": "babel selfContained runtime",
|
||||
"version": "5.2.7",
|
||||
"version": "5.3.1",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
export * from "./src/index";
|
||||
import "./plugins/flow";
|
||||
import "./plugins/jsx";
|
||||
|
||||
import inject from "acorn-jsx/inject";
|
||||
import * as acorn from "./src/index";
|
||||
inject(acorn);
|
||||
|
||||
@@ -153,10 +153,15 @@ pp.flow_parseTypeAlias = function (node) {
|
||||
node.typeParameters = null
|
||||
}
|
||||
|
||||
var oldInType = this.inType;
|
||||
this.inType = true;
|
||||
|
||||
this.expect(tt.eq)
|
||||
|
||||
node.right = this.flow_parseType()
|
||||
|
||||
this.inType = oldInType;
|
||||
|
||||
this.semicolon()
|
||||
|
||||
return this.finishNode(node, "TypeAlias")
|
||||
|
||||
@@ -1,658 +0,0 @@
|
||||
var acorn = require("../src/index")
|
||||
|
||||
var tt = acorn.tokTypes;
|
||||
var tc = acorn.tokContexts;
|
||||
|
||||
tc.j_oTag = new acorn.TokContext("<tag", false);
|
||||
tc.j_cTag = new acorn.TokContext("</tag", false);
|
||||
tc.j_expr = new acorn.TokContext("<tag>...</tag>", true, true);
|
||||
|
||||
tt.jsxName = new acorn.TokenType("jsxName");
|
||||
tt.jsxText = new acorn.TokenType("jsxText", {beforeExpr: true});
|
||||
tt.jsxTagStart = new acorn.TokenType("jsxTagStart");
|
||||
tt.jsxTagEnd = new acorn.TokenType("jsxTagEnd");
|
||||
|
||||
tt.jsxTagStart.updateContext = function() {
|
||||
this.context.push(tc.j_expr); // treat as beginning of JSX expression
|
||||
this.context.push(tc.j_oTag); // start opening tag context
|
||||
this.exprAllowed = false;
|
||||
};
|
||||
tt.jsxTagEnd.updateContext = function(prevType) {
|
||||
var out = this.context.pop();
|
||||
if (out === tc.j_oTag && prevType === tt.slash || out === tc.j_cTag) {
|
||||
this.context.pop();
|
||||
this.exprAllowed = this.curContext() === tc.j_expr;
|
||||
} else {
|
||||
this.exprAllowed = true;
|
||||
}
|
||||
};
|
||||
|
||||
var pp = acorn.Parser.prototype;
|
||||
|
||||
// Reads inline JSX contents token.
|
||||
|
||||
pp.jsx_readToken = function() {
|
||||
var out = "", chunkStart = this.pos;
|
||||
for (;;) {
|
||||
if (this.pos >= this.input.length)
|
||||
this.raise(this.start, "Unterminated JSX contents");
|
||||
var ch = this.input.charCodeAt(this.pos);
|
||||
|
||||
switch (ch) {
|
||||
case 60: // '<'
|
||||
case 123: // '{'
|
||||
if (this.pos === this.start) {
|
||||
if (ch === 60 && this.exprAllowed) {
|
||||
++this.pos;
|
||||
return this.finishToken(tt.jsxTagStart);
|
||||
}
|
||||
return this.getTokenFromCode(ch);
|
||||
}
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
return this.finishToken(tt.jsxText, out);
|
||||
|
||||
case 38: // '&'
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
out += this.jsx_readEntity();
|
||||
chunkStart = this.pos;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (acorn.isNewLine(ch)) {
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
++this.pos;
|
||||
if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
|
||||
++this.pos;
|
||||
out += "\n";
|
||||
} else {
|
||||
out += String.fromCharCode(ch);
|
||||
}
|
||||
if (this.options.locations) {
|
||||
++this.curLine;
|
||||
this.lineStart = this.pos;
|
||||
}
|
||||
chunkStart = this.pos;
|
||||
} else {
|
||||
++this.pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pp.jsx_readString = function(quote) {
|
||||
var out = "", chunkStart = ++this.pos;
|
||||
for (;;) {
|
||||
if (this.pos >= this.input.length)
|
||||
this.raise(this.start, "Unterminated string constant");
|
||||
var ch = this.input.charCodeAt(this.pos);
|
||||
if (ch === quote) break;
|
||||
if (ch === 38) { // '&'
|
||||
out += this.input.slice(chunkStart, this.pos);
|
||||
out += this.jsx_readEntity();
|
||||
chunkStart = this.pos;
|
||||
} else {
|
||||
++this.pos;
|
||||
}
|
||||
}
|
||||
out += this.input.slice(chunkStart, this.pos++);
|
||||
return this.finishToken(tt.string, out);
|
||||
};
|
||||
|
||||
var XHTMLEntities = {
|
||||
quot: '\u0022',
|
||||
amp: '&',
|
||||
apos: '\u0027',
|
||||
lt: '<',
|
||||
gt: '>',
|
||||
nbsp: '\u00A0',
|
||||
iexcl: '\u00A1',
|
||||
cent: '\u00A2',
|
||||
pound: '\u00A3',
|
||||
curren: '\u00A4',
|
||||
yen: '\u00A5',
|
||||
brvbar: '\u00A6',
|
||||
sect: '\u00A7',
|
||||
uml: '\u00A8',
|
||||
copy: '\u00A9',
|
||||
ordf: '\u00AA',
|
||||
laquo: '\u00AB',
|
||||
not: '\u00AC',
|
||||
shy: '\u00AD',
|
||||
reg: '\u00AE',
|
||||
macr: '\u00AF',
|
||||
deg: '\u00B0',
|
||||
plusmn: '\u00B1',
|
||||
sup2: '\u00B2',
|
||||
sup3: '\u00B3',
|
||||
acute: '\u00B4',
|
||||
micro: '\u00B5',
|
||||
para: '\u00B6',
|
||||
middot: '\u00B7',
|
||||
cedil: '\u00B8',
|
||||
sup1: '\u00B9',
|
||||
ordm: '\u00BA',
|
||||
raquo: '\u00BB',
|
||||
frac14: '\u00BC',
|
||||
frac12: '\u00BD',
|
||||
frac34: '\u00BE',
|
||||
iquest: '\u00BF',
|
||||
Agrave: '\u00C0',
|
||||
Aacute: '\u00C1',
|
||||
Acirc: '\u00C2',
|
||||
Atilde: '\u00C3',
|
||||
Auml: '\u00C4',
|
||||
Aring: '\u00C5',
|
||||
AElig: '\u00C6',
|
||||
Ccedil: '\u00C7',
|
||||
Egrave: '\u00C8',
|
||||
Eacute: '\u00C9',
|
||||
Ecirc: '\u00CA',
|
||||
Euml: '\u00CB',
|
||||
Igrave: '\u00CC',
|
||||
Iacute: '\u00CD',
|
||||
Icirc: '\u00CE',
|
||||
Iuml: '\u00CF',
|
||||
ETH: '\u00D0',
|
||||
Ntilde: '\u00D1',
|
||||
Ograve: '\u00D2',
|
||||
Oacute: '\u00D3',
|
||||
Ocirc: '\u00D4',
|
||||
Otilde: '\u00D5',
|
||||
Ouml: '\u00D6',
|
||||
times: '\u00D7',
|
||||
Oslash: '\u00D8',
|
||||
Ugrave: '\u00D9',
|
||||
Uacute: '\u00DA',
|
||||
Ucirc: '\u00DB',
|
||||
Uuml: '\u00DC',
|
||||
Yacute: '\u00DD',
|
||||
THORN: '\u00DE',
|
||||
szlig: '\u00DF',
|
||||
agrave: '\u00E0',
|
||||
aacute: '\u00E1',
|
||||
acirc: '\u00E2',
|
||||
atilde: '\u00E3',
|
||||
auml: '\u00E4',
|
||||
aring: '\u00E5',
|
||||
aelig: '\u00E6',
|
||||
ccedil: '\u00E7',
|
||||
egrave: '\u00E8',
|
||||
eacute: '\u00E9',
|
||||
ecirc: '\u00EA',
|
||||
euml: '\u00EB',
|
||||
igrave: '\u00EC',
|
||||
iacute: '\u00ED',
|
||||
icirc: '\u00EE',
|
||||
iuml: '\u00EF',
|
||||
eth: '\u00F0',
|
||||
ntilde: '\u00F1',
|
||||
ograve: '\u00F2',
|
||||
oacute: '\u00F3',
|
||||
ocirc: '\u00F4',
|
||||
otilde: '\u00F5',
|
||||
ouml: '\u00F6',
|
||||
divide: '\u00F7',
|
||||
oslash: '\u00F8',
|
||||
ugrave: '\u00F9',
|
||||
uacute: '\u00FA',
|
||||
ucirc: '\u00FB',
|
||||
uuml: '\u00FC',
|
||||
yacute: '\u00FD',
|
||||
thorn: '\u00FE',
|
||||
yuml: '\u00FF',
|
||||
OElig: '\u0152',
|
||||
oelig: '\u0153',
|
||||
Scaron: '\u0160',
|
||||
scaron: '\u0161',
|
||||
Yuml: '\u0178',
|
||||
fnof: '\u0192',
|
||||
circ: '\u02C6',
|
||||
tilde: '\u02DC',
|
||||
Alpha: '\u0391',
|
||||
Beta: '\u0392',
|
||||
Gamma: '\u0393',
|
||||
Delta: '\u0394',
|
||||
Epsilon: '\u0395',
|
||||
Zeta: '\u0396',
|
||||
Eta: '\u0397',
|
||||
Theta: '\u0398',
|
||||
Iota: '\u0399',
|
||||
Kappa: '\u039A',
|
||||
Lambda: '\u039B',
|
||||
Mu: '\u039C',
|
||||
Nu: '\u039D',
|
||||
Xi: '\u039E',
|
||||
Omicron: '\u039F',
|
||||
Pi: '\u03A0',
|
||||
Rho: '\u03A1',
|
||||
Sigma: '\u03A3',
|
||||
Tau: '\u03A4',
|
||||
Upsilon: '\u03A5',
|
||||
Phi: '\u03A6',
|
||||
Chi: '\u03A7',
|
||||
Psi: '\u03A8',
|
||||
Omega: '\u03A9',
|
||||
alpha: '\u03B1',
|
||||
beta: '\u03B2',
|
||||
gamma: '\u03B3',
|
||||
delta: '\u03B4',
|
||||
epsilon: '\u03B5',
|
||||
zeta: '\u03B6',
|
||||
eta: '\u03B7',
|
||||
theta: '\u03B8',
|
||||
iota: '\u03B9',
|
||||
kappa: '\u03BA',
|
||||
lambda: '\u03BB',
|
||||
mu: '\u03BC',
|
||||
nu: '\u03BD',
|
||||
xi: '\u03BE',
|
||||
omicron: '\u03BF',
|
||||
pi: '\u03C0',
|
||||
rho: '\u03C1',
|
||||
sigmaf: '\u03C2',
|
||||
sigma: '\u03C3',
|
||||
tau: '\u03C4',
|
||||
upsilon: '\u03C5',
|
||||
phi: '\u03C6',
|
||||
chi: '\u03C7',
|
||||
psi: '\u03C8',
|
||||
omega: '\u03C9',
|
||||
thetasym: '\u03D1',
|
||||
upsih: '\u03D2',
|
||||
piv: '\u03D6',
|
||||
ensp: '\u2002',
|
||||
emsp: '\u2003',
|
||||
thinsp: '\u2009',
|
||||
zwnj: '\u200C',
|
||||
zwj: '\u200D',
|
||||
lrm: '\u200E',
|
||||
rlm: '\u200F',
|
||||
ndash: '\u2013',
|
||||
mdash: '\u2014',
|
||||
lsquo: '\u2018',
|
||||
rsquo: '\u2019',
|
||||
sbquo: '\u201A',
|
||||
ldquo: '\u201C',
|
||||
rdquo: '\u201D',
|
||||
bdquo: '\u201E',
|
||||
dagger: '\u2020',
|
||||
Dagger: '\u2021',
|
||||
bull: '\u2022',
|
||||
hellip: '\u2026',
|
||||
permil: '\u2030',
|
||||
prime: '\u2032',
|
||||
Prime: '\u2033',
|
||||
lsaquo: '\u2039',
|
||||
rsaquo: '\u203A',
|
||||
oline: '\u203E',
|
||||
frasl: '\u2044',
|
||||
euro: '\u20AC',
|
||||
image: '\u2111',
|
||||
weierp: '\u2118',
|
||||
real: '\u211C',
|
||||
trade: '\u2122',
|
||||
alefsym: '\u2135',
|
||||
larr: '\u2190',
|
||||
uarr: '\u2191',
|
||||
rarr: '\u2192',
|
||||
darr: '\u2193',
|
||||
harr: '\u2194',
|
||||
crarr: '\u21B5',
|
||||
lArr: '\u21D0',
|
||||
uArr: '\u21D1',
|
||||
rArr: '\u21D2',
|
||||
dArr: '\u21D3',
|
||||
hArr: '\u21D4',
|
||||
forall: '\u2200',
|
||||
part: '\u2202',
|
||||
exist: '\u2203',
|
||||
empty: '\u2205',
|
||||
nabla: '\u2207',
|
||||
isin: '\u2208',
|
||||
notin: '\u2209',
|
||||
ni: '\u220B',
|
||||
prod: '\u220F',
|
||||
sum: '\u2211',
|
||||
minus: '\u2212',
|
||||
lowast: '\u2217',
|
||||
radic: '\u221A',
|
||||
prop: '\u221D',
|
||||
infin: '\u221E',
|
||||
ang: '\u2220',
|
||||
and: '\u2227',
|
||||
or: '\u2228',
|
||||
cap: '\u2229',
|
||||
cup: '\u222A',
|
||||
'int': '\u222B',
|
||||
there4: '\u2234',
|
||||
sim: '\u223C',
|
||||
cong: '\u2245',
|
||||
asymp: '\u2248',
|
||||
ne: '\u2260',
|
||||
equiv: '\u2261',
|
||||
le: '\u2264',
|
||||
ge: '\u2265',
|
||||
sub: '\u2282',
|
||||
sup: '\u2283',
|
||||
nsub: '\u2284',
|
||||
sube: '\u2286',
|
||||
supe: '\u2287',
|
||||
oplus: '\u2295',
|
||||
otimes: '\u2297',
|
||||
perp: '\u22A5',
|
||||
sdot: '\u22C5',
|
||||
lceil: '\u2308',
|
||||
rceil: '\u2309',
|
||||
lfloor: '\u230A',
|
||||
rfloor: '\u230B',
|
||||
lang: '\u2329',
|
||||
rang: '\u232A',
|
||||
loz: '\u25CA',
|
||||
spades: '\u2660',
|
||||
clubs: '\u2663',
|
||||
hearts: '\u2665',
|
||||
diams: '\u2666'
|
||||
};
|
||||
|
||||
var hexNumber = /^[\da-fA-F]+$/;
|
||||
var decimalNumber = /^\d+$/;
|
||||
|
||||
pp.jsx_readEntity = function() {
|
||||
var str = "", count = 0, entity;
|
||||
var ch = this.input[this.pos];
|
||||
if (ch !== "&")
|
||||
this.raise(this.pos, "Entity must start with an ampersand");
|
||||
var startPos = ++this.pos;
|
||||
while (this.pos < this.input.length && count++ < 10) {
|
||||
ch = this.input[this.pos++];
|
||||
if (ch === ";") {
|
||||
if (str[0] === "#") {
|
||||
if (str[1] === "x") {
|
||||
str = str.substr(2);
|
||||
if (hexNumber.test(str))
|
||||
entity = String.fromCharCode(parseInt(str, 16));
|
||||
} else {
|
||||
str = str.substr(1);
|
||||
if (decimalNumber.test(str))
|
||||
entity = String.fromCharCode(parseInt(str, 10));
|
||||
}
|
||||
} else {
|
||||
entity = XHTMLEntities[str];
|
||||
}
|
||||
break;
|
||||
}
|
||||
str += ch;
|
||||
}
|
||||
if (!entity) {
|
||||
this.pos = startPos;
|
||||
return "&";
|
||||
}
|
||||
return entity;
|
||||
};
|
||||
|
||||
|
||||
// Read a JSX identifier (valid tag or attribute name).
|
||||
//
|
||||
// Optimized version since JSX identifiers can't contain
|
||||
// escape characters and so can be read as single slice.
|
||||
// Also assumes that first character was already checked
|
||||
// by isIdentifierStart in readToken.
|
||||
|
||||
pp.jsx_readWord = function() {
|
||||
var ch, start = this.pos;
|
||||
do {
|
||||
ch = this.input.charCodeAt(++this.pos);
|
||||
} while (acorn.isIdentifierChar(ch) || ch === 45); // '-'
|
||||
return this.finishToken(tt.jsxName, this.input.slice(start, this.pos));
|
||||
};
|
||||
|
||||
// Transforms JSX element name to string.
|
||||
|
||||
function getQualifiedJSXName(object) {
|
||||
if (object.type === "JSXIdentifier")
|
||||
return object.name;
|
||||
|
||||
if (object.type === "JSXNamespacedName")
|
||||
return object.namespace.name + ':' + object.name.name;
|
||||
|
||||
if (object.type === "JSXMemberExpression")
|
||||
return getQualifiedJSXName(object.object) + '.' +
|
||||
getQualifiedJSXName(object.property);
|
||||
}
|
||||
|
||||
// Parse next token as JSX identifier
|
||||
|
||||
pp.jsx_parseIdentifier = function() {
|
||||
var node = this.startNode();
|
||||
if (this.type === tt.jsxName)
|
||||
node.name = this.value;
|
||||
else if (this.type.keyword)
|
||||
node.name = this.type.keyword;
|
||||
else
|
||||
this.unexpected();
|
||||
this.next();
|
||||
return this.finishNode(node, "JSXIdentifier");
|
||||
};
|
||||
|
||||
// Parse namespaced identifier.
|
||||
|
||||
pp.jsx_parseNamespacedName = function() {
|
||||
var start = this.markPosition();
|
||||
var name = this.jsx_parseIdentifier();
|
||||
if (!this.eat(tt.colon)) return name;
|
||||
var node = this.startNodeAt(start);
|
||||
node.namespace = name;
|
||||
node.name = this.jsx_parseIdentifier();
|
||||
return this.finishNode(node, "JSXNamespacedName");
|
||||
};
|
||||
|
||||
// Parses element name in any form - namespaced, member
|
||||
// or single identifier.
|
||||
|
||||
pp.jsx_parseElementName = function() {
|
||||
var start = this.markPosition();
|
||||
var node = this.jsx_parseNamespacedName();
|
||||
while (this.eat(tt.dot)) {
|
||||
var newNode = this.startNodeAt(start);
|
||||
newNode.object = node;
|
||||
newNode.property = this.jsx_parseIdentifier();
|
||||
node = this.finishNode(newNode, "JSXMemberExpression");
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
// Parses any type of JSX attribute value.
|
||||
|
||||
pp.jsx_parseAttributeValue = function() {
|
||||
switch (this.type) {
|
||||
case tt.braceL:
|
||||
var node = this.jsx_parseExpressionContainer();
|
||||
if (node.expression.type === "JSXEmptyExpression")
|
||||
this.raise(node.start, "JSX attributes must only be assigned a non-empty expression");
|
||||
return node;
|
||||
|
||||
case tt.jsxTagStart:
|
||||
case tt.string:
|
||||
return this.parseExprAtom();
|
||||
|
||||
default:
|
||||
this.raise(this.start, "JSX value should be either an expression or a quoted JSX text");
|
||||
}
|
||||
};
|
||||
|
||||
// JSXEmptyExpression is unique type since it doesn't actually parse anything,
|
||||
// and so it should start at the end of last read token (left brace) and finish
|
||||
// at the beginning of the next one (right brace).
|
||||
|
||||
pp.jsx_parseEmptyExpression = function() {
|
||||
var tmp = this.start;
|
||||
this.start = this.lastTokEnd;
|
||||
this.lastTokEnd = tmp;
|
||||
|
||||
tmp = this.startLoc;
|
||||
this.startLoc = this.lastTokEndLoc;
|
||||
this.lastTokEndLoc = tmp;
|
||||
|
||||
return this.finishNode(this.startNode(), "JSXEmptyExpression");
|
||||
};
|
||||
|
||||
// Parses JSX expression enclosed into curly brackets.
|
||||
|
||||
|
||||
pp.jsx_parseExpressionContainer = function() {
|
||||
var node = this.startNode();
|
||||
this.next();
|
||||
node.expression = this.type === tt.braceR
|
||||
? this.jsx_parseEmptyExpression()
|
||||
: this.parseExpression();
|
||||
this.expect(tt.braceR);
|
||||
return this.finishNode(node, "JSXExpressionContainer");
|
||||
};
|
||||
|
||||
// Parses following JSX attribute name-value pair.
|
||||
|
||||
pp.jsx_parseAttribute = function() {
|
||||
var node = this.startNode();
|
||||
if (this.eat(tt.braceL)) {
|
||||
this.expect(tt.ellipsis);
|
||||
node.argument = this.parseMaybeAssign();
|
||||
this.expect(tt.braceR);
|
||||
return this.finishNode(node, "JSXSpreadAttribute");
|
||||
}
|
||||
node.name = this.jsx_parseNamespacedName();
|
||||
node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null;
|
||||
return this.finishNode(node, "JSXAttribute");
|
||||
};
|
||||
|
||||
// Parses JSX opening tag starting after '<'.
|
||||
|
||||
pp.jsx_parseOpeningElementAt = function(start) {
|
||||
var node = this.startNodeAt(start);
|
||||
node.attributes = [];
|
||||
node.name = this.jsx_parseElementName();
|
||||
while (this.type !== tt.slash && this.type !== tt.jsxTagEnd)
|
||||
node.attributes.push(this.jsx_parseAttribute());
|
||||
node.selfClosing = this.eat(tt.slash);
|
||||
this.expect(tt.jsxTagEnd);
|
||||
return this.finishNode(node, "JSXOpeningElement");
|
||||
};
|
||||
|
||||
// Parses JSX closing tag starting after '</'.
|
||||
|
||||
pp.jsx_parseClosingElementAt = function(start) {
|
||||
var node = this.startNodeAt(start);
|
||||
node.name = this.jsx_parseElementName();
|
||||
this.expect(tt.jsxTagEnd);
|
||||
return this.finishNode(node, "JSXClosingElement");
|
||||
};
|
||||
|
||||
// Parses entire JSX element, including it's opening tag
|
||||
// (starting after '<'), attributes, contents and closing tag.
|
||||
|
||||
pp.jsx_parseElementAt = function(start) {
|
||||
var node = this.startNodeAt(start);
|
||||
var children = [];
|
||||
var openingElement = this.jsx_parseOpeningElementAt(start);
|
||||
var closingElement = null;
|
||||
|
||||
if (!openingElement.selfClosing) {
|
||||
contents: for (;;) {
|
||||
switch (this.type) {
|
||||
case tt.jsxTagStart:
|
||||
start = this.markPosition();
|
||||
this.next();
|
||||
if (this.eat(tt.slash)) {
|
||||
closingElement = this.jsx_parseClosingElementAt(start);
|
||||
break contents;
|
||||
}
|
||||
children.push(this.jsx_parseElementAt(start));
|
||||
break;
|
||||
|
||||
case tt.jsxText:
|
||||
children.push(this.parseExprAtom());
|
||||
break;
|
||||
|
||||
case tt.braceL:
|
||||
children.push(this.jsx_parseExpressionContainer());
|
||||
break;
|
||||
|
||||
default:
|
||||
this.unexpected();
|
||||
}
|
||||
}
|
||||
if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name))
|
||||
this.raise(
|
||||
closingElement.start,
|
||||
"Expected corresponding JSX closing tag for <" + getQualifiedJSXName(openingElement.name) + ">");
|
||||
}
|
||||
|
||||
node.openingElement = openingElement;
|
||||
node.closingElement = closingElement;
|
||||
node.children = children;
|
||||
return this.finishNode(node, "JSXElement");
|
||||
};
|
||||
|
||||
// Parses entire JSX element from current position.
|
||||
|
||||
pp.jsx_parseElement = function() {
|
||||
var start = this.markPosition();
|
||||
this.next();
|
||||
return this.jsx_parseElementAt(start);
|
||||
};
|
||||
|
||||
acorn.plugins.jsx = function(instance) {
|
||||
instance.extend("parseExprAtom", function(inner) {
|
||||
return function(refShortHandDefaultPos) {
|
||||
if (this.type === tt.jsxText)
|
||||
return this.parseLiteral(this.value);
|
||||
else if (this.type === tt.jsxTagStart)
|
||||
return this.jsx_parseElement();
|
||||
else
|
||||
return inner.call(this, refShortHandDefaultPos);
|
||||
};
|
||||
});
|
||||
|
||||
instance.extend("readToken", function(inner) {
|
||||
return function(code) {
|
||||
var context = this.curContext();
|
||||
|
||||
if (context === tc.j_expr) return this.jsx_readToken();
|
||||
|
||||
if (context === tc.j_oTag || context === tc.j_cTag) {
|
||||
if (acorn.isIdentifierStart(code)) return this.jsx_readWord();
|
||||
|
||||
if (code == 62) {
|
||||
++this.pos;
|
||||
return this.finishToken(tt.jsxTagEnd);
|
||||
}
|
||||
|
||||
if ((code === 34 || code === 39) && context == tc.j_oTag)
|
||||
return this.jsx_readString(code);
|
||||
}
|
||||
|
||||
if (code === 60 && this.exprAllowed) {
|
||||
++this.pos;
|
||||
return this.finishToken(tt.jsxTagStart);
|
||||
}
|
||||
return inner.call(this, code);
|
||||
};
|
||||
});
|
||||
|
||||
instance.extend("updateContext", function(inner) {
|
||||
return function(prevType) {
|
||||
if (this.type == tt.braceL) {
|
||||
var curContext = this.curContext();
|
||||
if (curContext == tc.j_oTag) this.context.push(tc.b_expr);
|
||||
else if (curContext == tc.j_expr) this.context.push(tc.b_tmpl);
|
||||
else inner.call(this, prevType);
|
||||
this.exprAllowed = true;
|
||||
} else if (this.type === tt.slash && prevType === tt.jsxTagStart) {
|
||||
this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
|
||||
this.context.push(tc.j_cTag); // reconsider as closing tag context
|
||||
this.exprAllowed = false;
|
||||
} else {
|
||||
return inner.call(this, prevType);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -474,7 +474,10 @@ pp.parseNew = function() {
|
||||
}
|
||||
let start = this.markPosition()
|
||||
node.callee = this.parseSubscripts(this.parseExprAtom(), start, true)
|
||||
if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false)
|
||||
if (this.eat(tt.parenL)) node.arguments = this.parseExprList(
|
||||
tt.parenR,
|
||||
this.options.features["es7.trailingFunctionCommas"]
|
||||
)
|
||||
else node.arguments = empty
|
||||
return this.finishNode(node, "NewExpression")
|
||||
}
|
||||
@@ -632,7 +635,7 @@ pp.parseMethod = function(isGenerator, isAsync) {
|
||||
let node = this.startNode()
|
||||
this.initFunction(node, isAsync)
|
||||
this.expect(tt.parenL)
|
||||
node.params = this.parseBindingList(tt.parenR, false, false)
|
||||
node.params = this.parseBindingList(tt.parenR, false, this.options.features["es7.trailingFunctionCommas"])
|
||||
if (this.options.ecmaVersion >= 6) {
|
||||
node.generator = isGenerator
|
||||
}
|
||||
|
||||
@@ -14,7 +14,11 @@ var STATE_KEYS = [
|
||||
"pos",
|
||||
"end",
|
||||
"type",
|
||||
"value"
|
||||
"value",
|
||||
"exprAllowed",
|
||||
"potentialArrowAt",
|
||||
"currLine",
|
||||
"input"
|
||||
];
|
||||
|
||||
pp.getState = function () {
|
||||
@@ -23,6 +27,7 @@ pp.getState = function () {
|
||||
var key = STATE_KEYS[i]
|
||||
state[key] = this[key]
|
||||
}
|
||||
state.context = this.context.slice()
|
||||
return state
|
||||
};
|
||||
|
||||
|
||||
@@ -504,7 +504,7 @@ pp.parseClass = function(node, isStatement) {
|
||||
this.parsePropertyName(method)
|
||||
}
|
||||
method.kind = "method"
|
||||
if (!method.computed && !isGenerator) {
|
||||
if (!method.computed && !isGenerator && !isAsync) {
|
||||
if (method.key.type === "Identifier") {
|
||||
if (this.type !== tt.parenL && (method.key.name === "get" || method.key.name === "set")) {
|
||||
method.kind = method.key.name
|
||||
|
||||
@@ -283,7 +283,7 @@ pp.readToken_lt_gt = function(code) { // '<>'
|
||||
}
|
||||
if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 &&
|
||||
this.input.charCodeAt(this.pos + 3) == 45) {
|
||||
if (this.inModule) unexpected()
|
||||
if (this.inModule) this.unexpected()
|
||||
// `<!--`, an XML-style comment that should be interpreted as a line comment
|
||||
this.skipLineComment(4)
|
||||
this.skipSpace()
|
||||
|
||||
@@ -53,7 +53,7 @@ export function transformFile(filename: string, opts?: Object, callback: Functio
|
||||
|
||||
export function transformFileSync(filename: string, opts?: Object = {}) {
|
||||
opts.filename = filename;
|
||||
return transform(fs.readFileSync(filename), opts);
|
||||
return transform(fs.readFileSync(filename, "utf8"), opts);
|
||||
}
|
||||
|
||||
export function parse(code, opts = {}) {
|
||||
|
||||
@@ -43,13 +43,13 @@ export function JSXElement(node, print) {
|
||||
if (open.selfClosing) return;
|
||||
|
||||
this.indent();
|
||||
each(node.children, (child) => {
|
||||
for (var child of (node.children: Array)) {
|
||||
if (t.isLiteral(child)) {
|
||||
this.push(child.value, true);
|
||||
} else {
|
||||
print(child);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.dedent();
|
||||
|
||||
print(node.closingElement);
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as t from "../../types";
|
||||
|
||||
export function ImportSpecifier(node, print) {
|
||||
print(node.imported);
|
||||
if (node.local && node.local !== node.imported) {
|
||||
if (node.local && node.local.name !== node.imported.name) {
|
||||
this.push(" as ");
|
||||
print(node.local);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export function ExportDefaultSpecifier(node, print) {
|
||||
|
||||
export function ExportSpecifier(node, print) {
|
||||
print(node.local);
|
||||
if (node.exported && node.local !== node.exported) {
|
||||
if (node.exported && node.local.name !== node.exported.name) {
|
||||
this.push(" as ");
|
||||
print(node.exported);
|
||||
}
|
||||
|
||||
@@ -182,8 +182,8 @@ export function VariableDeclaration(node, print, parent) {
|
||||
var hasInits = false;
|
||||
// don't add whitespace to loop heads
|
||||
if (!t.isFor(parent)) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
if (node.declarations[i].init) {
|
||||
for (var declar of (node.declarations: Array)) {
|
||||
if (declar.init) {
|
||||
// has an init so let's split it up over multiple lines
|
||||
hasInits = true;
|
||||
}
|
||||
@@ -191,7 +191,7 @@ export function VariableDeclaration(node, print, parent) {
|
||||
}
|
||||
|
||||
var sep = ",";
|
||||
if (!this.format.compact && hasInits) {
|
||||
if (!this.format.compact && !this.format.concise && hasInits && !this.format.retainLines) {
|
||||
sep += `\n${repeating(" ", node.kind.length + 1)}`;
|
||||
} else {
|
||||
sep += " ";
|
||||
|
||||
@@ -15,15 +15,15 @@ export function TemplateLiteral(node, print) {
|
||||
var quasis = node.quasis;
|
||||
var len = quasis.length;
|
||||
|
||||
each(quasis, (quasi, i) => {
|
||||
print(quasi);
|
||||
for (var i = 0; i < len; i++) {
|
||||
print(quasis[i]);
|
||||
|
||||
if (i + 1 < len) {
|
||||
this.push("${ ");
|
||||
print(node.expressions[i]);
|
||||
this.push(" }");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this._push("`");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import each from "lodash/collection/each";
|
||||
import * as t from "../../types";
|
||||
|
||||
export function Identifier(node) {
|
||||
this.push(node.name);
|
||||
@@ -39,7 +40,14 @@ export function Property(node, print) {
|
||||
this.push("]");
|
||||
} else {
|
||||
print(node.key);
|
||||
if (node.shorthand) return;
|
||||
|
||||
// shorthand!
|
||||
if (node.shorthand &&
|
||||
(t.isIdentifier(node.key) &&
|
||||
t.isIdentifier(node.value) &&
|
||||
node.key.name === node.value.name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.push(":");
|
||||
@@ -54,7 +62,8 @@ export function ArrayExpression(node, print) {
|
||||
|
||||
this.push("[");
|
||||
|
||||
each(elems, (elem, i) => {
|
||||
for (var i = 0; i < elems.length; i++) {
|
||||
var elem = elems[i];
|
||||
if (!elem) {
|
||||
// If the array expression ends with a hole, that hole
|
||||
// will be ignored by the interpreter, but if it ends with
|
||||
@@ -67,7 +76,7 @@ export function ArrayExpression(node, print) {
|
||||
print(elem);
|
||||
if (i < len - 1) this.push(",");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.push("]");
|
||||
}
|
||||
|
||||
@@ -105,11 +105,13 @@ class CodeGenerator {
|
||||
|
||||
this.print(ast);
|
||||
|
||||
var comments = [];
|
||||
each(ast.comments, function (comment) {
|
||||
if (!comment._displayed) comments.push(comment);
|
||||
});
|
||||
this._printComments(comments);
|
||||
if (ast.comments) {
|
||||
var comments = [];
|
||||
for (var comment of (ast.comments: Array)) {
|
||||
if (!comment._displayed) comments.push(comment);
|
||||
}
|
||||
this._printComments(comments);
|
||||
}
|
||||
|
||||
return {
|
||||
map: this.map.get(),
|
||||
@@ -249,7 +251,8 @@ class CodeGenerator {
|
||||
|
||||
if (opts.indent) this.indent();
|
||||
|
||||
each(nodes, (node, i) => {
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var node = nodes[i];
|
||||
print(node, {
|
||||
statement: opts.statement,
|
||||
addNewlines: opts.addNewlines,
|
||||
@@ -263,7 +266,7 @@ class CodeGenerator {
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (opts.indent) this.dedent();
|
||||
}
|
||||
@@ -314,9 +317,9 @@ class CodeGenerator {
|
||||
nodes.push(node.argument);
|
||||
}
|
||||
|
||||
each(nodes, (node) => {
|
||||
for (var node of (nodes: Array)) {
|
||||
comments = comments.concat(this._getComments(key, node));
|
||||
});
|
||||
}
|
||||
|
||||
return comments;
|
||||
}
|
||||
@@ -331,19 +334,21 @@ class CodeGenerator {
|
||||
if (!this.format.comments) return;
|
||||
if (!comments || !comments.length) return;
|
||||
|
||||
each(comments, (comment) => {
|
||||
for (var comment of (comments: Array)) {
|
||||
var skip = false;
|
||||
|
||||
// find the original comment in the ast and set it as displayed
|
||||
each(this.ast.comments, function (origComment) {
|
||||
if (origComment.start === comment.start) {
|
||||
// comment has already been output
|
||||
if (origComment._displayed) skip = true;
|
||||
if (this.ast.comments) {
|
||||
// find the original comment in the ast and set it as displayed
|
||||
for (var origComment of (this.ast.comments: Array)) {
|
||||
if (origComment.start === comment.start) {
|
||||
// comment has already been output
|
||||
if (origComment._displayed) skip = true;
|
||||
|
||||
origComment._displayed = true;
|
||||
return false;
|
||||
origComment._displayed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (skip) return;
|
||||
|
||||
@@ -387,7 +392,7 @@ class CodeGenerator {
|
||||
|
||||
// whitespace after
|
||||
this.newline(this.whitespace.getNewlinesAfter(comment));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,15 +18,15 @@ export const 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",
|
||||
codeGeneratorDeopt: "Note: The code generator has deoptimised the styling of $1 as it exceeds the max of $2.",
|
||||
missingTemplatesDirectory: "no templates directory - this is most likely the result of a broken `npm publish`. Please report to https://github.com/babel/babel/issues",
|
||||
unsupportedOutputType: "Unsupported output type $1",
|
||||
illegalMethodName: "Illegal method name $1",
|
||||
|
||||
traverseNeedsParent: "Must pass a scope and parentPath unless traversing a Program/File got a $1 node",
|
||||
traverseVerifyRootFunction: "You passed `traverse()` a function when it expected a visitor object, are you sure you didn't mean `{ enter: Function }`?",
|
||||
traverseVerifyVisitorFunction: "Hey! You passed \`traverse()\` a visitor object with the key $1 that's a straight up `Function` instead of `{ enter: Function }`. You need to normalise it with `traverse.explode(visitor)`.",
|
||||
traverseVerifyVisitorProperty: "You passed `traverse()` a visitor object with the property $1 that has the invalid property $2",
|
||||
traverseVerifyNodeType: "You gave us a visitor for the node type $1 but it's not a valid type",
|
||||
|
||||
pluginIllegalKind: "Illegal kind $1 for plugin $2",
|
||||
pluginIllegalPosition: "Illegal position $1 for plugin $2",
|
||||
|
||||
@@ -33,6 +33,9 @@ def("DoExpression")
|
||||
.build("body")
|
||||
.field("body", [def("Statement")]);
|
||||
|
||||
def("Super")
|
||||
.bases("Expression");
|
||||
|
||||
def("ExportDefaultDeclaration")
|
||||
.bases("Declaration")
|
||||
.build("declaration")
|
||||
|
||||
@@ -4,6 +4,7 @@ import moduleFormatters from "../modules";
|
||||
import PluginManager from "./plugin-manager";
|
||||
import shebangRegex from "shebang-regex";
|
||||
import TraversalPath from "../../traversal/path";
|
||||
import Transformer from "../transformer";
|
||||
import isFunction from "lodash/lang/isFunction";
|
||||
import isAbsolute from "path-is-absolute";
|
||||
import resolveRc from "../../tools/resolve-rc";
|
||||
@@ -23,24 +24,12 @@ import clone from "lodash/lang/clone";
|
||||
import * as util from "../../util";
|
||||
import * as api from "../../api/node";
|
||||
import path from "path";
|
||||
import each from "lodash/collection/each";
|
||||
import * as t from "../../types";
|
||||
|
||||
var checkTransformerVisitor = {
|
||||
exit(node, parent, scope, state) {
|
||||
checkPath(state.stack, this);
|
||||
}
|
||||
};
|
||||
|
||||
function checkPath(stack, path) {
|
||||
each(stack, function (pass) {
|
||||
if (pass.shouldRun || pass.ran) return;
|
||||
pass.checkPath(path);
|
||||
});
|
||||
}
|
||||
|
||||
export default class File {
|
||||
constructor(opts = {}, pipeline) {
|
||||
this.transformerDependencies = {};
|
||||
|
||||
this.dynamicImportTypes = {};
|
||||
this.dynamicImportIds = {};
|
||||
this.dynamicImports = [];
|
||||
@@ -49,7 +38,6 @@ export default class File {
|
||||
this.usedHelpers = {};
|
||||
this.dynamicData = {};
|
||||
this.data = {};
|
||||
this.uids = {};
|
||||
|
||||
this.pipeline = pipeline;
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
@@ -96,10 +84,7 @@ export default class File {
|
||||
"interop-require",
|
||||
];
|
||||
|
||||
static soloHelpers = [
|
||||
"ludicrous-proxy-create",
|
||||
"ludicrous-proxy-directory"
|
||||
];
|
||||
static soloHelpers = [];
|
||||
|
||||
static options = require("./options");
|
||||
|
||||
@@ -203,7 +188,8 @@ export default class File {
|
||||
var stack = [];
|
||||
|
||||
// build internal transformers
|
||||
each(this.pipeline.transformers, function (transformer, key) {
|
||||
for (var key in this.pipeline.transformers) {
|
||||
var transformer = this.pipeline.transformers[key];
|
||||
var pass = transformers[key] = transformer.buildPass(file);
|
||||
|
||||
if (pass.canTransform()) {
|
||||
@@ -217,7 +203,7 @@ export default class File {
|
||||
transformer.manipulateOptions(file.opts, file);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// init plugins!
|
||||
var beforePlugins = [];
|
||||
@@ -233,8 +219,55 @@ export default class File {
|
||||
}
|
||||
stack = beforePlugins.concat(stack, afterPlugins);
|
||||
|
||||
// register
|
||||
this.transformerStack = stack.concat(secondaryStack);
|
||||
// build transformer stack
|
||||
this.uncollapsedTransformerStack = stack = stack.concat(secondaryStack);
|
||||
|
||||
// build dependency graph
|
||||
for (var pass of (stack: Array)) {
|
||||
for (var dep of (pass.transformer.dependencies: Array)) {
|
||||
this.transformerDependencies[dep] = pass.key;
|
||||
}
|
||||
}
|
||||
|
||||
// collapse stack categories
|
||||
this.transformerStack = this.collapseStack(stack);
|
||||
}
|
||||
|
||||
collapseStack(_stack) {
|
||||
var stack = [];
|
||||
var ignore = [];
|
||||
|
||||
for (let pass of (_stack: Array)) {
|
||||
// been merged
|
||||
if (ignore.indexOf(pass) >= 0) continue;
|
||||
|
||||
var group = pass.transformer.metadata.group;
|
||||
|
||||
// can't merge
|
||||
if (!pass.canTransform() || !group) {
|
||||
stack.push(pass);
|
||||
continue;
|
||||
}
|
||||
|
||||
var mergeStack = [];
|
||||
for (let pass of (_stack: Array)) {
|
||||
if (pass.transformer.metadata.group === group) {
|
||||
mergeStack.push(pass);
|
||||
ignore.push(pass);
|
||||
}
|
||||
}
|
||||
|
||||
var visitors = [];
|
||||
for (let pass of (mergeStack: Array)) {
|
||||
visitors.push(pass.handlers);
|
||||
}
|
||||
var visitor = traverse.visitors.merge(visitors);
|
||||
var mergeTransformer = new Transformer(group, visitor);
|
||||
//console.log(mergeTransformer);
|
||||
stack.push(mergeTransformer.buildPass(this));
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
set(key: string, val): any {
|
||||
@@ -337,6 +370,7 @@ export default class File {
|
||||
ref._generated = true;
|
||||
ref.id = uid;
|
||||
ref.type = "FunctionDeclaration";
|
||||
this.attachAuxiliaryComment(ref);
|
||||
this.path.unshiftContainer("body", ref);
|
||||
} else {
|
||||
ref._compact = true;
|
||||
@@ -357,23 +391,6 @@ export default class File {
|
||||
return err;
|
||||
}
|
||||
|
||||
checkPath(path) {
|
||||
if (Array.isArray(path)) {
|
||||
for (var i = 0; i < path.length; i++) {
|
||||
this.checkPath(path[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = this.transformerStack;
|
||||
|
||||
checkPath(stack, path);
|
||||
|
||||
path.traverse(checkTransformerVisitor, {
|
||||
stack: stack
|
||||
});
|
||||
}
|
||||
|
||||
mergeSourceMap(map: Object) {
|
||||
var opts = this.opts;
|
||||
|
||||
@@ -444,16 +461,6 @@ export default class File {
|
||||
this.path = TraversalPath.get(null, null, ast, ast, "program", this);
|
||||
this.scope = this.path.scope;
|
||||
this.ast = ast;
|
||||
|
||||
this.path.traverse({
|
||||
enter(node, parent, scope) {
|
||||
if (this.isScope()) {
|
||||
for (var key in scope.bindings) {
|
||||
scope.bindings[key].setTypeAnnotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addAst(ast) {
|
||||
@@ -461,10 +468,6 @@ export default class File {
|
||||
this._addAst(ast);
|
||||
this.log.debug("End set AST");
|
||||
|
||||
this.log.debug("Start prepass");
|
||||
this.checkPath(this.path);
|
||||
this.log.debug("End prepass");
|
||||
|
||||
this.log.debug("Start module formatter init");
|
||||
var modFormatter = this.moduleFormatter = this.getModuleFormatter(this.opts.modules);
|
||||
if (modFormatter.init && this.transformers["es6.modules"].canTransform()) {
|
||||
@@ -473,13 +476,15 @@ export default class File {
|
||||
this.log.debug("End module formatter init");
|
||||
|
||||
this.call("pre");
|
||||
each(this.transformerStack, function (pass) {
|
||||
for (var pass of (this.transformerStack: Array)) {
|
||||
pass.transform();
|
||||
});
|
||||
}
|
||||
this.call("post");
|
||||
}
|
||||
|
||||
wrap(code, callback) {
|
||||
code = code + "";
|
||||
|
||||
try {
|
||||
if (this.shouldIgnore()) {
|
||||
return {
|
||||
@@ -538,10 +543,8 @@ export default class File {
|
||||
}
|
||||
|
||||
call(key: string) {
|
||||
var stack = this.transformerStack;
|
||||
for (var i = 0; i < stack.length; i++) {
|
||||
var transformer = stack[i].transformer;
|
||||
var fn = transformer[key];
|
||||
for (var pass of (this.uncollapsedTransformerStack: Array)) {
|
||||
var fn = pass.transformer[key];
|
||||
if (fn) fn(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import * as util from "../../util";
|
||||
import buildDebug from "debug/node";
|
||||
|
||||
var verboseDebug = buildDebug("babel:verbose");
|
||||
var generalDebug = buildDebug("babel");
|
||||
|
||||
export default class Logger {
|
||||
constructor(file: File, filename: string) {
|
||||
@@ -22,11 +25,15 @@ export default class Logger {
|
||||
}
|
||||
}
|
||||
|
||||
verbose(msg: string) {
|
||||
if (verboseDebug.enabled) verboseDebug(this._buildMessage(msg));
|
||||
}
|
||||
|
||||
debug(msg: string) {
|
||||
util.debug(this._buildMessage(msg));
|
||||
if (generalDebug.enabled) generalDebug(this._buildMessage(msg));
|
||||
}
|
||||
|
||||
deopt(node: Object, msg: string) {
|
||||
util.debug(this._buildMessage(msg));
|
||||
this.debug(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,11 @@
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
"getModuleId": {
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
"retainLines": {
|
||||
"hidden": true,
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "retain line numbers - will result in really ugly code"
|
||||
|
||||
@@ -57,6 +57,9 @@ export default class PluginManager {
|
||||
if (!plugin.buildPass || plugin.constructor.name !== "Transformer") {
|
||||
throw new TypeError(messages.get("pluginNotTransformer", name));
|
||||
}
|
||||
|
||||
// register as a plugin
|
||||
plugin.metadata.plugin = true;
|
||||
}
|
||||
|
||||
add(name) {
|
||||
@@ -65,7 +68,7 @@ export default class PluginManager {
|
||||
|
||||
if (name) {
|
||||
if (typeof name === "object" && name.transformer) {
|
||||
({ plugin: name, position } = name);
|
||||
({ transformer: plugin, position } = name);
|
||||
} else if (typeof name !== "string") {
|
||||
// not a string so we'll just assume that it's a direct Transformer instance, if not then
|
||||
// the checks later on will complain
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import explode from "./explode-assignable-expression";
|
||||
import * as t from "../../types";
|
||||
|
||||
export default function (exports, opts) {
|
||||
export default function (opts) {
|
||||
var exports = {};
|
||||
|
||||
var isAssignment = function (node) {
|
||||
return node.operator === opts.operator + "=";
|
||||
};
|
||||
@@ -10,10 +12,6 @@ export default function (exports, opts) {
|
||||
return t.assignmentExpression("=", left, right);
|
||||
};
|
||||
|
||||
exports.shouldVisit = function (node) {
|
||||
return node.operator && (node.operator === opts.operator || node.operator === opts.operator + "=");
|
||||
};
|
||||
|
||||
exports.ExpressionStatement = function (node, parent, scope, file) {
|
||||
// hit the `AssignmentExpression` one below
|
||||
if (this.isCompletionRecord()) return;
|
||||
@@ -44,4 +42,6 @@ export default function (exports, opts) {
|
||||
if (node.operator !== opts.operator) return;
|
||||
return opts.build(node.left, node.right);
|
||||
};
|
||||
|
||||
return exports;
|
||||
};
|
||||
|
||||
@@ -10,14 +10,8 @@ import * as react from "./react";
|
||||
import * as t from "../../types";
|
||||
|
||||
export default function (exports, opts) {
|
||||
exports.check = function (node) {
|
||||
if (t.isJSX(node)) return true;
|
||||
if (react.isCreateClass(node)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
exports.JSXIdentifier = function (node, parent) {
|
||||
if (node.name === "this" && t.isReferenced(node, parent)) {
|
||||
if (node.name === "this" && this.isReferenced()) {
|
||||
return t.thisExpression();
|
||||
} else if (esutils.keyword.isIdentifierNameES6(node.name)) {
|
||||
node.type = "Identifier";
|
||||
|
||||
@@ -26,7 +26,7 @@ export function push(mutatorMap, node, kind, file) {
|
||||
|
||||
if (node.decorators) {
|
||||
var decorators = map.decorators = map.decorators || t.arrayExpression([]);
|
||||
decorators.elements = decorators.elements.concat(node.decorators.map(dec => dec.expression));
|
||||
decorators.elements = decorators.elements.concat(node.decorators.map(dec => dec.expression).reverse());
|
||||
}
|
||||
|
||||
if (map.value || map.initializer) {
|
||||
|
||||
@@ -19,7 +19,7 @@ var awaitVisitor = {
|
||||
var referenceVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
var name = state.id.name;
|
||||
if (t.isReferencedIdentifier(node, parent, { name: name }) && scope.bindingIdentifierEquals(name, state.id)) {
|
||||
if (this.isReferencedIdentifier({ name: name }) && scope.bindingIdentifierEquals(name, state.id)) {
|
||||
return state.ref = state.ref || scope.generateUidIdentifier(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,13 @@ var pipeline = new Pipeline;
|
||||
//
|
||||
|
||||
import transformers from "./transformers";
|
||||
|
||||
for (var key in transformers) {
|
||||
var transformer = transformers[key];
|
||||
var metadata = transformer.metadata = transformer.metadata || {};
|
||||
metadata.group = metadata.group || "builtin-basic";
|
||||
}
|
||||
|
||||
pipeline.addTransformers(transformers);
|
||||
|
||||
//
|
||||
|
||||
@@ -7,57 +7,65 @@ import * as t from "../../types";
|
||||
|
||||
var remapVisitor = {
|
||||
enter(node, parent, scope, formatter) {
|
||||
var remap = formatter.internalRemap[node.name];
|
||||
if (this.isReferencedIdentifier() && remap) {
|
||||
if (!scope.hasBinding(node.name) || scope.bindingIdentifierEquals(node.name, formatter.localImports[node.name])) {
|
||||
return remap;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isUpdateExpression(node)) {
|
||||
var exported = formatter.getExport(node.argument, scope);
|
||||
|
||||
if (exported) {
|
||||
this.skip();
|
||||
|
||||
// expand to long file assignment expression
|
||||
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
|
||||
|
||||
// remap this assignment expression
|
||||
var remapped = formatter.remapExportAssignment(assign, exported);
|
||||
|
||||
// we don't need to change the result
|
||||
if (t.isExpressionStatement(parent) || node.prefix) {
|
||||
return remapped;
|
||||
}
|
||||
|
||||
var nodes = [];
|
||||
nodes.push(remapped);
|
||||
|
||||
var operator;
|
||||
if (node.operator === "--") {
|
||||
operator = "+";
|
||||
} else { // "++"
|
||||
operator = "-";
|
||||
}
|
||||
nodes.push(t.binaryExpression(operator, node.argument, t.literal(1)));
|
||||
|
||||
return t.sequenceExpression(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
if (node._skipModulesRemap) {
|
||||
return this.skip();
|
||||
}
|
||||
},
|
||||
|
||||
exit(node, parent, scope, formatter) {
|
||||
if (t.isAssignmentExpression(node) && !node._ignoreModulesRemap) {
|
||||
var exported = formatter.getExport(node.left, scope);
|
||||
if (exported) {
|
||||
return formatter.remapExportAssignment(node, exported);
|
||||
ReferencedIdentifier(node, parent, scope, formatter) {
|
||||
var remap = formatter.internalRemap[node.name];
|
||||
|
||||
if (remap && node !== remap) {
|
||||
if (!scope.hasBinding(node.name) || scope.bindingIdentifierEquals(node.name, formatter.localImports[node.name])) {
|
||||
if (this.key === "callee" && this.parentPath.isCallExpression()) {
|
||||
return t.sequenceExpression([t.literal(0), remap]);
|
||||
} else {
|
||||
return remap;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
AssignmentExpression: {
|
||||
exit(node, parent, scope, formatter) {
|
||||
if (!node._ignoreModulesRemap) {
|
||||
var exported = formatter.getExport(node.left, scope);
|
||||
if (exported) {
|
||||
return formatter.remapExportAssignment(node, exported);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
UpdateExpression(node, parent, scope, formatter) {
|
||||
var exported = formatter.getExport(node.argument, scope);
|
||||
if (!exported) return;
|
||||
|
||||
this.skip();
|
||||
|
||||
// expand to long file assignment expression
|
||||
var assign = t.assignmentExpression(node.operator[0] + "=", node.argument, t.literal(1));
|
||||
|
||||
// remap this assignment expression
|
||||
var remapped = formatter.remapExportAssignment(assign, exported);
|
||||
|
||||
// we don't need to change the result
|
||||
if (t.isExpressionStatement(parent) || node.prefix) {
|
||||
return remapped;
|
||||
}
|
||||
|
||||
var nodes = [];
|
||||
nodes.push(remapped);
|
||||
|
||||
var operator;
|
||||
if (node.operator === "--") {
|
||||
operator = "+";
|
||||
} else { // "++"
|
||||
operator = "-";
|
||||
}
|
||||
nodes.push(t.binaryExpression(operator, node.argument, t.literal(1)));
|
||||
|
||||
return t.sequenceExpression(nodes);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -70,7 +78,7 @@ var importsVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
var exportsVisitor = traverse.explode({
|
||||
var exportsVisitor = {
|
||||
ExportDeclaration: {
|
||||
enter(node, parent, scope, formatter) {
|
||||
formatter.hasLocalExports = true;
|
||||
@@ -102,7 +110,7 @@ var exportsVisitor = traverse.explode({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default class DefaultFormatter {
|
||||
constructor(file) {
|
||||
@@ -184,7 +192,10 @@ export default class DefaultFormatter {
|
||||
|
||||
getModuleName() {
|
||||
var opts = this.file.opts;
|
||||
if (opts.moduleId) return opts.moduleId;
|
||||
// moduleId is n/a if a `getModuleId()` is provided
|
||||
if (opts.moduleId && !opts.getModuleId) {
|
||||
return opts.moduleId;
|
||||
}
|
||||
|
||||
var filenameRelative = opts.filenameRelative;
|
||||
var moduleName = "";
|
||||
@@ -213,7 +224,12 @@ export default class DefaultFormatter {
|
||||
// normalize path separators
|
||||
moduleName = moduleName.replace(/\\/g, "/");
|
||||
|
||||
return moduleName;
|
||||
if (opts.getModuleId) {
|
||||
// If return is falsy, assume they want us to use our generated default name
|
||||
return opts.getModuleId(moduleName) || moduleName;
|
||||
} else {
|
||||
return moduleName;
|
||||
}
|
||||
}
|
||||
|
||||
_pushStatement(ref, nodes) {
|
||||
|
||||
@@ -23,7 +23,7 @@ export default class AMDFormatter extends DefaultFormatter {
|
||||
*/
|
||||
|
||||
transform(program) {
|
||||
DefaultFormatter.prototype.transform.apply(this, arguments);
|
||||
CommonFormatter.prototype.transform.apply(this, arguments);
|
||||
|
||||
var body = program.body;
|
||||
|
||||
@@ -108,12 +108,16 @@ export default class AMDFormatter extends DefaultFormatter {
|
||||
exportSpecifier(specifier, node, nodes) {
|
||||
if (this.doDefaultExportInterop(specifier)) {
|
||||
this.passModuleArg = true;
|
||||
nodes.push(util.template("exports-default-assign", {
|
||||
VALUE: specifier.local
|
||||
}, true));
|
||||
} else {
|
||||
CommonFormatter.prototype.exportSpecifier.apply(this, arguments);
|
||||
|
||||
if (specifier.exported !== specifier.local && !node.source) {
|
||||
nodes.push(util.template("exports-default-assign", {
|
||||
VALUE: specifier.local
|
||||
}, true));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CommonFormatter.prototype.exportSpecifier.apply(this, arguments);
|
||||
}
|
||||
|
||||
exportDeclaration(node, nodes) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import DefaultFormatter from "./_default";
|
||||
import AMDFormatter from "./amd";
|
||||
import object from "../../helpers/object";
|
||||
import * as util from "../../util";
|
||||
import last from "lodash/array/last";
|
||||
import each from "lodash/collection/each";
|
||||
@@ -60,12 +61,12 @@ var runnerSettersVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (node._importSource === state.source) {
|
||||
if (t.isVariableDeclaration(node)) {
|
||||
each(node.declarations, function (declar) {
|
||||
for (var declar of (node.declarations: Array)) {
|
||||
state.hoistDeclarators.push(t.variableDeclarator(declar.id));
|
||||
state.nodes.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", declar.id, declar.init)
|
||||
));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
state.nodes.push(node);
|
||||
}
|
||||
@@ -143,7 +144,7 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
]));
|
||||
}
|
||||
|
||||
this.internalRemap = {};
|
||||
this.internalRemap = object();
|
||||
|
||||
this._addImportSource(last(nodes), node);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
|
||||
if (descriptor.initializer) {
|
||||
descriptor.value = descriptor.initializer.call(target);
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
}
|
||||
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
}
|
||||
|
||||
return target;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
(function (target, key, descriptors) {
|
||||
var _descriptor = descriptors[key];
|
||||
if (!_descriptor) return;
|
||||
|
||||
// clone it
|
||||
var descriptor = {};
|
||||
for (var _key in _descriptor) descriptor[_key] = _descriptor[_key];
|
||||
|
||||
// initialize it
|
||||
if (!descriptor.initializer) return;
|
||||
descriptor.value = descriptor.initializer.call(target);
|
||||
|
||||
Object.defineProperty(target, key, descriptor);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Object(RIGHT)[LEFT] !== undefined;
|
||||
@@ -1,4 +0,0 @@
|
||||
(function (proxy, directory) {
|
||||
directory.push(proxy);
|
||||
return proxy;
|
||||
})
|
||||
@@ -1 +0,0 @@
|
||||
[];
|
||||
@@ -1,3 +1,3 @@
|
||||
for (var LEN = ARGUMENTS.length, ARRAY = Array(ARRAY_LEN), KEY = START; KEY < LEN; KEY++) {
|
||||
for (var LEN = ARGUMENTS.length, ARRAY: ARRAY_TYPE = Array(ARRAY_LEN), KEY = START; KEY < LEN; KEY++) {
|
||||
ARRAY[ARRAY_KEY] = ARGUMENTS[KEY];
|
||||
}
|
||||
|
||||
@@ -8,34 +8,26 @@ import traverse from "../traversal";
|
||||
|
||||
export default class TransformerPass {
|
||||
constructor(file: File, transformer: Transformer) {
|
||||
this.shouldTransform = !transformer.shouldVisit;
|
||||
this.transformer = transformer;
|
||||
this.handlers = transformer.handlers;
|
||||
this.skipKey = transformer.skipKey;
|
||||
this.file = file;
|
||||
this.ran = false;
|
||||
this.transformer = transformer;
|
||||
this.handlers = transformer.handlers;
|
||||
this.file = file;
|
||||
this.ran = false;
|
||||
this.key = transformer.key;
|
||||
}
|
||||
|
||||
canTransform(): boolean {
|
||||
return this.file.pipeline.canTransform(this.transformer, this.file.opts);
|
||||
}
|
||||
|
||||
checkPath(path: TraversalPath): boolean {
|
||||
if (this.shouldTransform || this.ran) return;
|
||||
|
||||
this.shouldTransform = this.transformer.shouldVisit(path.node);
|
||||
return this.file.transformerDependencies[this.key] ||
|
||||
this.file.pipeline.canTransform(this.transformer, this.file.opts);
|
||||
}
|
||||
|
||||
transform() {
|
||||
if (!this.shouldTransform) return;
|
||||
|
||||
var file = this.file;
|
||||
|
||||
file.log.debug(`Start transformer ${this.transformer.key}`);
|
||||
file.log.debug(`Start transformer ${this.key}`);
|
||||
|
||||
traverse(file.ast, this.handlers, file.scope, file);
|
||||
|
||||
file.log.debug(`Finish transformer ${this.transformer.key}`);
|
||||
file.log.debug(`Finish transformer ${this.key}`);
|
||||
|
||||
this.ran = true;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ export default class TransformerPipeline {
|
||||
}
|
||||
|
||||
canTransform(transformer, fileOpts) {
|
||||
if (transformer.metadata.plugin) return true;
|
||||
|
||||
for (var filter of (this.filters: Array)) {
|
||||
var result = filter(transformer, fileOpts);
|
||||
if (result != null) return result;
|
||||
|
||||
@@ -25,8 +25,8 @@ export default class Transformer {
|
||||
};
|
||||
|
||||
this.manipulateOptions = take("manipulateOptions");
|
||||
this.shouldVisit = take("shouldVisit");
|
||||
this.metadata = take("metadata") || {};
|
||||
this.dependencies = this.metadata.dependencies || [];
|
||||
this.parser = take("parser");
|
||||
this.post = take("post");
|
||||
this.pre = take("pre");
|
||||
@@ -41,18 +41,6 @@ export default class Transformer {
|
||||
|
||||
this.handlers = this.normalize(transformer);
|
||||
this.key = transformerKey;
|
||||
|
||||
//
|
||||
|
||||
if (!this.shouldVisit) {
|
||||
var types = Object.keys(this.handlers);
|
||||
this.shouldVisit = function (node) {
|
||||
for (var i = 0; i < types.length; i++) {
|
||||
if (node.type === types[i]) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
normalize(transformer: Object): Object {
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
"es6.symbols": "es6.spec.symbols",
|
||||
"es6.blockScopingTDZ": "es6.spec.blockScoping",
|
||||
|
||||
"utility.inlineExpressions": "minification.inlineExpressions",
|
||||
"utility.deadCodeElimination": "minification.deadCodeElimination",
|
||||
"minification.removeConsoleCalls": "utility.removeConsole",
|
||||
"minification.removeDebugger": "utility.removeDebugger"
|
||||
"utility.removeConsoleCalls": "minification.removeConsole",
|
||||
"utility.removeDebugger": "minification.removeDebugger"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function MemberExpression(node) {
|
||||
var prop = node.property;
|
||||
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
// foo.default -> foo["default"]
|
||||
node.property = t.literal(prop.name);
|
||||
node.computed = true;
|
||||
export var metadata = {
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
export var MemberExpression = {
|
||||
exit(node) {
|
||||
var prop = node.property;
|
||||
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
|
||||
// foo.default -> foo["default"]
|
||||
node.property = t.literal(prop.name);
|
||||
node.computed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function Property(node) {
|
||||
var key = node.key;
|
||||
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
// default: "bar" -> "default": "bar"
|
||||
node.key = t.literal(key.name);
|
||||
export var metadata = {
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
export var Property = {
|
||||
exit(node) {
|
||||
var key = node.key;
|
||||
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
|
||||
// default: "bar" -> "default": "bar"
|
||||
node.key = t.literal(key.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import * as defineMap from "../../helpers/define-map";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isProperty(node) && (node.kind === "get" || node.kind === "set");
|
||||
}
|
||||
|
||||
export function ObjectExpression(node, parent, scope, file) {
|
||||
var mutatorMap = {};
|
||||
var hasAny = false;
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var shouldVisit = t.isArrowFunctionExpression;
|
||||
|
||||
export function ArrowFunctionExpression(node) {
|
||||
t.ensureBlock(node);
|
||||
|
||||
node.expression = false;
|
||||
node.type = "FunctionExpression";
|
||||
node.shadow = true;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -32,14 +32,14 @@ function isVar(node, parent) {
|
||||
}
|
||||
|
||||
function standardizeLets(declars) {
|
||||
for (var i = 0; i < declars.length; i++) {
|
||||
delete declars[i]._let;
|
||||
for (var declar of (declars: Array)) {
|
||||
delete declar._let;
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isVariableDeclaration(node) && (node.kind === "let" || node.kind === "const");
|
||||
}
|
||||
export var metadata = {
|
||||
group: "builtin-advanced"
|
||||
};
|
||||
|
||||
export function VariableDeclaration(node, parent, scope, file) {
|
||||
if (!isLet(node, parent)) return;
|
||||
@@ -109,19 +109,14 @@ function traverseReplace(node, parent, scope, remaps) {
|
||||
}
|
||||
|
||||
var letReferenceBlockVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isFunction()) {
|
||||
this.traverse(letReferenceFunctionVisitor, state);
|
||||
return this.skip();
|
||||
}
|
||||
Function(node, parent, scope, state) {
|
||||
this.traverse(letReferenceFunctionVisitor, state);
|
||||
return this.skip();
|
||||
}
|
||||
};
|
||||
|
||||
var letReferenceFunctionVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
// not a direct reference
|
||||
if (!this.isReferencedIdentifier()) return;
|
||||
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
var ref = state.letReferences[node.name];
|
||||
|
||||
// not a part of our scope
|
||||
@@ -159,10 +154,8 @@ var hoistVarDeclarationsVisitor = {
|
||||
};
|
||||
|
||||
var loopLabelVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isLabeledStatement()) {
|
||||
state.innerLabels.push(node.label.name);
|
||||
}
|
||||
LabeledStatement(node, parent, scope, state) {
|
||||
state.innerLabels.push(node.label.name);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -187,19 +180,28 @@ var loopNodeTo = function (node) {
|
||||
};
|
||||
|
||||
var loopVisitor = {
|
||||
Loop(node, parent, scope, state) {
|
||||
var oldIgnoreLabeless = state.ignoreLabeless;
|
||||
state.ignoreLabeless = true;
|
||||
this.traverse(loopVisitor, state);
|
||||
state.ignoreLabeless = oldIgnoreLabeless;
|
||||
this.skip();
|
||||
},
|
||||
|
||||
Function() {
|
||||
this.skip();
|
||||
},
|
||||
|
||||
SwitchCase(node, parent, scope, state) {
|
||||
var oldInSwitchCase = state.inSwitchCase;
|
||||
state.inSwitchCase = true;
|
||||
this.traverse(loopVisitor, state);
|
||||
state.inSwitchCase = oldInSwitchCase;
|
||||
this.skip();
|
||||
},
|
||||
|
||||
enter(node, parent, scope, state) {
|
||||
var replace;
|
||||
|
||||
if (this.isLoop()) {
|
||||
state.ignoreLabeless = true;
|
||||
this.traverse(loopVisitor, state);
|
||||
state.ignoreLabeless = false;
|
||||
}
|
||||
|
||||
if (this.isFunction() || this.isLoop()) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
var loopText = loopNodeTo(node);
|
||||
|
||||
if (loopText) {
|
||||
@@ -215,6 +217,9 @@ var loopVisitor = {
|
||||
// they don't refer to the actual loop we're scopifying
|
||||
if (state.ignoreLabeless) return;
|
||||
|
||||
//
|
||||
if (state.inSwitchCase) return;
|
||||
|
||||
// break statements mean something different in this context
|
||||
if (t.isBreakStatement(node) && t.isSwitchCase(parent)) return;
|
||||
}
|
||||
@@ -233,6 +238,7 @@ var loopVisitor = {
|
||||
|
||||
if (replace) {
|
||||
replace = t.returnStatement(replace);
|
||||
this.skip();
|
||||
return t.inherits(replace, node);
|
||||
}
|
||||
}
|
||||
@@ -467,18 +473,17 @@ class BlockScoping {
|
||||
var block = this.block;
|
||||
|
||||
var declarators = block._letDeclarators || [];
|
||||
var declar;
|
||||
|
||||
//
|
||||
for (let i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
let declar = declarators[i];
|
||||
extend(this.outsideLetReferences, t.getBindingIdentifiers(declar));
|
||||
}
|
||||
|
||||
//
|
||||
if (block.body) {
|
||||
for (let i = 0; i < block.body.length; i++) {
|
||||
declar = block.body[i];
|
||||
let declar = block.body[i];
|
||||
if (isLet(declar, block)) {
|
||||
declarators = declarators.concat(declar.declarations);
|
||||
}
|
||||
@@ -487,7 +492,7 @@ class BlockScoping {
|
||||
|
||||
//
|
||||
for (let i = 0; i < declarators.length; i++) {
|
||||
declar = declarators[i];
|
||||
let declar = declarators[i];
|
||||
var keys = t.getBindingIdentifiers(declar);
|
||||
extend(this.letReferences, keys);
|
||||
this.hasLetReferences = true;
|
||||
@@ -524,6 +529,7 @@ class BlockScoping {
|
||||
var state = {
|
||||
hasBreakContinue: false,
|
||||
ignoreLabeless: false,
|
||||
inSwitchCase: false,
|
||||
innerLabels: [],
|
||||
hasReturn: false,
|
||||
isLoop: !!this.loop,
|
||||
@@ -551,9 +557,13 @@ class BlockScoping {
|
||||
*/
|
||||
|
||||
pushDeclar(node: { type: "VariableDeclaration" }): Array<Object> {
|
||||
this.body.push(t.variableDeclaration(node.kind, node.declarations.map(function (declar) {
|
||||
return t.variableDeclarator(declar.id);
|
||||
})));
|
||||
var declars = [];
|
||||
var names = t.getBindingIdentifiers(node);
|
||||
for (var name in names) {
|
||||
declars.push(t.variableDeclarator(names[name]));
|
||||
}
|
||||
|
||||
this.body.push(t.variableDeclaration(node.kind, declars));
|
||||
|
||||
var replace = [];
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ import * as t from "../../../types";
|
||||
|
||||
const PROPERTY_COLLISION_METHOD_NAME = "__initializeProperties";
|
||||
|
||||
export var shouldVisit = t.isClass;
|
||||
|
||||
export function ClassDeclaration(node, parent, scope, file) {
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(node.id, t.toExpression(node))
|
||||
@@ -37,7 +35,7 @@ var collectPropertyReferencesVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
var constructorVisitor = traverse.explode({
|
||||
var constructorVisitor = {
|
||||
ThisExpression: {
|
||||
enter(node, parent, scope, ref) {
|
||||
return ref;
|
||||
@@ -51,9 +49,9 @@ var constructorVisitor = traverse.explode({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var verifyConstructorVisitor = traverse.explode({
|
||||
var verifyConstructorVisitor = {
|
||||
MethodDefinition: {
|
||||
enter() {
|
||||
this.skip();
|
||||
@@ -98,7 +96,7 @@ var verifyConstructorVisitor = traverse.explode({
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
class ClassTransformer {
|
||||
|
||||
@@ -314,7 +312,7 @@ class ClassTransformer {
|
||||
if (isConstructor) {
|
||||
this.pushConstructor(node, path);
|
||||
} else {
|
||||
this.pushMethod(node);
|
||||
this.pushMethod(node, path);
|
||||
}
|
||||
} else if (t.isClassProperty(node)) {
|
||||
this.pushProperty(node);
|
||||
@@ -412,7 +410,7 @@ class ClassTransformer {
|
||||
this.pushMethod(t.methodDefinition(
|
||||
t.identifier(PROPERTY_COLLISION_METHOD_NAME),
|
||||
t.functionExpression(null, [], t.blockStatement(body))
|
||||
), true);
|
||||
), null, true);
|
||||
|
||||
if (this.hasSuper) {
|
||||
this.bareSuper.insertAfter(call);
|
||||
@@ -473,15 +471,15 @@ class ClassTransformer {
|
||||
* Push a method to its respective mutatorMap.
|
||||
*/
|
||||
|
||||
pushMethod(node: { type: "MethodDefinition" }, allowedIllegal?) {
|
||||
pushMethod(node: { type: "MethodDefinition" }, path?: TraversalPath, allowedIllegal?) {
|
||||
if (!allowedIllegal && t.isLiteral(t.toComputedKey(node), { value: PROPERTY_COLLISION_METHOD_NAME })) {
|
||||
throw this.file.errorWithNode(node, messages.get("illegalMethodName", PROPERTY_COLLISION_METHOD_NAME));
|
||||
}
|
||||
|
||||
if (node.kind === "method") {
|
||||
nameMethod.property(node, this.file, this.scope);
|
||||
nameMethod.property(node, this.file, path ? path.get("value").scope : this.scope);
|
||||
|
||||
if (this.isLoose) {
|
||||
if (this.isLoose && !node.decorators) {
|
||||
// use assignments instead of define properties for loose classes
|
||||
|
||||
var classRef = this.classRef;
|
||||
|
||||
@@ -1,48 +1,31 @@
|
||||
import * as messages from "../../../messages";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isVariableDeclaration(node, { kind: "const" }) || t.isImportDeclaration(node);
|
||||
}
|
||||
export function AssignmentExpression(node, parent, scope, file) {
|
||||
var ids = this.getBindingIdentifiers();
|
||||
|
||||
var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isAssignmentExpression() || this.isUpdateExpression()) {
|
||||
var ids = this.getBindingIdentifiers();
|
||||
for (var name in ids) {
|
||||
var id = ids[name];
|
||||
|
||||
for (var name in ids) {
|
||||
var id = ids[name];
|
||||
var binding = scope.getBinding(name);
|
||||
|
||||
var constant = state.constants[name];
|
||||
// no binding exists
|
||||
if (!binding) continue;
|
||||
|
||||
// no constant exists
|
||||
if (!constant) continue;
|
||||
// not a constant
|
||||
if (binding.kind !== "const" && binding.kind !== "module") continue;
|
||||
|
||||
var constantIdentifier = constant.identifier;
|
||||
// check if the assignment id matches the constant declaration id
|
||||
// if it does then it was the id used to initially declare the
|
||||
// constant so we can just ignore it
|
||||
if (binding.identifier === id) continue;
|
||||
|
||||
// check if the assignment id matches the constant declaration id
|
||||
// if it does then it was the id used to initially declare the
|
||||
// constant so we can just ignore it
|
||||
if (id === constantIdentifier) continue;
|
||||
|
||||
// check if there's been a local binding that shadows this constant
|
||||
if (!scope.bindingIdentifierEquals(name, constantIdentifier)) continue;
|
||||
|
||||
throw state.file.errorWithNode(id, messages.get("readOnly", name));
|
||||
}
|
||||
} else if (this.isScope()) {
|
||||
this.skip();
|
||||
}
|
||||
throw file.errorWithNode(id, messages.get("readOnly", name));
|
||||
}
|
||||
};
|
||||
|
||||
export function Scopable(node, parent, scope, file) {
|
||||
this.traverse(visitor, {
|
||||
constants: scope.getAllBindingsOfKind("const", "module"),
|
||||
file: file
|
||||
});
|
||||
}
|
||||
|
||||
export { AssignmentExpression as UpdateExpression };
|
||||
|
||||
export function VariableDeclaration(node) {
|
||||
if (node.kind === "const") node.kind = "let";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as messages from "../../../messages";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var shouldVisit = t.isPattern;
|
||||
export var metadata = {
|
||||
group: "builtin-advanced"
|
||||
};
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
var left = node.left;
|
||||
@@ -53,7 +55,7 @@ export function ForOfStatement(node, parent, scope, file) {
|
||||
|
||||
export { ForOfStatement as ForInStatement };
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
export function Func(node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuring = false;
|
||||
@@ -63,6 +65,7 @@ exports.Function = function (node, parent, scope, file) {
|
||||
|
||||
hasDestructuring = true;
|
||||
var ref = scope.generateUidIdentifier("ref");
|
||||
t.inherits(ref, pattern);
|
||||
|
||||
var destructuring = new DestructuringTransformer({
|
||||
blockHoist: node.params.length - i,
|
||||
@@ -82,8 +85,7 @@ exports.Function = function (node, parent, scope, file) {
|
||||
|
||||
var block = node.body;
|
||||
block.body = nodes.concat(block.body);
|
||||
return node;
|
||||
};
|
||||
}
|
||||
|
||||
export function CatchClause(node, parent, scope, file) {
|
||||
var pattern = node.param;
|
||||
@@ -103,8 +105,6 @@ export function CatchClause(node, parent, scope, file) {
|
||||
destructuring.init(pattern, ref);
|
||||
|
||||
node.body.body = nodes.concat(node.body.body);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export function ExpressionStatement(node, parent, scope, file) {
|
||||
@@ -179,7 +179,7 @@ export function VariableDeclaration(node, parent, scope, file) {
|
||||
file: file
|
||||
});
|
||||
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
if (t.isPattern(pattern)) {
|
||||
destructuring.init(pattern, patternId);
|
||||
|
||||
if (+i !== node.declarations.length - 1) {
|
||||
|
||||
@@ -2,8 +2,6 @@ import * as messages from "../../../messages";
|
||||
import * as util from "../../../util";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var shouldVisit = t.isForOfStatement;
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
if (this.get("right").isArrayExpression()) {
|
||||
return _ForOfStatementArray.call(this, node, scope, file);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export { check } from "../internal/modules";
|
||||
|
||||
function keepBlockHoist(node, nodes) {
|
||||
if (node._blockHoist) {
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
@@ -10,6 +8,10 @@ function keepBlockHoist(node, nodes) {
|
||||
}
|
||||
}
|
||||
|
||||
export var metadata = {
|
||||
group: "builtin-modules"
|
||||
};
|
||||
|
||||
export function ImportDeclaration(node, parent, scope, file) {
|
||||
// flow type
|
||||
if (node.isType) return;
|
||||
|
||||
@@ -1,33 +1,20 @@
|
||||
import ReplaceSupers from "../../helpers/replace-supers";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var shouldVisit = t.isSuper;
|
||||
|
||||
function Property(path, node, scope, getObjectRef, file) {
|
||||
if (!node.method) return;
|
||||
|
||||
var value = node.value;
|
||||
var thisExpr = scope.generateUidIdentifier("this");
|
||||
if (!node.method && node.kind === "init") return;
|
||||
if (!t.isFunction(node.value)) return;
|
||||
|
||||
var replaceSupers = new ReplaceSupers({
|
||||
topLevelThisReference: thisExpr,
|
||||
getObjectRef: getObjectRef,
|
||||
methodNode: node,
|
||||
methodPath: path,
|
||||
isStatic: true,
|
||||
scope: scope,
|
||||
file: file
|
||||
getObjectRef: getObjectRef,
|
||||
methodNode: node,
|
||||
methodPath: path,
|
||||
isStatic: true,
|
||||
scope: scope,
|
||||
file: file
|
||||
});
|
||||
|
||||
replaceSupers.replace();
|
||||
|
||||
if (replaceSupers.hasSuper) {
|
||||
value.body.body.unshift(
|
||||
t.variableDeclaration("var", [
|
||||
t.variableDeclarator(thisExpr, t.thisExpression())
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function ObjectExpression(node, parent, scope, file) {
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import callDelegate from "../../helpers/call-delegate";
|
||||
import * as util from "../../../util";
|
||||
import traverse from "../../../traversal";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isFunction(node) && hasDefaults(node);
|
||||
}
|
||||
|
||||
var hasDefaults = function (node) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
if (!t.isIdentifier(node.params[i])) return true;
|
||||
@@ -14,17 +11,18 @@ var hasDefaults = function (node) {
|
||||
};
|
||||
|
||||
var iifeVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (!this.isReferencedIdentifier()) return;
|
||||
if (!state.scope.hasOwnBinding(node.name)) return;
|
||||
if (state.scope.bindingIdentifierEquals(node.name, node)) return;
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (node.name !== "eval") {
|
||||
if (!state.scope.hasOwnBinding(node.name)) return;
|
||||
if (state.scope.bindingIdentifierEquals(node.name, node)) return;
|
||||
}
|
||||
|
||||
state.iife = true;
|
||||
this.stop();
|
||||
}
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
export function Func(node, parent, scope, file) {
|
||||
if (!hasDefaults(node)) return;
|
||||
|
||||
t.ensureBlock(node);
|
||||
@@ -96,6 +94,4 @@ exports.Function = function (node, parent, scope, file) {
|
||||
} else {
|
||||
node.body.body = body.concat(node.body.body);
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@ import isNumber from "lodash/lang/isNumber";
|
||||
import * as util from "../../../util";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var shouldVisit = t.isRestElement;
|
||||
|
||||
var memberExpressionOptimisationVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
// check if this scope has a local binding that will shadow the rest parameter
|
||||
@@ -55,10 +53,11 @@ var hasRest = function (node) {
|
||||
return t.isRestElement(node.params[node.params.length - 1]);
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
export function Func(node, parent, scope, file) {
|
||||
if (!hasRest(node)) return;
|
||||
|
||||
var rest = node.params.pop().argument;
|
||||
var restParam = node.params.pop();
|
||||
var rest = restParam.argument;
|
||||
|
||||
var argsId = t.identifier("arguments");
|
||||
|
||||
@@ -96,7 +95,7 @@ exports.Function = function (node, parent, scope, file) {
|
||||
candidate.replaceWith(argsId);
|
||||
optimizeMemberExpression(candidate.parent, node.params.length);
|
||||
}
|
||||
return node;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -127,15 +126,15 @@ exports.Function = function (node, parent, scope, file) {
|
||||
}
|
||||
|
||||
var loop = util.template("rest", {
|
||||
ARGUMENTS: argsId,
|
||||
ARRAY_KEY: arrKey,
|
||||
ARRAY_LEN: arrLen,
|
||||
START: start,
|
||||
ARRAY: rest,
|
||||
KEY: key,
|
||||
LEN: len
|
||||
ARRAY_TYPE: restParam.typeAnnotation,
|
||||
ARGUMENTS: argsId,
|
||||
ARRAY_KEY: arrKey,
|
||||
ARRAY_LEN: arrLen,
|
||||
START: start,
|
||||
ARRAY: rest,
|
||||
KEY: key,
|
||||
LEN: len
|
||||
});
|
||||
loop._blockHoist = node.params.length + 1;
|
||||
node.body.body.unshift(loop);
|
||||
return node;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,42 +63,40 @@ function spec(node, body, objId, initProps, file) {
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isProperty(node) && node.computed;
|
||||
}
|
||||
export var ObjectExpression = {
|
||||
exit(node, parent, scope, file) {
|
||||
var hasComputed = false;
|
||||
|
||||
export function ObjectExpression(node, parent, scope, file) {
|
||||
var hasComputed = false;
|
||||
for (var prop of (node.properties: Array)) {
|
||||
hasComputed = t.isProperty(prop, { computed: true, kind: "init" });
|
||||
if (hasComputed) break;
|
||||
}
|
||||
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
hasComputed = t.isProperty(node.properties[i], { computed: true, kind: "init" });
|
||||
if (hasComputed) break;
|
||||
if (!hasComputed) return;
|
||||
|
||||
var initProps = [];
|
||||
var objId = scope.generateUidBasedOnNode(parent);
|
||||
|
||||
//
|
||||
|
||||
var body = [];
|
||||
|
||||
//
|
||||
|
||||
var callback = spec;
|
||||
if (file.isLoose("es6.properties.computed")) callback = loose;
|
||||
|
||||
var result = callback(node, body, objId, initProps, file);
|
||||
if (result) return result;
|
||||
|
||||
//
|
||||
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(objId, t.objectExpression(initProps))
|
||||
]));
|
||||
|
||||
body.push(t.expressionStatement(objId));
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
if (!hasComputed) return;
|
||||
|
||||
var initProps = [];
|
||||
var objId = scope.generateUidBasedOnNode(parent);
|
||||
|
||||
//
|
||||
|
||||
var body = [];
|
||||
|
||||
//
|
||||
|
||||
var callback = spec;
|
||||
if (file.isLoose("es6.properties.computed")) callback = loose;
|
||||
|
||||
var result = callback(node, body, objId, initProps, file);
|
||||
if (result) return result;
|
||||
|
||||
//
|
||||
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(objId, t.objectExpression(initProps))
|
||||
]));
|
||||
|
||||
body.push(t.expressionStatement(objId));
|
||||
|
||||
return body;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isProperty(node) && (node.method || node.shorthand);
|
||||
}
|
||||
|
||||
export function Property(node) {
|
||||
if (node.method) {
|
||||
node.method = false;
|
||||
@@ -11,6 +5,5 @@ export function Property(node) {
|
||||
|
||||
if (node.shorthand) {
|
||||
node.shorthand = false;
|
||||
node.key = t.removeComments(t.clone(node.key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import * as regex from "../../helpers/regex";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return regex.is(node, "y");
|
||||
}
|
||||
|
||||
export function Literal(node) {
|
||||
if (!regex.is(node, "y")) return;
|
||||
return t.newExpression(t.identifier("RegExp"), [
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import rewritePattern from "regexpu/rewrite-pattern";
|
||||
import * as regex from "../../helpers/regex";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return regex.is(node, "u");
|
||||
}
|
||||
|
||||
export function Literal(node) {
|
||||
if (!regex.is(node, "u")) return;
|
||||
node.regex.pattern = rewritePattern(node.regex.pattern, node.regex.flags);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import traverse from "../../../traversal";
|
||||
import * as t from "../../../types";
|
||||
|
||||
var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (!this.isReferencedIdentifier()) return;
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (t.isFor(parent) && parent.left === node) return;
|
||||
|
||||
var declared = state.letRefs[node.name];
|
||||
@@ -28,17 +28,20 @@ var visitor = {
|
||||
};
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
group: "builtin-advanced"
|
||||
};
|
||||
|
||||
export function BlockStatement(node, parent, scope, file) {
|
||||
var letRefs = node._letReferences;
|
||||
if (!letRefs) return;
|
||||
export var BlockStatement = {
|
||||
exit(node, parent, scope, file) {
|
||||
var letRefs = node._letReferences;
|
||||
if (!letRefs) return;
|
||||
|
||||
this.traverse(visitor, {
|
||||
letRefs: letRefs,
|
||||
file: file
|
||||
});
|
||||
}
|
||||
this.traverse(visitor, {
|
||||
letRefs: letRefs,
|
||||
file: file
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export { BlockStatement as Program, BlockStatement as Loop };
|
||||
|
||||
@@ -44,8 +44,6 @@ function build(props, scope) {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
export var shouldVisit = t.isSpreadElement;
|
||||
|
||||
export function ArrayExpression(node, parent, scope) {
|
||||
var elements = node.elements;
|
||||
if (!hasSpread(elements)) return;
|
||||
|
||||
@@ -1,78 +1,57 @@
|
||||
import reduceRight from "lodash/collection/reduceRight";
|
||||
import * as messages from "../../../messages";
|
||||
import flatten from "lodash/array/flatten";
|
||||
import traverse from "../../../traversal";
|
||||
import * as util from "../../../util";
|
||||
import map from "lodash/collection/map";
|
||||
import * as t from "../../../types";
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
export var metadata = {
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
export function Func(node, parent, scope, file) {
|
||||
if (node.generator || node.async) return;
|
||||
var tailCall = new TailCallTransformer(this, scope, file);
|
||||
tailCall.run();
|
||||
};
|
||||
}
|
||||
|
||||
function returnBlock(expr) {
|
||||
return t.blockStatement([t.returnStatement(expr)]);
|
||||
}
|
||||
|
||||
// looks for and replaces tail recursion calls
|
||||
var firstPass = {
|
||||
var visitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isReturnStatement()) {
|
||||
this.skip();
|
||||
return state.subTransform(node.argument);
|
||||
} else if (t.isTryStatement(parent)) {
|
||||
if (t.isTryStatement(parent)) {
|
||||
if (node === parent.block) {
|
||||
this.skip();
|
||||
} else if (parent.finalizer && node !== parent.finalizer) {
|
||||
this.skip();
|
||||
}
|
||||
} else if (this.isFunction()) {
|
||||
this.skip();
|
||||
} else if (this.isVariableDeclaration()) {
|
||||
this.skip();
|
||||
state.vars.push(node);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
// hoists up function declarations, replaces `this` and `arguments` and marks
|
||||
// them as needed
|
||||
var secondPass = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isThisExpression()) {
|
||||
state.needsThis = true;
|
||||
return state.getThisId();
|
||||
} else if (this.isReferencedIdentifier({ name: "arguments" })) {
|
||||
ReturnStatement(node, parent, scope, state) {
|
||||
return state.subTransform(node.argument);
|
||||
},
|
||||
|
||||
Function(node, parent, scope, state) {
|
||||
this.skip();
|
||||
},
|
||||
|
||||
VariableDeclaration(node, parent, scope, state) {
|
||||
state.vars.push(node);
|
||||
},
|
||||
|
||||
ThisExpression(node, parent, scope, state) {
|
||||
state.needsThis = true;
|
||||
state.thisPaths.push(this);
|
||||
},
|
||||
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (node.name === "arguments") {
|
||||
state.needsArguments = true;
|
||||
return state.getArgumentsId();
|
||||
} else if (this.isFunction()) {
|
||||
this.skip();
|
||||
if (this.isFunctionDeclaration()) {
|
||||
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(node, parent, scope, state) {
|
||||
if (!this.isExpressionStatement()) 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);
|
||||
});
|
||||
state.argumentsPaths.push(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -80,11 +59,16 @@ var thirdPass = {
|
||||
class TailCallTransformer {
|
||||
constructor(path, scope, file) {
|
||||
this.hasTailRecursion = false;
|
||||
this.needsArguments = false;
|
||||
this.setsArguments = false;
|
||||
this.needsThis = false;
|
||||
this.ownerId = path.node.id;
|
||||
this.vars = [];
|
||||
|
||||
this.needsArguments = false;
|
||||
this.argumentsPaths = [];
|
||||
this.setsArguments = false;
|
||||
|
||||
this.needsThis = false;
|
||||
this.thisPaths = [];
|
||||
|
||||
this.ownerId = path.node.id;
|
||||
this.vars = [];
|
||||
|
||||
this.scope = scope;
|
||||
this.path = path;
|
||||
@@ -150,10 +134,12 @@ class TailCallTransformer {
|
||||
if (!ownerId) return;
|
||||
|
||||
// traverse the function and look for tail recursion
|
||||
this.path.traverse(firstPass, this);
|
||||
this.path.traverse(visitor, this);
|
||||
|
||||
// has no tail call recursion
|
||||
if (!this.hasTailRecursion) return;
|
||||
|
||||
// the function binding isn't constant so we can't be sure that it's the same function :(
|
||||
if (this.hasDeopt()) {
|
||||
this.file.log.deopt(node, messages.get("tailCallReassignmentDeopt"));
|
||||
return;
|
||||
@@ -161,21 +147,27 @@ class TailCallTransformer {
|
||||
|
||||
//
|
||||
|
||||
this.path.traverse(secondPass, this);
|
||||
|
||||
if (!this.needsThis || !this.needsArguments) {
|
||||
this.path.traverse(thirdPass, this);
|
||||
}
|
||||
|
||||
var body = t.ensureBlock(node).body;
|
||||
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
var bodyNode = body[i];
|
||||
if (!t.isFunctionDeclaration(bodyNode)) continue;
|
||||
|
||||
bodyNode = body[i] = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(bodyNode.id, t.toExpression(bodyNode))
|
||||
]);
|
||||
bodyNode._blockHoist = 2;
|
||||
}
|
||||
|
||||
if (this.vars.length > 0) {
|
||||
var declarations = flatten(map(this.vars, function (decl) {
|
||||
return decl.declarations;
|
||||
}));
|
||||
|
||||
var assignment = reduceRight(declarations, function (expr, decl) {
|
||||
return t.assignmentExpression("=", decl.id, expr);
|
||||
}, t.identifier("undefined"));
|
||||
|
||||
var statement = t.expressionStatement(assignment);
|
||||
statement._blockHoist = Infinity;
|
||||
body.unshift(statement);
|
||||
@@ -183,7 +175,9 @@ class TailCallTransformer {
|
||||
|
||||
var paramDecls = this.paramDecls;
|
||||
if (paramDecls.length > 0) {
|
||||
body.unshift(t.variableDeclaration("var", paramDecls));
|
||||
var paramDecl = t.variableDeclaration("var", paramDecls);
|
||||
paramDecl._blockHoist = Infinity;
|
||||
body.unshift(paramDecl);
|
||||
}
|
||||
|
||||
body.unshift(t.expressionStatement(
|
||||
@@ -191,22 +185,28 @@ class TailCallTransformer {
|
||||
);
|
||||
|
||||
node.body = util.template("tail-call-body", {
|
||||
AGAIN_ID: this.getAgainId(),
|
||||
THIS_ID: this.thisId,
|
||||
ARGUMENTS_ID: this.argumentsId,
|
||||
FUNCTION_ID: this.getFunctionId(),
|
||||
BLOCK: node.body
|
||||
FUNCTION_ID: this.getFunctionId(),
|
||||
AGAIN_ID: this.getAgainId(),
|
||||
BLOCK: node.body
|
||||
});
|
||||
|
||||
var topVars = [];
|
||||
|
||||
if (this.needsThis) {
|
||||
for (var path of (this.thisPaths: Array)) {
|
||||
path.replaceWith(this.getThisId());
|
||||
}
|
||||
|
||||
topVars.push(t.variableDeclarator(this.getThisId(), t.thisExpression()));
|
||||
}
|
||||
|
||||
if (this.needsArguments || this.setsArguments) {
|
||||
var decl = t.variableDeclarator(this.getArgumentsId());
|
||||
if (this.needsArguments) {
|
||||
for (var path of (this.argumentsPaths: Array)) {
|
||||
path.replaceWith(this.argumentsId);
|
||||
}
|
||||
|
||||
var decl = t.variableDeclarator(this.argumentsId);
|
||||
if (this.argumentsId) {
|
||||
decl.init = t.identifier("arguments");
|
||||
}
|
||||
topVars.push(decl);
|
||||
@@ -319,7 +319,7 @@ class TailCallTransformer {
|
||||
|
||||
var body = [];
|
||||
|
||||
if (!t.isThisExpression(thisBinding)) {
|
||||
if (this.needsThis && !t.isThisExpression(thisBinding)) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
this.getThisId(),
|
||||
@@ -332,29 +332,35 @@ class TailCallTransformer {
|
||||
}
|
||||
|
||||
var argumentsId = this.getArgumentsId();
|
||||
var params = this.getParams();
|
||||
var params = this.getParams();
|
||||
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
argumentsId,
|
||||
args
|
||||
)));
|
||||
|
||||
var i, param;
|
||||
if (this.needsArguments) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
argumentsId,
|
||||
args
|
||||
)));
|
||||
}
|
||||
|
||||
if (t.isArrayExpression(args)) {
|
||||
var elems = args.elements;
|
||||
for (i = 0; i < elems.length && i < params.length; i++) {
|
||||
param = params[i];
|
||||
for (let i = 0; i < elems.length && i < params.length; i++) {
|
||||
let param = params[i];
|
||||
var elem = elems[i] || (elems[i] = t.identifier("undefined"));
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
elems[i] = t.assignmentExpression("=", param, elem);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.needsArguments) {
|
||||
for (var elem of (elems: Array)) {
|
||||
body.push(t.expressionStatement(elem));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.setsArguments = true;
|
||||
for (i = 0; i < params.length; i++) {
|
||||
param = params[i];
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
let param = params[i];
|
||||
if (!param._isDefaultPlaceholder) {
|
||||
body.push(t.expressionStatement(t.assignmentExpression(
|
||||
"=",
|
||||
@@ -368,6 +374,7 @@ class TailCallTransformer {
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", this.getAgainId(), t.literal(true))
|
||||
));
|
||||
|
||||
body.push(t.continueStatement(this.getFunctionId()));
|
||||
|
||||
return body;
|
||||
|
||||
@@ -4,10 +4,6 @@ var buildBinaryExpression = function (left, right) {
|
||||
return t.binaryExpression("+", left, right);
|
||||
};
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isTemplateLiteral(node) || t.isTaggedTemplateExpression(node);
|
||||
}
|
||||
|
||||
export function TaggedTemplateExpression(node, parent, scope, file) {
|
||||
var quasi = node.quasi;
|
||||
var args = [];
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
export var metadata = {
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function shouldVisit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
export var metadata = {
|
||||
stage: 0
|
||||
stage: 0,
|
||||
dependencies: ["es6.classes"]
|
||||
};
|
||||
|
||||
export function shouldVisit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,14 +3,11 @@ import * as defineMap from "../../helpers/define-map";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
dependencies: ["es6.classes"],
|
||||
optional: true,
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return !!node.decorators;
|
||||
}
|
||||
|
||||
export function ObjectExpression(node, parent, scope, file) {
|
||||
var hasDecorators = false;
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
|
||||
@@ -5,8 +5,6 @@ export var metadata = {
|
||||
stage: 0
|
||||
};
|
||||
|
||||
export var shouldVisit = t.isDoExpression;
|
||||
|
||||
export function DoExpression(node) {
|
||||
var body = node.body.body;
|
||||
if (body.length) {
|
||||
|
||||
@@ -9,10 +9,20 @@ export var metadata = {
|
||||
|
||||
var MATH_POW = t.memberExpression(t.identifier("Math"), t.identifier("pow"));
|
||||
|
||||
build(exports, {
|
||||
var {
|
||||
ExpressionStatement,
|
||||
AssignmentExpression,
|
||||
BinaryExpression
|
||||
} = build({
|
||||
operator: "**",
|
||||
|
||||
build(left, right) {
|
||||
return t.callExpression(MATH_POW, [left, right]);
|
||||
}
|
||||
});
|
||||
|
||||
export {
|
||||
ExpressionStatement,
|
||||
AssignmentExpression,
|
||||
BinaryExpression
|
||||
};
|
||||
|
||||
@@ -6,10 +6,6 @@ export var metadata = {
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isExportDefaultSpecifier(node) || t.isExportNamespaceSpecifier(node);
|
||||
}
|
||||
|
||||
function build(node, nodes, scope) {
|
||||
var first = node.specifiers[0];
|
||||
if (!t.isExportNamespaceSpecifier(first) && !t.isExportDefaultSpecifier(first)) return;
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
stage: 1
|
||||
stage: 1,
|
||||
dependencies: ["es6.destructuring"]
|
||||
};
|
||||
|
||||
export function manipulateOptions(opts) {
|
||||
if (opts.whitelist) opts.whitelist.push("es6.destructuring");
|
||||
}
|
||||
|
||||
var hasSpread = function (node) {
|
||||
for (var i = 0; i < node.properties.length; i++) {
|
||||
if (t.isSpreadProperty(node.properties[i])) {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
export var metadata = {
|
||||
stage: 1
|
||||
};
|
||||
|
||||
export function shouldVisit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,123 +1,85 @@
|
||||
export default {
|
||||
_modules: require("./internal/modules"),
|
||||
//- builtin-setup
|
||||
_explode: require("./internal/explode"),
|
||||
_validation: require("./internal/validation"),
|
||||
_hoistDirectives: require("./internal/hoist-directives"),
|
||||
"minification.removeDebugger": require("./minification/remove-debugger"),
|
||||
"minification.removeConsole": require("./minification/remove-console"),
|
||||
"utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"),
|
||||
"minification.inlineExpressions": require("./minification/inline-expressions"),
|
||||
"minification.deadCodeElimination": require("./minification/dead-code-elimination"),
|
||||
_modules: require("./internal/modules"),
|
||||
"spec.functionName": require("./spec/function-name"),
|
||||
|
||||
//- builtin-basic
|
||||
// this is where the bulk of the ES6 transformations take place, none of them require traversal state
|
||||
// so they can all be concatenated together for performance
|
||||
"es7.classProperties": require("./es7/class-properties"),
|
||||
"es7.trailingFunctionCommas": require("./es7/trailing-function-commas"),
|
||||
"es7.asyncFunctions": require("./es7/async-functions"),
|
||||
"es7.decorators": require("./es7/decorators"),
|
||||
|
||||
strict: require("./other/strict"),
|
||||
|
||||
_validation: require("./internal/validation"),
|
||||
|
||||
"validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"),
|
||||
"validation.react": require("./validation/react"),
|
||||
|
||||
// this goes at the start so we only transform the original user code
|
||||
"spec.functionName": require("./spec/function-name"),
|
||||
|
||||
// needs to be before `_shadowFunctions`
|
||||
"es6.arrowFunctions": require("./es6/arrow-functions"),
|
||||
|
||||
"spec.blockScopedFunctions": require("./spec/block-scoped-functions"),
|
||||
|
||||
"optimisation.react.constantElements": require("./optimisation/react.constant-elements"),
|
||||
"optimisation.react.inlineElements": require("./optimisation/react.inline-elements"),
|
||||
reactCompat: require("./other/react-compat"),
|
||||
react: require("./other/react"),
|
||||
|
||||
// needs to be before `regenerator` due to generator comprehensions
|
||||
// needs to be before `_shadowFunctions`
|
||||
"es7.comprehensions": require("./es7/comprehensions"),
|
||||
|
||||
"es6.classes": require("./es6/classes"),
|
||||
|
||||
asyncToGenerator: require("./other/async-to-generator"),
|
||||
bluebirdCoroutines: require("./other/bluebird-coroutines"),
|
||||
|
||||
"es6.objectSuper": require("./es6/object-super"),
|
||||
"es7.objectRestSpread": require("./es7/object-rest-spread"),
|
||||
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
|
||||
|
||||
"es6.spec.templateLiterals": require("./es6/spec.template-literals"),
|
||||
"es6.templateLiterals": require("./es6/template-literals"),
|
||||
|
||||
"es5.properties.mutators": require("./es5/properties.mutators"),
|
||||
"es6.properties.shorthand": require("./es6/properties.shorthand"),
|
||||
|
||||
// needs to be before `_shadowFunctions` due to define property closure
|
||||
"es6.properties.computed": require("./es6/properties.computed"),
|
||||
|
||||
"optimisation.flow.forOf": require("./optimisation/flow.for-of"),
|
||||
"es6.forOf": require("./es6/for-of"),
|
||||
|
||||
"es6.regex.sticky": require("./es6/regex.sticky"),
|
||||
"es6.regex.unicode": require("./es6/regex.unicode"),
|
||||
|
||||
"es6.constants": require("./es6/constants"),
|
||||
|
||||
// needs to be before `es6.parameters.default` as default parameters will destroy the rest param
|
||||
"es6.parameters.rest": require("./es6/parameters.rest"),
|
||||
|
||||
// needs to be after `es6.parameters.rest` as we use `toArray` and avoid turning an already known array into one
|
||||
"es6.spread": require("./es6/spread"),
|
||||
|
||||
// needs to be before `es6.blockScoping` as default parameters have a TDZ
|
||||
"es6.parameters.default": require("./es6/parameters.default"),
|
||||
"es7.exportExtensions": require("./es7/export-extensions"),
|
||||
"spec.protoToAssign": require("./spec/proto-to-assign"),
|
||||
"es7.doExpressions": require("./es7/do-expressions"),
|
||||
"es6.spec.symbols": require("./es6/spec.symbols"),
|
||||
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
|
||||
jscript: require("./other/jscript"),
|
||||
flow: require("./other/flow"),
|
||||
|
||||
// needs to be before `es6.blockScoping` as let variables may be produced
|
||||
//- builtin-advanced
|
||||
"es6.destructuring": require("./es6/destructuring"),
|
||||
|
||||
// needs to be before `_shadowFunctions` due to block scopes sometimes being wrapped in a
|
||||
// closure
|
||||
"es6.blockScoping": require("./es6/block-scoping"),
|
||||
|
||||
// needs to be after `es6.blockScoping` due to needing `letReferences` set on blocks
|
||||
"es6.spec.blockScoping": require("./es6/spec.block-scoping"),
|
||||
|
||||
// needs to be after `es6.parameters.*` and `es6.blockScoping` due to needing pure
|
||||
// identifiers in parameters and variable declarators
|
||||
"es6.tailCall": require("./es6/tail-call"),
|
||||
// es6 syntax transformation is **forbidden** past this point since regenerator will chuck a massive
|
||||
// hissy fit
|
||||
|
||||
//- regenerator
|
||||
regenerator: require("./other/regenerator"),
|
||||
|
||||
// needs to be after `regenerator` due to needing `regeneratorRuntime` references
|
||||
// needs to be after `es6.forOf` due to needing `Symbol.iterator` references
|
||||
// needs to be before `es6.modules` due to dynamic imports
|
||||
runtime: require("./other/runtime"),
|
||||
|
||||
// needs to be before `_blockHoist` due to function hoisting etc
|
||||
"es7.exportExtensions": require("./es7/export-extensions"),
|
||||
//- builtin-modules
|
||||
runtime: require("./other/runtime"),
|
||||
"es6.modules": require("./es6/modules"),
|
||||
|
||||
_blockHoist: require("./internal/block-hoist"),
|
||||
|
||||
"spec.protoToAssign": require("./spec/proto-to-assign"),
|
||||
|
||||
_shadowFunctions: require("./internal/shadow-functions"),
|
||||
|
||||
"es7.doExpressions": require("./es7/do-expressions"),
|
||||
|
||||
"es6.spec.symbols": require("./es6/spec.symbols"),
|
||||
ludicrous: require("./other/ludicrous"),
|
||||
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
|
||||
|
||||
_strict: require("./internal/strict"),
|
||||
_moduleFormatter: require("./internal/module-formatter"),
|
||||
|
||||
//- builtin-trailing
|
||||
// these clean up the output and do finishing up transformations, it's important to note that by this
|
||||
// stage you can't import any new modules or insert new ES6 as all those transformers have already
|
||||
// been ran
|
||||
"es6.tailCall": require("./es6/tail-call"),
|
||||
_shadowFunctions: require("./internal/shadow-functions"),
|
||||
"es3.propertyLiterals": require("./es3/property-literals"),
|
||||
"es3.memberExpressionLiterals": require("./es3/member-expression-literals"),
|
||||
|
||||
"utility.removeDebugger": require("./utility/remove-debugger"),
|
||||
"utility.removeConsole": require("./utility/remove-console"),
|
||||
|
||||
"utility.inlineEnvironmentVariables": require("./utility/inline-environment-variables"),
|
||||
"utility.inlineExpressions": require("./utility/inline-expressions"),
|
||||
|
||||
"minification.memberExpressionLiterals": require("./minification/member-expression-literals"),
|
||||
"minification.propertyLiterals": require("./minification/property-literals"),
|
||||
|
||||
jscript: require("./other/jscript"),
|
||||
flow: require("./other/flow")
|
||||
_blockHoist: require("./internal/block-hoist"),
|
||||
};
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import sortBy from "lodash/collection/sortBy";
|
||||
|
||||
export var metadata = {
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
// Priority:
|
||||
//
|
||||
// - 0 We want this to be at the **very** bottom
|
||||
|
||||
30
src/babel/transformation/transformers/internal/explode.js
Normal file
30
src/babel/transformation/transformers/internal/explode.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import clone from "lodash/lang/clone";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
function buildClone(bindingKey, refKey) {
|
||||
return function (node) {
|
||||
if (node[bindingKey] === node[refKey]) {
|
||||
node[refKey] = t.removeComments(clone(node[refKey]));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function buildListClone(listKey, bindingKey, refKey) {
|
||||
var clone = buildClone(bindingKey, refKey);
|
||||
|
||||
return function (node) {
|
||||
if (!node[listKey]) return;
|
||||
|
||||
for (var subNode of (node[listKey]: Array)) {
|
||||
clone(subNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export var Property = buildClone("value", "key");
|
||||
export var ExportDeclaration = buildListClone("specifiers", "local", "exported");
|
||||
export var ImportDeclaration = buildListClone("specifiers", "local", "imported");
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export var BlockStatement = {
|
||||
exit(node) {
|
||||
for (var i = 0; i < node.body.length; i++) {
|
||||
var bodyNode = node.body[i];
|
||||
if (t.isExpressionStatement(bodyNode) && t.isLiteral(bodyNode.expression)) {
|
||||
bodyNode._blockHoist = Infinity;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { BlockStatement as Program };
|
||||
@@ -1,15 +1,24 @@
|
||||
import * as strict from "../../helpers/strict";
|
||||
|
||||
export function Program(program, parent, scope, file) {
|
||||
this.stop();
|
||||
export var metadata = {
|
||||
group: "builtin-modules"
|
||||
};
|
||||
|
||||
strict.wrap(program, function () {
|
||||
program.body = file.dynamicImports.concat(program.body);
|
||||
});
|
||||
export var Program = {
|
||||
exit(program, parent, scope, file) {
|
||||
strict.wrap(program, function () {
|
||||
// ensure that these are at the top, just like normal imports
|
||||
for (var node of (file.dynamicImports: Array)) {
|
||||
node._blockHoist = 3;
|
||||
}
|
||||
|
||||
if (!file.transformers["es6.modules"].canTransform()) return;
|
||||
program.body = file.dynamicImports.concat(program.body);
|
||||
});
|
||||
|
||||
if (file.moduleFormatter.transform) {
|
||||
file.moduleFormatter.transform(program);
|
||||
if (!file.transformers["es6.modules"].canTransform()) return;
|
||||
|
||||
if (file.moduleFormatter.transform) {
|
||||
file.moduleFormatter.transform(program);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
// a generator function as a default then regenerator will destroy the export
|
||||
// declaration and leave a variable declaration in it's place... yeah, handy.
|
||||
|
||||
import clone from "lodash/lang/clone";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isImportDeclaration(node) || t.isExportDeclaration(node);
|
||||
}
|
||||
export var metadata = {
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export function ImportDeclaration(node, parent, scope, file) {
|
||||
if (node.source) {
|
||||
@@ -48,6 +49,10 @@ export function ExportDefaultDeclaration(node, parent, scope) {
|
||||
}
|
||||
}
|
||||
|
||||
function buildExportSpecifier(id) {
|
||||
return t.exportSpecifier(clone(id), clone(id));
|
||||
}
|
||||
|
||||
export function ExportNamedDeclaration(node, parent, scope) {
|
||||
ImportDeclaration.apply(this, arguments);
|
||||
|
||||
@@ -60,12 +65,12 @@ export function ExportNamedDeclaration(node, parent, scope) {
|
||||
|
||||
if (t.isClassDeclaration(declar)) {
|
||||
// export class Foo {}
|
||||
node.specifiers = [t.exportSpecifier(declar.id, declar.id)];
|
||||
node.specifiers = [buildExportSpecifier(declar.id)];
|
||||
node.declaration = null;
|
||||
return [getDeclar(), node];
|
||||
} else if (t.isFunctionDeclaration(declar)) {
|
||||
// export function Foo() {}
|
||||
node.specifiers = [t.exportSpecifier(declar.id, declar.id)];
|
||||
node.specifiers = [buildExportSpecifier(declar.id)];
|
||||
node.declaration = null;
|
||||
node._blockHoist = 2;
|
||||
return [getDeclar(), node];
|
||||
@@ -74,8 +79,7 @@ export function ExportNamedDeclaration(node, parent, scope) {
|
||||
var specifiers = [];
|
||||
var bindings = this.get("declaration").getBindingIdentifiers();
|
||||
for (var key in bindings) {
|
||||
var id = bindings[key];
|
||||
specifiers.push(t.exportSpecifier(id, id));
|
||||
specifiers.push(buildExportSpecifier(bindings[key]));
|
||||
}
|
||||
return [declar, t.exportNamedDeclaration(null, specifiers)];
|
||||
}
|
||||
|
||||
@@ -1,102 +1,33 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
var functionChildrenVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (this.isClass(node)) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (this.isFunction() && !node.shadow) {
|
||||
return this.skip();
|
||||
}
|
||||
|
||||
if (node._shadowedFunctionLiteral) return this.skip();
|
||||
|
||||
var getId;
|
||||
|
||||
if (this.isIdentifier() && node.name === "arguments") {
|
||||
getId = state.getArgumentsId;
|
||||
} else if (this.isThisExpression()) {
|
||||
getId = state.getThisId;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isReferenced()) return getId();
|
||||
}
|
||||
export var metadata = {
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
var functionVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (!node.shadow) {
|
||||
if (this.isFunction()) {
|
||||
// stop traversal of this node as it'll be hit again by this transformer
|
||||
return this.skip();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
function remap(path, key, create) {
|
||||
// ensure that we're shadowed
|
||||
if (!path.inShadow()) return;
|
||||
|
||||
// traverse all child nodes of this function and find `arguments` and `this`
|
||||
this.traverse(functionChildrenVisitor, state);
|
||||
var fnPath = path.findParent((node, path) => !node.shadow && (path.isFunction() || path.isProgram()));
|
||||
|
||||
node.shadow = false;
|
||||
var cached = fnPath.getData(key);
|
||||
if (cached) return cached;
|
||||
|
||||
return this.skip();
|
||||
}
|
||||
};
|
||||
var init = create();
|
||||
var id = path.scope.generateUidIdentifier(key);
|
||||
|
||||
function aliasFunction(getBody, path, scope) {
|
||||
var argumentsId;
|
||||
var thisId;
|
||||
fnPath.setData(key, id);
|
||||
fnPath.scope.push({ id, init });
|
||||
|
||||
var state = {
|
||||
getArgumentsId() {
|
||||
return argumentsId = argumentsId || scope.generateUidIdentifier("arguments");
|
||||
},
|
||||
|
||||
getThisId() {
|
||||
return thisId = thisId || scope.generateUidIdentifier("this");
|
||||
}
|
||||
};
|
||||
|
||||
// traverse the function and find all alias functions so we can alias
|
||||
// `arguments` and `this` if necessary
|
||||
path.traverse(functionVisitor, state);
|
||||
|
||||
var body;
|
||||
|
||||
var pushDeclaration = function (id, init) {
|
||||
body = body || getBody();
|
||||
body.unshift(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(id, init)
|
||||
]));
|
||||
};
|
||||
|
||||
if (argumentsId) {
|
||||
pushDeclaration(argumentsId, t.identifier("arguments"));
|
||||
}
|
||||
|
||||
if (thisId) {
|
||||
pushDeclaration(thisId, t.thisExpression());
|
||||
}
|
||||
};
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return true;
|
||||
return id;
|
||||
}
|
||||
|
||||
export function Program(node, parent, scope) {
|
||||
aliasFunction(function () {
|
||||
return node.body;
|
||||
}, this, scope);
|
||||
};
|
||||
|
||||
export function FunctionDeclaration(node, parent, scope) {
|
||||
aliasFunction(function () {
|
||||
t.ensureBlock(node);
|
||||
return node.body.body;
|
||||
}, this, scope);
|
||||
export function ThisExpression() {
|
||||
return remap(this, "this", () => t.thisExpression());
|
||||
}
|
||||
|
||||
export { FunctionDeclaration as FunctionExpression };
|
||||
export function ReferencedIdentifier(node) {
|
||||
if (node.name === "arguments" && !node._shadowedFunctionLiteral) {
|
||||
return remap(this, "arguments", () => t.identifier("arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function Program(program, parent, scope, file) {
|
||||
if (file.transformers.strict.canTransform()) {
|
||||
var directive = file.get("existingStrictDirective");
|
||||
|
||||
if (!directive) {
|
||||
directive = t.expressionStatement(t.literal("use strict"));
|
||||
var first = program.body[0];
|
||||
if (first) {
|
||||
directive.leadingComments = first.leadingComments;
|
||||
first.leadingComments = [];
|
||||
}
|
||||
}
|
||||
|
||||
this.unshiftContainer("body", [directive]);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import * as messages from "../../../messages";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
readOnly: true
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
@@ -43,16 +43,3 @@ export function Property(node, parent, scope, file) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function BlockStatement(node) {
|
||||
for (var i = 0; i < node.body.length; i++) {
|
||||
var bodyNode = node.body[i];
|
||||
if (t.isExpressionStatement(bodyNode) && t.isLiteral(bodyNode.expression)) {
|
||||
bodyNode._blockHoist = Infinity;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { BlockStatement as Program };
|
||||
|
||||
@@ -18,23 +18,23 @@ function toStatements(node) {
|
||||
}
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export function Identifier(node, parent, scope) {
|
||||
if (!this.isReferenced()) return;
|
||||
|
||||
export function ReferencedIdentifier(node, parent, scope) {
|
||||
var binding = scope.getBinding(node.name);
|
||||
if (!binding || binding.references > 1 || !binding.constant) return;
|
||||
if (binding.kind === "param") return;
|
||||
|
||||
var replacement = binding.path.node;
|
||||
if (t.isVariableDeclarator(replacement)) {
|
||||
replacement = replacement.init;
|
||||
}
|
||||
if (!replacement) return;
|
||||
|
||||
t.toExpression(replacement);
|
||||
|
||||
scope.removeBinding(node.name);
|
||||
|
||||
binding.path.remove();
|
||||
return replacement;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true,
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export var Expression = {
|
||||
exit(node, parent, scope) {
|
||||
var res = this.evaluate();
|
||||
if (res.confident) return t.valueToNode(res.value);
|
||||
}
|
||||
};
|
||||
|
||||
export function Identifier() {
|
||||
// override Expression
|
||||
}
|
||||
@@ -1,14 +1,17 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
export function MemberExpression(node) {
|
||||
var prop = node.property;
|
||||
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
|
||||
// foo["bar"] => foo.bar
|
||||
node.property = t.identifier(prop.value);
|
||||
node.computed = false;
|
||||
export var MemberExpression = {
|
||||
exit(node) {
|
||||
var prop = node.property;
|
||||
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
|
||||
// foo["bar"] => foo.bar
|
||||
node.property = t.identifier(prop.value);
|
||||
node.computed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
export function Property(node) {
|
||||
var key = node.key;
|
||||
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
|
||||
// "foo": "bar" -> foo: "bar"
|
||||
node.key = t.identifier(key.value);
|
||||
node.computed = false;
|
||||
export var Property = {
|
||||
exit(node) {
|
||||
var key = node.key;
|
||||
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
|
||||
// "foo": "bar" -> foo: "bar"
|
||||
node.key = t.identifier(key.value);
|
||||
node.computed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export function CallExpression(node, parent) {
|
||||
@@ -1,7 +1,8 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export function ExpressionStatement(node) {
|
||||
@@ -1,8 +1,9 @@
|
||||
import { _ForOfStatementArray } from "../es6/for-of";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var shouldVisit = t.isForOfStatement;
|
||||
export var optional = true;
|
||||
export var metadata = {
|
||||
optional: true
|
||||
};
|
||||
|
||||
export function ForOfStatement(node, parent, scope, file) {
|
||||
if (this.get("right").isTypeGeneric("Array")) {
|
||||
|
||||
@@ -3,11 +3,12 @@ import remapAsyncToGenerator from "../../helpers/remap-async-to-generator";
|
||||
export { manipulateOptions } from "./bluebird-coroutines";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
dependencies: ["es7.asyncFunctions", "es6.classes"]
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
export function Func(node, parent, scope, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"), scope);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ import remapAsyncToGenerator from "../../helpers/remap-async-to-generator";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function manipulateOptions(opts) {
|
||||
opts.optional.push("es7.asyncFunctions");
|
||||
opts.blacklist.push("regenerator");
|
||||
}
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
dependencies: ["es7.asyncFunctions", "es6.classes"]
|
||||
};
|
||||
|
||||
exports.Function = function (node, parent, scope, file) {
|
||||
export function Func(node, parent, scope, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return remapAsyncToGenerator(
|
||||
@@ -18,4 +18,4 @@ exports.Function = function (node, parent, scope, file) {
|
||||
t.memberExpression(file.addImport("bluebird", null, "absolute"), t.identifier("coroutine")),
|
||||
scope
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return node.isType || node.optional || node.implements || node.typeAnnotation || t.isFlow(node);
|
||||
}
|
||||
|
||||
export function Flow(node) {
|
||||
this.remove();
|
||||
}
|
||||
|
||||
export function ClassProperty(node) {
|
||||
node.typeAnnotation = null;
|
||||
if (!node.value) this.remove();
|
||||
}
|
||||
|
||||
export function Class(node) {
|
||||
node.implements = null;
|
||||
}
|
||||
|
||||
exports.Function = function (node) {
|
||||
export function Func(node) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
var param = node.params[i];
|
||||
param.optional = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function TypeCastExpression(node) {
|
||||
return node.expression;
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import * as t from "../../../types";
|
||||
import * as util from "../../../util";
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
};
|
||||
|
||||
// foo in bar
|
||||
export function BinaryExpression(node) {
|
||||
if (node.operator === "in") {
|
||||
return util.template("ludicrous-in", {
|
||||
LEFT: node.left,
|
||||
RIGHT: node.right
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// { 1: "foo" }
|
||||
export function Property(node) {
|
||||
var key = node.key;
|
||||
if (t.isLiteral(key) && typeof key.value === "number") {
|
||||
key.value = "" + key.value;
|
||||
}
|
||||
}
|
||||
|
||||
// /foobar/g
|
||||
export function Literal(node) {
|
||||
if (node.regex) {
|
||||
node.regex.pattern = "foobar";
|
||||
node.regex.flags = "";
|
||||
}
|
||||
}
|
||||
|
||||
// foo.bar
|
||||
export function MemberExpression(node) {
|
||||
|
||||
}
|
||||
|
||||
// Object.setPrototypeOf
|
||||
// Object.preventExtensions
|
||||
// Object.keys
|
||||
// Object.isExtensible
|
||||
// Object.getOwnPropertyDescriptor
|
||||
// Object.defineProperty
|
||||
export function CallExpression(node) {
|
||||
|
||||
}
|
||||
|
||||
// delete foo.bar
|
||||
export function UnaryExpression(node) {
|
||||
|
||||
}
|
||||
|
||||
// foo.bar = bar;
|
||||
export function AssignmentExpression(node) {
|
||||
|
||||
}
|
||||
|
||||
// new Proxy
|
||||
export function NewExpression(node, parent, scope, file) {
|
||||
if (this.get("callee").isIdentifier({ name: "Proxy" })) {
|
||||
return t.callExpression(file.addHelper("proxy-create"), [node.arguments[0], file.addHelper("proxy-directory")]);
|
||||
} else {
|
||||
// possible proxy constructor
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
import regenerator from "regenerator";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function shouldVisit(node) {
|
||||
return t.isFunction(node) && (node.async || node.generator);
|
||||
}
|
||||
|
||||
export var Program = {
|
||||
enter(ast) {
|
||||
regenerator.transform(ast);
|
||||
this.stop();
|
||||
this.checkSelf();
|
||||
}
|
||||
export var metadata = {
|
||||
group: "regenerator"
|
||||
};
|
||||
|
||||
export function Program(ast) {
|
||||
regenerator.transform(ast);
|
||||
this.stop();
|
||||
}
|
||||
|
||||
@@ -9,98 +9,12 @@ var isSymbolIterator = t.buildMatchMemberExpression("Symbol.iterator");
|
||||
|
||||
const RUNTIME_MODULE_NAME = "babel-runtime";
|
||||
|
||||
var astVisitor = traverse.explode({
|
||||
Identifier(node, parent, scope, file) {
|
||||
if (!this.isReferenced()) return;
|
||||
if (t.isMemberExpression(parent)) return;
|
||||
if (!has(definitions.builtins, node.name)) return;
|
||||
if (scope.getBindingIdentifier(node.name)) return;
|
||||
|
||||
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
|
||||
var modulePath = definitions.builtins[node.name];
|
||||
return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, "absoluteDefault");
|
||||
},
|
||||
|
||||
CallExpression(node, parent, scope, file) {
|
||||
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
|
||||
|
||||
var callee = node.callee;
|
||||
if (node.arguments.length) return;
|
||||
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (!callee.computed) return;
|
||||
|
||||
var prop = callee.property;
|
||||
if (!isSymbolIterator(prop)) return;
|
||||
|
||||
return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]);
|
||||
},
|
||||
|
||||
BinaryExpression(node, parent, scope, file) {
|
||||
// Symbol.iterator in arr -> core.$for.isIterable(arr)
|
||||
|
||||
if (node.operator !== "in") return;
|
||||
|
||||
var left = node.left;
|
||||
if (!isSymbolIterator(left)) return;
|
||||
|
||||
return t.callExpression(
|
||||
file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"),
|
||||
[node.right]
|
||||
);
|
||||
},
|
||||
|
||||
MemberExpression: {
|
||||
enter(node, parent, scope, file) {
|
||||
// Array.from -> _core.Array.from
|
||||
|
||||
if (!this.isReferenced()) return;
|
||||
|
||||
var obj = node.object;
|
||||
var prop = node.property;
|
||||
|
||||
if (!t.isReferenced(obj, node)) return;
|
||||
|
||||
if (node.computed) return;
|
||||
|
||||
if (!has(definitions.methods, obj.name)) return;
|
||||
|
||||
var methods = definitions.methods[obj.name];
|
||||
if (!has(methods, prop.name)) return;
|
||||
|
||||
if (scope.getBindingIdentifier(obj.name)) return;
|
||||
|
||||
var modulePath = methods[prop.name];
|
||||
return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}$${prop.name}`, "absoluteDefault");
|
||||
},
|
||||
|
||||
exit(node, parent, scope, file) {
|
||||
if (!this.isReferenced()) return;
|
||||
|
||||
var prop = node.property;
|
||||
var obj = node.object;
|
||||
|
||||
if (!has(definitions.builtins, obj.name)) return;
|
||||
if (scope.getBindingIdentifier(obj.name)) return;
|
||||
|
||||
var modulePath = definitions.builtins[obj.name];
|
||||
return t.memberExpression(
|
||||
file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}`, "absoluteDefault"),
|
||||
prop
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
exports.metadata = {
|
||||
optional: true
|
||||
export var metadata = {
|
||||
optional: true,
|
||||
group: "builtin-post-modules"
|
||||
};
|
||||
|
||||
exports.Program = function (node, parent, scope, file) {
|
||||
this.traverse(astVisitor, file);
|
||||
};
|
||||
|
||||
exports.pre = function (file) {
|
||||
export function pre(file) {
|
||||
file.set("helperGenerator", function (name) {
|
||||
return file.addImport(`${RUNTIME_MODULE_NAME}/helpers/${name}`, name, "absoluteDefault");
|
||||
});
|
||||
@@ -108,10 +22,84 @@ exports.pre = function (file) {
|
||||
file.setDynamic("regeneratorIdentifier", function () {
|
||||
return file.addImport(`${RUNTIME_MODULE_NAME}/regenerator`, "regeneratorRuntime", "absoluteDefault");
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
exports.Identifier = function (node, parent, scope, file) {
|
||||
if (this.isReferencedIdentifier({ name: "regeneratorRuntime" })) {
|
||||
export function ReferencedIdentifier(node, parent, scope, file) {
|
||||
if (node.name === "regeneratorRuntime") {
|
||||
return file.get("regeneratorIdentifier");
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(parent)) return;
|
||||
if (!has(definitions.builtins, node.name)) return;
|
||||
if (scope.getBindingIdentifier(node.name)) return;
|
||||
|
||||
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
|
||||
var modulePath = definitions.builtins[node.name];
|
||||
return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, "absoluteDefault");
|
||||
}
|
||||
|
||||
export function CallExpression(node, parent, scope, file) {
|
||||
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
|
||||
|
||||
if (node.arguments.length) return;
|
||||
|
||||
var callee = node.callee;
|
||||
if (!t.isMemberExpression(callee)) return;
|
||||
if (!callee.computed) return;
|
||||
if (!this.get("callee.property").matchesPattern("Symbol.iterator")) return;
|
||||
|
||||
return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]);
|
||||
}
|
||||
|
||||
export function BinaryExpression(node, parent, scope, file) {
|
||||
// Symbol.iterator in arr -> core.$for.isIterable(arr)
|
||||
|
||||
if (node.operator !== "in") return;
|
||||
if (!this.get("left").matchesPattern("Symbol.iterator")) return;
|
||||
|
||||
return t.callExpression(
|
||||
file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"),
|
||||
[node.right]
|
||||
);
|
||||
}
|
||||
|
||||
export var MemberExpression = {
|
||||
enter(node, parent, scope, file) {
|
||||
// Array.from -> _core.Array.from
|
||||
|
||||
if (!this.isReferenced()) return;
|
||||
|
||||
var obj = node.object;
|
||||
var prop = node.property;
|
||||
|
||||
if (!t.isReferenced(obj, node)) return;
|
||||
|
||||
if (node.computed) return;
|
||||
|
||||
if (!has(definitions.methods, obj.name)) return;
|
||||
|
||||
var methods = definitions.methods[obj.name];
|
||||
if (!has(methods, prop.name)) return;
|
||||
|
||||
if (scope.getBindingIdentifier(obj.name)) return;
|
||||
|
||||
var modulePath = methods[prop.name];
|
||||
return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}$${prop.name}`, "absoluteDefault");
|
||||
},
|
||||
|
||||
exit(node, parent, scope, file) {
|
||||
if (!this.isReferenced()) return;
|
||||
|
||||
var prop = node.property;
|
||||
var obj = node.object;
|
||||
|
||||
if (!has(definitions.builtins, obj.name)) return;
|
||||
if (scope.getBindingIdentifier(obj.name)) return;
|
||||
|
||||
var modulePath = definitions.builtins[obj.name];
|
||||
return t.memberExpression(
|
||||
file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}`, "absoluteDefault"),
|
||||
prop
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
import * as messages from "../../../messages";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export function Program(program, parent, scope, file) {
|
||||
var first = program.body[0];
|
||||
if (t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" })) {
|
||||
file.set("existingStrictDirective", program.body.shift());
|
||||
const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassExpression", "ClassDeclaration"];
|
||||
|
||||
export var Program = {
|
||||
enter(program, parent, scope, file) {
|
||||
var first = program.body[0];
|
||||
|
||||
var directive;
|
||||
if (t.isExpressionStatement(first) && t.isLiteral(first.expression, { value: "use strict" })) {
|
||||
directive = first;
|
||||
} else {
|
||||
directive = t.expressionStatement(t.literal("use strict"));
|
||||
this.unshiftContainer("body", directive);
|
||||
if (first) {
|
||||
directive.leadingComments = first.leadingComments;
|
||||
first.leadingComments = [];
|
||||
}
|
||||
}
|
||||
directive._blockHoist = Infinity;
|
||||
}
|
||||
}
|
||||
|
||||
export function FunctionExpression() {
|
||||
this.skip();
|
||||
}
|
||||
|
||||
export { FunctionExpression as FunctionDeclaration };
|
||||
export { FunctionExpression as Class };
|
||||
|
||||
export function ThisExpression() {
|
||||
return t.identifier("undefined");
|
||||
}
|
||||
|
||||
export function CallExpression(node, parent, scope, file) {
|
||||
if (t.isIdentifier(node.callee, { name: "eval" })) {
|
||||
throw file.errorWithNode(node, messages.get("evalInStrictMode"));
|
||||
if (!this.findParent((node) => !node.shadow && THIS_BREAK_KEYS.indexOf(node.type) >= 0)) {
|
||||
return t.identifier("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,21 +23,6 @@ function statementList(key, path, file) {
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldVisit(node) {
|
||||
var body;
|
||||
if (node.type === "SwitchCase") {
|
||||
body = node.consequent;
|
||||
} else if (node.type === "BlockStatement") {
|
||||
body = node.body;
|
||||
}
|
||||
if (body) {
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
if (body[i].type === "FunctionDeclaration") return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function BlockStatement(node, parent, scope, file) {
|
||||
if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) {
|
||||
return;
|
||||
|
||||
@@ -1 +1,11 @@
|
||||
export { bare as FunctionExpression, bare as ArrowFunctionExpression } from "../../helpers/name-method";
|
||||
import { bare } from "../../helpers/name-method";
|
||||
|
||||
export var metadata = {
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export var FunctionExpression = {
|
||||
exit: bare
|
||||
};
|
||||
|
||||
export { FunctionExpression as ArrowFunctionExpression };
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user