start moving more transformers to packages and finish import of plugins from babel-plugins

This commit is contained in:
Sebastian McKenzie
2015-09-01 08:37:37 +01:00
parent 9f9d9cd84b
commit 1ea835f42f
255 changed files with 3785 additions and 1265 deletions

View File

@@ -1,41 +0,0 @@
import * as t from "babel-types";
export var metadata = {
group: "builtin-trailing"
};
/**
* Turn member expression reserved word properties into literals.
*
* @example
*
* **In**
*
* ```javascript
* foo.catch;
* ```
*
* **Out**
*
* ```javascript
* foo["catch"];
* ```
*/
export var visitor = {
/**
* Look for non-computed properties with names that are not valid identifiers.
* Turn them into computed properties with literal names.
*/
MemberExpression: {
exit(node) {
var prop = node.property;
if (!node.computed && t.isIdentifier(prop) && !t.isValidIdentifier(prop.name)) {
// foo.default -> foo["default"]
node.property = t.stringLiteral(prop.name);
node.computed = true;
}
}
}
};

View File

@@ -1,42 +0,0 @@
import * as t from "babel-types";
export var metadata = {
group: "builtin-trailing"
};
/**
* Turn reserved word properties into literals.
*
* **In**
*
* ```javascript
* var foo = {
* catch: function () {}
* };
* ```
*
* **Out**
*
* ```javascript
* var foo = {
* "catch": function () {}
* };
* ```
*/
export var visitor = {
/**
* Look for non-computed keys with names that are not valid identifiers.
* Turn them into literals.
*/
Property: {
exit(node) {
var key = node.key;
if (!node.computed && t.isIdentifier(key) && !t.isValidIdentifier(key.name)) {
// default: "bar" -> "default": "bar"
node.key = t.stringLiteral(key.name);
}
}
}
};

View File

@@ -1,32 +0,0 @@
/**
* Turn arrow functions into normal functions.
*
* @example
*
* **In**
*
* ```javascript
* arr.map(x => x * x);
* ```
*
* **Out**
*
* ```javascript
* arr.map(function (x) {
* return x * x;
* });
*/
export var visitor = {
/**
* Look for arrow functions and mark them as "shadow functions".
* @see /transformation/transformers/internal/shadow-functions.js
*/
ArrowFunctionExpression(node) {
this.ensureBlock();
node.expression = false;
node.type = "FunctionExpression";
node.shadow = node.shadow || true;
}
};

View File

