Permalink
Browse files

fixes #1630: `in` should check indices of the right operand when it can

pass a `hasOwnProperty` check for them
  • Loading branch information...
1 parent 8686e31 commit 2ff6c4c3fcb853acf364227e1f58cd3487bb611b @michaelficarra michaelficarra committed Aug 26, 2011
Showing with 35 additions and 24 deletions.
  1. +2 −2 lib/coffee-script/lexer.js
  2. +17 −8 lib/coffee-script/nodes.js
  3. +2 −2 lib/coffee-script/rewriter.js
  4. +11 −12 src/nodes.coffee
  5. +3 −0 test/operators.coffee

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -590,7 +590,6 @@ exports.Extends = class Extends extends Base
# Hooks one constructor into another's prototype chain.
compile: (o) ->
- utility 'hasProp'
new Call(new Value(new Literal utility 'extends'), [@child, @parent]).compile o
#### Access
@@ -1593,7 +1592,7 @@ exports.For = class For extends Base
varPart = "\n#{idt1}#{namePart};" if namePart
if @object
forPart = "#{ivar} in #{svar}"
- guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" if @own
+ guardPart = "\n#{idt1}if (!#{utility 'hasProp'}.call(#{svar}, #{ivar})) continue;" if @own
body = body.compile merge(o, indent: idt1), LEVEL_TOP
body = '\n' + body + '\n' if body
"""
@@ -1801,35 +1800,35 @@ UTILITIES =
# Correctly set up a prototype chain for inheritance, including a reference
# to the superclass for `super()` calls, and copies of any static properties.
- extends: '''
+ extends: -> """
function(child, parent) {
- for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
+ for (var key in parent) { if (#{utility 'hasProp'}.call(parent, key)) child[key] = parent[key]; }
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.__super__ = parent.prototype;
return child;
}
- '''
+ """
# Create a function bound to the current value of "this".
- bind: '''
+ bind: -> '''
function(fn, me){ return function(){ return fn.apply(me, arguments); }; }
'''
# Discover if an item is in an array.
- indexOf: '''
+ indexOf: -> """
Array.prototype.indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
- if (this[i] === item) return i;
+ if (#{utility 'hasProp'}.call(this, i) && this[i] === item) return i;
@jdalton

jdalton Oct 15, 2011

Array#indexOf doesn't use an equiv to Object#hasOwnProperty internally, instead it uses something more like the in operator.
Relevant comment on c1d24944.

}
return -1;
}
- '''
+ """
# Shortcuts to speed up the lookup time for native functions.
- hasProp: 'Object.prototype.hasOwnProperty'
- slice : 'Array.prototype.slice'
+ hasProp: -> 'Object.prototype.hasOwnProperty'
+ slice : -> 'Array.prototype.slice'
# Levels indicate a node's position in the AST. Useful for knowing if
# parens are necessary or superfluous.
@@ -1871,7 +1870,7 @@ IS_STRING = /^['"]/
# Helper for ensuring that utility functions are assigned at the top level.
utility = (name) ->
ref = "__#{name}"
- Scope.root.assign ref, UTILITIES[name]
+ Scope.root.assign ref, UTILITIES[name]()
ref
multident = (code, tab) ->
View
@@ -197,6 +197,9 @@ test "#1100: precedence in or-test compilation of `in`", ->
ok 0 in [1, 1 and 0]
ok not (0 in [1, 0 or 1])
+test "#1630: `in` should check `hasOwnProperty`", ->
+ ok undefined not in length: 1
+
# Chained Comparison

0 comments on commit 2ff6c4c

Please sign in to comment.