Fixing IE DontEnum bug in Scope. Ignoring everywhere else.

This commit is contained in:
Timothy Jones 2010-10-20 12:02:38 +13:00
parent 502d444ebd
commit 083fc61dfb
2 changed files with 48 additions and 20 deletions

View File

@ -45,11 +45,10 @@
return false;
};
Scope.prototype.any = function(fn) {
var _ref2, k, v;
for (v in _ref2 = this.variables) {
if (!__hasProp.call(_ref2, v)) continue;
k = _ref2[v];
if (fn(v, k)) {
var _i, _len, _ref2, v;
for (_i = 0, _len = (_ref2 = this.allVariables()).length; _i < _len; _i++) {
v = _ref2[_i];
if (fn(v[0], v[1])) {
return true;
}
}
@ -87,6 +86,28 @@
assigned: true
});
};
Scope.prototype.allVariables = function() {
var _i, _len, _ref2, _result, k, v, vars;
vars = (function() {
_result = [];
for (v in _ref2 = this.variables) {
if (!__hasProp.call(_ref2, v)) continue;
k = _ref2[v];
_result.push([v, k]);
}
return _result;
}).call(this);
return v.__defineGetter__ ? vars : vars.concat((function() {
_result = [];
for (_i = 0, _len = (_ref2 = 'toString toLocaleString\nhasOwnProperty valueOf constructor propertyIsEnumerable\nisPrototypeOf'.split(' ')).length; _i < _len; _i++) {
v = _ref2[_i];
if (this.variables.hasOwnProperty(v)) {
_result.push([v, this.variables[v]]);
}
}
return _result;
}).call(this));
};
Scope.prototype.hasDeclarations = function(body) {
return body === this.expressions && this.any(function(k, val) {
return (val === 'var' || val === 'reuse');
@ -98,27 +119,25 @@
});
};
Scope.prototype.declaredVariables = function() {
var _ref2, _result, key, val;
var _i, _len, _ref2, _ref3, _result, v;
return (function() {
_result = [];
for (key in _ref2 = this.variables) {
if (!__hasProp.call(_ref2, key)) continue;
val = _ref2[key];
if ((val === 'var' || val === 'reuse')) {
_result.push(key);
for (_i = 0, _len = (_ref2 = this.allVariables()).length; _i < _len; _i++) {
v = _ref2[_i];
if (((_ref3 = v[1]) === 'var' || _ref3 === 'reuse')) {
_result.push(v[0]);
}
}
return _result;
}).call(this).sort();
};
Scope.prototype.assignedVariables = function() {
var _ref2, _result, key, val;
var _i, _len, _ref2, _result, v;
_result = [];
for (key in _ref2 = this.variables) {
if (!__hasProp.call(_ref2, key)) continue;
val = _ref2[key];
if (val.assigned) {
_result.push("" + key + " = " + (val.value));
for (_i = 0, _len = (_ref2 = this.allVariables()).length; _i < _len; _i++) {
v = _ref2[_i];
if (v[1].assigned) {
_result.push("" + (v[0]) + " = " + (v[1].value));
}
}
return _result;

View File

@ -44,7 +44,7 @@ exports.Scope = class Scope
# Test variables and return true the first time fn(v, k) returns true
any: (fn) ->
for v, k of @variables when fn(v, k)
for v in @allVariables() when fn(v[0], v[1])
return true
return false
@ -81,6 +81,15 @@ exports.Scope = class Scope
assign: (name, value) ->
@variables[name] = value: value, assigned: true
# Gets around a bug in IE where it won't enumerate of redefined prototype properties.
allVariables: ->
vars = [v, k] for v, k of @variables
if v.__defineGetter__ then vars
else vars.concat(for v in '''toString toLocaleString
hasOwnProperty valueOf constructor propertyIsEnumerable
isPrototypeOf'''.split(' ') when @variables.hasOwnProperty v
[v, @variables[v]])
# Does this scope reference any variables that need to be declared in the
# given function body?
hasDeclarations: (body) ->
@ -93,12 +102,12 @@ exports.Scope = class Scope
# Return the list of variables first declared in this scope.
declaredVariables: ->
(key for key, val of @variables when val in ['var', 'reuse']).sort()
(v[0] for v in @allVariables() when v[1] in ['var', 'reuse']).sort()
# Return the list of assignments that are supposed to be made at the top
# of this scope.
assignedVariables: ->
"#{key} = #{val.value}" for key, val of @variables when val.assigned
"#{v[0]} = #{v[1].value}" for v in @allVariables() when v[1].assigned
# Compile the JavaScript for all of the variable declarations in this scope.
compiledDeclarations: ->