Updating Underscore to 1.1.0, fixing a hasOwnProperty glitch in Scope, and a double-semicolon bug in ParentheticalNode.
This commit is contained in:
parent
6ed33fcc6d
commit
87693d84cb
File diff suppressed because one or more lines are too long
|
@ -71,7 +71,7 @@
|
||||||
|
|
||||||
|
|
||||||
# Current version.
|
# Current version.
|
||||||
_.VERSION = '1.0.2'
|
_.VERSION = '1.1.0'
|
||||||
|
|
||||||
|
|
||||||
# Collection Functions
|
# Collection Functions
|
||||||
|
@ -104,8 +104,10 @@
|
||||||
|
|
||||||
# **Reduce** builds up a single result from a list of values. Also known as
|
# **Reduce** builds up a single result from a list of values. Also known as
|
||||||
# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
|
# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
|
||||||
_.reduce = (obj, memo, iterator, context) ->
|
_.reduce = (obj, iterator, memo, context) ->
|
||||||
return obj.reduce(_.bind(iterator, context), memo) if nativeReduce and obj.reduce is nativeReduce
|
if nativeReduce and obj.reduce is nativeReduce
|
||||||
|
iterator = _.bind iterator, context if context
|
||||||
|
return obj.reduce iterator, memo
|
||||||
_.each obj, (value, index, list) ->
|
_.each obj, (value, index, list) ->
|
||||||
memo = iterator.call context, memo, value, index, list
|
memo = iterator.call context, memo, value, index, list
|
||||||
memo
|
memo
|
||||||
|
@ -113,11 +115,12 @@
|
||||||
|
|
||||||
# The right-associative version of **reduce**, also known as **foldr**. Uses
|
# The right-associative version of **reduce**, also known as **foldr**. Uses
|
||||||
# JavaScript 1.8's version of **reduceRight**, if available.
|
# JavaScript 1.8's version of **reduceRight**, if available.
|
||||||
_.reduceRight = (obj, memo, iterator, context) ->
|
_.reduceRight = (obj, iterator, memo, context) ->
|
||||||
return obj.reduceRight(_.bind(iterator, context), memo) if nativeReduceRight and obj.reduceRight is nativeReduceRight
|
if nativeReduceRight and obj.reduceRight is nativeReduceRight
|
||||||
_.each _.clone(_.toArray(obj)).reverse(), (value, index) ->
|
iterator = _.bind iterator, context if context
|
||||||
memo = iterator.call context, memo, value, index, obj
|
return obj.reduceRight iterator, memo
|
||||||
memo
|
reversed = _.clone(_.toArray(obj)).reverse()
|
||||||
|
_.reduce reversed, iterator, memo, context
|
||||||
|
|
||||||
|
|
||||||
# Return the first value which passes a truth test.
|
# Return the first value which passes a truth test.
|
||||||
|
@ -273,10 +276,11 @@
|
||||||
|
|
||||||
# Return a completely flattened version of an array.
|
# Return a completely flattened version of an array.
|
||||||
_.flatten = (array) ->
|
_.flatten = (array) ->
|
||||||
_.reduce array, [], (memo, value) ->
|
_.reduce array, (memo, value) ->
|
||||||
return memo.concat(_.flatten(value)) if _.isArray value
|
return memo.concat(_.flatten(value)) if _.isArray value
|
||||||
memo.push value
|
memo.push value
|
||||||
memo
|
memo
|
||||||
|
, []
|
||||||
|
|
||||||
|
|
||||||
# Return a version of the array that does not contain the specified value(s).
|
# Return a version of the array that does not contain the specified value(s).
|
||||||
|
@ -378,6 +382,16 @@
|
||||||
setTimeout((-> func.apply(func, args)), wait)
|
setTimeout((-> func.apply(func, args)), wait)
|
||||||
|
|
||||||
|
|
||||||
|
# Memoize an expensive function by storing its results.
|
||||||
|
_.memoize = (func, hasher) ->
|
||||||
|
memo = {}
|
||||||
|
hasher or= _.identity
|
||||||
|
->
|
||||||
|
key = hasher.apply this, arguments
|
||||||
|
return memo[key] if key of memo
|
||||||
|
memo[key] = func.apply this, arguments
|
||||||
|
|
||||||
|
|
||||||
# Defers a function, scheduling it to run after the current call stack has
|
# Defers a function, scheduling it to run after the current call stack has
|
||||||
# cleared.
|
# cleared.
|
||||||
_.defer = (func) ->
|
_.defer = (func) ->
|
||||||
|
@ -457,7 +471,7 @@
|
||||||
# Check dates' integer values.
|
# Check dates' integer values.
|
||||||
return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
|
return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
|
||||||
# Both are NaN?
|
# Both are NaN?
|
||||||
return true if _.isNaN(a) and _.isNaN(b)
|
return false if _.isNaN(a) and _.isNaN(b)
|
||||||
# Compare regular expressions.
|
# Compare regular expressions.
|
||||||
if _.isRegExp(a) and _.isRegExp(b)
|
if _.isRegExp(a) and _.isRegExp(b)
|
||||||
return a.source is b.source and
|
return a.source is b.source and
|
||||||
|
@ -473,13 +487,13 @@
|
||||||
# Different object sizes?
|
# Different object sizes?
|
||||||
return false if aKeys.length isnt bKeys.length
|
return false if aKeys.length isnt bKeys.length
|
||||||
# Recursive comparison of contents.
|
# Recursive comparison of contents.
|
||||||
(return false) for key, val of a when !(key in b) or !_.isEqual(val, b[key])
|
(return false) for all key, val of a when !(key of b) or !_.isEqual(val, b[key])
|
||||||
true
|
true
|
||||||
|
|
||||||
|
|
||||||
# Is a given array or object empty?
|
# Is a given array or object empty?
|
||||||
_.isEmpty = (obj) ->
|
_.isEmpty = (obj) ->
|
||||||
return obj.length is 0 if _.isArray obj
|
return obj.length is 0 if _.isArray(obj) or _.isString(obj)
|
||||||
(return false) for key of obj when hasOwnProperty.call(obj, key)
|
(return false) for key of obj when hasOwnProperty.call(obj, key)
|
||||||
true
|
true
|
||||||
|
|
||||||
|
@ -582,16 +596,19 @@
|
||||||
# JavaScript templating a-la **ERB**, pilfered from John Resig's
|
# JavaScript templating a-la **ERB**, pilfered from John Resig's
|
||||||
# *Secrets of the JavaScript Ninja*, page 83.
|
# *Secrets of the JavaScript Ninja*, page 83.
|
||||||
# Single-quote fix from Rick Strahl.
|
# Single-quote fix from Rick Strahl.
|
||||||
|
# With alterations for arbitrary delimiters, and to preserve whitespace.
|
||||||
_.template = (str, data) ->
|
_.template = (str, data) ->
|
||||||
c = _.templateSettings
|
c = _.templateSettings
|
||||||
endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
|
endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
|
||||||
fn = new Function 'obj',
|
fn = new Function 'obj',
|
||||||
'var p=[],print=function(){p.push.apply(p,arguments);};' +
|
'var p=[],print=function(){p.push.apply(p,arguments);};' +
|
||||||
'with(obj){p.push(\'' +
|
'with(obj||{}){p.push(\'' +
|
||||||
str.replace(/[\r\t\n]/g, " ")
|
str.replace(/\r/g, '\\r')
|
||||||
.replace(endMatch,"\t")
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\t/g, '\\t')
|
||||||
|
.replace(endMatch,"✄")
|
||||||
.split("'").join("\\'")
|
.split("'").join("\\'")
|
||||||
.split("\t").join("'")
|
.split("✄").join("'")
|
||||||
.replace(c.interpolate, "',$1,'")
|
.replace(c.interpolate, "',$1,'")
|
||||||
.split(c.start).join("');")
|
.split(c.start).join("');")
|
||||||
.split(c.end).join("p.push('") +
|
.split(c.end).join("p.push('") +
|
||||||
|
@ -608,6 +625,7 @@
|
||||||
_.select = _.filter
|
_.select = _.filter
|
||||||
_.all = _.every
|
_.all = _.every
|
||||||
_.any = _.some
|
_.any = _.some
|
||||||
|
_.contains = _.include
|
||||||
_.head = _.first
|
_.head = _.first
|
||||||
_.tail = _.rest
|
_.tail = _.rest
|
||||||
_.methods = _.functions
|
_.methods = _.functions
|
||||||
|
|
|
@ -1531,6 +1531,9 @@
|
||||||
top = del(o, 'top');
|
top = del(o, 'top');
|
||||||
this.expression.parenthetical = true;
|
this.expression.parenthetical = true;
|
||||||
code = this.expression.compile(o);
|
code = this.expression.compile(o);
|
||||||
|
if (top && this.expression.isPureStatement(o)) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
if (this.parenthetical || this.isStatement(o)) {
|
if (this.parenthetical || this.isStatement(o)) {
|
||||||
return top ? this.tab + code + ';' : code;
|
return top ? this.tab + code + ';' : code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
return (this.variables[name] = 'param');
|
return (this.variables[name] = 'param');
|
||||||
};
|
};
|
||||||
Scope.prototype.check = function(name) {
|
Scope.prototype.check = function(name) {
|
||||||
if (this.variables.hasOwnProperty(name)) {
|
if (Object.prototype.hasOwnProperty.call(this.variables, name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return !!(this.parent && this.parent.check(name));
|
return !!(this.parent && this.parent.check(name));
|
||||||
|
|
|
@ -1301,6 +1301,7 @@ exports.ParentheticalNode = class ParentheticalNode extends BaseNode
|
||||||
top = del o, 'top'
|
top = del o, 'top'
|
||||||
@expression.parenthetical = true
|
@expression.parenthetical = true
|
||||||
code = @expression.compile(o)
|
code = @expression.compile(o)
|
||||||
|
return code if top and @expression.isPureStatement o
|
||||||
if @parenthetical or @isStatement o
|
if @parenthetical or @isStatement o
|
||||||
return if top then @tab + code + ';' else code
|
return if top then @tab + code + ';' else code
|
||||||
"(#{code})"
|
"(#{code})"
|
||||||
|
|
|
@ -46,7 +46,7 @@ exports.Scope = class Scope
|
||||||
|
|
||||||
# Just check to see if a variable has already been declared, without reserving.
|
# Just check to see if a variable has already been declared, without reserving.
|
||||||
check: (name) ->
|
check: (name) ->
|
||||||
return true if @variables.hasOwnProperty name
|
return true if Object::hasOwnProperty.call @variables, name
|
||||||
!!(@parent and @parent.check(name))
|
!!(@parent and @parent.check(name))
|
||||||
|
|
||||||
# If we need to store an intermediate result, find an available name for a
|
# If we need to store an intermediate result, find an available name for a
|
||||||
|
|
Loading…
Reference in New Issue