@@ -5,12 +5,11 @@ import { bare } from "../../../helpers/name-method";
export var visitor = {
ClassDeclaration(node) {
return t.variableDeclaration("let", [
return t.variableDeclaration("var", [
t.variableDeclarator(node.id, t.toExpression(node))
]);
},
ClassExpression(node, parent, scope, file) {
var inferred = bare(node, parent, scope);
if (inferred) return inferred;

View File

@@ -1,49 +0,0 @@
import * as messages from "babel-messages";
/**
* Turn constants into variables.
* Ensure there are no constant violations in any scope.
*
* @example
*
* **In**
*
* ```javascript
* const MULTIPLIER = 5;
* ```
*
* **Out**
*
* ```javascript
* var MULTIPLIER = 5;
* ```
*/
export var visitor = {
/**
* Look for any constants (or modules) in scope.
* If they have any `constantViolations` throw an error.
*/
Scope(node, parent, scope) {
for (var name in scope.bindings) {
var binding = scope.bindings[name];
// not a constant
if (binding.kind !== "const" && binding.kind !== "module") continue;
for (var violation of (binding.constantViolations: Array)) {
throw violation.errorWithNode(messages.get("readOnly", name));
}
}
},
/**
* Look for constants.
* Turn them into `let` variables.
*/
VariableDeclaration(node) {
if (node.kind === "const") node.kind = "let";
}
};

View File

@@ -1,532 +0,0 @@
import * as messages from "babel-messages";
import * as t from "babel-types";
export var metadata = {
group: "builtin-advanced"
};
export var visitor = {
ForXStatement(node, parent, scope, file) {
var left = node.left;
if (t.isPattern(left)) {
// for ({ length: k } in { abc: 3 });
var temp = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration("var", [
t.variableDeclarator(temp)
]);
this.ensureBlock();
node.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(left, temp)
]));
return;
}
if (!t.isVariableDeclaration(left)) return;
var pattern = left.declarations[0].id;
if (!t.isPattern(pattern)) return;
var key = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration(left.kind, [
t.variableDeclarator(key, null)
]);
var nodes = [];
var destructuring = new DestructuringTransformer({
kind: left.kind,
file: file,
scope: scope,
nodes: nodes
});
destructuring.init(pattern, key);
this.ensureBlock();
var block = node.body;
block.body = nodes.concat(block.body);
},
Function(node, parent, scope, file) {
var hasDestructuring = false;
for (let pattern of (node.params: Array)) {
if (t.isPattern(pattern)) {
hasDestructuring = true;
break;
}
}
if (!hasDestructuring) return;
var nodes = [];
for (var i = 0; i < node.params.length; i++) {
let pattern = node.params[i];
if (!t.isPattern(pattern)) continue;
var ref = scope.generateUidIdentifier("ref");
if (t.isAssignmentPattern(pattern)) {
var _pattern = pattern;
pattern = pattern.left;
_pattern.left = ref;
} else {
node.params[i] = ref;
}
t.inherits(ref, pattern);
var destructuring = new DestructuringTransformer({
blockHoist: node.params.length - i + 1,
nodes: nodes,
scope: scope,
file: file,
kind: "let"
});
destructuring.init(pattern, ref);
}
this.ensureBlock();
var block = node.body;
block.body = nodes.concat(block.body);
},
CatchClause(node, parent, scope, file) {
var pattern = node.param;
if (!t.isPattern(pattern)) return;
var ref = scope.generateUidIdentifier("ref");
node.param = ref;
var nodes = [];
var destructuring = new DestructuringTransformer({
kind: "let",
file: file,
scope: scope,
nodes: nodes
});
destructuring.init(pattern, ref);
node.body.body = nodes.concat(node.body.body);
},
AssignmentExpression(node, parent, scope, file) {
if (!t.isPattern(node.left)) return;
var nodes = [];
var destructuring = new DestructuringTransformer({
operator: node.operator,
file: file,
scope: scope,
nodes: nodes
});
var ref;
if (this.isCompletionRecord() || !this.parentPath.isExpressionStatement()) {
ref = scope.generateUidIdentifierBasedOnNode(node.right, "ref");
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(ref, node.right)
]));
if (t.isArrayExpression(node.right)) {
destructuring.arrays[ref.name] = true;
}
}
destructuring.init(node.left, ref || node.right);
if (ref) {
nodes.push(t.expressionStatement(ref));
}
return nodes;
},
VariableDeclaration(node, parent, scope, file) {
if (t.isForXStatement(parent)) return;
if (!variableDeclarationHasPattern(node)) return;
var nodes = [];
var declar;
for (var i = 0; i < node.declarations.length; i++) {
declar = node.declarations[i];
var patternId = declar.init;
var pattern = declar.id;
var destructuring = new DestructuringTransformer({
nodes: nodes,
scope: scope,
kind: node.kind,
file: file
});
if (t.isPattern(pattern)) {
destructuring.init(pattern, patternId);
if (+i !== node.declarations.length - 1) {
// we aren't the last declarator so let's just make the
// last transformed node inherit from us
t.inherits(nodes[nodes.length - 1], declar);
}
} else {
nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar));
}
}
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
// https://github.com/babel/babel/issues/113
// for (let [x] = [0]; false;) {}
declar = null;
for (i = 0; i < nodes.length; i++) {
node = nodes[i];
declar = declar || t.variableDeclaration(node.kind, []);
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
throw file.errorWithNode(node, messages.get("invalidParentForThisNode"));
}
declar.declarations = declar.declarations.concat(node.declarations);
}
return declar;
}
return nodes;
}
};
/**
* Test if a VariableDeclaration's declarations contains any Patterns.
*/
function variableDeclarationHasPattern(node) {
for (var i = 0; i < node.declarations.length; i++) {
if (t.isPattern(node.declarations[i].id)) {
return true;
}
}
return false;
}
/**
* Test if an ArrayPattern's elements contain any RestElements.
*/
function hasRest(pattern) {
for (var i = 0; i < pattern.elements.length; i++) {
if (t.isRestElement(pattern.elements[i])) {
return true;
}
}
return false;
}
var arrayUnpackVisitor = {
ReferencedIdentifier(node, parent, scope, state) {
if (state.bindings[node.name]) {
state.deopt = true;
this.stop();
}
}
};
class DestructuringTransformer {
constructor(opts) {
this.blockHoist = opts.blockHoist;
this.operator = opts.operator;
this.arrays = {};
this.nodes = opts.nodes || [];
this.scope = opts.scope;
this.file = opts.file;
this.kind = opts.kind;
}
buildVariableAssignment(id, init) {
var op = this.operator;
if (t.isMemberExpression(id)) op = "=";
var node;
if (op) {
node = t.expressionStatement(t.assignmentExpression(op, id, init));
} else {
node = t.variableDeclaration(this.kind, [
t.variableDeclarator(id, init)
]);
}
node._blockHoist = this.blockHoist;
return node;
}
buildVariableDeclaration(id, init) {
var declar = t.variableDeclaration("var", [
t.variableDeclarator(id, init)
]);
declar._blockHoist = this.blockHoist;
return declar;
}
push(id, init) {
if (t.isObjectPattern(id)) {
this.pushObjectPattern(id, init);
} else if (t.isArrayPattern(id)) {
this.pushArrayPattern(id, init);
} else if (t.isAssignmentPattern(id)) {
this.pushAssignmentPattern(id, init);
} else {
this.nodes.push(this.buildVariableAssignment(id, init));
}
}
toArray(node, count) {
if (this.file.isLoose("es6.destructuring") || (t.isIdentifier(node) && this.arrays[node.name])) {
return node;
} else {
return this.scope.toArray(node, count);
}
}
pushAssignmentPattern(pattern, valueRef) {
// we need to assign the current value of the assignment to avoid evaluating
// it more than once
var tempValueRef = this.scope.generateUidIdentifierBasedOnNode(valueRef);
var declar = t.variableDeclaration("var", [
t.variableDeclarator(tempValueRef, valueRef)
]);
declar._blockHoist = this.blockHoist;
this.nodes.push(declar);
//
var tempConditional = t.conditionalExpression(
t.binaryExpression("===", tempValueRef, t.identifier("undefined")),
pattern.right,
tempValueRef
);
var left = pattern.left;
if (t.isPattern(left)) {
var tempValueDefault = t.expressionStatement(
t.assignmentExpression("=", tempValueRef, tempConditional)
);
tempValueDefault._blockHoist = this.blockHoist;
this.nodes.push(tempValueDefault);
this.push(left, tempValueRef);
} else {
this.nodes.push(this.buildVariableAssignment(left, tempConditional));
}
}
pushObjectSpread(pattern, objRef, spreadProp, spreadPropIndex) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i = 0; i < pattern.properties.length; i++) {
var prop = pattern.properties[i];
// we've exceeded the index of the spread property to all properties to the
// right need to be ignored
if (i >= spreadPropIndex) break;
// ignore other spread properties
if (t.isSpreadProperty(prop)) continue;
var key = prop.key;
if (t.isIdentifier(key) && !prop.computed) key = t.stringLiteral(prop.key.name);
keys.push(key);
}
keys = t.arrayExpression(keys);
//
var value = t.callExpression(this.file.addHelper("object-without-properties"), [objRef, keys]);
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
}
pushObjectProperty(prop, propRef) {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern = prop.value;
var objRef = t.memberExpression(propRef, prop.key, prop.computed);
if (t.isPattern(pattern)) {
this.push(pattern, objRef);
} else {
this.nodes.push(this.buildVariableAssignment(pattern, objRef));
}
}
pushObjectPattern(pattern, objRef) {
// https://github.com/babel/babel/issues/681
if (!pattern.properties.length) {
this.nodes.push(t.expressionStatement(
t.callExpression(this.file.addHelper("object-destructuring-empty"), [objRef])
));
}
// if we have more than one properties in this pattern and the objectRef is a
// member expression then we need to assign it to a temporary variable so it's
// only evaluated once
if (pattern.properties.length > 1 && !this.scope.isStatic(objRef)) {
var temp = this.scope.generateUidIdentifierBasedOnNode(objRef);
this.nodes.push(this.buildVariableDeclaration(temp, objRef));
objRef = temp;
}
//
for (var i = 0; i < pattern.properties.length; i++) {
var prop = pattern.properties[i];
if (t.isSpreadProperty(prop)) {
this.pushObjectSpread(pattern, objRef, prop, i);
} else {
this.pushObjectProperty(prop, objRef);
}
}
}
canUnpackArrayPattern(pattern, arr) {
// not an array so there's no way we can deal with this
if (!t.isArrayExpression(arr)) return false;
// pattern has less elements than the array and doesn't have a rest so some
// elements wont be evaluated
if (pattern.elements.length > arr.elements.length) return;
if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) return false;
for (let elem of (pattern.elements: Array)) {
// deopt on holes
if (!elem) return false;
// deopt on member expressions as they may be included in the RHS
if (t.isMemberExpression(elem)) return false;
}
for (let elem of (arr.elements: Array)) {
// deopt on spread elements
if (t.isSpreadElement(elem)) return false;
}
// deopt on reference to left side identifiers
var bindings = t.getBindingIdentifiers(pattern);
var state = { deopt: false, bindings };
this.scope.traverse(arr, arrayUnpackVisitor, state);
return !state.deopt;
}
pushUnpackedArrayPattern(pattern, arr) {
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
if (t.isRestElement(elem)) {
this.push(elem.argument, t.arrayExpression(arr.elements.slice(i)));
} else {
this.push(elem, arr.elements[i]);
}
}
}
pushArrayPattern(pattern, arrayRef) {
if (!pattern.elements) return;
// optimise basic array destructuring of an array expression
//
// we can't do this to a pattern of unequal size to it's right hand
// array expression as then there will be values that wont be evaluated
//
// eg: var [a, b] = [1, 2];
if (this.canUnpackArrayPattern(pattern, arrayRef)) {
return this.pushUnpackedArrayPattern(pattern, arrayRef);
}
// if we have a rest then we need all the elements so don't tell
// `scope.toArray` to only get a certain amount
var count = !hasRest(pattern) && pattern.elements.length;
// so we need to ensure that the `arrayRef` is an array, `scope.toArray` will
// return a locally bound identifier if it's been inferred to be an array,
// otherwise it'll be a call to a helper that will ensure it's one
var toArray = this.toArray(arrayRef, count);
if (t.isIdentifier(toArray)) {
// we've been given an identifier so it must have been inferred to be an
// array
arrayRef = toArray;
} else {
arrayRef = this.scope.generateUidIdentifierBasedOnNode(arrayRef);
this.arrays[arrayRef.name] = true;
this.nodes.push(this.buildVariableDeclaration(arrayRef, toArray));
}
//
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
// hole
if (!elem) continue;
var elemRef;
if (t.isRestElement(elem)) {
elemRef = this.toArray(arrayRef);
if (i > 0) {
elemRef = t.callExpression(t.memberExpression(elemRef, t.identifier("slice")), [t.numberLiteral(i)]);
}
// set the element to the rest element argument since we've dealt with it
// being a rest already
elem = elem.argument;
} else {
elemRef = t.memberExpression(arrayRef, t.numberLiteral(i), true);
}
this.push(elem, elemRef);
}
}
init(pattern, ref) {
// trying to destructure a value that we can't evaluate more than once so we
// need to save it to a variable
if (!t.isArrayExpression(ref) && !t.isMemberExpression(ref)) {
var memo = this.scope.maybeGenerateMemoised(ref, true);
if (memo) {
this.nodes.push(this.buildVariableDeclaration(memo, ref));
ref = memo;
}
}
//
this.push(pattern, ref);
return this.nodes;
}
}

