use actual parameter reference for non-last default parameters - fixes #1690
This commit is contained in:
@@ -3,7 +3,10 @@ import * as t from "../../types";
|
||||
export default function (node) {
|
||||
var lastNonDefault = 0;
|
||||
for (var i = 0; i < node.params.length; i++) {
|
||||
if (!t.isAssignmentPattern(node.params[i])) lastNonDefault = i + 1;
|
||||
var param = node.params[i];
|
||||
if (!t.isAssignmentPattern(param) && !t.isRestElement(param)) {
|
||||
lastNonDefault = i + 1;
|
||||
}
|
||||
}
|
||||
return lastNonDefault;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
if (VARIABLE_NAME === undefined) VARIABLE_NAME = DEFAULT_VALUE;
|
||||
@@ -1,4 +1,5 @@
|
||||
import callDelegate from "../../helpers/call-delegate";
|
||||
import getFunctionArity from "../../helpers/get-function-arity";
|
||||
import * as util from "../../../util";
|
||||
import * as t from "../../../types";
|
||||
|
||||
@@ -24,37 +25,54 @@ var iifeVisitor = {
|
||||
export function Func/*tion*/(node, parent, scope, file) {
|
||||
if (!hasDefaults(node)) return;
|
||||
|
||||
// ensure it's a block, useful for arrow functions
|
||||
t.ensureBlock(node);
|
||||
|
||||
var state = {
|
||||
iife: false,
|
||||
scope: scope
|
||||
};
|
||||
|
||||
var body = [];
|
||||
|
||||
//
|
||||
var argsIdentifier = t.identifier("arguments");
|
||||
argsIdentifier._shadowedFunctionLiteral = true;
|
||||
|
||||
var lastNonDefaultParam = 0;
|
||||
|
||||
var state = { iife: false, scope: scope };
|
||||
|
||||
var pushDefNode = function (left, right, i) {
|
||||
var defNode = util.template("default-parameter", {
|
||||
VARIABLE_NAME: left,
|
||||
DEFAULT_VALUE: right,
|
||||
ARGUMENT_KEY: t.literal(i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true);
|
||||
// push a default parameter definition
|
||||
function pushDefNode(left, right, i) {
|
||||
var defNode;
|
||||
if (exceedsLastNonDefault(i) || t.isPattern(left) || file.transformers["es6.spec.blockScoping"].canTransform()) {
|
||||
defNode = util.template("default-parameter", {
|
||||
VARIABLE_NAME: left,
|
||||
DEFAULT_VALUE: right,
|
||||
ARGUMENT_KEY: t.literal(i),
|
||||
ARGUMENTS: argsIdentifier
|
||||
}, true);
|
||||
} else {
|
||||
defNode = util.template("default-parameter-assign", {
|
||||
VARIABLE_NAME: left,
|
||||
DEFAULT_VALUE: right
|
||||
}, true);
|
||||
}
|
||||
defNode._blockHoist = node.params.length - i;
|
||||
body.push(defNode);
|
||||
};
|
||||
}
|
||||
|
||||
// check if an index exceeds the functions arity
|
||||
function exceedsLastNonDefault(i) {
|
||||
return i + 1 > lastNonDefaultParam;
|
||||
}
|
||||
|
||||
//
|
||||
var lastNonDefaultParam = getFunctionArity(node);
|
||||
|
||||
//
|
||||
var params = this.get("params");
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var param = params[i];
|
||||
|
||||
if (!param.isAssignmentPattern()) {
|
||||
if (!param.isRestElement()) {
|
||||
lastNonDefaultParam = i + 1;
|
||||
}
|
||||
|
||||
if (!param.isIdentifier()) {
|
||||
param.traverse(iifeVisitor, state);
|
||||
}
|
||||
@@ -69,9 +87,13 @@ export function Func/*tion*/(node, parent, scope, file) {
|
||||
var left = param.get("left");
|
||||
var right = param.get("right");
|
||||
|
||||
var placeholder = scope.generateUidIdentifier("x");
|
||||
placeholder._isDefaultPlaceholder = true;
|
||||
node.params[i] = placeholder;
|
||||
if (exceedsLastNonDefault(i) || left.isPattern()) {
|
||||
var placeholder = scope.generateUidIdentifier("x");
|
||||
placeholder._isDefaultPlaceholder = true;
|
||||
node.params[i] = placeholder;
|
||||
} else {
|
||||
node.params[i] = left.node;
|
||||
}
|
||||
|
||||
if (!state.iife) {
|
||||
if (right.isIdentifier() && scope.hasOwnBinding(right.node.name)) {
|
||||
|
||||
Reference in New Issue
Block a user