add proper ordering to function param logic - fixes #549

This commit is contained in:
Sebastian McKenzie 2015-01-21 10:17:52 +11:00
parent 193a3c167e
commit 3c258c4716
5 changed files with 60 additions and 29 deletions

View File

@ -71,8 +71,8 @@ _.each({
templateLiterals: require("./transformers/es6-template-literals"), templateLiterals: require("./transformers/es6-template-literals"),
propertyMethodAssignment: require("./transformers/es6-property-method-assignment"), propertyMethodAssignment: require("./transformers/es6-property-method-assignment"),
computedPropertyNames: require("./transformers/es6-computed-property-names"), computedPropertyNames: require("./transformers/es6-computed-property-names"),
destructuring: require("./transformers/es6-destructuring"),
defaultParameters: require("./transformers/es6-default-parameters"), defaultParameters: require("./transformers/es6-default-parameters"),
destructuring: require("./transformers/es6-destructuring"),
forOf: require("./transformers/es6-for-of"), forOf: require("./transformers/es6-for-of"),
unicodeRegex: require("./transformers/es6-unicode-regex"), unicodeRegex: require("./transformers/es6-unicode-regex"),
abstractReferences: require("./transformers/es7-abstract-references"), abstractReferences: require("./transformers/es7-abstract-references"),

View File

@ -15,7 +15,7 @@ exports.Function = function (node, parent, scope, context, file) {
var iife = false; var iife = false;
var def; var def;
var checkTDZ = function (ids) { var checkTDZ = function (param, def, ids) {
var check = function (node, parent) { var check = function (node, parent) {
if (!t.isReferencedIdentifier(node, parent)) return; if (!t.isReferencedIdentifier(node, parent)) return;
@ -29,7 +29,10 @@ exports.Function = function (node, parent, scope, context, file) {
}; };
check(def, node); check(def, node);
traverse(def, { enter: check });
if (!t.isPattern(param)) {
traverse(def, { enter: check });
}
}; };
for (var i = 0; i < node.defaults.length; i++) { 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 // are to the right - ie. uninitialized parameters
var rightIds = ids.slice(i); var rightIds = ids.slice(i);
for (var i2 = 0; i2 < rightIds.length; i2++) { 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 // 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; continue;
} }
body.push(util.template("default-parameter", { var def = util.template("default-parameter", {
VARIABLE_NAME: node.params[i], VARIABLE_NAME: node.params[i],
DEFAULT_VALUE: def, DEFAULT_VALUE: def,
ARGUMENT_KEY: t.literal(+i), ARGUMENT_KEY: t.literal(+i),
ARGUMENTS: argsIdentifier ARGUMENTS: argsIdentifier
}, true)); }, true);
def._blockHoist = node.defaults.length - i;
body.push(def);
} }
// we need to cut off all trailing default parameters // we need to cut off all trailing default parameters

View File

@ -8,13 +8,27 @@ var buildVariableAssign = function (opts, id, init) {
var op = opts.operator; var op = opts.operator;
if (t.isMemberExpression(id)) op = "="; if (t.isMemberExpression(id)) op = "=";
var node;
if (op) { if (op) {
return t.expressionStatement(t.assignmentExpression(op, id, init)); node = t.expressionStatement(t.assignmentExpression(op, id, init));
} else { } else {
return t.variableDeclaration(opts.kind, [ node = t.variableDeclaration(opts.kind, [
t.variableDeclarator(id, init) 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) { 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 toArray = opts.file.toArray(parentId, !hasSpreadElement && pattern.elements.length);
var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file); var _parentId = opts.scope.generateUidBasedOnNode(parentId, opts.file);
nodes.push(t.variableDeclaration("var", [ nodes.push(buildVariableDeclar(opts, _parentId, toArray));
t.variableDeclarator(_parentId, toArray)
]));
parentId = _parentId; parentId = _parentId;
for (i = 0; i < pattern.elements.length; i++) { 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)) { if (!t.isArrayExpression(parentId) && !t.isMemberExpression(parentId) && !t.isIdentifier(parentId)) {
var key = scope.generateUidBasedOnNode(parentId, file); var key = scope.generateUidBasedOnNode(parentId, file);
nodes.push(buildVariableDeclar(opts, key, parentId));
nodes.push(t.variableDeclaration("var", [
t.variableDeclarator(key, parentId)
]));
parentId = key; parentId = key;
} }
@ -181,19 +189,20 @@ exports.Function = function (node, parent, scope, context, file) {
var hasDestructuring = false; var hasDestructuring = false;
node.params = node.params.map(function (pattern) { node.params = node.params.map(function (pattern, i) {
if (!t.isPattern(pattern)) return pattern; if (!t.isPattern(pattern)) return pattern;
hasDestructuring = true; hasDestructuring = true;
var parentId = file.generateUidIdentifier("ref", scope); var parentId = file.generateUidIdentifier("ref", scope);
pushPattern({ pushPattern({
kind: "var", blockHoist: node.params.length - i,
nodes: nodes, pattern: pattern,
pattern: pattern, nodes: nodes,
id: parentId, scope: scope,
file: file, file: file,
scope: scope kind: "var",
id: parentId
}); });
return parentId; return parentId;
@ -294,12 +303,12 @@ exports.VariableDeclaration = function (node, parent, scope, context, file) {
var patternId = declar.init; var patternId = declar.init;
var pattern = declar.id; var pattern = declar.id;
var opts = { var opts = {
kind: node.kind,
nodes: nodes,
pattern: pattern, pattern: pattern,
id: patternId, nodes: nodes,
scope: scope,
kind: node.kind,
file: file, file: file,
scope: scope id: patternId,
}; };
if (t.isPattern(pattern) && patternId) { if (t.isPattern(pattern) && patternId) {

View File

@ -1,5 +1,3 @@
var t = require("../../types");
exports.optional = true; exports.optional = true;
exports.Identifier = function (node, parent, scope, context, file) { exports.Identifier = function (node, parent, scope, context, file) {

View 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);