View File

@@ -1,19 +0,0 @@
export var metadata = {
group: "builtin-pre"
};
export var visitor = {
NumberLiteral(node) {
// number octal like 0b10 or 0o70
if (/^0[ob]/i.test(node.raw)) {
node.raw = undefined;
}
},
StringLiteral(node) {
// unicode escape
if (/\\[u]/gi.test(node.raw)) {
node.raw = undefined;
}
}
};

View File

@@ -78,9 +78,9 @@ export var visitor = {
param.traverse(iifeVisitor, state);
}
if (file.transformers["es6.spec.blockScoping"].canTransform() && param.isIdentifier()) {
pushDefNode(param.node, t.identifier("undefined"), i);
}
//if (file.transformers["es6.spec.blockScoping"].canTransform() && param.isIdentifier()) {
// pushDefNode(param.node, t.identifier("undefined"), i);
//}
continue;
}

View File

@@ -1,106 +0,0 @@
import * as t from "babel-types";
function loose(node, body, objId) {
for (var prop of (node.properties: Array)) {
body.push(t.expressionStatement(
t.assignmentExpression(
"=",
t.memberExpression(objId, prop.key, prop.computed || t.isLiteral(prop.key)),
prop.value
)
));
}
}
function spec(node, body, objId, initProps, file) {
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
// otherwise use Object.defineProperty
for (let prop of (node.properties: Array)) {
// this wont work with Object.defineProperty
if (t.isLiteral(t.toComputedKey(prop), { value: "__proto__" })) {
initProps.push(prop);
continue;
}
let key = prop.key;
if (t.isIdentifier(key) && !prop.computed) {
key = t.stringLiteral(key.name);
}
var bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
body.push(t.expressionStatement(bodyNode));
}
// only one node and it's a Object.defineProperty that returns the object
if (body.length === 1) {
var first = body[0].expression;
if (t.isCallExpression(first)) {
first.arguments[0] = t.objectExpression(initProps);
return first;
}
}
}
export var visitor = {
ObjectExpression: {
exit(node, parent, scope, file) {
var hasComputed = false;
for (let prop of (node.properties: Array)) {
hasComputed = t.isProperty(prop, { computed: true, kind: "init" });
if (hasComputed) break;
}
if (!hasComputed) return;
// put all getters/setters into the first object expression as well as all initialisers up
// to the first computed property
var initProps = [];
var stopInits = false;
node.properties = node.properties.filter(function (prop) {
if (prop.computed) {
stopInits = true;
}
if (prop.kind !== "init" || !stopInits) {
initProps.push(prop);
return false;
} else {
return true;
}
});
//
var objId = scope.generateUidIdentifierBasedOnNode(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;
}
}
};

View File

@@ -1,15 +0,0 @@
/**
* [Please add a description.]
*/
export var visitor = {
Property(node) {
if (node.method) {
node.method = false;
}
if (node.shorthand) {
node.shorthand = false;
}
}
};

View File

@@ -1,124 +0,0 @@
import * as t from "babel-types";
function getSpreadLiteral(spread, scope) {
if (scope.hub.file.isLoose("es6.spread") && !t.isIdentifier(spread.argument, { name: "arguments" })) {
return spread.argument;
} else {
return scope.toArray(spread.argument, true);
}
}
function hasSpread(nodes) {
for (var i = 0; i < nodes.length; i++) {
if (t.isSpreadElement(nodes[i])) {
return true;
}
}
return false;
}
function build(props, scope) {
var nodes = [];
var _props = [];
var push = function () {
if (!_props.length) return;
nodes.push(t.arrayExpression(_props));
_props = [];
};
for (var i = 0; i < props.length; i++) {
var prop = props[i];
if (t.isSpreadElement(prop)) {
push();
nodes.push(getSpreadLiteral(prop, scope));
} else {
_props.push(prop);
}
}
push();
return nodes;
}
export var metadata = {
group: "builtin-advanced"
};
export var visitor = {
ArrayExpression(node, parent, scope) {
var elements = node.elements;
if (!hasSpread(elements)) return;
var nodes = build(elements, scope);
var first = nodes.shift();
if (!t.isArrayExpression(first)) {
nodes.unshift(first);
first = t.arrayExpression([]);
}
return t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes);
},
CallExpression(node, parent, scope) {
var args = node.arguments;
if (!hasSpread(args)) return;
var contextLiteral = t.identifier("undefined");
node.arguments = [];
var nodes;
if (args.length === 1 && args[0].argument.name === "arguments") {
nodes = [args[0].argument];
} else {
nodes = build(args, scope);
}
var first = nodes.shift();
if (nodes.length) {
node.arguments.push(t.callExpression(t.memberExpression(first, t.identifier("concat")), nodes));
} else {
node.arguments.push(first);
}
var callee = node.callee;
if (this.get("callee").isMemberExpression()) {
var temp = scope.maybeGenerateMemoised(callee.object);
if (temp) {
callee.object = t.assignmentExpression("=", temp, callee.object);
contextLiteral = temp;
} else {
contextLiteral = callee.object;
}
t.appendToMemberExpression(callee, t.identifier("apply"));
} else {
node.callee = t.memberExpression(node.callee, t.identifier("apply"));
}
node.arguments.unshift(contextLiteral);
},
NewExpression(node, parent, scope, file) {
var args = node.arguments;
if (!hasSpread(args)) return;
var nodes = build(args, scope);
var context = t.arrayExpression([t.nullLiteral()]);
args = t.callExpression(t.memberExpression(context, t.identifier("concat")), nodes);
return t.newExpression(
t.callExpression(
t.memberExpression(file.addHelper("bind"), t.identifier("apply")),
[node.callee, args]
),
[]
);
}
};

