Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f61754a24 | ||
|
|
3910d18bc9 | ||
|
|
583111ebfb | ||
|
|
1b15481460 | ||
|
|
fd9c98ff86 | ||
|
|
41b5607ef3 | ||
|
|
ae77ea807f | ||
|
|
ad44190c6b | ||
|
|
024e4454a1 | ||
|
|
14dddcda36 | ||
|
|
d4fb924b6a | ||
|
|
b02c97af60 | ||
|
|
cc611cb71c | ||
|
|
b8a01a9919 | ||
|
|
55c99661be | ||
|
|
1563b216df | ||
|
|
a9d4b485d9 | ||
|
|
360daa6267 | ||
|
|
724bf52929 | ||
|
|
7407b37bd9 | ||
|
|
da765cc4c1 | ||
|
|
4f862eee6e | ||
|
|
e05d7cf49a | ||
|
|
fd8e94a90f | ||
|
|
a6cf28c5b5 | ||
|
|
6b07b13a8e | ||
|
|
561c4dcc25 | ||
|
|
b516ea596a | ||
|
|
248758eee3 | ||
|
|
a808602ae0 | ||
|
|
40e3436e95 | ||
|
|
f704770b26 | ||
|
|
330665f150 | ||
|
|
af41899d74 | ||
|
|
d12f4d0bc8 | ||
|
|
97680e9dfd | ||
|
|
51341ca6c3 | ||
|
|
ab54bfa50e | ||
|
|
60aa933fb6 | ||
|
|
1a299b2bcc | ||
|
|
37f662d790 | ||
|
|
b0317f9bab | ||
|
|
be2dfaf081 | ||
|
|
2c8437ae92 | ||
|
|
2a0bcfd086 | ||
|
|
2cf41afac3 | ||
|
|
e318f5f3be | ||
|
|
939decb86c | ||
|
|
1baa0df948 | ||
|
|
e8956a8c44 | ||
|
|
2f0fdbbc26 | ||
|
|
5f931525bc | ||
|
|
b86545a320 | ||
|
|
06e75c42bf | ||
|
|
05dd65244d | ||
|
|
c4ebfeb0fa | ||
|
|
1aa0bbfac9 | ||
|
|
58f1e6cbc6 | ||
|
|
83e0be3038 | ||
|
|
5fc242e4ec | ||
|
|
dc101adad3 | ||
|
|
faade72787 | ||
|
|
2a78ae9889 |
33
CHANGELOG.md
33
CHANGELOG.md
@@ -13,6 +13,38 @@ _Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
|
||||
## 5.4.0
|
||||
|
||||
* **New Feature**
|
||||
* Added [function bind syntax](https://github.com/zenparsing/es-function-bind) behind stage 0. Thanks [@RReverser](https://github.com/rreverser)!
|
||||
* Added `env` option. Especially handy when using the `.babelrc`.
|
||||
* **Bug Fix**
|
||||
* Fix files not properly being ignored when `babel.transform` ignores them when using `$ babel`.
|
||||
* Fix scope tracking registering loop head bindings to their `VariableDeclaration` instead of `VariableDeclarator`.
|
||||
* **Polish**
|
||||
* Normalise path separators for souce map paths when using `$ babel`.
|
||||
* Rework `PathHoister` to ignore global references and to not deopt on reassignments to referenced bindings, instead it tries to hoist to the highest scope.
|
||||
* Added missing exponential operator inlining. Thanks [@nkt](https://github.com/nkt)!
|
||||
* Optimise `regenerator` transformer. Thanks [@benjamn](https://github.com/benjamn)!
|
||||
|
||||
## 5.3.3
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix `minification.deadCodeElimination` transformer incorrectly trying to inline import declarations.
|
||||
* Fix `minification.inlineExpression` transformer getting into an infinite loop.
|
||||
|
||||
## 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**
|
||||
@@ -30,6 +62,7 @@ See [CHANGELOG - 6to5](CHANGELOG-6to5.md) for the pre-4.0.0 version changelog.
|
||||
* Properly hoist temp param declarations when doing TCO.
|
||||
* **Internal**
|
||||
* Add `--harmony_generators` flag to `$ babel-node`.
|
||||
* Internal AST traversals have been minimised **drastically**. Transformers have been grouped together which means entire tree traversals are much fewer. Visiting nodes is now also skipped if the traversal context can detect that the handler is a noop. This sames precious cycles as it avoids constructing traversal paths and creating a new traversal context. See issues [#1472](https://github.com/babel/babel/issues/1472) and [#1486](https://github.com/babel/babel/issues/1486) for related discussion.
|
||||
* **Polish**
|
||||
* Move many `utility` transformers to `minification`.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "babel-core",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.3.0",
|
||||
"version": "5.4.0",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
@@ -64,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",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
var outputFileSync = require("output-file-sync");
|
||||
var chokidar = require("chokidar");
|
||||
var slash = require("slash");
|
||||
var path = require("path");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
@@ -13,8 +14,9 @@ module.exports = function (commander, filenames, opts) {
|
||||
var dest = path.join(commander.outDir, relative);
|
||||
|
||||
var data = util.compile(src, {
|
||||
sourceFileName: path.relative(dest + "/..", src)
|
||||
sourceFileName: slash(path.relative(dest + "/..", src))
|
||||
});
|
||||
if (data.ignored) return;
|
||||
|
||||
if (commander.sourceMaps && commander.sourceMaps !== "inline") {
|
||||
var mapLoc = dest + ".map";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
var convertSourceMap = require("convert-source-map");
|
||||
var sourceMap = require("source-map");
|
||||
var chokidar = require("chokidar");
|
||||
var slash = require("slash");
|
||||
var path = require("path");
|
||||
var util = require("./util");
|
||||
var fs = require("fs");
|
||||
@@ -15,7 +16,7 @@ module.exports = function (commander, filenames, opts) {
|
||||
|
||||
var buildResult = function () {
|
||||
var map = new sourceMap.SourceMapGenerator({
|
||||
file: commander.outFile || "stdout"
|
||||
file: slash(commander.outFile || "stdout")
|
||||
});
|
||||
|
||||
var code = "";
|
||||
@@ -27,11 +28,12 @@ module.exports = function (commander, filenames, opts) {
|
||||
|
||||
if (result.map) {
|
||||
var consumer = new sourceMap.SourceMapConsumer(result.map);
|
||||
var sourceFilename = filename;
|
||||
|
||||
var sourceFilename = filename;
|
||||
if (commander.outFile) {
|
||||
sourceFilename = path.relative(path.dirname(commander.outFile), sourceFilename);
|
||||
}
|
||||
sourceFilename = slash(sourceFilename);
|
||||
|
||||
map._sources.add(sourceFilename);
|
||||
map.setSourceContent(sourceFilename, result.actual);
|
||||
@@ -114,7 +116,9 @@ module.exports = function (commander, filenames, opts) {
|
||||
_.each(_filenames, function (filename) {
|
||||
if (util.shouldIgnore(filename)) return;
|
||||
|
||||
results.push(util.compile(filename));
|
||||
var data = util.compile(filename);
|
||||
if (data.ignored) return;
|
||||
results.push(data);
|
||||
});
|
||||
|
||||
output();
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{
|
||||
"name": "babel",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "5.2.17",
|
||||
"version": "5.3.3",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://babeljs.io/",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"preferGlobal": true,
|
||||
"dependencies": {
|
||||
"babel-core": "^5.2.17",
|
||||
"babel-core": "^5.3.3",
|
||||
"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.17",
|
||||
"version": "5.3.3",
|
||||
"license": "MIT",
|
||||
"repository": "babel/babel",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"dependencies": {
|
||||
|
||||
48
sebmck-bjs.nfo
Normal file
48
sebmck-bjs.nfo
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
====== ==========M=
|
||||
============= == ======O= ======= MM ==
|
||||
M==+=== ==M === ==== == === ==
|
||||
=D === === ====MM ==M ==M ==M ===
|
||||
===M ====M ==== =D ===M === === ==
|
||||
==7 ====M ==M == ======== =========M ==M
|
||||
=========== ======M ===MMM === ==M ==
|
||||
=======MM==========MM== ==M ==M=== ==
|
||||
==M === M== ==M == === === =D =
|
||||
==M ===+ == == == ==$M =========== ============M
|
||||
=== ====M == ==M ===M== ====?MMMM M M
|
||||
== ===== ==M == ==MM M
|
||||
==M===M=M =M =MM M M
|
||||
==MM=M ==
|
||||
MMM =M
|
||||
M
|
||||
|
||||
> ú B ú A ú B ú E ú L ú <
|
||||
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
|
||||
³ SOFTWARE .. : JavaScript Compiler ³ COMPANY ... : N/A ³
|
||||
³ SUPPLIER .. : N/A ³ CRACKER ... : Sebastian McKenzie ³
|
||||
³ RATING .... : depends.. ³ PACKAGER .. : Sebastian McKenzie ³
|
||||
³ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ³
|
||||
³ GRAFIX .... : - ³ SOUND ..... : - ³
|
||||
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
|
||||
|
||||
Babel is a JavaScript compiler and transformation platform for writing NeXt
|
||||
GeNeRaTiOn JavaScript.
|
||||
|
||||
ÆÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍ͵
|
||||
³ :: Greets :: ³
|
||||
³ ³
|
||||
³ sebmck, thejameskyle, RReverser, zloirock, monsanto, gaearon, zertosh, ³
|
||||
³ stefanpenner, eventualbuddha, AluisioASG, Apoxx, Couto, dominicbarnes, ³
|
||||
³ es128, gordonkristan, hkjels, jmeas, josh, loganfsmyth, nightire, ³
|
||||
³ Rich-Harris, shinnn, shuhei, sindresorhus, tricknotes ³
|
||||
³ ³
|
||||
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
|
||||
|
||||
-*- JavaScripts for all , All for JavaScripts ! -*-
|
||||
|
||||
ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸
|
||||
³ If you want to Contact us, call 555-720-4228, Use the Handle "BABEL" w/ ³
|
||||
³ password : VISITOR and leave a mail to Sebastian or James. ³
|
||||
ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;
|
||||
|
||||
-=- We LoVe fun Too! -=-
|
||||
@@ -214,7 +214,12 @@ pp.parseExprSubscripts = function(refShorthandDefaultPos) {
|
||||
}
|
||||
|
||||
pp.parseSubscripts = function(base, start, noCalls) {
|
||||
if (this.eat(tt.dot)) {
|
||||
if (!noCalls && this.eat(tt.doubleColon)) {
|
||||
let node = this.startNodeAt(start)
|
||||
node.object = base
|
||||
node.callee = this.parseNoCallExpr()
|
||||
return this.parseSubscripts(this.finishNode(node, "BindExpression"), start, noCalls)
|
||||
} else if (this.eat(tt.dot)) {
|
||||
let node = this.startNodeAt(start)
|
||||
node.object = base
|
||||
node.property = this.parseIdent(true)
|
||||
@@ -240,6 +245,13 @@ pp.parseSubscripts = function(base, start, noCalls) {
|
||||
} return base
|
||||
}
|
||||
|
||||
// Parse a no-call expression (like argument of `new` or `::` operators).
|
||||
|
||||
pp.parseNoCallExpr = function() {
|
||||
let start = this.markPosition()
|
||||
return this.parseSubscripts(this.parseExprAtom(), start, true)
|
||||
}
|
||||
|
||||
// Parse an atomic expression — either a single token that is an
|
||||
// expression, an expression started by a keyword like `function` or
|
||||
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
|
||||
@@ -363,6 +375,15 @@ pp.parseExprAtom = function(refShorthandDefaultPos) {
|
||||
case tt.backQuote:
|
||||
return this.parseTemplate()
|
||||
|
||||
case tt.doubleColon:
|
||||
node = this.startNode()
|
||||
this.next()
|
||||
node.object = null
|
||||
let callee = node.callee = this.parseNoCallExpr()
|
||||
if (callee.type !== "MemberExpression")
|
||||
this.raise(callee.start, "Binding should be performed on object property.")
|
||||
return this.finishNode(node, "BindExpression")
|
||||
|
||||
default:
|
||||
this.unexpected()
|
||||
}
|
||||
@@ -472,8 +493,7 @@ pp.parseNew = function() {
|
||||
this.raise(node.property.start, "The only valid meta property for new is new.target")
|
||||
return this.finishNode(node, "MetaProperty")
|
||||
}
|
||||
let start = this.markPosition()
|
||||
node.callee = this.parseSubscripts(this.parseExprAtom(), start, true)
|
||||
node.callee = this.parseNoCallExpr()
|
||||
if (this.eat(tt.parenL)) node.arguments = this.parseExprList(
|
||||
tt.parenR,
|
||||
this.options.features["es7.trailingFunctionCommas"]
|
||||
|
||||
@@ -320,7 +320,13 @@ pp.getTokenFromCode = function(code) {
|
||||
case 93: ++this.pos; return this.finishToken(tt.bracketR)
|
||||
case 123: ++this.pos; return this.finishToken(tt.braceL)
|
||||
case 125: ++this.pos; return this.finishToken(tt.braceR)
|
||||
case 58: ++this.pos; return this.finishToken(tt.colon)
|
||||
|
||||
case 58:
|
||||
if (this.options.features["es7.functionBind"] && this.input.charCodeAt(this.pos + 1) === 58)
|
||||
return this.finishOp(tt.doubleColon, 2)
|
||||
++this.pos
|
||||
return this.finishToken(tt.colon)
|
||||
|
||||
case 63: ++this.pos; return this.finishToken(tt.question)
|
||||
case 64: ++this.pos; return this.finishToken(tt.at)
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ export const types = {
|
||||
comma: new TokenType(",", beforeExpr),
|
||||
semi: new TokenType(";", beforeExpr),
|
||||
colon: new TokenType(":", beforeExpr),
|
||||
doubleColon: new TokenType("::", beforeExpr),
|
||||
dot: new TokenType("."),
|
||||
question: new TokenType("?", beforeExpr),
|
||||
arrow: new TokenType("=>", beforeExpr),
|
||||
|
||||
@@ -133,6 +133,12 @@ export function AssignmentExpression(node, print) {
|
||||
print(node.right);
|
||||
}
|
||||
|
||||
export function BindExpression(node, print) {
|
||||
print(node.object);
|
||||
this.push("::");
|
||||
print(node.callee);
|
||||
}
|
||||
|
||||
export {
|
||||
AssignmentExpression as BinaryExpression,
|
||||
AssignmentExpression as LogicalExpression,
|
||||
|
||||
17
src/babel/helpers/merge.js
Normal file
17
src/babel/helpers/merge.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import merge from "lodash/object/merge";
|
||||
|
||||
export default function (dest, src) {
|
||||
if (!dest || !src) return;
|
||||
|
||||
return merge(dest, src, function(a, b) {
|
||||
if (Array.isArray(a)) {
|
||||
var c = a.slice(0);
|
||||
for (var v of b) {
|
||||
if (a.indexOf(v) < 0) {
|
||||
c.push(v);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -72,4 +72,10 @@ def("ExportAllDeclaration")
|
||||
.field("exported", def("Identifier"))
|
||||
.field("source", def("Literal"));
|
||||
|
||||
def("BindExpression")
|
||||
.bases("Expression")
|
||||
.build("object", "callee")
|
||||
.field("object", or(def("Expression"), null))
|
||||
.field("callee", def("Expression"));
|
||||
|
||||
types.finalize();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import stripJsonComments from "strip-json-comments";
|
||||
import merge from "lodash/object/merge";
|
||||
import merge from "../helpers/merge";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
@@ -42,17 +42,7 @@ export default function (loc, opts = {}) {
|
||||
opts.babelrc.push(file);
|
||||
|
||||
if (json.breakConfig) return;
|
||||
merge(opts, json, function(a, b) {
|
||||
if (Array.isArray(a)) {
|
||||
var c = a.slice(0);
|
||||
for (var v of b) {
|
||||
if (a.indexOf(v) < 0) {
|
||||
c.push(v);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
});
|
||||
merge(opts, json);
|
||||
}
|
||||
|
||||
var up = path.dirname(start);
|
||||
|
||||
@@ -19,6 +19,7 @@ import assign from "lodash/object/assign";
|
||||
import Logger from "./logger";
|
||||
import parse from "../../helpers/parse";
|
||||
import Scope from "../../traversal/scope";
|
||||
import merge from "../../helpers/merge";
|
||||
import slash from "slash";
|
||||
import clone from "lodash/lang/clone";
|
||||
import * as util from "../../util";
|
||||
@@ -37,6 +38,7 @@ export default class File {
|
||||
this.declarations = {};
|
||||
this.usedHelpers = {};
|
||||
this.dynamicData = {};
|
||||
this.metadata = {};
|
||||
this.data = {};
|
||||
|
||||
this.pipeline = pipeline;
|
||||
@@ -106,6 +108,9 @@ export default class File {
|
||||
if (!option) this.log.error(`Unknown option: ${key}`, ReferenceError);
|
||||
}
|
||||
|
||||
var envKey = process.env.BABEL_ENV || process.env.NODE_ENV || "development";
|
||||
if (opts.env) merge(opts, opts.env[envKey]);
|
||||
|
||||
for (let key in File.options) {
|
||||
let option = File.options[key];
|
||||
|
||||
@@ -461,16 +466,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) {
|
||||
@@ -498,7 +493,8 @@ export default class File {
|
||||
try {
|
||||
if (this.shouldIgnore()) {
|
||||
return {
|
||||
metadata: {},
|
||||
metadata: this.metadata,
|
||||
ignored: true,
|
||||
code: code,
|
||||
map: null,
|
||||
ast: null
|
||||
@@ -591,7 +587,7 @@ export default class File {
|
||||
var ast = this.ast;
|
||||
|
||||
var result = {
|
||||
metadata: {},
|
||||
metadata: this.metadata,
|
||||
code: "",
|
||||
map: null,
|
||||
ast: null
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
"default": {}
|
||||
},
|
||||
|
||||
"env": {
|
||||
"hidden": true,
|
||||
"default": {}
|
||||
},
|
||||
|
||||
"moduleId": {
|
||||
"description": "specify a custom name for module ids",
|
||||
"type": "string"
|
||||
|
||||
@@ -26,7 +26,7 @@ var getObjRef = function (node, nodes, file, scope) {
|
||||
throw new Error(`We can't explode this node type ${node.type}`);
|
||||
}
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(ref);
|
||||
var temp = scope.generateUidIdentifierBasedOnNode(ref);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, ref)
|
||||
]));
|
||||
@@ -38,7 +38,7 @@ var getPropRef = function (node, nodes, file, scope) {
|
||||
var key = t.toComputedKey(node, prop);
|
||||
if (t.isLiteral(key)) return key;
|
||||
|
||||
var temp = scope.generateUidBasedOnNode(prop);
|
||||
var temp = scope.generateUidIdentifierBasedOnNode(prop);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(temp, prop)
|
||||
]));
|
||||
|
||||
@@ -6,7 +6,7 @@ export default function (decorators, scope) {
|
||||
var expression = decorator.expression;
|
||||
if (!t.isMemberExpression(expression)) continue;
|
||||
|
||||
var temp = scope.generateMemoisedReference(expression.object);
|
||||
var temp = scope.maybeGenerateMemoised(expression.object);
|
||||
var ref;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
@@ -17,7 +17,11 @@ var remapVisitor = {
|
||||
|
||||
if (remap && node !== remap) {
|
||||
if (!scope.hasBinding(node.name) || scope.bindingIdentifierEquals(node.name, formatter.localImports[node.name])) {
|
||||
return remap;
|
||||
if (this.key === "callee" && this.parentPath.isCallExpression()) {
|
||||
return t.sequenceExpression([t.literal(0), remap]);
|
||||
} else {
|
||||
return remap;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -52,7 +52,7 @@ export default class CommonJSFormatter extends DefaultFormatter {
|
||||
} else if (this.noInteropRequireImport) {
|
||||
this.internalRemap[variableName.name] = t.memberExpression(ref, t.identifier("default"));
|
||||
} else {
|
||||
var uid = this.scope.generateUidBasedOnNode(node, "import");
|
||||
var uid = this.scope.generateUidIdentifierBasedOnNode(node, "import");
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(uid, t.callExpression(this.file.addHelper("interop-require-default"), [ref]))
|
||||
@@ -111,7 +111,7 @@ export default class CommonJSFormatter extends DefaultFormatter {
|
||||
} else if (this.isModuleType(node, "absoluteDefault")) {
|
||||
call = t.memberExpression(call, t.identifier("default"));
|
||||
} else {
|
||||
uid = this.scope.generateUidBasedOnNode(node, "import");
|
||||
uid = this.scope.generateUidIdentifierBasedOnNode(node, "import");
|
||||
}
|
||||
|
||||
uid = uid || node.specifiers[0].local;
|
||||
|
||||
@@ -21,7 +21,7 @@ var hoistVariablesVisitor = {
|
||||
}
|
||||
|
||||
// ignore block hoisted nodes as these can be left in
|
||||
if (state.formatter.canHoist(node)) return;
|
||||
if (state.formatter._canHoist(node)) return;
|
||||
|
||||
var nodes = [];
|
||||
|
||||
@@ -50,7 +50,7 @@ var hoistFunctionsVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
if (t.isFunction(node)) this.skip();
|
||||
|
||||
if (t.isFunctionDeclaration(node) || state.formatter.canHoist(node)) {
|
||||
if (t.isFunctionDeclaration(node) || state.formatter._canHoist(node)) {
|
||||
state.handlerBody.push(node);
|
||||
this.remove();
|
||||
}
|
||||
@@ -101,14 +101,14 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
var right = objectIdentifier;
|
||||
|
||||
var block = t.blockStatement([
|
||||
t.expressionStatement(this.buildExportCall(leftIdentifier, valIdentifier))
|
||||
t.expressionStatement(this._buildExportCall(leftIdentifier, valIdentifier))
|
||||
]);
|
||||
|
||||
return this._addImportSource(t.forInStatement(left, right, block), node);
|
||||
}
|
||||
|
||||
buildExportsAssignment(id, init, node) {
|
||||
var call = this.buildExportCall(t.literal(id.name), init, true);
|
||||
var call = this._buildExportCall(t.literal(id.name), init, true);
|
||||
return this._addImportSource(call, node);
|
||||
}
|
||||
|
||||
@@ -120,13 +120,13 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
var assign = node;
|
||||
|
||||
for (var i = 0; i < exported.length; i++) {
|
||||
assign = this.buildExportCall(t.literal(exported[i].name), assign);
|
||||
assign = this._buildExportCall(t.literal(exported[i].name), assign);
|
||||
}
|
||||
|
||||
return assign;
|
||||
}
|
||||
|
||||
buildExportCall(id, init, isStatement) {
|
||||
_buildExportCall(id, init, isStatement) {
|
||||
var call = t.callExpression(this.exportIdentifier, [id, init]);
|
||||
if (isStatement) {
|
||||
return t.expressionStatement(call);
|
||||
@@ -149,7 +149,7 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
this._addImportSource(last(nodes), node);
|
||||
}
|
||||
|
||||
buildRunnerSetters(block, hoistDeclarators) {
|
||||
_buildRunnerSetters(block, hoistDeclarators) {
|
||||
var scope = this.file.scope;
|
||||
|
||||
return t.arrayExpression(map(this.ids, function (uid, source) {
|
||||
@@ -165,7 +165,7 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
}));
|
||||
}
|
||||
|
||||
canHoist(node) {
|
||||
_canHoist(node) {
|
||||
return node._blockHoist && !this.file.dynamicImports.length;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ export default class SystemFormatter extends AMDFormatter {
|
||||
MODULE_DEPENDENCIES: t.arrayExpression(this.buildDependencyLiterals()),
|
||||
EXPORT_IDENTIFIER: this.exportIdentifier,
|
||||
MODULE_NAME: moduleNameLiteral,
|
||||
SETTERS: this.buildRunnerSetters(block, hoistDeclarators),
|
||||
SETTERS: this._buildRunnerSetters(block, hoistDeclarators),
|
||||
EXECUTE: t.functionExpression(null, [], block)
|
||||
}, true);
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -557,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 = [];
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ class ClassTransformer {
|
||||
if (this.hasSuper) {
|
||||
closureArgs.push(superName);
|
||||
|
||||
superName = this.scope.generateUidBasedOnNode(superName);
|
||||
superName = this.scope.generateUidIdentifierBasedOnNode(superName);
|
||||
closureParams.push(superName);
|
||||
|
||||
this.superName = superName;
|
||||
|
||||
@@ -55,7 +55,7 @@ export function ForOfStatement(node, parent, scope, file) {
|
||||
|
||||
export { ForOfStatement as ForInStatement };
|
||||
|
||||
export function Func(node, parent, scope, file) {
|
||||
export function Func/*tion*/(node, parent, scope, file) {
|
||||
var nodes = [];
|
||||
|
||||
var hasDestructuring = false;
|
||||
@@ -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) {
|
||||
@@ -295,7 +295,7 @@ class DestructuringTransformer {
|
||||
// we need to assign the current value of the assignment to avoid evaluating
|
||||
// it more than once
|
||||
|
||||
var tempValueRef = this.scope.generateUidBasedOnNode(valueRef);
|
||||
var tempValueRef = this.scope.generateUidIdentifierBasedOnNode(valueRef);
|
||||
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(tempValueRef, valueRef)
|
||||
@@ -377,7 +377,7 @@ class DestructuringTransformer {
|
||||
// only evaluated once
|
||||
|
||||
if (pattern.properties.length > 1 && t.isMemberExpression(objRef)) {
|
||||
var temp = this.scope.generateUidBasedOnNode(objRef, this.file);
|
||||
var temp = this.scope.generateUidIdentifierBasedOnNode(objRef, this.file);
|
||||
this.nodes.push(this.buildVariableDeclaration(temp, objRef));
|
||||
objRef = temp;
|
||||
}
|
||||
@@ -461,7 +461,7 @@ class DestructuringTransformer {
|
||||
// array
|
||||
arrayRef = toArray;
|
||||
} else {
|
||||
arrayRef = this.scope.generateUidBasedOnNode(arrayRef);
|
||||
arrayRef = this.scope.generateUidIdentifierBasedOnNode(arrayRef);
|
||||
this.arrays[arrayRef.name] = true;
|
||||
this.nodes.push(this.buildVariableDeclaration(arrayRef, toArray));
|
||||
}
|
||||
@@ -500,7 +500,7 @@ class DestructuringTransformer {
|
||||
|
||||
var shouldMemoise = true;
|
||||
if (!t.isArrayExpression(ref) && !t.isMemberExpression(ref)) {
|
||||
var memo = this.scope.generateMemoisedReference(ref, true);
|
||||
var memo = this.scope.maybeGenerateMemoised(ref, true);
|
||||
if (memo) {
|
||||
this.nodes.push(this.buildVariableDeclaration(memo, ref));
|
||||
ref = memo;
|
||||
|
||||
@@ -22,7 +22,7 @@ var iifeVisitor = {
|
||||
}
|
||||
};
|
||||
|
||||
export function Func(node, parent, scope, file) {
|
||||
export function Func/*tion*/(node, parent, scope, file) {
|
||||
if (!hasDefaults(node)) return;
|
||||
|
||||
t.ensureBlock(node);
|
||||
|
||||
@@ -53,10 +53,11 @@ var hasRest = function (node) {
|
||||
return t.isRestElement(node.params[node.params.length - 1]);
|
||||
};
|
||||
|
||||
export function Func(node, parent, scope, file) {
|
||||
export function Func/*tion*/(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");
|
||||
|
||||
@@ -125,13 +126,14 @@ export function Func(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);
|
||||
|
||||
@@ -75,7 +75,7 @@ export var ObjectExpression = {
|
||||
if (!hasComputed) return;
|
||||
|
||||
var initProps = [];
|
||||
var objId = scope.generateUidBasedOnNode(parent);
|
||||
var objId = scope.generateUidIdentifierBasedOnNode(parent);
|
||||
|
||||
//
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export function CallExpression(node, parent, scope) {
|
||||
var callee = node.callee;
|
||||
|
||||
if (this.get("callee").isMemberExpression()) {
|
||||
var temp = scope.generateMemoisedReference(callee.object);
|
||||
var temp = scope.maybeGenerateMemoised(callee.object);
|
||||
if (temp) {
|
||||
callee.object = t.assignmentExpression("=", temp, callee.object);
|
||||
contextLiteral = temp;
|
||||
|
||||
@@ -10,7 +10,7 @@ export var metadata = {
|
||||
group: "builtin-trailing"
|
||||
};
|
||||
|
||||
export function Func(node, parent, scope, file) {
|
||||
export function Func/*tion*/(node, parent, scope, file) {
|
||||
if (node.generator || node.async) return;
|
||||
var tailCall = new TailCallTransformer(this, scope, file);
|
||||
tailCall.run();
|
||||
@@ -20,8 +20,7 @@ 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 (t.isTryStatement(parent)) {
|
||||
if (node === parent.block) {
|
||||
@@ -33,7 +32,6 @@ var firstPass = {
|
||||
},
|
||||
|
||||
ReturnStatement(node, parent, scope, state) {
|
||||
this.skip();
|
||||
return state.subTransform(node.argument);
|
||||
},
|
||||
|
||||
@@ -42,46 +40,18 @@ var firstPass = {
|
||||
},
|
||||
|
||||
VariableDeclaration(node, parent, scope, state) {
|
||||
this.skip();
|
||||
state.vars.push(node);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
// hoists up function declarations, replaces `this` and `arguments` and marks
|
||||
// them as needed
|
||||
var secondPass = {
|
||||
ThisExpression(node, parent, scope, state) {
|
||||
state.needsThis = true;
|
||||
return state.getThisId();
|
||||
state.thisPaths.push(this);
|
||||
},
|
||||
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (node.name !== "arguments") return;
|
||||
state.needsArguments = true;
|
||||
return state.getArgumentsId();
|
||||
},
|
||||
|
||||
Function(node, parent, scope, state) {
|
||||
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 = {
|
||||
AssignmentExpression(node, parent, scope, state) {
|
||||
if (!state.needsThis && node.left === state.getThisId()) {
|
||||
this.remove();
|
||||
} else if (!state.needsArguments && node.left === state.getArgumentsId() && t.isArrayExpression(node.right)) {
|
||||
return map(node.right.elements, function (elem) {
|
||||
return t.expressionStatement(elem);
|
||||
});
|
||||
if (node.name === "arguments") {
|
||||
state.needsArguments = true;
|
||||
state.argumentsPaths.push(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -89,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;
|
||||
@@ -159,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;
|
||||
@@ -170,14 +147,18 @@ 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;
|
||||
@@ -204,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);
|
||||
@@ -332,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(),
|
||||
@@ -345,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(
|
||||
"=",
|
||||
@@ -381,6 +374,7 @@ class TailCallTransformer {
|
||||
body.push(t.expressionStatement(
|
||||
t.assignmentExpression("=", this.getAgainId(), t.literal(true))
|
||||
));
|
||||
|
||||
body.push(t.continueStatement(this.getFunctionId()));
|
||||
|
||||
return body;
|
||||
|
||||
@@ -26,7 +26,7 @@ function generator(node) {
|
||||
}
|
||||
|
||||
function array(node, parent, scope, file) {
|
||||
var uid = scope.generateUidBasedOnNode(parent);
|
||||
var uid = scope.generateUidIdentifierBasedOnNode(parent);
|
||||
|
||||
var container = util.template("array-comprehension-container", {
|
||||
KEY: uid
|
||||
|
||||
51
src/babel/transformation/transformers/es7/function-bind.js
Normal file
51
src/babel/transformation/transformers/es7/function-bind.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// https://github.com/zenparsing/es-function-bind
|
||||
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
optional: true,
|
||||
stage: 0
|
||||
};
|
||||
|
||||
function getTempId(scope) {
|
||||
var id = scope.path.getData("functionBind");
|
||||
if (id) return id;
|
||||
|
||||
id = scope.generateDeclaredUidIdentifier("context");
|
||||
return scope.path.setData("functionBind", id);
|
||||
}
|
||||
|
||||
function getStaticContext(bind, scope) {
|
||||
var object = bind.object || bind.callee.object;
|
||||
return scope.isStatic(object) && object;
|
||||
}
|
||||
|
||||
function inferBindContext(bind, scope) {
|
||||
var staticContext = getStaticContext(bind, scope);
|
||||
if (staticContext) return staticContext;
|
||||
|
||||
var tempId = getTempId(scope);
|
||||
if (bind.object) {
|
||||
bind.callee = t.sequenceExpression([
|
||||
t.assignmentExpression("=", tempId, bind.object),
|
||||
bind.callee
|
||||
]);
|
||||
} else {
|
||||
bind.callee.object = t.assignmentExpression("=", tempId, bind.callee.object);
|
||||
}
|
||||
return tempId;
|
||||
}
|
||||
|
||||
export function CallExpression(node, parent, scope, file) {
|
||||
var bind = node.callee;
|
||||
if (!t.isBindExpression(bind)) return;
|
||||
|
||||
var context = inferBindContext(bind, scope);
|
||||
node.callee = t.memberExpression(bind.callee, t.identifier("call"));
|
||||
node.arguments.unshift(context);
|
||||
}
|
||||
|
||||
export function BindExpression(node, parent, scope, file) {
|
||||
var context = inferBindContext(node, scope);
|
||||
return t.callExpression(t.memberExpression(node.callee, t.identifier("bind")), [context]);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
export default {
|
||||
//- builtin-setup
|
||||
strict: require("./other/strict"),
|
||||
_explode: require("./internal/explode"),
|
||||
_validation: require("./internal/validation"),
|
||||
_hoistDirectives: require("./internal/hoist-directives"),
|
||||
@@ -18,15 +19,12 @@ export default {
|
||||
"es7.trailingFunctionCommas": require("./es7/trailing-function-commas"),
|
||||
"es7.asyncFunctions": require("./es7/async-functions"),
|
||||
"es7.decorators": require("./es7/decorators"),
|
||||
strict: require("./other/strict"),
|
||||
"validation.undeclaredVariableCheck": require("./validation/undeclared-variable-check"),
|
||||
"validation.react": require("./validation/react"),
|
||||
"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"),
|
||||
"es7.comprehensions": require("./es7/comprehensions"),
|
||||
"es6.classes": require("./es6/classes"),
|
||||
asyncToGenerator: require("./other/async-to-generator"),
|
||||
@@ -51,6 +49,7 @@ export default {
|
||||
"spec.protoToAssign": require("./spec/proto-to-assign"),
|
||||
"es7.doExpressions": require("./es7/do-expressions"),
|
||||
"es6.spec.symbols": require("./es6/spec.symbols"),
|
||||
"es7.functionBind": require("./es7/function-bind"),
|
||||
"spec.undefinedToVoid": require("./spec/undefined-to-void"),
|
||||
jscript: require("./other/jscript"),
|
||||
flow: require("./other/flow"),
|
||||
@@ -59,6 +58,8 @@ export default {
|
||||
"es6.destructuring": require("./es6/destructuring"),
|
||||
"es6.blockScoping": require("./es6/block-scoping"),
|
||||
"es6.spec.blockScoping": require("./es6/spec.block-scoping"),
|
||||
reactCompat: require("./other/react-compat"),
|
||||
react: require("./other/react"),
|
||||
|
||||
// es6 syntax transformation is **forbidden** past this point since regenerator will chuck a massive
|
||||
// hissy fit
|
||||
|
||||
@@ -13,6 +13,18 @@ function buildClone(bindingKey, 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 ExportSpecifier = buildClone("local", "exported");
|
||||
export var ImportSpecifier = buildClone("local", "imported");
|
||||
export var ExportDeclaration = buildListClone("specifiers", "local", "exported");
|
||||
export var ImportDeclaration = buildListClone("specifiers", "local", "imported");
|
||||
|
||||
@@ -49,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);
|
||||
|
||||
@@ -61,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];
|
||||
@@ -75,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(clone(id), clone(id)));
|
||||
specifiers.push(buildExportSpecifier(bindings[key]));
|
||||
}
|
||||
return [declar, t.exportNamedDeclaration(null, specifiers)];
|
||||
}
|
||||
|
||||
@@ -22,21 +22,19 @@ export var metadata = {
|
||||
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;
|
||||
if (binding.kind === "param" || binding.kind === "module") 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;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@ export var metadata = {
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
export function Expression(node, parent, scope) {
|
||||
var res = this.evaluate();
|
||||
if (res.confident) return t.valueToNode(res.value);
|
||||
}
|
||||
export var Expression = {
|
||||
exit(node, parent, scope) {
|
||||
var res = this.evaluate();
|
||||
if (res.confident) return t.valueToNode(res.value);
|
||||
}
|
||||
};
|
||||
|
||||
export function Identifier() {
|
||||
// override Expression
|
||||
|
||||
@@ -35,9 +35,8 @@ export function JSXElement(node, parent, scope, file) {
|
||||
this.traverse(immutabilityVisitor, state);
|
||||
|
||||
if (state.isImmutable) {
|
||||
this.hoist();
|
||||
this.skip();
|
||||
return this.hoist();
|
||||
} else {
|
||||
node._hoisted = true;
|
||||
}
|
||||
|
||||
node._hoisted = true;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export var metadata = {
|
||||
dependencies: ["es7.asyncFunctions", "es6.classes"]
|
||||
};
|
||||
|
||||
export function Func(node, parent, scope, file) {
|
||||
export function Func/*tion*/(node, parent, scope, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return remapAsyncToGenerator(node, file.addHelper("async-to-generator"), scope);
|
||||
|
||||
@@ -10,7 +10,7 @@ export var metadata = {
|
||||
dependencies: ["es7.asyncFunctions", "es6.classes"]
|
||||
};
|
||||
|
||||
export function Func(node, parent, scope, file) {
|
||||
export function Func/*tion*/(node, parent, scope, file) {
|
||||
if (!node.async || node.generator) return;
|
||||
|
||||
return remapAsyncToGenerator(
|
||||
|
||||
@@ -12,7 +12,7 @@ export function Class(node) {
|
||||
node.implements = null;
|
||||
}
|
||||
|
||||
export function Func(node) {
|
||||
export function Func/*tion*/(node) {
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
var param = node.params[i];
|
||||
param.optional = false;
|
||||
|
||||
@@ -6,7 +6,8 @@ export function manipulateOptions(opts) {
|
||||
}
|
||||
|
||||
export var metadata = {
|
||||
optional: true
|
||||
optional: true,
|
||||
group: "builtin-advanced"
|
||||
};
|
||||
|
||||
require("../../helpers/build-react-transformer")(exports, {
|
||||
|
||||
@@ -3,6 +3,10 @@ import * as t from "../../../types";
|
||||
|
||||
var JSX_ANNOTATION_REGEX = /^\*\s*@jsx\s+([^\s]+)/;
|
||||
|
||||
export var metadata = {
|
||||
group: "builtin-advanced"
|
||||
};
|
||||
|
||||
export function Program(node, parent, scope, file) {
|
||||
var id = file.opts.jsxPragma;
|
||||
|
||||
|
||||
@@ -1,10 +1,69 @@
|
||||
import regenerator from "regenerator";
|
||||
import * as t from "../../../types";
|
||||
import { NodePath } from "ast-types";
|
||||
|
||||
export var metadata = {
|
||||
group: "regenerator"
|
||||
};
|
||||
|
||||
export function Program(ast) {
|
||||
regenerator.transform(ast);
|
||||
export function Func/*tion*/(node) {
|
||||
if (node.async || node.generator) {
|
||||
// Although this code transforms only the subtree rooted at the given
|
||||
// Function node, that node might contain other generator functions
|
||||
// that will also be transformed. It might help performance to ignore
|
||||
// nested functions, and rely on the traversal to visit them later,
|
||||
// but that's a small optimization. Starting here instead of at the
|
||||
// root of the AST is the key optimization, since huge async/generator
|
||||
// functions are relatively rare.
|
||||
regenerator.transform(convertTraversalPathToNodePath(this));
|
||||
}
|
||||
}
|
||||
|
||||
// Given a TraversalPath, return a NodePath that includes full ancestry
|
||||
// information (up to and including the Program node). This is complicated
|
||||
// by having to include intermediate objects like blockStatement.body
|
||||
// arrays, in addition to Node objects.
|
||||
function convertTraversalPathToNodePath(path) {
|
||||
var programNode;
|
||||
var keysAlongPath = [];
|
||||
|
||||
while (path) {
|
||||
var pp = path.parentPath;
|
||||
var parentNode = pp && pp.node;
|
||||
if (parentNode) {
|
||||
keysAlongPath.push(path.key);
|
||||
|
||||
if (parentNode !== path.container) {
|
||||
var found = Object.keys(parentNode).some(containerKey => {
|
||||
if (parentNode[containerKey] === path.container) {
|
||||
keysAlongPath.push(containerKey);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
throw new Error("Failed to find container object in parent node");
|
||||
}
|
||||
}
|
||||
|
||||
if (t.isProgram(parentNode)) {
|
||||
programNode = parentNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
path = pp;
|
||||
}
|
||||
|
||||
if (!programNode) {
|
||||
throw new Error("Failed to find root Program node");
|
||||
}
|
||||
|
||||
var nodePath = new NodePath(programNode);
|
||||
|
||||
while (keysAlongPath.length > 0) {
|
||||
nodePath = nodePath.get(keysAlongPath.pop());
|
||||
}
|
||||
|
||||
return nodePath;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import * as messages from "../../../messages";
|
||||
import * as t from "../../../types";
|
||||
|
||||
export var metadata = {
|
||||
group: "builtin-setup"
|
||||
};
|
||||
|
||||
const THIS_BREAK_KEYS = ["FunctionExpression", "FunctionDeclaration", "ClassExpression", "ClassDeclaration"];
|
||||
|
||||
export var Program = {
|
||||
|
||||
@@ -24,7 +24,7 @@ export function AssignmentExpression(node, parent, scope, file) {
|
||||
|
||||
var nodes = [];
|
||||
var left = node.left.object;
|
||||
var temp = scope.generateMemoisedReference(left);
|
||||
var temp = scope.maybeGenerateMemoised(left);
|
||||
|
||||
nodes.push(t.expressionStatement(t.assignmentExpression("=", temp, left)));
|
||||
nodes.push(buildDefaultsCallExpression(node, temp, file));
|
||||
|
||||
@@ -92,6 +92,7 @@ export function evaluate(): { confident: boolean; value: any } {
|
||||
case "!": return !arg;
|
||||
case "+": return +arg;
|
||||
case "-": return -arg;
|
||||
case "~": return ~arg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +120,7 @@ export function evaluate(): { confident: boolean; value: any } {
|
||||
case "/": return left / right;
|
||||
case "*": return left * right;
|
||||
case "%": return left % right;
|
||||
case "**": return Math.pow(left, right);
|
||||
case "<": return left < right;
|
||||
case ">": return left > right;
|
||||
case "<=": return left <= right;
|
||||
|
||||
@@ -2,26 +2,24 @@ import * as react from "../../transformation/helpers/react";
|
||||
import * as t from "../../types";
|
||||
|
||||
var referenceVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
ReferencedIdentifier(node, parent, scope, state) {
|
||||
if (this.isJSXIdentifier() && react.isCompatTag(node.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isJSXIdentifier() || this.isIdentifier()) {
|
||||
// direct references that we need to track to hoist this to the highest scope we can
|
||||
if (this.isReferenced()) {
|
||||
var bindingInfo = scope.getBinding(node.name);
|
||||
// direct references that we need to track to hoist this to the highest scope we can
|
||||
var bindingInfo = scope.getBinding(node.name);
|
||||
if (!bindingInfo) return;
|
||||
|
||||
// this binding isn't accessible from the parent scope so we can safely ignore it
|
||||
// eg. it's in a closure etc
|
||||
if (bindingInfo !== state.scope.getBinding(node.name)) return;
|
||||
// this binding isn't accessible from the parent scope so we can safely ignore it
|
||||
// eg. it's in a closure etc
|
||||
if (bindingInfo !== state.scope.getBinding(node.name)) return;
|
||||
|
||||
if (bindingInfo && bindingInfo.constant) {
|
||||
state.bindings[node.name] = bindingInfo;
|
||||
} else {
|
||||
state.foundIncompatible = true;
|
||||
this.stop();
|
||||
}
|
||||
if (bindingInfo.constant) {
|
||||
state.bindings[node.name] = bindingInfo;
|
||||
} else {
|
||||
for (var violationPath of (bindingInfo.constantViolations: Array)) {
|
||||
state.breakOnScopePaths.push(violationPath.scope.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,10 +27,10 @@ var referenceVisitor = {
|
||||
|
||||
export default class PathHoister {
|
||||
constructor(path, scope) {
|
||||
this.foundIncompatible = false;
|
||||
this.breakOnScopePaths = [];
|
||||
this.bindings = {};
|
||||
this.scope = scope;
|
||||
this.scopes = [];
|
||||
this.scope = scope;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@@ -43,32 +41,41 @@ export default class PathHoister {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
getCompatibleScopes() {
|
||||
var checkScope = this.path.scope;
|
||||
var scope = this.path.scope;
|
||||
do {
|
||||
if (this.isCompatibleScope(checkScope)) {
|
||||
this.scopes.push(checkScope);
|
||||
if (this.isCompatibleScope(scope)) {
|
||||
this.scopes.push(scope);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(checkScope = checkScope.parent);
|
||||
|
||||
if (this.breakOnScopePaths.indexOf(scope.path) >= 0) {
|
||||
break;
|
||||
}
|
||||
} while(scope = scope.parent);
|
||||
}
|
||||
|
||||
getAttachmentPath() {
|
||||
var scopes = this.scopes;
|
||||
|
||||
var scope = scopes.pop();
|
||||
if (!scope) return;
|
||||
|
||||
if (scope.path.isFunction()) {
|
||||
if (this.hasNonParamBindings()) {
|
||||
// can't be attached to this scope
|
||||
return this.getNextScopeStatementParent();
|
||||
} else {
|
||||
if (this.hasOwnParamBindings(scope)) {
|
||||
// should ignore this scope since it's ourselves
|
||||
if (this.scope.is(scope)) return;
|
||||
|
||||
// needs to be attached to the body
|
||||
return scope.path.get("body").get("body")[0];
|
||||
} else {
|
||||
// doesn't need to be be attached to this scope
|
||||
return this.getNextScopeStatementParent();
|
||||
}
|
||||
} else if (scope.path.isProgram()) {
|
||||
return this.getNextScopeStatementParent();
|
||||
@@ -80,10 +87,12 @@ export default class PathHoister {
|
||||
if (scope) return scope.path.getStatementParent();
|
||||
}
|
||||
|
||||
hasNonParamBindings() {
|
||||
hasOwnParamBindings(scope) {
|
||||
for (var name in this.bindings) {
|
||||
if (!scope.hasOwnBinding(name)) continue
|
||||
|
||||
var binding = this.bindings[name];
|
||||
if (binding.kind !== "param") return true;
|
||||
if (binding.kind === "param") return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -94,7 +103,6 @@ export default class PathHoister {
|
||||
node._hoisted = true;
|
||||
|
||||
this.path.traverse(referenceVisitor, this);
|
||||
if (this.foundIncompatible) return;
|
||||
|
||||
this.getCompatibleScopes();
|
||||
|
||||
@@ -117,6 +125,6 @@ export default class PathHoister {
|
||||
uid = t.jSXExpressionContainer(uid);
|
||||
}
|
||||
|
||||
this.path.replaceWith(uid);
|
||||
return uid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,14 +228,16 @@ export default class TraversalPath {
|
||||
paths.push(TraversalPath.get(this, null, node, this.container, to));
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
_containerInsertBefore(nodes) {
|
||||
this._containerInsert(this.key, nodes);
|
||||
return this._containerInsert(this.key, nodes);
|
||||
}
|
||||
|
||||
_containerInsertAfter(nodes) {
|
||||
this._containerInsert(this.key + 1, nodes);
|
||||
return this._containerInsert(this.key + 1, nodes);
|
||||
}
|
||||
|
||||
_maybePopFromStatements(nodes) {
|
||||
@@ -285,7 +287,7 @@ export default class TraversalPath {
|
||||
return this.parentPath.insertAfter(nodes);
|
||||
} else if (this.isPreviousType("Expression") || (this.parentPath.isForStatement() && this.key === "init")) {
|
||||
if (this.node) {
|
||||
var temp = this.scope.generateTemp();
|
||||
var temp = this.scope.generateDeclaredUidIdentifier();
|
||||
nodes.unshift(t.expressionStatement(t.assignmentExpression("=", temp, this.node)));
|
||||
nodes.push(t.expressionStatement(temp));
|
||||
}
|
||||
@@ -922,6 +924,14 @@ export default class TraversalPath {
|
||||
return !this.has(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
equals(key, value): boolean {
|
||||
return this.node[key] === value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
@@ -939,7 +949,7 @@ export default class TraversalPath {
|
||||
annotation: null
|
||||
};
|
||||
|
||||
var type = this.node.typeAnnotation;
|
||||
var type = this.node && this.node.typeAnnotation;
|
||||
|
||||
if (!type) {
|
||||
info.inferred = true;
|
||||
@@ -1017,36 +1027,36 @@ export default class TraversalPath {
|
||||
path = path.resolve();
|
||||
if (!path) return;
|
||||
|
||||
if (path.isRestElement() || path.parentPath.isRestElement() || path.isArrayExpression()) {
|
||||
if (path.isPreviousType("RestElement") || path.parentPath.isPreviousType("RestElement") || path.isPreviousType("ArrayExpression")) {
|
||||
return t.genericTypeAnnotation(t.identifier("Array"));
|
||||
}
|
||||
|
||||
if (path.parentPath.isTypeCastExpression()) {
|
||||
if (path.parentPath.isPreviousType("TypeCastExpression")) {
|
||||
return path.parentPath.node.typeAnnotation;
|
||||
}
|
||||
|
||||
if (path.isTypeCastExpression()) {
|
||||
if (path.isPreviousType("TypeCastExpression")) {
|
||||
return path.node.typeAnnotation;
|
||||
}
|
||||
|
||||
if (path.isObjectExpression()) {
|
||||
if (path.isPreviousType("ObjectExpression")) {
|
||||
return t.genericTypeAnnotation(t.identifier("Object"));
|
||||
}
|
||||
|
||||
if (path.isFunction()) {
|
||||
if (path.isPreviousType("Function")) {
|
||||
return t.identifier("Function");
|
||||
}
|
||||
|
||||
if (path.isLiteral()) {
|
||||
if (path.isPreviousType("Literal")) {
|
||||
var value = path.node.value;
|
||||
if (isString(value)) return t.stringTypeAnnotation();
|
||||
if (isNumber(value)) return t.numberTypeAnnotation();
|
||||
if (isBoolean(value)) return t.booleanTypeAnnotation();
|
||||
}
|
||||
|
||||
if (path.isCallExpression()) {
|
||||
if (path.isPreviousType("CallExpression")) {
|
||||
var callee = path.get("callee").resolve();
|
||||
if (callee && callee.isFunction()) return callee.node.returnType;
|
||||
if (callee && callee.isPreviousType("Function")) return callee.node.returnType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import * as t from "../types";
|
||||
import * as t from "../../types";
|
||||
|
||||
export default class Binding {
|
||||
constructor({ identifier, scope, path, kind }) {
|
||||
this.constantViolations = [];
|
||||
this.constant = true;
|
||||
|
||||
this.identifier = identifier;
|
||||
this.references = 0;
|
||||
this.referenced = false;
|
||||
this.constant = true;
|
||||
|
||||
this.scope = scope;
|
||||
this.path = path;
|
||||
this.kind = kind;
|
||||
@@ -51,8 +54,9 @@ export default class Binding {
|
||||
* Description
|
||||
*/
|
||||
|
||||
reassign() {
|
||||
reassign(path) {
|
||||
this.constant = false;
|
||||
this.constantViolations.push(path);
|
||||
|
||||
if (this.typeAnnotationInferred) {
|
||||
// destroy the inferred typeAnnotation
|
||||
@@ -69,6 +73,15 @@ export default class Binding {
|
||||
this.references++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
dereference() {
|
||||
this.references--;
|
||||
this.referenced = !!this.references;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
@@ -1,15 +1,15 @@
|
||||
import includes from "lodash/collection/includes";
|
||||
import { explode } from "./visitors";
|
||||
import traverse from "./index";
|
||||
import { explode } from "../visitors";
|
||||
import traverse from "../index";
|
||||
import defaults from "lodash/object/defaults";
|
||||
import * as messages from "../messages";
|
||||
import * as messages from "../../messages";
|
||||
import Binding from "./binding";
|
||||
import globals from "globals";
|
||||
import flatten from "lodash/array/flatten";
|
||||
import extend from "lodash/object/extend";
|
||||
import object from "../helpers/object";
|
||||
import object from "../../helpers/object";
|
||||
import each from "lodash/collection/each";
|
||||
import * as t from "../types";
|
||||
import * as t from "../../types";
|
||||
|
||||
var functionVariableVisitor = {
|
||||
enter(node, parent, scope, state) {
|
||||
@@ -163,11 +163,22 @@ export default class Scope {
|
||||
traverse(node, opts, this, state, this.path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Since `Scope` instances are unique to their traversal we need some other
|
||||
* way to compare if scopes are the same. Here we just compare `this.bindings`
|
||||
* as it will be the same across all instances.
|
||||
*/
|
||||
|
||||
is(scope) {
|
||||
return this.bindings === scope.bindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
generateTemp(name: string = "temp") {
|
||||
generateDeclaredUidIdentifier(name: string = "temp") {
|
||||
var id = this.generateUidIdentifier(name);
|
||||
this.push({ id });
|
||||
return id;
|
||||
@@ -213,7 +224,7 @@ export default class Scope {
|
||||
* Description
|
||||
*/
|
||||
|
||||
generateUidBasedOnNode(parent: Object, defaultName?: String): Object {
|
||||
generateUidIdentifierBasedOnNode(parent: Object, defaultName?: String): Object {
|
||||
var node = parent;
|
||||
|
||||
if (t.isAssignmentExpression(parent)) {
|
||||
@@ -264,21 +275,39 @@ export default class Scope {
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
* Determine whether evaluating the specific input `node` is a consequenceless reference. ie.
|
||||
* evaluating it wont result in potentially arbitrary code from being ran. The following are
|
||||
* whitelisted and determined not cause side effects:
|
||||
*
|
||||
* - `this` expressions
|
||||
* - `super` expressions
|
||||
* - Bound identifiers
|
||||
*/
|
||||
|
||||
generateMemoisedReference(node: Object, dontPush?: boolean): ?Object {
|
||||
isStatic(node: Object): boolean {
|
||||
if (t.isThisExpression(node) || t.isSuper(node)) {
|
||||
return null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isIdentifier(node) && this.hasBinding(node.name)) {
|
||||
return null;
|
||||
return true;
|
||||
}
|
||||
|
||||
var id = this.generateUidBasedOnNode(node);
|
||||
if (!dontPush) this.push({ id });
|
||||
return id;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
|
||||
maybeGenerateMemoised(node: Object, dontPush?: boolean): ?Object {
|
||||
if (this.isStatic(node)) {
|
||||
return null;
|
||||
} else {
|
||||
var id = this.generateUidIdentifierBasedOnNode(node);
|
||||
if (!dontPush) this.push({ id });
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,11 +446,13 @@ export default class Scope {
|
||||
for (var name in ids) {
|
||||
var binding = this.getBinding(name);
|
||||
if (!binding) continue;
|
||||
|
||||
if (right) {
|
||||
var rightType = right.typeAnnotation;
|
||||
if (rightType && binding.isCompatibleWithType(rightType)) continue;
|
||||
}
|
||||
binding.reassign();
|
||||
|
||||
binding.reassign(left, right);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,6 +463,14 @@ export default class Scope {
|
||||
registerBinding(kind: string, path: TraversalPath) {
|
||||
if (!kind) throw new ReferenceError("no `kind`");
|
||||
|
||||
if (path.isVariableDeclaration()) {
|
||||
var declarators = path.get("declarations");
|
||||
for (var declar of (declarators: Array)) {
|
||||
this.registerBinding(kind, declar);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var ids = path.getBindingIdentifiers();
|
||||
|
||||
for (var name in ids) {
|
||||
@@ -631,13 +670,14 @@ export default class Scope {
|
||||
var declar = !unique && path.getData(dataKey);
|
||||
|
||||
if (!declar) {
|
||||
declar = t.variableDeclaration(opts.kind || "var", []);
|
||||
declar = t.variableDeclaration(kind, []);
|
||||
declar._generated = true;
|
||||
declar._blockHoist = 2;
|
||||
|
||||
this.file.attachAuxiliaryComment(declar);
|
||||
|
||||
path.get("body")[0]._containerInsertBefore([declar]);
|
||||
var [declarPath] = path.get("body")[0]._containerInsertBefore([declar]);
|
||||
this.registerBinding(kind, declarPath);
|
||||
if (!unique) path.setData(dataKey, declar);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
"right": null
|
||||
},
|
||||
|
||||
"BindExpression": {
|
||||
"object": null,
|
||||
"callee": null
|
||||
},
|
||||
|
||||
"BlockStatement": {
|
||||
"body": null
|
||||
},
|
||||
|
||||
@@ -49,12 +49,27 @@ export function isReferenced(node: Object, parent: Object): boolean {
|
||||
return parent.id !== node;
|
||||
|
||||
// no: export { foo as NODE };
|
||||
// yes: export { NODE as foo };
|
||||
// no: export { NODE as foo } from "foo";
|
||||
case "ExportSpecifier":
|
||||
return parent.exported !== node;
|
||||
if (parent.source) {
|
||||
return false;
|
||||
} else {
|
||||
return parent.local === node;
|
||||
}
|
||||
|
||||
// no: import NODE from "foo";
|
||||
case "ImportDefaultSpecifier":
|
||||
return false;
|
||||
|
||||
// no: import * as NODE from "foo";
|
||||
case "ImportNamespaceSpecifier":
|
||||
return false;
|
||||
|
||||
// no: import { NODE as foo } from "foo";
|
||||
// no: import { foo as NODE } from "foo";
|
||||
case "ImportSpecifier":
|
||||
return parent.imported !== node;
|
||||
return false;
|
||||
|
||||
// no: class NODE {}
|
||||
case "ClassDeclaration":
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"AssignmentPattern": ["left", "right"],
|
||||
"AwaitExpression": ["argument"],
|
||||
"BinaryExpression": ["left", "right"],
|
||||
"BindExpression": ["object", "callee"],
|
||||
"BlockStatement": ["body"],
|
||||
"BreakStatement": ["label"],
|
||||
"CallExpression": ["callee", "arguments"],
|
||||
|
||||
@@ -99,6 +99,47 @@ suite("api", function () {
|
||||
});
|
||||
});
|
||||
|
||||
suite("env option", function () {
|
||||
var oldBabelEnv = process.env.BABEL_ENV;
|
||||
var oldNodeEnv = process.env.NODE_ENV;
|
||||
|
||||
before(function () {
|
||||
delete process.env.BABEL_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
});
|
||||
|
||||
after(function () {
|
||||
process.env.BABEL_ENV = oldBabelEnv;
|
||||
process.env.NODE_ENV = oldNodeEnv;
|
||||
});
|
||||
|
||||
test("default", function () {
|
||||
assert.equal(transform("foo;", {
|
||||
env: {
|
||||
development: { blacklist: "strict" }
|
||||
}
|
||||
}).code, "foo;");
|
||||
});
|
||||
|
||||
test("BABEL_ENV", function () {
|
||||
process.env.BABEL_ENV = "foo";
|
||||
assert.equal(transform("foo;", {
|
||||
env: {
|
||||
foo: { blacklist: "strict" }
|
||||
}
|
||||
}).code, "foo;");
|
||||
});
|
||||
|
||||
test("NODE_ENV", function () {
|
||||
process.env.NODE_ENV = "foo";
|
||||
assert.equal(transform("foo;", {
|
||||
env: {
|
||||
foo: { blacklist: "strict" }
|
||||
}
|
||||
}).code, "foo;");
|
||||
});
|
||||
});
|
||||
|
||||
test("addHelper unknown", function () {
|
||||
var file = new File({}, transform.pipeline);
|
||||
assert.throws(function () {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
::foo.bar.foo;
|
||||
::foo.bar["foo"];
|
||||
|
||||
ctx::foo.bar.foo;
|
||||
ctx::foo.bar["foo"];
|
||||
@@ -0,0 +1,5 @@
|
||||
::foo.bar.foo;
|
||||
::foo.bar["foo"];
|
||||
|
||||
ctx::foo.bar.foo;
|
||||
ctx::foo.bar["foo"];
|
||||
@@ -1,5 +1,6 @@
|
||||
for (let i of nums) {
|
||||
var x = 5;
|
||||
var { f } = { f: 2 };
|
||||
fns.push(function () {
|
||||
return i * x;
|
||||
});
|
||||
|
||||
@@ -8,6 +8,8 @@ try {
|
||||
var _loop = function () {
|
||||
var i = _step.value;
|
||||
x = 5;
|
||||
var _f = { f: 2 };
|
||||
f = _f.f;
|
||||
|
||||
fns.push(function () {
|
||||
return i * x;
|
||||
@@ -16,6 +18,7 @@ try {
|
||||
|
||||
for (var _iterator = nums[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var x;
|
||||
var f;
|
||||
|
||||
_loop();
|
||||
}
|
||||
@@ -32,4 +35,4 @@ try {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ define(["exports", "./evens"], function (exports, _evens) {
|
||||
exports.nextOdd = nextOdd;
|
||||
|
||||
function nextOdd(n) {
|
||||
return _evens.isEven(n) ? n + 1 : n + 2;
|
||||
return (0, _evens.isEven)(n) ? n + 1 : n + 2;
|
||||
}
|
||||
|
||||
var isOdd = (function (isEven) {
|
||||
|
||||
@@ -8,7 +8,7 @@ exports.nextOdd = nextOdd;
|
||||
var _evens = require("./evens");
|
||||
|
||||
function nextOdd(n) {
|
||||
return _evens.isEven(n) ? n + 1 : n + 2;
|
||||
return (0, _evens.isEven)(n) ? n + 1 : n + 2;
|
||||
}
|
||||
|
||||
var isOdd = (function (isEven) {
|
||||
@@ -16,4 +16,4 @@ var isOdd = (function (isEven) {
|
||||
return !isEven(n);
|
||||
};
|
||||
})(_evens.isEven);
|
||||
exports.isOdd = isOdd;
|
||||
exports.isOdd = isOdd;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
exports.nextOdd = nextOdd;
|
||||
|
||||
function nextOdd(n) {
|
||||
return _evens.isEven(n) ? n + 1 : n + 2;
|
||||
return (0, _evens.isEven)(n) ? n + 1 : n + 2;
|
||||
}
|
||||
|
||||
var isOdd = (function (isEven) {
|
||||
@@ -28,4 +28,4 @@
|
||||
};
|
||||
})(_evens.isEven);
|
||||
exports.isOdd = isOdd;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ var Foo = (function () {
|
||||
}
|
||||
|
||||
var _Foo = Foo;
|
||||
Foo = _foo2["default"](Foo) || Foo;
|
||||
Foo = (0, _foo2["default"])(Foo) || Foo;
|
||||
return Foo;
|
||||
})();
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
var f = ctx::ns.obj.func;
|
||||
var g = ::ns.obj.func;
|
||||
var h = new X::y;
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var _context;
|
||||
|
||||
var f = (_context = ctx, ns.obj.func).bind(_context);
|
||||
var g = (_context = ns.obj).func.bind(_context);
|
||||
var h = (_context = new X(), y).bind(_context);
|
||||
@@ -0,0 +1,4 @@
|
||||
ctx::ns.obj.func();
|
||||
::ns.obj.func();
|
||||
|
||||
ns.obj2::ns.obj1.func();
|
||||
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var _context;
|
||||
|
||||
(_context = ctx, ns.obj.func).call(_context);
|
||||
(_context = ns.obj).func.call(_context);
|
||||
|
||||
(_context = ns.obj2, ns.obj1.func).call(_context);
|
||||
@@ -0,0 +1,6 @@
|
||||
import { map, takeWhile, forEach } from "iterlib";
|
||||
|
||||
getPlayers()
|
||||
::map(x => x.character())
|
||||
::takeWhile(x => x.strength > 100)
|
||||
::forEach(x => console.log(x));
|
||||
@@ -0,0 +1,27 @@
|
||||
var operations = [];
|
||||
|
||||
var lib = {};
|
||||
|
||||
for (let key of ['f', 'g', 'h']) {
|
||||
let func = () => operations.push(`lib.${key}()`);
|
||||
Object.defineProperty(lib, key, {
|
||||
get() {
|
||||
operations.push(`get lib.${key}`);
|
||||
return func;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
({prop:'value'})
|
||||
::lib.f()
|
||||
::lib.g()
|
||||
::lib.h();
|
||||
|
||||
assert.deepEqual(operations, [
|
||||
'get lib.f',
|
||||
'lib.f()',
|
||||
'get lib.g',
|
||||
'lib.g()',
|
||||
'get lib.h',
|
||||
'lib.h()'
|
||||
]);
|
||||
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
var _context;
|
||||
|
||||
var _iterlib = require("iterlib");
|
||||
|
||||
(_context = (_context = (_context = getPlayers(), _iterlib.map).call(_context, function (x) {
|
||||
return x.character();
|
||||
}), _iterlib.takeWhile).call(_context, function (x) {
|
||||
return x.strength > 100;
|
||||
}), _iterlib.forEach).call(_context, function (x) {
|
||||
return console.log(x);
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"optional": "es7.functionBind"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
var bar = function () {};
|
||||
foo::bar;
|
||||
|
||||
var foo = {};
|
||||
::foo.bar;
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var bar = function bar() {};
|
||||
bar.bind(foo);
|
||||
|
||||
var foo = {};
|
||||
foo.bar.bind(foo);
|
||||
@@ -0,0 +1,5 @@
|
||||
var Foo = React.createClass({
|
||||
render: function render() {
|
||||
return <div foo={notDeclared}></div>;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var _ref = <div foo={notDeclared}></div>;
|
||||
|
||||
var Foo = React.createClass({
|
||||
render: function render() {
|
||||
return _ref;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
function render(text) {
|
||||
return function () {
|
||||
return <div>{text}</div>;
|
||||
};
|
||||
}
|
||||
|
||||
function render() {
|
||||
return function (text) {
|
||||
return <div>{text}</div>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
function render(text) {
|
||||
var _ref = <div>{text}</div>;
|
||||
|
||||
return function () {
|
||||
return _ref;
|
||||
};
|
||||
}
|
||||
|
||||
function render() {
|
||||
return function (text) {
|
||||
return <div>{text}</div>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
function render(text) {
|
||||
text += "yes";
|
||||
|
||||
return function () {
|
||||
return <div>{text}</div>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
function render(text) {
|
||||
text += "yes";
|
||||
|
||||
var _ref = <div>{text}</div>;
|
||||
|
||||
return function () {
|
||||
return _ref;
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,2 @@
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
React.createElement(Component, _extends({}, props, {
|
||||
React.createElement(Component, babelHelpers._extends({}, props, {
|
||||
sound: "moo" }));
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
class App extends React.Component {
|
||||
render() {
|
||||
const navbarHeader = <div className="navbar-header">
|
||||
<a className="navbar-brand" href="/">
|
||||
<img src="/img/logo/logo-96x36.png" />
|
||||
</a>
|
||||
</div>;
|
||||
|
||||
return <div>
|
||||
<nav className="navbar navbar-default">
|
||||
<div className="container">
|
||||
{navbarHeader}
|
||||
</div>
|
||||
</nav>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
var _ref = React.createElement(
|
||||
"div",
|
||||
{ className: "navbar-header" },
|
||||
React.createElement(
|
||||
"a",
|
||||
{ className: "navbar-brand", href: "/" },
|
||||
React.createElement("img", { src: "/img/logo/logo-96x36.png" })
|
||||
)
|
||||
);
|
||||
|
||||
var App = (function (_React$Component) {
|
||||
function App() {
|
||||
babelHelpers.classCallCheck(this, App);
|
||||
|
||||
if (_React$Component != null) {
|
||||
_React$Component.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
babelHelpers.inherits(App, _React$Component);
|
||||
babelHelpers.createClass(App, [{
|
||||
key: "render",
|
||||
value: function render() {
|
||||
var navbarHeader = _ref;
|
||||
|
||||
return React.createElement(
|
||||
"div",
|
||||
null,
|
||||
React.createElement(
|
||||
"nav",
|
||||
{ className: "navbar navbar-default" },
|
||||
React.createElement(
|
||||
"div",
|
||||
{ className: "container" },
|
||||
navbarHeader
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}]);
|
||||
return App;
|
||||
})(React.Component);
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"optional": ["optimisation.react.constantElements"]
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"externalHelpers": true,
|
||||
"blacklist": ["strict"]
|
||||
}
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
React.createElement(Component, _extends({}, x, { y: 2, z: true }));
|
||||
React.createElement(Component, babelHelpers._extends({}, x, { y: 2, z: true }));
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
React.createElement(Component, _extends({ y: 2, z: true }, x));
|
||||
React.createElement(Component, babelHelpers._extends({ y: 2, z: true }, x));
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
React.createElement(Component, _extends({ y: 2 }, x, { z: true }));
|
||||
React.createElement(Component, babelHelpers._extends({ y: 2 }, x, { z: true }));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
define(["exports", "foo", "babel-runtime/helpers/interop-require"], function (exports, _foo, _babelRuntimeHelpersInteropRequire) {
|
||||
"use strict";
|
||||
|
||||
var _foo2 = _babelRuntimeHelpersInteropRequire["default"](_foo);
|
||||
var _foo2 = (0, _babelRuntimeHelpersInteropRequire["default"])(_foo);
|
||||
|
||||
_foo2;
|
||||
});
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
})(this, function (exports, _foo, _babelRuntimeHelpersInteropRequire) {
|
||||
"use strict";
|
||||
|
||||
var _foo2 = _babelRuntimeHelpersInteropRequire["default"](_foo);
|
||||
});
|
||||
var _foo2 = (0, _babelRuntimeHelpersInteropRequire["default"])(_foo);
|
||||
});
|
||||
|
||||
@@ -20,11 +20,11 @@ var Container = (function () {
|
||||
return;
|
||||
}
|
||||
|
||||
return _lodashArrayLast2["default"](this.tokens.get(key));
|
||||
return (0, _lodashArrayLast2["default"])(this.tokens.get(key));
|
||||
}
|
||||
}]);
|
||||
return Container;
|
||||
})();
|
||||
|
||||
exports["default"] = Container;
|
||||
module.exports = exports["default"];
|
||||
module.exports = exports["default"];
|
||||
|
||||
@@ -19,11 +19,11 @@ var Login = (function (_React$Component) {
|
||||
babelHelpers.createClass(Login, [{
|
||||
key: "getForm",
|
||||
value: function getForm() {
|
||||
return _store.getForm().toJS();
|
||||
return (0, _store.getForm)().toJS();
|
||||
}
|
||||
}]);
|
||||
return Login;
|
||||
})(React.Component);
|
||||
|
||||
exports["default"] = Login;
|
||||
module.exports = exports["default"];
|
||||
module.exports = exports["default"];
|
||||
|
||||
@@ -34,7 +34,8 @@ _.each(helper.get("generation"), function (testSuite) {
|
||||
features: {
|
||||
"es7.comprehensions": true,
|
||||
"es7.asyncFunctions": true,
|
||||
"es7.exportExtensions": true
|
||||
"es7.exportExtensions": true,
|
||||
"es7.functionBind": true
|
||||
}
|
||||
});
|
||||
var actualCode = generate(actualAst, task.options, actual.code).code;
|
||||
|
||||
Reference in New Issue
Block a user