From 8fd78d38199d7c58525448c3f3852fb670a1aedc Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Thu, 23 Dec 2010 09:33:12 -0800 Subject: [PATCH] Fixing literals that should be statements, and adding failed compilation tests. --- lib/nodes.js | 23 ++++++++++++----------- src/nodes.coffee | 12 ++++++++---- test/test_compilation.coffee | 11 +++++++++++ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index 02ccbcff..216f4c6f 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -320,22 +320,21 @@ this.value = value; } Literal.prototype.makeReturn = function() { - if (this.jumps()) { - return this; - } else { - return new Return(this); - } + return new Return(this); }; Literal.prototype.isAssignable = function() { return IDENTIFIER.test(this.value); }; + Literal.prototype.isStatement = function() { + var _ref; + return (_ref = this.value) === 'break' || _ref === 'continue' || _ref === 'debugger'; + }; Literal.prototype.isComplex = NO; Literal.prototype.assigns = function(name) { return name === this.value; }; Literal.prototype.jumps = function(o) { - var _ref; - if ((_ref = this.value) !== 'break' && _ref !== 'continue' && _ref !== 'debugger') { + if (!this.isStatement()) { return false; } if (!(o && (o.loop || o.block && (this.value !== 'continue')))) { @@ -344,11 +343,13 @@ return false; } }; - Literal.prototype.compile = function() { - if (this.value.reserved) { - return "\"" + this.value + "\""; + Literal.prototype.compileNode = function(o) { + var code; + code = this.value.reserved ? "\"" + this.value + "\"" : this.value; + if (this.isStatement()) { + return "" + this.tab + code + ";"; } else { - return this.value; + return code; } }; Literal.prototype.toString = function() { diff --git a/src/nodes.coffee b/src/nodes.coffee index 3053c820..6bab0b71 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -271,22 +271,26 @@ exports.Literal = class Literal extends Base constructor: (@value) -> makeReturn: -> - if @jumps() then this else new Return this + new Return this isAssignable: -> IDENTIFIER.test @value + isStatement: -> + @value in ['break', 'continue', 'debugger'] + isComplex: NO assigns: (name) -> name is @value jumps: (o) -> - return no unless @value in ['break', 'continue', 'debugger'] + return no unless @isStatement() if not (o and (o.loop or o.block and (@value isnt 'continue'))) then this else no - compile: -> - if @value.reserved then "\"#{@value}\"" else @value + compileNode: (o) -> + code = if @value.reserved then "\"#{@value}\"" else @value + if @isStatement() then "#{@tab}#{code};" else code toString: -> ' "' + @value + '"' diff --git a/test/test_compilation.coffee b/test/test_compilation.coffee index 360a93d2..5d0c4b2c 100644 --- a/test/test_compilation.coffee +++ b/test/test_compilation.coffee @@ -13,3 +13,14 @@ catch e then eq e.message, 'unclosed CALL_START on line 1' eq CoffeeScript.compile('for k of o then', bare: on, globals: on), 'for (k in o) {}' +# Compilations that should fail. +cantCompile = (code) -> + throws -> CoffeeScript.compile code + +cantCompile 'a = (break)' + +cantCompile 'a = (return 5 for item in list)' + +cantCompile 'a = (return 5 while condition)' + +cantCompile 'a = for x in y\n return 5' \ No newline at end of file