Fixing IE DontEnum bug in Scope. Ignoring everywhere else.
This commit is contained in:
parent
502d444ebd
commit
083fc61dfb
53
lib/scope.js
53
lib/scope.js
|
@ -45,11 +45,10 @@
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
Scope.prototype.any = function(fn) {
|
Scope.prototype.any = function(fn) {
|
||||||
var _ref2, k, v;
|
var _i, _len, _ref2, v;
|
||||||
for (v in _ref2 = this.variables) {
|
for (_i = 0, _len = (_ref2 = this.allVariables()).length; _i < _len; _i++) {
|
||||||
if (!__hasProp.call(_ref2, v)) continue;
|
v = _ref2[_i];
|
||||||
k = _ref2[v];
|
if (fn(v[0], v[1])) {
|
||||||
if (fn(v, k)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +86,28 @@
|
||||||
assigned: true
|
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) {
|
Scope.prototype.hasDeclarations = function(body) {
|
||||||
return body === this.expressions && this.any(function(k, val) {
|
return body === this.expressions && this.any(function(k, val) {
|
||||||
return (val === 'var' || val === 'reuse');
|
return (val === 'var' || val === 'reuse');
|
||||||
|
@ -98,27 +119,25 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
Scope.prototype.declaredVariables = function() {
|
Scope.prototype.declaredVariables = function() {
|
||||||
var _ref2, _result, key, val;
|
var _i, _len, _ref2, _ref3, _result, v;
|
||||||
return (function() {
|
return (function() {
|
||||||
_result = [];
|
_result = [];
|
||||||
for (key in _ref2 = this.variables) {
|
for (_i = 0, _len = (_ref2 = this.allVariables()).length; _i < _len; _i++) {
|
||||||
if (!__hasProp.call(_ref2, key)) continue;
|
v = _ref2[_i];
|
||||||
val = _ref2[key];
|
if (((_ref3 = v[1]) === 'var' || _ref3 === 'reuse')) {
|
||||||
if ((val === 'var' || val === 'reuse')) {
|
_result.push(v[0]);
|
||||||
_result.push(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _result;
|
return _result;
|
||||||
}).call(this).sort();
|
}).call(this).sort();
|
||||||
};
|
};
|
||||||
Scope.prototype.assignedVariables = function() {
|
Scope.prototype.assignedVariables = function() {
|
||||||
var _ref2, _result, key, val;
|
var _i, _len, _ref2, _result, v;
|
||||||
_result = [];
|
_result = [];
|
||||||
for (key in _ref2 = this.variables) {
|
for (_i = 0, _len = (_ref2 = this.allVariables()).length; _i < _len; _i++) {
|
||||||
if (!__hasProp.call(_ref2, key)) continue;
|
v = _ref2[_i];
|
||||||
val = _ref2[key];
|
if (v[1].assigned) {
|
||||||
if (val.assigned) {
|
_result.push("" + (v[0]) + " = " + (v[1].value));
|
||||||
_result.push("" + key + " = " + (val.value));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _result;
|
return _result;
|
||||||
|
|
|
@ -44,7 +44,7 @@ exports.Scope = class Scope
|
||||||
|
|
||||||
# Test variables and return true the first time fn(v, k) returns true
|
# Test variables and return true the first time fn(v, k) returns true
|
||||||
any: (fn) ->
|
any: (fn) ->
|
||||||
for v, k of @variables when fn(v, k)
|
for v in @allVariables() when fn(v[0], v[1])
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
@ -81,6 +81,15 @@ exports.Scope = class Scope
|
||||||
assign: (name, value) ->
|
assign: (name, value) ->
|
||||||
@variables[name] = value: value, assigned: true
|
@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
|
# Does this scope reference any variables that need to be declared in the
|
||||||
# given function body?
|
# given function body?
|
||||||
hasDeclarations: (body) ->
|
hasDeclarations: (body) ->
|
||||||
|
@ -93,12 +102,12 @@ exports.Scope = class Scope
|
||||||
|
|
||||||
# Return the list of variables first declared in this scope.
|
# Return the list of variables first declared in this scope.
|
||||||
declaredVariables: ->
|
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
|
# Return the list of assignments that are supposed to be made at the top
|
||||||
# of this scope.
|
# of this scope.
|
||||||
assignedVariables: ->
|
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.
|
# Compile the JavaScript for all of the variable declarations in this scope.
|
||||||
compiledDeclarations: ->
|
compiledDeclarations: ->
|
||||||
|
|
Loading…
Reference in New Issue