add more reliable iife detection for default parameter independent scope

This commit is contained in:
Sebastian McKenzie 2015-01-28 15:18:50 +11:00
parent a9e682836b
commit 64766eea44
2 changed files with 26 additions and 7 deletions

View File

@ -11,6 +11,11 @@
_Note: Gaps between patch versions are faulty/broken releases._ _Note: Gaps between patch versions are faulty/broken releases._
## 3.0.5
* **Internal**
* More reliable default parameter scope.
## 3.0.4 ## 3.0.4
* **Bug Fix** * **Bug Fix**

View File

@ -1,7 +1,8 @@
"use strict"; "use strict";
var util = require("../../../util"); var traverse = require("../../../traverse");
var t = require("../../../types"); var util = require("../../../util");
var t = require("../../../types");
var hasDefaults = function (node) { var hasDefaults = function (node) {
for (var i = 0; i < node.params.length; i++) { for (var i = 0; i < node.params.length; i++) {
@ -10,6 +11,15 @@ var hasDefaults = function (node) {
return false; return false;
}; };
var iifeVisitor = {
enter: function (node, parent, scope, context, state) {
if (t.isReferencedIdentifier(node, parent) && scope.hasOwn(node.name)) {
state.iife = true;
context.stop();
}
}
};
exports.Function = function (node, parent, scope) { exports.Function = function (node, parent, scope) {
if (!hasDefaults(node)) return; if (!hasDefaults(node)) return;
@ -23,6 +33,8 @@ exports.Function = function (node, parent, scope) {
var lastNonDefaultParam = 0; var lastNonDefaultParam = 0;
var state = { iife: false, scope: scope };
for (var i = 0; i < node.params.length; i++) { for (var i = 0; i < node.params.length; i++) {
var param = node.params[i]; var param = node.params[i];
@ -36,10 +48,12 @@ exports.Function = function (node, parent, scope) {
node.params[i] = scope.generateUidIdentifier("x"); node.params[i] = scope.generateUidIdentifier("x");
// we're accessing a variable that's already defined within this function if (!state.iife) {
var localDeclar = scope.get(left.name, true); if (t.isIdentifier(right) && scope.hasOwn(right.name)) {
if (localDeclar !== left) { state.iife = true;
iife = true; } else {
traverse(right, iifeVisitor, scope, state);
}
} }
var defNode = util.template("default-parameter", { var defNode = util.template("default-parameter", {
@ -55,7 +69,7 @@ exports.Function = function (node, parent, scope) {
// we need to cut off all trailing default parameters // we need to cut off all trailing default parameters
node.params = node.params.slice(0, lastNonDefaultParam); node.params = node.params.slice(0, lastNonDefaultParam);
if (iife) { if (state.iife) {
var container = t.functionExpression(null, [], node.body, node.generator); var container = t.functionExpression(null, [], node.body, node.generator);
container._aliasFunction = true; container._aliasFunction = true;