From f7e6dabf6b6d45323b87f81cc462c509591f2d6d Mon Sep 17 00:00:00 2001 From: satyr Date: Sat, 2 Oct 2010 20:19:37 +0900 Subject: [PATCH] fixed a regression where destructuring `for` miscompiles --- lib/nodes.js | 25 ++++++++++--------------- src/nodes.coffee | 22 +++++++++++++--------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/nodes.js b/lib/nodes.js index 1ee05a2f..7dbdd21b 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1592,7 +1592,7 @@ return ''; }; ForNode.prototype.compileNode = function(o) { - var body, codeInBody, forPart, guardPart, index, ivar, lvar, name, namePart, range, ref, returnResult, rvar, scope, source, sourcePart, stepPart, svar, topLevel, varPart, vars; + var body, codeInBody, forPart, guardPart, idt1, index, ivar, lvar, name, namePart, range, ref, returnResult, rvar, scope, source, sourcePart, stepPart, svar, topLevel, varPart, vars; topLevel = del(o, 'top') && !this.returns; range = this.source instanceof ValueNode && this.source.base instanceof RangeNode && !this.source.properties.length; source = range ? this.source.base : this.source; @@ -1622,6 +1622,7 @@ varPart = ''; guardPart = ''; body = Expressions.wrap([this.body]); + idt1 = this.idt(1); if (range) { sourcePart = source.compileVariables(o); forPart = source.compile(merge(o, { @@ -1639,17 +1640,9 @@ sourcePart = ("" + (ref) + " = " + (svar) + ";"); svar = ref; } - if (this.pattern) { - namePart = new AssignNode(this.name, literal("" + (svar) + "[" + (ivar) + "]")).compile(merge(o, { - indent: this.idt(1), - top: true, - keepLevel: true - })) + '\n'; - } else { - if (name) { - namePart = ("" + (name) + " = " + (svar) + "[" + (ivar) + "]"); - } - } + namePart = this.pattern ? new AssignNode(this.name, literal("" + (svar) + "[" + (ivar) + "]")).compile(merge(o, { + top: true + })) : (name ? ("" + (name) + " = " + (svar) + "[" + (ivar) + "]") : undefined); if (!(this.object)) { lvar = scope.freeVariable('len'); stepPart = this.step ? ("" + (ivar) + " += " + (this.step.compile(o))) : ("" + (ivar) + "++"); @@ -1677,16 +1670,18 @@ } body = ClosureNode.wrap(body, true); } else { - varPart = (namePart || '') && (this.pattern ? namePart : ("" + (this.idt(1)) + (namePart) + ";\n")); + if (namePart) { + varPart = ("" + (idt1) + (namePart) + ";\n"); + } } if (this.object) { forPart = ("" + (ivar) + " in " + (svar)); if (!(this.raw)) { - guardPart = ("\n" + (this.idt(1)) + "if (!" + (utility('hasProp')) + ".call(" + (svar) + ", " + (ivar) + ")) continue;"); + guardPart = ("\n" + (idt1) + "if (!" + (utility('hasProp')) + ".call(" + (svar) + ", " + (ivar) + ")) continue;"); } } body = body.compile(merge(o, { - indent: this.idt(1), + indent: idt1, top: true })); vars = range ? name : ("" + (name) + ", " + (ivar)); diff --git a/src/nodes.coffee b/src/nodes.coffee index 35ea4318..f9ce91ee 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1425,6 +1425,7 @@ exports.ForNode = class ForNode extends BaseNode varPart = '' guardPart = '' body = Expressions.wrap([@body]) + idt1 = @idt 1 if range sourcePart = source.compileVariables(o) forPart = source.compile merge o, index: ivar, step: @step @@ -1436,10 +1437,10 @@ exports.ForNode = class ForNode extends BaseNode ref = scope.freeVariable 'ref' sourcePart = "#{ref} = #{svar};" svar = ref - if @pattern - namePart = new AssignNode(@name, literal("#{svar}[#{ivar}]")).compile(merge o, {indent: @idt(1), top: true, keepLevel: yes}) + '\n' - else - namePart = "#{name} = #{svar}[#{ivar}]" if name + namePart = if @pattern + new AssignNode(@name, literal "#{svar}[#{ivar}]").compile merge o, top: on + else if name + "#{name} = #{svar}[#{ivar}]" unless @object lvar = scope.freeVariable 'len' stepPart = if @step then "#{ivar} += #{ @step.compile(o) }" else "#{ivar}++" @@ -1447,7 +1448,6 @@ exports.ForNode = class ForNode extends BaseNode sourcePart = (if rvar then "#{rvar} = []; " else '') + sourcePart sourcePart = if sourcePart then "#{@tab}#{sourcePart}\n#{@tab}" else @tab returnResult = @compileReturnValue(rvar, o) - body = PushNode.wrap(rvar, body) unless topLevel if @guard body = Expressions.wrap([new IfNode(@guard, body)]) @@ -1457,13 +1457,17 @@ exports.ForNode = class ForNode extends BaseNode body.unshift literal "var #{index} = #{ivar}" if index body = ClosureNode.wrap(body, true) else - varPart = (namePart or '') and (if @pattern then namePart else "#{@idt(1)}#{namePart};\n") + varPart = "#{idt1}#{namePart};\n" if namePart if @object forPart = "#{ivar} in #{svar}" - guardPart = "\n#{@idt(1)}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw - body = body.compile(merge(o, {indent: @idt(1), top: true})) + guardPart = "\n#{idt1}if (!#{utility('hasProp')}.call(#{svar}, #{ivar})) continue;" unless @raw + body = body.compile merge o, indent: idt1, top: true vars = if range then name else "#{name}, #{ivar}" - "#{sourcePart}for (#{forPart}) {#{guardPart}\n#{varPart}#{body}\n#{@tab}}#{returnResult}" + """ + #{sourcePart}for (#{forPart}) {#{guardPart} + #{varPart}#{body} + #{@tab}}#{returnResult} + """ #### SwitchNode