View File

@@ -1,87 +0,0 @@
/* eslint no-unused-vars: 0 */
import * as t from "babel-types";
export var metadata = {
group: "builtin-pre"
};
function isString(node) {
return t.isLiteral(node) && typeof node.value === "string";
}
function buildBinaryExpression(left, right) {
var node = t.binaryExpression("+", left, right);
node._templateLiteralProduced = true;
return node;
}
function crawl(path) {
if (path.is("_templateLiteralProduced")) {
crawl(path.get("left"));
crawl(path.get("right"));
} else if (!path.isBaseType("string") && !path.isBaseType("number")) {
path.replaceWith(t.callExpression(t.identifier("String"), [path.node]));
}
}
export var visitor = {
TaggedTemplateExpression(node, parent, scope, file) {
var quasi = node.quasi;
var args = [];
var strings = [];
var raw = [];
for (var elem of (quasi.quasis: Array)) {
strings.push(t.stringLiteral(elem.value.cooked));
raw.push(t.stringLiteral(elem.value.raw));
}
strings = t.arrayExpression(strings);
raw = t.arrayExpression(raw);
var templateName = "tagged-template-literal";
if (file.isLoose("es6.templateLiterals")) templateName += "-loose";
var templateObject = file.addTemplateObject(templateName, strings, raw);
args.push(templateObject);
args = args.concat(quasi.expressions);
return t.callExpression(node.tag, args);
},
TemplateLiteral(node, parent, scope, file) {
var nodes = [];
for (let elem of (node.quasis: Array)) {
nodes.push(t.stringLiteral(elem.value.cooked));
var expr = node.expressions.shift();
if (expr) nodes.push(expr);
}
// filter out empty string literals
nodes = nodes.filter(n => !t.isLiteral(n, { value: "" }));
// since `+` is left-to-right associative
// ensure the first node is a string if first/second isn't
if (!isString(nodes[0]) && !isString(nodes[1])) {
nodes.unshift(t.stringLiteral(""));
}
if (nodes.length > 1) {
var root = buildBinaryExpression(nodes.shift(), nodes.shift());
for (let node of (nodes: Array)) {
root = buildBinaryExpression(root, node);
}
this.replaceWith(root);
//crawl(this);
} else {
return nodes[0];
}
}
};

View File

