1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

fixes #1844: bound functions in nested comprehensions

causing empty var statements
This commit is contained in:
Michael Ficarra 2011-11-10 03:08:38 -05:00
parent a296957771
commit 6d6a5f609a
8 changed files with 51 additions and 30 deletions

View file

@ -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');

View file

@ -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;

View file

@ -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 (declars || assigns) {
if (i) code += '\n';
code += "" + this.tab + "var ";
if (declars) code += scope.declaredVariables().join(', ');
if (assigns) {
code += "" + this.tab + "var " + (multident(scope.assignedVariables().join(', '), this.tab)) + ";\n";
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;

View file

@ -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() {

View file

@ -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;
};

View file

@ -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 or assigns
code += '\n' if i
code += "#{@tab}var "
if declars
code += "#{@tab}var #{ scope.declaredVariables().join(', ') };\n"
code += scope.declaredVariables().join ', '
if assigns
code += "#{@tab}var #{ multident scope.assignedVariables().join(', '), @tab };\n"
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

View file

@ -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?

View file

@ -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