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:
parent
a296957771
commit
6d6a5f609a
8 changed files with 51 additions and 30 deletions
|
@ -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');
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue