Skip to content
12 changes: 6 additions & 6 deletions lib/coffeescript/nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 5 additions & 7 deletions src/nodes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2859,22 +2859,20 @@ exports.Param = class Param extends Base
# A splat, either as a parameter to a function, an argument to a call,
# or as part of a destructuring assignment.
exports.Splat = class Splat extends Base
constructor: (name) ->
super()
@name = if name.compile then name else new Literal name

children: ['name']

isAssignable: ->
@name.isAssignable() and (not @name.isAtomic or @name.isAtomic())

constructor: (name) ->
super()
@name = if name.compile then name else new Literal name

assigns: (name) ->
@name.assigns name

compileToFragments: (o) ->
[ @makeCode('...')
@name.compileToFragments(o)... ]
compileNode: (o) ->
[@makeCode('...'), @name.compileToFragments(o, LEVEL_OP)...]

unwrap: -> @name

Expand Down
50 changes: 48 additions & 2 deletions test/arrays.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ test "array splat expansions with assignments", ->


test "mixed shorthand objects in array lists", ->

arr = [
a:1
'b'
Expand All @@ -58,7 +57,6 @@ test "mixed shorthand objects in array lists", ->
eq arr[2].b, 1
eq arr[3], 'b'


test "array splats with nested arrays", ->
nonce = {}
a = [nonce]
Expand All @@ -70,6 +68,54 @@ test "array splats with nested arrays", ->
list = [1, 2, a...]
arrayEq list, [1, 2, [nonce]]

test "#4260: splat after existential operator soak", ->
a = {b: [3]}
foo = (a) -> [a]
arrayEq [a?.b...], [3]
arrayEq [c?.b ? []...], []
arrayEq [...a?.b], [3]
arrayEq [...c?.b ? []], []
arrayEq foo(a?.b...), [3]
arrayEq foo(...a?.b), [3]
arrayEq foo(c?.b ? []...), [undefined]
arrayEq foo(...c?.b ? []), [undefined]
e = yes
f = null
arrayEq [(a if e)?.b...], [3]
arrayEq [(a if f)?.b ? []...], []
arrayEq [...(a if e)?.b], [3]
arrayEq [...(a if f)?.b ? []], []
arrayEq foo((a if e)?.b...), [3]
arrayEq foo(...(a if e)?.b), [3]
arrayEq foo((a if f)?.b ? []...), [undefined]
arrayEq foo(...(a if f)?.b ? []), [undefined]

# Should not trigger implicit call, e.g. rest ... => rest(...)
arrayEq [... a?.b], [3]
arrayEq [... c?.b ? []], []
arrayEq [a?.b ...], [3]
arrayEq [(a if e)?.b ...], [3]
arrayEq foo(a?.b ...), [3]
arrayEq foo(... a?.b), [3]

test "#1349: trailing if after splat", ->
a = [3]
b = yes
c = null
foo = (a) -> [a]
arrayEq [a if b...], [3]
arrayEq [(a if c) ? []...], []
arrayEq [...a if b], [3]
arrayEq [...(a if c) ? []], []
arrayEq foo((a if b)...), [3]
arrayEq foo(...(a if b)), [3]
arrayEq foo((a if c) ? []...), [undefined]
arrayEq foo(...(a if c) ? []), [undefined]

# Should not trigger implicit call, e.g. rest ... => rest(...)
arrayEq [... a if b], [3]
arrayEq [a if b ...], [3]

test "#1274: `[] = a()` compiles to `false` instead of `a()`", ->
a = false
fn = -> a = true
Expand Down