diff --git a/lib/coffee-script/coffee-script.js b/lib/coffee-script/coffee-script.js index e8e6f140..da3883cf 100644 --- a/lib/coffee-script/coffee-script.js +++ b/lib/coffee-script/coffee-script.js @@ -1,6 +1,6 @@ (function() { - var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref; - var __hasProp = Object.prototype.hasOwnProperty; + var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref, + __hasProp = Object.prototype.hasOwnProperty; fs = require('fs'); diff --git a/lib/coffee-script/lexer.js b/lib/coffee-script/lexer.js index a4178c71..81c16da4 100644 --- a/lib/coffee-script/lexer.js +++ b/lib/coffee-script/lexer.js @@ -1,6 +1,7 @@ (function() { - var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref2; - var __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }; + var BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, key, last, starts, _ref, _ref2, + __hasProp = Object.prototype.hasOwnProperty, + __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }; _ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES; diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index 5d8647ea..ade4c359 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -1,6 +1,8 @@ (function() { - var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__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; }, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }; + var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, starts, unfoldSoak, utility, _ref, + __hasProp = Object.prototype.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__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; }, + __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }; Scope = require('./scope').Scope; @@ -312,7 +314,7 @@ }; Block.prototype.compileWithDeclarations = function(o) { - var assigns, code, declars, exp, i, post, rest, scope, _len, _ref2; + var assigns, code, declars, exp, i, post, rest, scope, tab, _len, _ref2; code = post = ''; _ref2 = this.expressions; for (i = 0, _len = _ref2.length; i < _len; i++) { @@ -333,12 +335,19 @@ if (scope.expressions === this) { declars = o.scope.hasDeclarations(); assigns = scope.hasAssignments; - if ((declars || assigns) && i) code += '\n'; - if (declars) { - code += "" + this.tab + "var " + (scope.declaredVariables().join(', ')) + ";\n"; - } - if (assigns) { - code += "" + this.tab + "var " + (multident(scope.assignedVariables().join(', '), this.tab)) + ";\n"; + if (declars || assigns) { + if (i) code += '\n'; + code += "" + this.tab + "var "; + if (declars) code += scope.declaredVariables().join(', '); + if (assigns) { + tab = this.tab; + if (declars) { + tab += TAB; + code += ",\n" + tab; + } + code += scope.assignedVariables().join(",\n" + tab); + } + code += ';\n'; } } return code + post; @@ -559,8 +568,8 @@ }; Value.prototype.unfoldSoak = function(o) { - var result; - var _this = this; + var result, + _this = this; if (this.unfoldedSoak != null) return this.unfoldedSoak; result = (function() { var fst, i, ifn, prop, ref, snd, _len, _ref2; diff --git a/lib/coffee-script/rewriter.js b/lib/coffee-script/rewriter.js index 578741b0..549d5eff 100644 --- a/lib/coffee-script/rewriter.js +++ b/lib/coffee-script/rewriter.js @@ -1,6 +1,8 @@ (function() { - var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref; - var __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }, __slice = Array.prototype.slice; + var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_BLOCK, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, left, rite, _i, _len, _ref, + __hasProp = Object.prototype.hasOwnProperty, + __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (__hasProp.call(this, i) && this[i] === item) return i; } return -1; }, + __slice = Array.prototype.slice; exports.Rewriter = (function() { diff --git a/lib/coffee-script/scope.js b/lib/coffee-script/scope.js index df1415ea..1abb5641 100644 --- a/lib/coffee-script/scope.js +++ b/lib/coffee-script/scope.js @@ -22,10 +22,9 @@ } Scope.prototype.add = function(name, type, immediate) { - var pos; if (this.shared && !immediate) return this.parent.add(name, type, immediate); - if (typeof (pos = this.positions[name]) === 'number') { - return this.variables[pos].type = type; + if (this.positions.hasOwnProperty(name)) { + return this.variables[this.positions[name]].type = type; } else { return this.positions[name] = this.variables.push({ name: name, @@ -84,7 +83,7 @@ this.add(name, { value: value, assigned: true - }); + }, true); return this.hasAssignments = true; }; diff --git a/src/nodes.coffee b/src/nodes.coffee index 00d266a4..979e6c48 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -269,12 +269,18 @@ exports.Block = class Block extends Base if scope.expressions is this declars = o.scope.hasDeclarations() assigns = scope.hasAssignments - if (declars or assigns) and i - code += '\n' - if declars - code += "#{@tab}var #{ scope.declaredVariables().join(', ') };\n" - if assigns - code += "#{@tab}var #{ multident scope.assignedVariables().join(', '), @tab };\n" + if declars or assigns + code += '\n' if i + code += "#{@tab}var " + if declars + code += scope.declaredVariables().join ', ' + if assigns + tab = @tab + if declars + tab += TAB + code += ",\n#{tab}" + code += scope.assignedVariables().join ",\n#{tab}" + code += ';\n' code + post # Wrap up the given nodes as a **Block**, unless it already happens diff --git a/src/scope.coffee b/src/scope.coffee index 99b329c0..53a6b62b 100644 --- a/src/scope.coffee +++ b/src/scope.coffee @@ -25,8 +25,8 @@ exports.Scope = class Scope # Adds a new variable or overrides an existing one. add: (name, type, immediate) -> return @parent.add name, type, immediate if @shared and not immediate - if typeof (pos = @positions[name]) is 'number' - @variables[pos].type = type + if @positions.hasOwnProperty name + @variables[@positions[name]].type = type else @positions[name] = @variables.push({name, type}) - 1 @@ -73,7 +73,7 @@ exports.Scope = class Scope # Ensure that an assignment is made at the top of this scope # (or at the top-level scope, if requested). assign: (name, value) -> - @add name, value: value, assigned: true + @add name, (value: value, assigned: true), yes @hasAssignments = yes # Does this scope have any declared variables? diff --git a/test/functions.coffee b/test/functions.coffee index 5276b63f..0327cedf 100644 --- a/test/functions.coffee +++ b/test/functions.coffee @@ -178,3 +178,7 @@ test "arguments vs parameters", -> doesNotThrow -> CoffeeScript.compile "f(x) ->" f = (g) -> g() eq 5, f (x) -> 5 + +test "#1844: bound functions in nested comprehensions causing empty var statements", -> + a = ((=>) for a in [0] for b in [0]) + eq 1, a.length