@@ -28,9 +28,8 @@ export default {
"es7.trailingFunctionCommas": require("./es7/trailing-function-commas"),
"es7.asyncFunctions": require("./es7/async-functions"),
"es7.decorators": require("./es7/decorators"),
"validation.react": require("./validation/react"),
"es6.arrowFunctions": require("./es6/arrow-functions"),
"spec.blockScopedFunctions": require("./spec/block-scoped-functions"),
"spec.blockScopedFunctions": require("babel-plugin-es2015-block-scoped-functions"),
"optimisation.react.constantElements": require("babel-plugin-react-constant-elements"),
"optimisation.react.inlineElements": require("./optimisation/react.inline-elements"),
"es7.comprehensions": require("./es7/comprehensions"),
@@ -41,13 +40,13 @@ export default {
"es7.objectRestSpread": require("./es7/object-rest-spread"),
"es7.exponentiationOperator": require("./es7/exponentiation-operator"),
"es5.properties.mutators": require("./es5/properties.mutators"),
"es6.properties.shorthand": require("./es6/properties.shorthand"),
"es6.properties.computed": require("./es6/properties.computed"),
"es6.properties.shorthand": require("babel-plugin-es2015-shorthand-properties"),
"es6.properties.computed": require("babel-plugin-es2015-computed-properties"),
"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"),
"es6.forOf": require("babel-plugin-es2015-for-of"),
"es6.regex.sticky": require("babel-plugin-es2015-sticky-regex"),
"es6.regex.unicode": require("babel-plugin-es2015-unicode-regex"),
"es6.constants": require("babel-plugin-es2015-constants"),
"es7.exportExtensions": require("./es7/export-extensions"),
"spec.protoToAssign": require("babel-plugin-proto-to-assign"),
"es7.doExpressions": require("./es7/do-expressions"),
@@ -56,10 +55,10 @@ export default {
"spec.undefinedToVoid": require("babel-plugin-undefined-to-void"),
//- builtin-advanced
"es6.spread": require("./es6/spread"),
"es6.parameters": require("./es6/parameters"),
"es6.destructuring": require("./es6/destructuring"),
"es6.blockScoping": require("./es6/block-scoping"),
"es6.spread": require("babel-plugin-es2015-spread"),
"es6.parameters": require("babel-plugin-es2015-parameters"),
"es6.destructuring": require("babel-plugin-es2015-destructuring"),
"es6.blockScoping": require("babel-plugin-es2015-block-scoping"),
reactCompat: require("./other/react-compat"),
react: require("./other/react"),
regenerator: require("./other/regenerator"),
@@ -76,14 +75,14 @@ export default {
// 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"),
"es6.tailCall": require("babel-plugin-es2015-tail-call"),
_shadowFunctions: require("./internal/shadow-functions"),
"es3.propertyLiterals": require("./es3/property-literals"),
"es3.memberExpressionLiterals": require("./es3/member-expression-literals"),
"es3.propertyLiterals": require("babel-plugin-es3-property-literals"),
"es3.memberExpressionLiterals": require("babel-plugin-es3-member-expression-literals"),
"minification.memberExpressionLiterals": require("babel-plugin-member-expression-literals"),
"minification.propertyLiterals": require("babel-plugin-property-literals"),
_blockHoist: require("./internal/block-hoist"),
jscript: require("babel-plugin-jscript"),
flow: require("./other/flow"),
flow: require("babel-plugin-flow-strip-types"),
"optimisation.modules.system": require("./optimisation/modules.system"),
};

View File

@@ -1,48 +0,0 @@
import * as t from "babel-types";
export var metadata = {
group: "builtin-trailing"
};
const FLOW_DIRECTIVE = "@flow";
export var visitor = {
Program(node, parent, scope, file) {
for (var comment of (file.ast.comments: Array)) {
if (comment.value.indexOf(FLOW_DIRECTIVE) >= 0) {
// remove flow directive
comment.value = comment.value.replace(FLOW_DIRECTIVE, "");
// remove the comment completely if it only consists of whitespace and/or stars
if (!comment.value.replace(/\*/g, "").trim()) comment._displayed = true;
}
}
},
Flow() {
this.dangerouslyRemove();
},
ClassProperty(node) {
node.typeAnnotation = null;
if (!node.value) this.dangerouslyRemove();
},
Class(node) {
node.implements = null;
},
Function(node) {
for (var i = 0; i < node.params.length; i++) {
var param = node.params[i];
param.optional = false;
}
},
TypeCastExpression(node) {
do {
node = node.expression;
} while(t.isTypeCastExpression(node));
return node;
}
};

View File

@@ -1,38 +0,0 @@
import * as t from "babel-types";
function statementList(key, path) {
var paths = path.get(key);
for (var i = 0; i < paths.length; i++) {
let path = paths[i];
var func = path.node;
if (!t.isFunctionDeclaration(func)) continue;
var declar = t.variableDeclaration("let", [
t.variableDeclarator(func.id, t.toExpression(func))
]);
// hoist it up above everything else
declar._blockHoist = 2;
// todo: name this
func.id = null;
path.replaceWith(declar);
}
}
export var visitor = {
BlockStatement(node, parent) {
if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) {
return;
}
statementList("body", this);
},
SwitchCase() {
statementList("consequent", this);
}
};

View File

@@ -1,26 +0,0 @@
import * as messages from "babel-messages";
import * as t from "babel-types";
// check if the input Literal `source` is an alternate casing of "react"
function check(source, file) {
if (t.isLiteral(source)) {
var name = source.value;
var lower = name.toLowerCase();
if (lower === "react" && name !== lower) {
throw file.errorWithNode(source, messages.get("didYouMean", "react"));
}
}
}
export var visitor = {
CallExpression(node, parent, scope, file) {
if (this.get("callee").isIdentifier({ name: "require" }) && node.arguments.length === 1) {
check(node.arguments[0], file);
}
},
ModuleDeclaration(node, parent, scope, file) {
check(node.source, file);
}
};

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-async-functions
Compile async functions to ES5
## Installation
```sh
$ npm install babel-plugin-async-functions
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["async-functions"]
}
```
### Via CLI
```sh
$ babel --plugins async-functions script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["async-functions"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-async-functions",
"version": "1.0.0",
"description": "Compile async functions to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-async-to-bluebird-coroutines
Turn async functions into a Bluebird coroutine
## Installation
```sh
$ npm install babel-plugin-async-to-bluebird-coroutines
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["async-to-bluebird-coroutines"]
}
```
### Via CLI
```sh
$ babel --plugins async-to-bluebird-coroutines script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["async-to-bluebird-coroutines"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-async-to-bluebird-coroutines",
"version": "1.0.0",
"description": "Turn async functions into a Bluebird coroutine",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-async-to-generator
Turn async functions into ES2015 generators
## Installation
```sh
$ npm install babel-plugin-async-to-generator
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["async-to-generator"]
}
```
### Via CLI
```sh
$ babel --plugins async-to-generator script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["async-to-generator"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-async-to-generator",
"version": "1.0.0",
"description": "Turn async functions into ES2015 generators",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-class-properties
## Installation
```sh
$ npm install babel-plugin-class-properties
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["class-properties"]
}
```
### Via CLI
```sh
$ babel --plugins class-properties script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["class-properties"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-class-properties",
"version": "1.0.0",
"description": "",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-comprehensions
Compile array and generator comprehensions to ES5
## Installation
```sh
$ npm install babel-plugin-comprehensions
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["comprehensions"]
}
```
### Via CLI
```sh
$ babel --plugins comprehensions script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["comprehensions"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-comprehensions",
"version": "1.0.0",
"description": "Compile array and generator comprehensions to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -2,17 +2,9 @@
"name": "babel-plugin-constant-folding",
"version": "1.0.1",
"description": "Compile static constants (ie. code that we can statically determine to be constant at runtime)",
"repository": "babel-plugins/babel-plugin-constant-folding",
"repository": "babel/babelbabel-plugin-constant-folding",
"license": "MIT",
"main": "lib/index.js",
"devDependencies": {
"babel": "^5.6.0"
},
"scripts": {
"build": "babel-plugin build",
"push": "babel-plugin publish",
"test": "babel-plugin test"
},
"keywords": [
"babel-plugin"
]

View File

@@ -1,10 +1,10 @@
export default function ({ Plugin, types: t }) {
return new Plugin("constant-folding", {
return {
metadata: {
group: "builtin-prepass",
experimental: true
},
visitor: {
AssignmentExpression() {
var left = this.get("left");
@@ -70,5 +70,5 @@ export default function ({ Plugin, types: t }) {
}
}
}
});
};
}

View File

@@ -2,17 +2,9 @@
"name": "babel-plugin-dead-code-elimination",
"version": "1.0.2",
"description": "Eliminate dead code",
"repository": "babel-plugins/babel-plugin-dead-code-elimination",
"repository": "babel/babelbabel-plugin-dead-code-elimination",
"license": "MIT",
"main": "lib/index.js",
"devDependencies": {
"babel": "^5.6.0"
},
"scripts": {
"build": "babel-plugin build",
"push": "babel-plugin publish",
"test": "babel-plugin test"
},
"keywords": [
"babel-plugin"
]

View File

@@ -146,12 +146,12 @@ export default function ({ Plugin, types: t }) {
}
};
return new Plugin("dead-code-elimination", {
return {
metadata: {
group: "builtin-pre",
experimental: true
},
visitor
});
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-decorators
Compile class and object decorators to ES5
## Installation
```sh
$ npm install babel-plugin-decorators
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["decorators"]
}
```
### Via CLI
```sh
$ babel --plugins decorators script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["decorators"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-decorators",
"version": "1.0.0",
"description": "Compile class and object decorators to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-do-expressions
Compile do expressions to ES5
## Installation
```sh
$ npm install babel-plugin-do-expressions
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["do-expressions"]
}
```
### Via CLI
```sh
$ babel --plugins do-expressions script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["do-expressions"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-do-expressions",
"version": "1.0.0",
"description": "Compile do expressions to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-arrow-functions
Compile ES2015 arrow functions to ES5
## Installation
```sh
$ npm install babel-plugin-es2015-arrow-functions
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-arrow-functions"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-arrow-functions script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-arrow-functions"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-arrow-functions",
"version": "1.0.0",
"description": "Compile ES2015 arrow functions to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,12 @@
export default function ({ types: t }) {
return {
visitor: {
ArrowFunctionExpression(node) {
this.ensureBlock();
node.expression = false;
node.type = "FunctionExpression";
node.shadow = node.shadow || true;
}
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-block-scoped-functions
Babel plugin to ensure function declarations at the block level are block scoped.
## Installation
```sh
$ npm install babel-plugin-es2015-block-scoped-functions
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-block-scoped-functions"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-block-scoped-functions script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-block-scoped-functions"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-block-scoped-functions",
"version": "1.0.4",
"description": "Babel plugin to ensure function declarations at the block level are block scoped",
"repository": "babel/babelbabel-plugin-jscript",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,40 @@
export default function ({ Plugin, types: t }) {
function statementList(key, path) {
var paths = path.get(key);
for (var i = 0; i < paths.length; i++) {
let path = paths[i];
var func = path.node;
if (!t.isFunctionDeclaration(func)) continue;
var declar = t.variableDeclaration("let", [
t.variableDeclarator(func.id, t.toExpression(func))
]);
// hoist it up above everything else
declar._blockHoist = 2;
// todo: name this
func.id = null;
path.replaceWith(declar);
}
}
return {
visitor: {
BlockStatement(node, parent) {
if ((t.isFunction(parent) && parent.body === node) || t.isExportDeclaration(parent)) {
return;
}
statementList("body", this);
},
SwitchCase() {
statementList("consequent", this);
}
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-block-scoping
Compile ES2015 block scoping (const and let) to ES5
## Installation
```sh
$ npm install babel-plugin-es2015-block-scoping
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-block-scoping"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-block-scoping script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-block-scoping"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-block-scoping",
"version": "1.0.0",
"description": "Compile ES2015 block scoping (const and let) to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-classes
Compile ES2015 classes to ES5
## Installation
```sh
$ npm install babel-plugin-es2015-classes
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-classes"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-classes script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-classes"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-classes",
"version": "1.0.0",
"description": "Compile ES2015 classes to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-computed-properties
Compile ES2015 computed properties to ES5
## Installation
```sh
$ npm install babel-plugin-es2015-computed-properties
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-computed-properties"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-computed-properties script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-computed-properties"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-computed-properties",
"version": "1.0.0",
"description": "Compile ES2015 computed properties to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,108 @@
export default function ({ types: t }) {
function loose(node, body, objId) {
for (var prop of (node.properties: Array)) {
body.push(t.expressionStatement(
t.assignmentExpression(
"=",
t.memberExpression(objId, prop.key, prop.computed || t.isLiteral(prop.key)),
prop.value
)
));
}
}
function spec(node, body, objId, initProps, file) {
// add a simple assignment for all Symbol member expressions due to symbol polyfill limitations
// otherwise use Object.defineProperty
for (let prop of (node.properties: Array)) {
// this wont work with Object.defineProperty
if (t.isLiteral(t.toComputedKey(prop), { value: "__proto__" })) {
initProps.push(prop);
continue;
}
let key = prop.key;
if (t.isIdentifier(key) && !prop.computed) {
key = t.stringLiteral(key.name);
}
var bodyNode = t.callExpression(file.addHelper("define-property"), [objId, key, prop.value]);
body.push(t.expressionStatement(bodyNode));
}
// only one node and it's a Object.defineProperty that returns the object
if (body.length === 1) {
var first = body[0].expression;
if (t.isCallExpression(first)) {
first.arguments[0] = t.objectExpression(initProps);
return first;
}
}
}
return {
visitor: {
ObjectExpression: {
exit(node, parent, scope, file) {
var hasComputed = false;
for (let prop of (node.properties: Array)) {
hasComputed = t.isProperty(prop, { computed: true, kind: "init" });
if (hasComputed) break;
}
if (!hasComputed) return;
// put all getters/setters into the first object expression as well as all initialisers up
// to the first computed property
var initProps = [];
var stopInits = false;
node.properties = node.properties.filter(function (prop) {
if (prop.computed) {
stopInits = true;
}
if (prop.kind !== "init" || !stopInits) {
initProps.push(prop);
return false;
} else {
return true;
}
});
//
var objId = scope.generateUidIdentifierBasedOnNode(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;
}
}
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-constants
Compile ES2015 constants to ES5
## Installation
```sh
$ npm install babel-plugin-es2015-constants
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-constants"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-constants script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-constants"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-constants",
"version": "1.0.0",
"description": "Compile ES2015 constants to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,22 @@
export default function ({ messages }) {
return {
visitor: {
Scope(node, parent, scope) {
for (var name in scope.bindings) {
var binding = scope.bindings[name];
// not a constant
if (binding.kind !== "const" && binding.kind !== "module") continue;
for (var violation of (binding.constantViolations: Array)) {
throw violation.errorWithNode(messages.get("readOnly", name));
}
}
},
VariableDeclaration(node) {
if (node.kind === "const") node.kind = "let";
}
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-destructuring
Compile ES2015 destructuring to ES5
## Installation
```sh
$ npm install babel-plugin-es2015-destructuring
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-destructuring"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-destructuring script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-destructuring"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-destructuring",
"version": "1.0.0",
"description": "Compile ES2015 destructuring to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,535 @@
export default function ({ types: t, messages }) {
/**
* Test if a VariableDeclaration's declarations contains any Patterns.
*/
function variableDeclarationHasPattern(node) {
for (var i = 0; i < node.declarations.length; i++) {
if (t.isPattern(node.declarations[i].id)) {
return true;
}
}
return false;
}
/**
* Test if an ArrayPattern's elements contain any RestElements.
*/
function hasRest(pattern) {
for (var i = 0; i < pattern.elements.length; i++) {
if (t.isRestElement(pattern.elements[i])) {
return true;
}
}
return false;
}
var arrayUnpackVisitor = {
ReferencedIdentifier(node, parent, scope, state) {
if (state.bindings[node.name]) {
state.deopt = true;
this.stop();
}
}
};
class DestructuringTransformer {
constructor(opts) {
this.blockHoist = opts.blockHoist;
this.operator = opts.operator;
this.arrays = {};
this.nodes = opts.nodes || [];
this.scope = opts.scope;
this.file = opts.file;
this.kind = opts.kind;
}
buildVariableAssignment(id, init) {
var op = this.operator;
if (t.isMemberExpression(id)) op = "=";
var node;
if (op) {
node = t.expressionStatement(t.assignmentExpression(op, id, init));
} else {
node = t.variableDeclaration(this.kind, [
t.variableDeclarator(id, init)
]);
}
node._blockHoist = this.blockHoist;
return node;
}
buildVariableDeclaration(id, init) {
var declar = t.variableDeclaration("var", [
t.variableDeclarator(id, init)
]);
declar._blockHoist = this.blockHoist;
return declar;
}
push(id, init) {
if (t.isObjectPattern(id)) {
this.pushObjectPattern(id, init);
} else if (t.isArrayPattern(id)) {
this.pushArrayPattern(id, init);
} else if (t.isAssignmentPattern(id)) {
this.pushAssignmentPattern(id, init);
} else {
this.nodes.push(this.buildVariableAssignment(id, init));
}
}
toArray(node, count) {
if (this.file.isLoose("es6.destructuring") || (t.isIdentifier(node) && this.arrays[node.name])) {
return node;
} else {
return this.scope.toArray(node, count);
}
}
pushAssignmentPattern(pattern, valueRef) {
// we need to assign the current value of the assignment to avoid evaluating
// it more than once
var tempValueRef = this.scope.generateUidIdentifierBasedOnNode(valueRef);
var declar = t.variableDeclaration("var", [
t.variableDeclarator(tempValueRef, valueRef)
]);
declar._blockHoist = this.blockHoist;
this.nodes.push(declar);
//
var tempConditional = t.conditionalExpression(
t.binaryExpression("===", tempValueRef, t.identifier("undefined")),
pattern.right,
tempValueRef
);
var left = pattern.left;
if (t.isPattern(left)) {
var tempValueDefault = t.expressionStatement(
t.assignmentExpression("=", tempValueRef, tempConditional)
);
tempValueDefault._blockHoist = this.blockHoist;
this.nodes.push(tempValueDefault);
this.push(left, tempValueRef);
} else {
this.nodes.push(this.buildVariableAssignment(left, tempConditional));
}
}
pushObjectSpread(pattern, objRef, spreadProp, spreadPropIndex) {
// get all the keys that appear in this object before the current spread
var keys = [];
for (var i = 0; i < pattern.properties.length; i++) {
var prop = pattern.properties[i];
// we've exceeded the index of the spread property to all properties to the
// right need to be ignored
if (i >= spreadPropIndex) break;
// ignore other spread properties
if (t.isSpreadProperty(prop)) continue;
var key = prop.key;
if (t.isIdentifier(key) && !prop.computed) key = t.stringLiteral(prop.key.name);
keys.push(key);
}
keys = t.arrayExpression(keys);
//
var value = t.callExpression(this.file.addHelper("object-without-properties"), [objRef, keys]);
this.nodes.push(this.buildVariableAssignment(spreadProp.argument, value));
}
pushObjectProperty(prop, propRef) {
if (t.isLiteral(prop.key)) prop.computed = true;
var pattern = prop.value;
var objRef = t.memberExpression(propRef, prop.key, prop.computed);
if (t.isPattern(pattern)) {
this.push(pattern, objRef);
} else {
this.nodes.push(this.buildVariableAssignment(pattern, objRef));
}
}
pushObjectPattern(pattern, objRef) {
// https://github.com/babel/babel/issues/681
if (!pattern.properties.length) {
this.nodes.push(t.expressionStatement(
t.callExpression(this.file.addHelper("object-destructuring-empty"), [objRef])
));
}
// if we have more than one properties in this pattern and the objectRef is a
// member expression then we need to assign it to a temporary variable so it's
// only evaluated once
if (pattern.properties.length > 1 && !this.scope.isStatic(objRef)) {
var temp = this.scope.generateUidIdentifierBasedOnNode(objRef);
this.nodes.push(this.buildVariableDeclaration(temp, objRef));
objRef = temp;
}
//
for (var i = 0; i < pattern.properties.length; i++) {
var prop = pattern.properties[i];
if (t.isSpreadProperty(prop)) {
this.pushObjectSpread(pattern, objRef, prop, i);
} else {
this.pushObjectProperty(prop, objRef);
}
}
}
canUnpackArrayPattern(pattern, arr) {
// not an array so there's no way we can deal with this
if (!t.isArrayExpression(arr)) return false;
// pattern has less elements than the array and doesn't have a rest so some
// elements wont be evaluated
if (pattern.elements.length > arr.elements.length) return;
if (pattern.elements.length < arr.elements.length && !hasRest(pattern)) return false;
for (let elem of (pattern.elements: Array)) {
// deopt on holes
if (!elem) return false;
// deopt on member expressions as they may be included in the RHS
if (t.isMemberExpression(elem)) return false;
}
for (let elem of (arr.elements: Array)) {
// deopt on spread elements
if (t.isSpreadElement(elem)) return false;
}
// deopt on reference to left side identifiers
var bindings = t.getBindingIdentifiers(pattern);
var state = { deopt: false, bindings };
this.scope.traverse(arr, arrayUnpackVisitor, state);
return !state.deopt;
}
pushUnpackedArrayPattern(pattern, arr) {
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
if (t.isRestElement(elem)) {
this.push(elem.argument, t.arrayExpression(arr.elements.slice(i)));
} else {
this.push(elem, arr.elements[i]);
}
}
}
pushArrayPattern(pattern, arrayRef) {
if (!pattern.elements) return;
// optimise basic array destructuring of an array expression
//
// we can't do this to a pattern of unequal size to it's right hand
// array expression as then there will be values that wont be evaluated
//
// eg: var [a, b] = [1, 2];
if (this.canUnpackArrayPattern(pattern, arrayRef)) {
return this.pushUnpackedArrayPattern(pattern, arrayRef);
}
// if we have a rest then we need all the elements so don't tell
// `scope.toArray` to only get a certain amount
var count = !hasRest(pattern) && pattern.elements.length;
// so we need to ensure that the `arrayRef` is an array, `scope.toArray` will
// return a locally bound identifier if it's been inferred to be an array,
// otherwise it'll be a call to a helper that will ensure it's one
var toArray = this.toArray(arrayRef, count);
if (t.isIdentifier(toArray)) {
// we've been given an identifier so it must have been inferred to be an
// array
arrayRef = toArray;
} else {
arrayRef = this.scope.generateUidIdentifierBasedOnNode(arrayRef);
this.arrays[arrayRef.name] = true;
this.nodes.push(this.buildVariableDeclaration(arrayRef, toArray));
}
//
for (var i = 0; i < pattern.elements.length; i++) {
var elem = pattern.elements[i];
// hole
if (!elem) continue;
var elemRef;
if (t.isRestElement(elem)) {
elemRef = this.toArray(arrayRef);
if (i > 0) {
elemRef = t.callExpression(t.memberExpression(elemRef, t.identifier("slice")), [t.numberLiteral(i)]);
}
// set the element to the rest element argument since we've dealt with it
// being a rest already
elem = elem.argument;
} else {
elemRef = t.memberExpression(arrayRef, t.numberLiteral(i), true);
}
this.push(elem, elemRef);
}
}
init(pattern, ref) {
// trying to destructure a value that we can't evaluate more than once so we
// need to save it to a variable
if (!t.isArrayExpression(ref) && !t.isMemberExpression(ref)) {
var memo = this.scope.maybeGenerateMemoised(ref, true);
if (memo) {
this.nodes.push(this.buildVariableDeclaration(memo, ref));
ref = memo;
}
}
//
this.push(pattern, ref);
return this.nodes;
}
}
return {
metadata: {
group: "builtin-advanced"
},
visitor: {
ForXStatement(node, parent, scope, file) {
var left = node.left;
if (t.isPattern(left)) {
// for ({ length: k } in { abc: 3 });
var temp = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration("var", [
t.variableDeclarator(temp)
]);
this.ensureBlock();
node.body.body.unshift(t.variableDeclaration("var", [
t.variableDeclarator(left, temp)
]));
return;
}
if (!t.isVariableDeclaration(left)) return;
var pattern = left.declarations[0].id;
if (!t.isPattern(pattern)) return;
var key = scope.generateUidIdentifier("ref");
node.left = t.variableDeclaration(left.kind, [
t.variableDeclarator(key, null)
]);
var nodes = [];
var destructuring = new DestructuringTransformer({
kind: left.kind,
file: file,
scope: scope,
nodes: nodes
});
destructuring.init(pattern, key);
this.ensureBlock();
var block = node.body;
block.body = nodes.concat(block.body);
},
Function(node, parent, scope, file) {
var hasDestructuring = false;
for (let pattern of (node.params: Array)) {
if (t.isPattern(pattern)) {
hasDestructuring = true;
break;
}
}
if (!hasDestructuring) return;
var nodes = [];
for (var i = 0; i < node.params.length; i++) {
let pattern = node.params[i];
if (!t.isPattern(pattern)) continue;
var ref = scope.generateUidIdentifier("ref");
if (t.isAssignmentPattern(pattern)) {
var _pattern = pattern;
pattern = pattern.left;
_pattern.left = ref;
} else {
node.params[i] = ref;
}
t.inherits(ref, pattern);
var destructuring = new DestructuringTransformer({
blockHoist: node.params.length - i + 1,
nodes: nodes,
scope: scope,
file: file,
kind: "let"
});
destructuring.init(pattern, ref);
}
this.ensureBlock();
var block = node.body;
block.body = nodes.concat(block.body);
},
CatchClause(node, parent, scope, file) {
var pattern = node.param;
if (!t.isPattern(pattern)) return;
var ref = scope.generateUidIdentifier("ref");
node.param = ref;
var nodes = [];
var destructuring = new DestructuringTransformer({
kind: "let",
file: file,
scope: scope,
nodes: nodes
});
destructuring.init(pattern, ref);
node.body.body = nodes.concat(node.body.body);
},
AssignmentExpression(node, parent, scope, file) {
if (!t.isPattern(node.left)) return;
var nodes = [];
var destructuring = new DestructuringTransformer({
operator: node.operator,
file: file,
scope: scope,
nodes: nodes
});
var ref;
if (this.isCompletionRecord() || !this.parentPath.isExpressionStatement()) {
ref = scope.generateUidIdentifierBasedOnNode(node.right, "ref");
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(ref, node.right)
]));
if (t.isArrayExpression(node.right)) {
destructuring.arrays[ref.name] = true;
}
}
destructuring.init(node.left, ref || node.right);
if (ref) {
nodes.push(t.expressionStatement(ref));
}
return nodes;
},
VariableDeclaration(node, parent, scope, file) {
if (t.isForXStatement(parent)) return;
if (!variableDeclarationHasPattern(node)) return;
var nodes = [];
var declar;
for (var i = 0; i < node.declarations.length; i++) {
declar = node.declarations[i];
var patternId = declar.init;
var pattern = declar.id;
var destructuring = new DestructuringTransformer({
nodes: nodes,
scope: scope,
kind: node.kind,
file: file
});
if (t.isPattern(pattern)) {
destructuring.init(pattern, patternId);
if (+i !== node.declarations.length - 1) {
// we aren't the last declarator so let's just make the
// last transformed node inherit from us
t.inherits(nodes[nodes.length - 1], declar);
}
} else {
nodes.push(t.inherits(destructuring.buildVariableAssignment(declar.id, declar.init), declar));
}
}
if (!t.isProgram(parent) && !t.isBlockStatement(parent)) {
// https://github.com/babel/babel/issues/113
// for (let [x] = [0]; false;) {}
declar = null;
for (i = 0; i < nodes.length; i++) {
node = nodes[i];
declar = declar || t.variableDeclaration(node.kind, []);
if (!t.isVariableDeclaration(node) && declar.kind !== node.kind) {
throw file.errorWithNode(node, messages.get("invalidParentForThisNode"));
}
declar.declarations = declar.declarations.concat(node.declarations);
}
return declar;
}
return nodes;
}
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-for-of
Compile ES2015 for...of to ES5
## Installation
```sh
$ npm install babel-plugin-es2015-for-of
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-for-of"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-for-of script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-for-of"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-for-of",
"version": "1.0.0",
"description": "Compile ES2015 for...of to ES5",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-es2015-function-name
Apply ES2015 function.name semantics to all functions
## Installation
```sh
$ npm install babel-plugin-es2015-function-name
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["es2015-function-name"]
}
```
### Via CLI
```sh
$ babel --plugins es2015-function-name script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["es2015-function-name"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-es2015-function-name",
"version": "1.0.0",
"description": "Apply ES2015 function.name semantics to all functions",
"repository": "babel/babel",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,7 @@
export default function ({ types: t }) {
return {
visitor: {
// your visitor methods go here
}
};
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
lib

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

Some files were not shown because too many files have changed in this diff Show More