Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
194c080c64 | ||
|
|
4c6076e529 | ||
|
|
df65ec08a2 | ||
|
|
62f11011b0 | ||
|
|
9385c7e4ad | ||
|
|
3c06e68cae | ||
|
|
e8810f5124 | ||
|
|
3c258c4716 | ||
|
|
193a3c167e | ||
|
|
4b525daf72 | ||
|
|
e46f42872a | ||
|
|
4790e4068a | ||
|
|
26cb5d5a65 | ||
|
|
031bda61cc | ||
|
|
61f1fae83b | ||
|
|
d911bdaf63 | ||
|
|
f322252c36 | ||
|
|
da16bf1e42 | ||
|
|
4a1addc558 |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -11,6 +11,23 @@
|
||||
|
||||
_Note: Gaps between patch versions are faulty/broken releases._
|
||||
|
||||
## 2.13.5
|
||||
|
||||
* **Bug Fix**
|
||||
* Allow rest parameters to be destructuring patterns.
|
||||
* **Internal**
|
||||
* Upgrade `kexec` to `1.1.0`.
|
||||
|
||||
## 2.13.4
|
||||
|
||||
* **Bug Fix**
|
||||
* Fix ordering of destructuring and default params.
|
||||
* Fix loop body scope.
|
||||
* Fix `for...of` transformation not retaining it's scope.
|
||||
* Add destructuring assignment support to scope tracking.
|
||||
* **Polish**
|
||||
* More reliable newlines for pretty printing variable declarations.
|
||||
|
||||
## 2.13.3
|
||||
|
||||
* **Internal**
|
||||
|
||||
@@ -169,20 +169,19 @@ exports.DebuggerStatement = function () {
|
||||
exports.VariableDeclaration = function (node, print, parent) {
|
||||
this.push(node.kind + " ");
|
||||
|
||||
var inits = 0;
|
||||
var noInits = 0;
|
||||
var hasInits = false;
|
||||
// don't add whitespace to loop heads
|
||||
if (!t.isFor(parent)) {
|
||||
for (var i = 0; i < node.declarations.length; i++) {
|
||||
if (node.declarations[i].init) {
|
||||
inits++;
|
||||
} else {
|
||||
noInits++;
|
||||
// has an init so let's split it up over multiple lines
|
||||
hasInits = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sep = ",";
|
||||
if (inits > noInits) { // more inits than no inits so let's add a newline
|
||||
if (hasInits) {
|
||||
sep += "\n" + util.repeat(node.kind.length + 1);
|
||||
} else {
|
||||
sep += " ";
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
ARRAY.forEach(function (KEY) {
|
||||
|
||||
});
|
||||
@@ -71,8 +71,9 @@ _.each({
|
||||
templateLiterals: require("./transformers/es6-template-literals"),
|
||||
propertyMethodAssignment: require("./transformers/es6-property-method-assignment"),
|
||||
computedPropertyNames: require("./transformers/es6-computed-property-names"),
|
||||
destructuring: require("./transformers/es6-destructuring"),
|
||||
defaultParameters: require("./transformers/es6-default-parameters"),
|
||||
restParameters: require("./transformers/es6-rest-parameters"),
|
||||
destructuring: require("./transformers/es6-destructuring"),
|
||||
forOf: require("./transformers/es6-for-of"),
|
||||
unicodeRegex: require("./transformers/es6-unicode-regex"),
|
||||
abstractReferences: require("./transformers/es7-abstract-references"),
|
||||
@@ -84,7 +85,6 @@ _.each({
|
||||
_blockHoist: require("./transformers/_block-hoist"),
|
||||
|
||||
generators: require("./transformers/es6-generators"),
|
||||
restParameters: require("./transformers/es6-rest-parameters"),
|
||||
|
||||
protoToAssign: require("./transformers/optional-proto-to-assign"),
|
||||
|
||||
@@ -98,6 +98,7 @@ _.each({
|
||||
typeofSymbol: require("./transformers/optional-typeof-symbol"),
|
||||
coreAliasing: require("./transformers/optional-core-aliasing"),
|
||||
undefinedToVoid: require("./transformers/optional-undefined-to-void"),
|
||||
undeclaredVariableCheck: require("./transformers/optional-undeclared-variable-check"),
|
||||
|
||||
// spec
|
||||
specPropertyLiterals: require("./transformers/spec-property-literals"),
|
||||
|
||||
@@ -15,9 +15,9 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
var iife = false;
|
||||
var def;
|
||||
|
||||
var checkTDZ = function (ids) {
|
||||
var checkTDZ = function (param, def, ids) {
|
||||
var check = function (node, parent) {
|
||||
if (!t.isIdentifier(node) || !t.isReferenced(node, parent)) return;
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
if (ids.indexOf(node.name) >= 0) {
|
||||
throw file.errorWithNode(node, "Temporal dead zone - accessing a variable before it's initialized");
|
||||
@@ -29,7 +29,10 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
};
|
||||
|
||||
check(def, node);
|
||||
traverse(def, { enter: check });
|
||||
|
||||
if (!t.isPattern(param)) {
|
||||
traverse(def, { enter: check });
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < node.defaults.length; i++) {
|
||||
@@ -42,7 +45,7 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
// are to the right - ie. uninitialized parameters
|
||||
var rightIds = ids.slice(i);
|
||||
for (var i2 = 0; i2 < rightIds.length; i2++) {
|
||||
checkTDZ(rightIds[i2]);
|
||||
checkTDZ(param, def, rightIds[i2]);
|
||||
}
|
||||
|
||||
// we're accessing a variable that's already defined within this function
|
||||
@@ -66,12 +69,14 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
body.push(util.template("default-parameter", {
|
||||
var defNode = util.template("default-parameter", {
|
||||
VARIABLE_NAME: node.params[i],
|
||||
DEFAULT_VALUE: def,
|
||||
ARGUMENT_KEY: t.literal(+i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true));
|
||||
}, true);
|
||||
defNode._blockHoist = node.defaults.length - i;
|
||||
body.push(defNode);
|
||||
}
|
||||
|
||||
// we need to cut off all trailing default parameters
|
||||
|
||||
@@ -8,13 +8,27 @@ var buildVariableAssign = function (opts, id, init) {
|
||||
var op = opts.operator;
|
||||
if (t.isMemberExpression(id)) op = "=";
|
||||
|
||||
var node;
|
||||
|
||||
if (op) {
|
||||
return t.expressionStatement(t.assignmentExpression(op, id, init));
|
||||
node = t.expressionStatement(t.assignmentExpression(op, id, init));
|
||||
} else {
|
||||
return t.variableDeclaration(opts.kind, [
|
||||
node = t.variableDeclaration(opts.kind, [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
}
|
||||
|
||||
node._blockHoist = opts.blockHoist;
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
var buildVariableDeclar = function (opts, id, init) {
|
||||
var declar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(id, init)
|
||||
]);
|
||||
declar._blockHoist = opts.blockHoist;
|
||||
return declar;
|
||||
};
|
||||
|
||||
var push = function (opts, nodes, elem, parentId) {
|
||||
@@ -100,9 +114,7 @@ var pushArrayPattern = function (opts, nodes, pattern, parentId) {
|
||||
var toArray = opts.file.toArray(parentId, !hasSpreadElement && pattern.elements.length);
|
||||
|
||||
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(_parentId, toArray)
|
||||
]));
|
||||
nodes.push(buildVariableDeclar(opts, _parentId, toArray));
|
||||
parentId = _parentId;
|
||||
|
||||
for (i = 0; i < pattern.elements.length; i++) {
|
||||
@@ -138,11 +150,7 @@ var pushPattern = function (opts) {
|
||||
|
||||
if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
|
||||
var key = scope.generateUidBasedOnNode(parentId, file);
|
||||
|
||||
nodes.push(t.variableDeclaration("var", [
|
||||
t.variableDeclarator(key, parentId)
|
||||
]));
|
||||
|
||||
nodes.push(buildVariableDeclar(opts, key, parentId));
|
||||
parentId = key;
|
||||
}
|
||||
|
||||
@@ -181,19 +189,20 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
|
||||
var hasDestructuring = false;
|
||||
|
||||
node.params = node.params.map(function (pattern) {
|
||||
node.params = node.params.map(function (pattern, i) {
|
||||
if (!t.isPattern(pattern)) return pattern;
|
||||
|
||||
hasDestructuring = true;
|
||||
var parentId = file.generateUidIdentifier("ref", scope);
|
||||
|
||||
pushPattern({
|
||||
kind: "var",
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: parentId,
|
||||
file: file,
|
||||
scope: scope
|
||||
blockHoist: node.params.length - i,
|
||||
pattern: pattern,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
file: file,
|
||||
kind: "var",
|
||||
id: parentId
|
||||
});
|
||||
|
||||
return parentId;
|
||||
@@ -294,12 +303,12 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
|
||||
var patternId = declar.init;
|
||||
var pattern = declar.id;
|
||||
var opts = {
|
||||
kind: node.kind,
|
||||
nodes: nodes,
|
||||
pattern: pattern,
|
||||
id: patternId,
|
||||
nodes: nodes,
|
||||
scope: scope,
|
||||
kind: node.kind,
|
||||
file: file,
|
||||
scope: scope
|
||||
id: patternId,
|
||||
};
|
||||
|
||||
if (t.isPattern(pattern) && patternId) {
|
||||
|
||||
@@ -30,6 +30,9 @@ exports.ForOfStatement = function (node, parent, scope, context, file) {
|
||||
// push the rest of the original loop body onto our new body
|
||||
block.body = block.body.concat(node.body.body);
|
||||
|
||||
// todo: find out why this is necessary? #538
|
||||
loop._scopeInfo = node._scopeInfo;
|
||||
|
||||
return loop;
|
||||
};
|
||||
|
||||
|
||||
@@ -117,9 +117,10 @@ LetScoping.prototype.run = function () {
|
||||
*/
|
||||
|
||||
LetScoping.prototype.remap = function () {
|
||||
var letRefs = this.letReferences;
|
||||
var scope = this.scope;
|
||||
var file = this.file;
|
||||
var hasRemaps = false;
|
||||
var letRefs = this.letReferences;
|
||||
var scope = this.scope;
|
||||
var file = this.file;
|
||||
|
||||
// alright, so since we aren't wrapping this block in a closure
|
||||
// we have to check if any of our let variables collide with
|
||||
@@ -136,6 +137,7 @@ LetScoping.prototype.remap = function () {
|
||||
var uid = file.generateUidIdentifier(ref.name, scope).name;
|
||||
ref.name = uid;
|
||||
|
||||
hasRemaps = true;
|
||||
remaps[key] = remaps[uid] = {
|
||||
node: ref,
|
||||
uid: uid
|
||||
@@ -143,11 +145,12 @@ LetScoping.prototype.remap = function () {
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRemaps) return;
|
||||
|
||||
//
|
||||
|
||||
var replace = function (node, parent, scope, context, remaps) {
|
||||
if (!t.isIdentifier(node)) return;
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
var remap = remaps[node.name];
|
||||
if (!remap) return;
|
||||
@@ -266,11 +269,8 @@ LetScoping.prototype.getLetReferences = function () {
|
||||
if (t.isFunction(node)) {
|
||||
traverse(node, {
|
||||
enter: function (node, parent) {
|
||||
// not an identifier so we have no use
|
||||
if (!t.isIdentifier(node)) return;
|
||||
|
||||
// not a direct reference
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
// this scope has a variable with the same name so it couldn't belong
|
||||
// to our let scope
|
||||
|
||||
@@ -41,6 +41,22 @@ exports.Function = function (node, parent, scope, context, file) {
|
||||
);
|
||||
}
|
||||
|
||||
// support patterns
|
||||
if (t.isPattern(rest)) {
|
||||
var pattern = rest;
|
||||
rest = file.generateUidIdentifier("ref", scope);
|
||||
|
||||
// let the destructuring transformer handle this
|
||||
var restDeclar = t.variableDeclaration("var", [
|
||||
t.variableDeclarator(pattern, rest)
|
||||
]);
|
||||
|
||||
// retain evaluation position
|
||||
restDeclar._blockHoist = node.params.length + 1;
|
||||
|
||||
node.body.body.unshift(restDeclar);
|
||||
}
|
||||
|
||||
node.body.body.unshift(
|
||||
util.template("rest", {
|
||||
ARGUMENTS: argsId,
|
||||
|
||||
@@ -16,8 +16,7 @@ exports.BlockStatement = function (node, parent, scope, context, file) {
|
||||
|
||||
traverse(node, {
|
||||
enter: function (node, parent, scope, context, state) {
|
||||
if (!t.isIdentifier(node)) return;
|
||||
if (!t.isReferenced(node, parent)) return;
|
||||
if (!t.isReferencedIdentifier(node, parent)) return;
|
||||
|
||||
var declared = state.letRefs[node.name];
|
||||
if (!declared) return;
|
||||
|
||||
@@ -42,7 +42,7 @@ exports.ast = {
|
||||
context.skip();
|
||||
return t.prependToMemberExpression(node, file._coreId);
|
||||
}
|
||||
} else if (t.isIdentifier(node) && !t.isMemberExpression(parent) && t.isReferenced(node, parent) && _.contains(ALIASABLE_CONSTRUCTORS, node.name)) {
|
||||
} else if (t.isReferencedIdentifier(node, parent) && !t.isMemberExpression(parent) && _.contains(ALIASABLE_CONSTRUCTORS, node.name)) {
|
||||
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
|
||||
return t.memberExpression(file._coreId, node);
|
||||
} else if (t.isCallExpression(node)) {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
exports.optional = true;
|
||||
|
||||
exports.Identifier = function (node, parent, scope, context, file) {
|
||||
if (!scope.has(node.name, true)) {
|
||||
throw file.errorWithNode(node, "Reference to undeclared variable");
|
||||
}
|
||||
};
|
||||
@@ -120,6 +120,7 @@ Scope.prototype.generateTempBasedOnNode = function (node, file) {
|
||||
};
|
||||
|
||||
Scope.prototype.getInfo = function () {
|
||||
var parent = this.parent;
|
||||
var block = this.block;
|
||||
if (block._scopeInfo) return block._scopeInfo;
|
||||
|
||||
@@ -132,6 +133,10 @@ Scope.prototype.getInfo = function () {
|
||||
if (!reference) Scope.add(node, declarations);
|
||||
};
|
||||
|
||||
if (parent && t.isBlockStatement(block) && t.isFor(parent.block)) {
|
||||
return info;
|
||||
}
|
||||
|
||||
// ForStatement - left, init
|
||||
|
||||
if (t.isFor(block)) {
|
||||
@@ -139,6 +144,10 @@ Scope.prototype.getInfo = function () {
|
||||
var node = block[key];
|
||||
if (t.isBlockScoped(node)) add(node);
|
||||
});
|
||||
|
||||
if (t.isBlockStatement(block.body)) {
|
||||
block = block.body;
|
||||
}
|
||||
}
|
||||
|
||||
// Program, BlockStatement - let variables
|
||||
|
||||
@@ -263,6 +263,18 @@ t.isReferenced = function (node, parent) {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
* @param {Object} node
|
||||
* @param {Object} parent
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
t.isReferencedIdentifier = function (node, parent) {
|
||||
return t.isIdentifier(node) && t.isReferenced(node, parent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Description
|
||||
*
|
||||
@@ -475,7 +487,8 @@ t.getIds.nodes = {
|
||||
MemeberExpression: ["object"],
|
||||
SpreadElement: ["argument"],
|
||||
Property: ["value"],
|
||||
ComprehensionBlock: ["left"]
|
||||
ComprehensionBlock: ["left"],
|
||||
AssignmentPattern: ["left"]
|
||||
};
|
||||
|
||||
t.getIds.arrays = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "6to5",
|
||||
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
|
||||
"version": "2.13.3",
|
||||
"version": "2.13.5",
|
||||
"author": "Sebastian McKenzie <sebmck@gmail.com>",
|
||||
"homepage": "https://6to5.org/",
|
||||
"repository": "6to5/6to5",
|
||||
@@ -63,6 +63,6 @@
|
||||
"uglify-js": "2.4.16"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"kexec": "0.2.0"
|
||||
"kexec": "1.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ let foo = "foo";
|
||||
var foo = "bar";
|
||||
const foo = "foo";
|
||||
|
||||
let foo, bar = "bar";
|
||||
var foo, bar = "bar";
|
||||
let foo,
|
||||
bar = "bar";
|
||||
var foo,
|
||||
bar = "bar";
|
||||
|
||||
let foo = "foo",
|
||||
bar = "bar";
|
||||
|
||||
19
test/fixtures/transformation/es6-default-parameters/destructuring/exec.js
vendored
Normal file
19
test/fixtures/transformation/es6-default-parameters/destructuring/exec.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
function required(msg) {
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
function sum(
|
||||
{ arr = required('arr is required') } = { arr: arr = [] },
|
||||
length = arr.length
|
||||
) {
|
||||
let i = 0;
|
||||
let acc = 0;
|
||||
for (let item of arr) {
|
||||
if (i >= length) return acc;
|
||||
acc += item;
|
||||
i++;
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
assert.equal(sum({arr:[1,2]}), 3);
|
||||
2
test/fixtures/transformation/es6-let-scoping/exec-collision-array-comprehension/exec.js
vendored
Normal file
2
test/fixtures/transformation/es6-let-scoping/exec-collision-array-comprehension/exec.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
var foo = [];
|
||||
assert.deepEqual([for (foo of [1, 2, 3]) foo], [1, 2, 3]);
|
||||
3
test/fixtures/transformation/es6-let-scoping/exec-collision-array-comprehension/options.json
vendored
Normal file
3
test/fixtures/transformation/es6-let-scoping/exec-collision-array-comprehension/options.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"experimental": true
|
||||
}
|
||||
6
test/fixtures/transformation/es6-let-scoping/exec-collision-for/exec.js
vendored
Normal file
6
test/fixtures/transformation/es6-let-scoping/exec-collision-for/exec.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
let x = 0;
|
||||
for (;;) {
|
||||
let x = 1;
|
||||
assert.equal(x, 1);
|
||||
break;
|
||||
}
|
||||
5
test/fixtures/transformation/es6-let-scoping/exec-destructuring-defaults/exec.js
vendored
Normal file
5
test/fixtures/transformation/es6-let-scoping/exec-destructuring-defaults/exec.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
var fields = [{ name: "title" }, { name: "content" }];
|
||||
|
||||
for (let { name, value = "Default value" } of fields) {
|
||||
assert.equal(value, "Default value");
|
||||
}
|
||||
5
test/fixtures/transformation/optional-undeclared-variable-check/declared/exec.js
vendored
Normal file
5
test/fixtures/transformation/optional-undeclared-variable-check/declared/exec.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
function foo() {
|
||||
|
||||
}
|
||||
|
||||
foo();
|
||||
3
test/fixtures/transformation/optional-undeclared-variable-check/options.json
vendored
Normal file
3
test/fixtures/transformation/optional-undeclared-variable-check/options.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"optional": ["undeclaredVariableCheck"]
|
||||
}
|
||||
1
test/fixtures/transformation/optional-undeclared-variable-check/undeclared/exec.js
vendored
Normal file
1
test/fixtures/transformation/optional-undeclared-variable-check/undeclared/exec.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo();
|
||||
3
test/fixtures/transformation/optional-undeclared-variable-check/undeclared/options.json
vendored
Normal file
3
test/fixtures/transformation/optional-undeclared-variable-check/undeclared/options.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"throws": "Reference to undeclared variable"
|
||||
}
|
||||
Reference in New Issue
Block a user