always use closure wrap - fixes #864

This commit is contained in:
Sebastian McKenzie
2015-02-22 23:23:34 +11:00
parent 7bff8239a1
commit 52ea7b5f59
2 changed files with 33 additions and 55 deletions

View File

@@ -15,49 +15,20 @@ var visitor = {
if (localDeclar !== state.outerDeclar) return;
state.selfReference = true;
state.references.push(this);
if (t.isPattern(parent) || t.isAssignmentExpression(parent) || t.isUpdateExpression(parent)) {
state.selfAssignment = true;
}
this.stop();
}
};
var wrapIncludesSelfReference = function (state, method, id, scope) {
var outerId = scope.generateUidIdentifier("getOuter");
var outerIdCall = t.callExpression(outerId, []);
for (var i = 0; i < state.references.length; i++) {
state.references[i].replaceNode(outerIdCall);
}
method.id = id;
return util.template("named-function", {
GET_OUTER_ID: outerId,
FUNCTION_ID: id,
FUNCTION: method
});
};
var wrapIncludesSelfAssignment = function (state, method, id, scope) {
var templateName = "property-method-assignment-wrapper";
if (method.generator) templateName += "-generator";
return util.template(templateName, {
FUNCTION: method,
FUNCTION_ID: id,
FUNCTION_KEY: scope.generateUidIdentifier(id.name),
WRAPPER_KEY: scope.generateUidIdentifier(id.name + "Wrapper")
});
};
var wrap = function (state, method, id, scope) {
if (state.selfReference) {
if (state.selfAssignment) {
return wrapIncludesSelfAssignment(state, method, id, scope);
} else {
return wrapIncludesSelfReference(state, method, id, scope);
}
var templateName = "property-method-assignment-wrapper";
if (method.generator) templateName += "-generator";
return util.template(templateName, {
FUNCTION: method,
FUNCTION_ID: id,
FUNCTION_KEY: scope.generateUidIdentifier(id.name),
WRAPPER_KEY: scope.generateUidIdentifier(id.name + "Wrapper")
});
} else {
method.id = id;
return method;
@@ -92,7 +63,6 @@ var visit = function (node, name, scope) {
// this isn't to the spec and they've invented this behaviour which is
// **extremely** annoying so we avoid setting the name if it has a param
// with the same id
state.selfAssignment = true;
state.selfReference = true;
} else {
// otherwise it's defined somewhere in scope like:

View File

@@ -9,15 +9,19 @@ var obj = {
},
// self reference
h: (function () {
function _getOuter() {
return h;
}
return function h() {
console.log(_getOuter());
h: (function (_h) {
var _hWrapper = function h() {
return _h.apply(this, arguments);
};
})(),
_hWrapper.toString = function () {
return _h.toString();
};
return _hWrapper;
})(function () {
console.log(h);
}),
// no reference
m: function m() {
@@ -31,15 +35,19 @@ var f = function f() {
};
// self reference
var f = (function () {
function _getOuter() {
return f;
}
return function f() {
console.log(_getOuter(), g);
var f = (function (_f) {
var _fWrapper = function f() {
return _f.apply(this, arguments);
};
})();
_fWrapper.toString = function () {
return _f.toString();
};
return _fWrapper;
})(function () {
console.log(f, g);
});
// no reference
var g = function g() {