diff --git a/lib/coffee-script/nodes.js b/lib/coffee-script/nodes.js index f5eb07723a..13bd8dc8d8 100644 --- a/lib/coffee-script/nodes.js +++ b/lib/coffee-script/nodes.js @@ -1428,7 +1428,7 @@ Obj.prototype.children = ['properties']; Obj.prototype.compileNode = function(o) { - var answer, dynamicIndex, hasDynamic, i, idt, indent, j, join, k, key, l, lastNoncom, len1, len2, len3, node, oref, prop, props, ref3, value; + var answer, i, idt, indent, j, join, k, key, lastNoncom, len1, len2, node, prop, props, ref3, value; props = this.properties; if (this.generated) { for (j = 0, len1 = props.length; j < len1; j++) { @@ -1438,34 +1438,14 @@ } } } - for (dynamicIndex = k = 0, len2 = props.length; k < len2; dynamicIndex = ++k) { - prop = props[dynamicIndex]; - if ((prop.variable || prop).base instanceof Parens) { - break; - } - } - hasDynamic = dynamicIndex < props.length; idt = o.indent += TAB; lastNoncom = this.lastNonComment(this.properties); answer = []; - if (hasDynamic) { - oref = o.scope.freeVariable('obj'); - answer.push(this.makeCode("(\n" + idt + oref + " = ")); - } - answer.push(this.makeCode("{" + (props.length === 0 || dynamicIndex === 0 ? '}' : '\n'))); - for (i = l = 0, len3 = props.length; l < len3; i = ++l) { + answer.push(this.makeCode("{" + (props.length === 0 ? '}' : '\n'))); + for (i = k = 0, len2 = props.length; k < len2; i = ++k) { prop = props[i]; - if (i === dynamicIndex) { - if (i !== 0) { - answer.push(this.makeCode("\n" + idt + "}")); - } - answer.push(this.makeCode(',\n')); - } - join = i === props.length - 1 || i === dynamicIndex - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; + join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n'; indent = prop instanceof Comment ? '' : idt; - if (hasDynamic && i < dynamicIndex) { - indent += TAB; - } if (prop instanceof Assign) { if (prop.context !== 'object') { prop.operatorToken.error("unexpected " + prop.operatorToken.value); @@ -1477,22 +1457,15 @@ if (prop instanceof Value && prop["this"]) { prop = new Assign(prop.properties[0].name, prop, 'object'); } - if (!(prop instanceof Comment)) { - if (i < dynamicIndex) { - if (!(prop instanceof Assign)) { - prop = new Assign(prop, prop, 'object'); + if (!(prop instanceof Comment) && !(prop instanceof Assign)) { + if (prop.isComplex()) { + ref3 = prop.base.cache(o), key = ref3[0], value = ref3[1]; + if (key instanceof IdentifierLiteral) { + key = new PropertyName(key.value); } + prop = new Assign(key, value, 'object'); } else { - if (prop instanceof Assign) { - key = prop.variable; - value = prop.value; - } else { - ref3 = prop.base.cache(o), key = ref3[0], value = ref3[1]; - if (key instanceof IdentifierLiteral) { - key = new PropertyName(key.value); - } - } - prop = new Assign(new Value(new IdentifierLiteral(oref), [new Access(key)]), value); + prop = new Assign(prop, prop, 'object'); } } if (indent) { @@ -1503,14 +1476,10 @@ answer.push(this.makeCode(join)); } } - if (hasDynamic) { - answer.push(this.makeCode(",\n" + idt + oref + "\n" + this.tab + ")")); - } else { - if (props.length !== 0) { - answer.push(this.makeCode("\n" + this.tab + "}")); - } + if (props.length !== 0) { + answer.push(this.makeCode("\n" + this.tab + "}")); } - if (this.front && !hasDynamic) { + if (this.front) { return this.wrapInBraces(answer); } else { return answer; @@ -2193,7 +2162,10 @@ } compiledName = this.variable.compileToFragments(o, LEVEL_LIST); if (this.context === 'object') { - if (ref8 = fragmentsToText(compiledName), indexOf.call(JS_FORBIDDEN, ref8) >= 0) { + if (this.variable.isComplex()) { + compiledName.unshift(this.makeCode('[')); + compiledName.push(this.makeCode(']')); + } else if (ref8 = fragmentsToText(compiledName), indexOf.call(JS_FORBIDDEN, ref8) >= 0) { compiledName.unshift(this.makeCode('"')); compiledName.push(this.makeCode('"')); } diff --git a/src/nodes.coffee b/src/nodes.coffee index 680bb21f01..781a2bcfb7 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -981,27 +981,18 @@ exports.Obj = class Obj extends Base if @generated for node in props when node instanceof Value node.error 'cannot have an implicit value in an implicit object' - break for prop, dynamicIndex in props when (prop.variable or prop).base instanceof Parens - hasDynamic = dynamicIndex < props.length - idt = o.indent += TAB - lastNoncom = @lastNonComment @properties + idt = o.indent += TAB + lastNoncom = @lastNonComment @properties answer = [] - if hasDynamic - oref = o.scope.freeVariable 'obj' - answer.push @makeCode "(\n#{idt}#{oref} = " - answer.push @makeCode "{#{if props.length is 0 or dynamicIndex is 0 then '}' else '\n'}" + answer.push @makeCode "{#{if props.length is 0 then '}' else '\n'}" for prop, i in props - if i is dynamicIndex - answer.push @makeCode "\n#{idt}}" unless i is 0 - answer.push @makeCode ',\n' - join = if i is props.length - 1 or i is dynamicIndex - 1 + join = if i is props.length - 1 '' else if prop is lastNoncom or prop instanceof Comment '\n' else ',\n' indent = if prop instanceof Comment then '' else idt - indent += TAB if hasDynamic and i < dynamicIndex if prop instanceof Assign if prop.context isnt 'object' prop.operatorToken.error "unexpected #{prop.operatorToken.value}" @@ -1009,26 +1000,18 @@ exports.Obj = class Obj extends Base prop.variable.error 'invalid object key' if prop instanceof Value and prop.this prop = new Assign prop.properties[0].name, prop, 'object' - if prop not instanceof Comment - if i < dynamicIndex - if prop not instanceof Assign - prop = new Assign prop, prop, 'object' + if prop not instanceof Comment and prop not instanceof Assign + if prop.isComplex() + [key, value] = prop.base.cache o + key = new PropertyName key.value if key instanceof IdentifierLiteral + prop = new Assign key, value, 'object' else - if prop instanceof Assign - key = prop.variable - value = prop.value - else - [key, value] = prop.base.cache o - key = new PropertyName key.value if key instanceof IdentifierLiteral - prop = new Assign (new Value (new IdentifierLiteral oref), [new Access key]), value + prop = new Assign prop, prop, 'object' if indent then answer.push @makeCode indent answer.push prop.compileToFragments(o, LEVEL_TOP)... if join then answer.push @makeCode join - if hasDynamic - answer.push @makeCode ",\n#{idt}#{oref}\n#{@tab})" - else - answer.push @makeCode "\n#{@tab}}" unless props.length is 0 - if @front and not hasDynamic then @wrapInBraces answer else answer + answer.push @makeCode "\n#{@tab}}" unless props.length is 0 + if @front then @wrapInBraces answer else answer assigns: (name) -> for prop in @properties when prop.assigns name then return yes @@ -1431,7 +1414,10 @@ exports.Assign = class Assign extends Base compiledName = @variable.compileToFragments o, LEVEL_LIST if @context is 'object' - if fragmentsToText(compiledName) in JS_FORBIDDEN + if @variable.isComplex() + compiledName.unshift @makeCode '[' + compiledName.push @makeCode ']' + else if fragmentsToText(compiledName) in JS_FORBIDDEN compiledName.unshift @makeCode '"' compiledName.push @makeCode '"' return compiledName.concat @makeCode(": "), val