PageSourceSearch

https://coffeescript.org/test.html

html coffeescript.org collected 2026-09-24 07:19:30 UTC 691,390 bytes, 33,753 lines download raw bytes

1<!DOCTYPE html>
2<html>
3<head>
4  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
5  <title>CoffeeScript Test Suite</title>
6  
6<script nomodule src="browser-compiler-legacy/coffeescript.js"></script>
6
7  
7<script type="module">
8    import CoffeeScript from './browser-compiler-modern/coffeescript.js';
9    window.CoffeeScript = CoffeeScript;
10    window.addEventListener('DOMContentLoaded', CoffeeScript.runScripts, false);
11  </script>
11
12  
12<script src="https://cdn.jsdelivr.net/underscorejs/1.8.3/underscore-min.js"></script>
12
13  <style>
14    body, pre {
15      font-family: Consolas, Menlo, Monaco, monospace;
16    }
17    body {
18      margin: 1em;
19    }
20    h1 {
21      font-size: 1.3em;
22    }
23    div {
24      margin: 0.6em;
25    }
26    .good {
27      color: #22b24c
28    }
29    .bad {
30      color: #eb6864
31    }
32    .subtle {
33      font-size: 0.7em;
34      color: #999999
35    }
36  </style>
37</head>
38<body>
39
40<h1>CoffeeScript Test Suite</h1>
41
42<pre id="stdout"></pre>
43
44<script type="text/coffeescript">
45@testingBrowser = yes
46@global = window
47@bold = @red = @green = @reset = ''
48stdout = document.getElementById 'stdout'
49start = new Date
50@currentFile = ''
51@passedTests = failedTests = total = done = 0
52
53say = (msg, className, id) ->
54  div = document.createElement 'div'
55  div.className = className if className?
56  div.id = id if id?
57  div.appendChild document.createTextNode msg
58  stdout.appendChild div
59  msg
60
61asyncTests = []
62onFail = (description, fn, err) ->
63  failures.push
64    error: err
65    description: description
66    source: fn.toString() if fn.toString?
67
68@test = (description, fn) ->
69  ++total
70  try
71    result = fn.call(fn)
72    if result instanceof Promise # An async test.
73      asyncTests.push result
74      result.then ->
75        passedTests++
76      .catch (err) ->
77        onFail description, fn, err
78    else
79      passedTests++
80  catch err
81    onFail description, fn, err
82
83@failures =
84  push: (failure) -> # Match function called by regular tests
85    ++failedTests
86    say "#{failure.description}:", 'bad'
87    say failure.source, 'subtle' if failure.source?
88    say failure.error, 'bad'
89    console.error failure.error
90
91@ok = (good, msg = 'Error') ->
92  throw Error msg unless good
93
94# Polyfill Node assert’s fail
95@fail = ->
96  ok no
97
98# Polyfill Node assert’s deepEqual with Underscore’s isEqual
99@deepEqual = (a, b) ->
100  ok _.isEqual(a, b), "Expected #{JSON.stringify a} to deep equal #{JSON.stringify b}"
101
102# See [http://wiki.ecmascript.org/doku.php?id=harmony:egal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
103egal = (a, b) ->
104  if a is b
105    a isnt 0 or 1/a is 1/b
106  else
107    a isnt a and b isnt b
108
109# A recursive functional equivalence helper; uses egal for testing equivalence.
110arrayEgal = (a, b) ->
111  if egal a, b then yes
112  else if a instanceof Array and b instanceof Array
113    return no unless a.length is b.length
114    return no for el, idx in a when not arrayEgal el, b[idx]
115    yes
116
117diffOutput = (expectedOutput, actualOutput) ->
118  expectedOutputLines = expectedOutput.split '\n'
119  actualOutputLines = actualOutput.split '\n'
120  for line, i in actualOutputLines
121    if line isnt expectedOutputLines[i]
122      actualOutputLines[i] = "#{yellow}#{line}#{reset}"
123  """Expected generated JavaScript to be:
124  #{reset}#{expectedOutput}#{red}
125    but instead it was:
126  #{reset}#{actualOutputLines.join '\n'}#{red}"""
127
128@eq = (a, b, msg) ->
129  ok egal(a, b), msg or
130  "Expected #{reset}#{a}#{red} to equal #{reset}#{b}#{red}"
131
132@arrayEq = (a, b, msg) ->
133  ok arrayEgal(a, b), msg or
134  "Expected #{reset}#{a}#{red} to deep equal #{reset}#{b}#{red}"
135
136@eqJS = (input, expectedOutput, msg) ->
137  actualOutput = CoffeeScript.compile input, bare: yes
138  .replace /^\s+|\s+$/g, '' # Trim leading/trailing whitespace.
139  ok egal(expectedOutput, actualOutput), msg or diffOutput expectedOutput, actualOutput
140
141@isWindows = -> process.platform is 'win32'
142
143@inspect = (obj) ->
144  if global.testingBrowser
145    JSON.stringify obj, null, 2
146  else
147    require('util').inspect obj,
148      depth: 10
149      colors: if process.env.NODE_DISABLE_COLORS then no else yes
150
151# Helpers to get AST nodes for a string of code.
152@getAstRoot = getAstRoot = (code) ->
153  CoffeeScript.compile code, ast: yes
154
155# The root node is always a `File` node, so for brevity in the tests return its
156# children from `program.body`.
157getAstExpressions = (code) ->
158  ast = getAstRoot code
159  ast.program.body
160
161# Many tests want just the root node.
162@getAstExpression = (code) ->
163  expressionStatementAst = getAstExpressions(code)[0]
164  ok expressionStatementAst.type is 'ExpressionStatement', 'Expected ExpressionStatement AST wrapper'
165  expressionStatementAst.expression
166
167@getAstStatement = (code) ->
168  statement = getAstExpressions(code)[0]
169  ok statement.type isnt 'ExpressionStatement', "Didn't expect ExpressionStatement AST wrapper"
170  statement
171
172@getAstExpressionOrStatement = (code) ->
173  expressionAst = getAstExpressions(code)[0]
174  return expressionAst unless expressionAst.type is 'ExpressionStatement'
175  expressionAst.expression
176
177@throwsCompileError = (code, compileOpts, args...) ->
178  throws -> CoffeeScript.compile code, compileOpts, args...
179  throws -> CoffeeScript.compile code, Object.assign({}, (compileOpts ? {}), ast: yes), args...
180
181@doesNotThrowCompileError = (code, compileOpts, args...) ->
182  doesNotThrow -> CoffeeScript.compile code, compileOpts, args...
183  doesNotThrow -> CoffeeScript.compile code, Object.assign({}, (compileOpts ? {}), ast: yes), args...
184
185
186@doesNotThrow = (fn) ->
187  fn()
188  ok yes
189
190@throws = (fun, err, msg) ->
191  try
192    fun()
193  catch e
194    if err
195      if typeof err is 'function' and e instanceof err # Handle comparing exceptions
196        ok yes
197      else if e.toString().indexOf('[stdin]') is 0 # Handle comparing error messages
198        ok err e
199      else if err instanceof RegExp
200        ok err.test e
201      else
202        eq e, err
203    else
204      ok yes
205    return
206  ok no
207
208
209# Run the tests
210for test in document.getElementsByClassName 'test'
211  say '\u2714 ' + test.id
212  options = {}
213  options.filename = currentFile = test.id
214  options.literate = yes if test.type is 'text/x-literate-coffeescript'
215  CoffeeScript.run test.innerHTML, options
216
217# Finish up
218done = ->
219  yay = passedTests is total and not failedTests
220  sec = (new Date - start) / 1000
221  msg = "passed #{passedTests} tests in #{sec.toFixed 2} seconds"
222  msg = "failed #{total - passedTests} tests and #{msg}" unless yay
223  say msg, (if yay then 'good' else 'bad'), 'result'
224
225  gtag 'event', 'tests_complete',
226    event_category: 'tests'
227    event_label: if yay then 'passed' else 'failed'
228    value: if yay then passedTests else total - passedTests
229  gtag 'event', 'tests_report',
230    event_category: 'tests'
231    event_label: msg
232  gtag 'event', 'timing_complete',
233    name: 'tests_run'
234    value: sec * 1000
235
236Promise.all(asyncTests).then(done).catch(done)
237</script>
237
238
239<script type="text/x-coffeescript" class="test" id="abstract_syntax_tree">
240# Astract Syntax Tree generation
241# ------------------------------
242
243# Recursively compare all values of enumerable properties of `expected` with
244# those of `actual`. Use `looseArray` helper function to skip array length
245# comparison.
246deepStrictIncludeExpectedProperties = (actual, expected) ->
247  eq actual.length, expected.length if expected instanceof Array and not expected.loose
248  for key, val of expected
249    if val? and typeof val is 'object'
250      fail "Property #{reset}#{key}#{red} expected, but was missing" unless actual[key]
251      deepStrictIncludeExpectedProperties actual[key], val
252    else
253      eq actual[key], val, """
254        Property #{reset}#{key}#{red}: expected #{reset}#{actual[key]}#{red} to equal #{reset}#{val}#{red}
255          Expected AST output to include:
256          #{reset}#{inspect expected}#{red}
257          but instead it was:
258          #{reset}#{inspect actual}#{red}
259      """
260  actual
261
262# Flag array for loose comparison. See reference to `.loose` in
263# `deepStrictIncludeExpectedProperties` above.
264looseArray = (arr) ->
265  Object.defineProperty arr, 'loose',
266    value: yes
267    enumerable: no
268  arr
269
270testAgainstExpected = (ast, expected) ->
271  if expected?
272    deepStrictIncludeExpectedProperties ast, expected
273  else
274    # Convenience for creating new tests; call `testExpression` with no second
275    # parameter to see what the current AST generation is for your input code.
276    console.log inspect ast
277
278testExpression = (code, expected) ->
279  ast = getAstExpression code
280  testAgainstExpected ast, expected
281
282testStatement = (code, expected) ->
283  ast = getAstStatement code
284  testAgainstExpected ast, expected
285
286testComments = (code, expected) ->
287  ast = getAstRoot code
288  testAgainstExpected ast.comments, expected
289
290test 'Confirm functionality of `deepStrictIncludeExpectedProperties`', ->
291  actual =
292    name: 'Name'
293    a:
294      b: 1
295      c: 2
296    x: [1, 2, 3]
297
298  check = (message, test, expected) ->
299    test (-> deepStrictIncludeExpectedProperties actual, expected), null, message
300
301  check 'Expected property does not match', throws,
302    name: '"Name"'
303
304  check 'Array length mismatch', throws,
305    x: [1, 2]
306
307  check 'Skip array length check', doesNotThrow,
308    x: looseArray [
309      1
310      2
311    ]
312
313  check 'Array length matches', doesNotThrow,
314    x: [1, 2, 3]
315
316  check 'Array prop mismatch', throws,
317    x: [3, 2, 1]
318
319  check 'Partial object comparison', doesNotThrow,
320    a:
321      c: 2
322    forbidden: undefined
323
324  check 'Actual has forbidden prop', throws,
325    a:
326      b: 1
327      c: undefined
328
329  check 'Check prop for existence only', doesNotThrow,
330    name: {}
331    a: {}
332    x: {}
333
334  check 'Prop is missing', throws,
335    missingProp: {}
336
337# Shorthand helpers for common AST patterns.
338
339EMPTY_BLOCK =
340  type: 'BlockStatement'
341  body: []
342  directives: []
343
344ID = (name, additionalProperties = {}) ->
345  Object.assign({
346    type: 'Identifier'
347    name
348  }, additionalProperties)
349
350NUMBER = (value) -> {
351  type: 'NumericLiteral'
352  value
353}
354
355STRING = (value) -> {
356  type: 'StringLiteral'
357  value
358}
359
360# Check each node type in the same order as they appear in `nodes.coffee`.
361# For nodes that have equivalents in Babel’s AST spec, we’re checking that
362# the type and properties match. When relevant, also check that values of
363# properties are as expected.
364
365test "AST as expected for Block node", ->
366  deepStrictIncludeExpectedProperties CoffeeScript.compile('a', ast: yes),
367    type: 'File'
368    program:
369      type: 'Program'
370      # sourceType: 'module'
371      body: [
372        type: 'ExpressionStatement'
373        expression:
374          type: 'Identifier'
375      ]
376      directives: []
377    comments: []
378
379  deepStrictIncludeExpectedProperties CoffeeScript.compile('# comment', ast: yes),
380    type: 'File'
381    program:
382      type: 'Program'
383      body: []
384      directives: []
385    comments: [
386      type: 'CommentLine'
387      value: ' comment'
388    ]
389
390  deepStrictIncludeExpectedProperties CoffeeScript.compile('', ast: yes),
391    type: 'File'
392    program:
393      type: 'Program'
394      body: []
395      directives: []
396
397  deepStrictIncludeExpectedProperties CoffeeScript.compile(' ', ast: yes),
398    type: 'File'
399    program:
400      type: 'Program'
401      body: []
402      directives: []
403
404test "AST as expected for NumberLiteral node", ->
405  testExpression '42',
406    type: 'NumericLiteral'
407    value: 42
408    extra:
409      rawValue: 42
410      raw: '42'
411
412  testExpression '0xE1',
413    type: 'NumericLiteral'
414    value: 225
415    extra:
416      rawValue: 225
417      raw: '0xE1'
418
419  testExpression '10_000',
420    type: 'NumericLiteral'
421    value: 10000
422    extra:
423      rawValue: 10000
424      raw: '10_000'
425
426  testExpression '1_2.34_5e6_7',
427    type: 'NumericLiteral'
428    value: 12.345e67
429    extra:
430      rawValue: 12.345e67
431      raw: '1_2.34_5e6_7'
432
433  testExpression '0o7_7_7',
434    type: 'NumericLiteral'
435    value: 0o777
436    extra:
437      rawValue: 0o777
438      raw: '0o7_7_7'
439
440  testExpression '42n',
441    type: 'BigIntLiteral'
442    value: '42'
443    extra:
444      rawValue: '42'
445      raw: '42n'
446
447  testExpression '2e3_08',
448    type: 'NumericLiteral'
449    value: Infinity
450    extra:
451      rawValue: Infinity
452      raw: '2e3_08'
453
454test "AST as expected for InfinityLiteral node", ->
455  testExpression 'Infinity',
456    type: 'Identifier'
457    name: 'Infinity'
458
459  testExpression '2e308',
460    type: 'NumericLiteral'
461    value: Infinity
462    extra:
463      raw: '2e308'
464      rawValue: Infinity
465
466test "AST as expected for NaNLiteral node", ->
467  testExpression 'NaN',
468    type: 'Identifier'
469    name: 'NaN'
470
471test "AST as expected for StringLiteral node", ->
472  # Just a standalone string literal would be treated as a directive,
473  # so embed the string literal in an enclosing expression (e.g. a call).
474  testExpression 'a "string cheese"',
475    type: 'CallExpression'
476    arguments: [
477      type: 'StringLiteral'
478      value: 'string cheese'
479      extra:
480        raw: '"string cheese"'
481    ]
482
483  testExpression "b 'cheese string'",
484    type: 'CallExpression'
485    arguments: [
486      type: 'StringLiteral'
487      value: 'cheese string'
488      extra:
489        raw: "'cheese string'"
490    ]
491
492  testExpression "'''heredoc'''",
493    type: 'TemplateLiteral'
494    expressions: []
495    quasis: [
496      type: 'TemplateElement'
497      value:
498        raw: 'heredoc'
499      tail: yes
500    ]
501    quote: "'''"
502
503test "AST as expected for PassthroughLiteral node", ->
504  code = 'const CONSTANT = "unreassignable!"'
505  testExpression "`#{code}`",
506    type: 'PassthroughLiteral'
507    value: code
508    here: no
509
510  code = '\nconst CONSTANT = "unreassignable!"\n'
511  testExpression "```#{code}```",
512    type: 'PassthroughLiteral'
513    value: code
514    here: yes
515
516  testExpression "``",
517    type: 'PassthroughLiteral'
518    value: ''
519    here: no
520
521  # escaped backticks
522  testExpression "`\\`abc\\``",
523    type: 'PassthroughLiteral'
524    value: '\\`abc\\`'
525    here: no
526
527test "AST as expected for IdentifierLiteral node", ->
528  testExpression 'id',
529    type: 'Identifier'
530    name: 'id'
531
532test "AST as expected for JSXTag node", ->
533  testExpression '<CSXY />',
534    type: 'JSXElement'
535    openingElement:
536      type: 'JSXOpeningElement'
537      name:
538        type: 'JSXIdentifier'
539        name: 'CSXY'
540      attributes: []
541      selfClosing: yes
542    closingElement: null
543    children: []
544
545  testExpression '<div></div>',
546    type: 'JSXElement'
547    openingElement:
548      type: 'JSXOpeningElement'
549      name:
550        type: 'JSXIdentifier'
551        name: 'div'
552      attributes: []
553      selfClosing: no
554    closingElement:
555      type: 'JSXClosingElement'
556      name:
557        type: 'JSXIdentifier'
558        name: 'div'
559    children: []
560
561  testExpression '<A.B />',
562    type: 'JSXElement'
563    openingElement:
564      type: 'JSXOpeningElement'
565      name:
566        type: 'JSXMemberExpression'
567        object:
568          type: 'JSXIdentifier'
569          name: 'A'
570        property:
571          type: 'JSXIdentifier'
572          name: 'B'
573      attributes: []
574      selfClosing: yes
575    closingElement: null
576    children: []
577
578  testExpression '<Tag.Name.Here></Tag.Name.Here>',
579    type: 'JSXElement'
580    openingElement:
581      type: 'JSXOpeningElement'
582      name:
583        type: 'JSXMemberExpression'
584        object:
585          type: 'JSXMemberExpression'
586          object:
587            type: 'JSXIdentifier'
588            name: 'Tag'
589          property:
590            type: 'JSXIdentifier'
591            name: 'Name'
592        property:
593          type: 'JSXIdentifier'
594          name: 'Here'
595      attributes: []
596      selfClosing: no
597    closingElement:
598      type: 'JSXClosingElement'
599      name:
600        type: 'JSXMemberExpression'
601        object:
602          type: 'JSXMemberExpression'
603          object:
604            type: 'JSXIdentifier'
605            name: 'Tag'
606          property:
607            type: 'JSXIdentifier'
608            name: 'Name'
609        property:
610          type: 'JSXIdentifier'
611          name: 'Here'
612    children: []
613
614  testExpression '<></>',
615    type: 'JSXFragment'
616    openingFragment:
617      type: 'JSXOpeningFragment'
618    closingFragment:
619      type: 'JSXClosingFragment'
620    children: []
621
622  testExpression '<div a b="c" d={e} {...f} />',
623    type: 'JSXElement'
624    openingElement:
625      type: 'JSXOpeningElement'
626      name:
627        type: 'JSXIdentifier'
628        name: 'div'
629      attributes: [
630        type: 'JSXAttribute'
631        name:
632          type: 'JSXIdentifier'
633          name: 'a'
634      ,
635        type: 'JSXAttribute'
636        name:
637          type: 'JSXIdentifier'
638          name: 'b'
639        value:
640          type: 'StringLiteral'
641          value: 'c'
642      ,
643        type: 'JSXAttribute'
644        name:
645          type: 'JSXIdentifier'
646          name: 'd'
647        value:
648          type: 'JSXExpressionContainer'
649          expression:
650            type: 'Identifier'
651            name: 'e'
652      ,
653        type: 'JSXSpreadAttribute'
654        argument:
655          type: 'Identifier'
656          name: 'f'
657        postfix: no
658      ]
659      selfClosing: yes
660    closingElement: null
661    children: []
662
663  testExpression '<div {f...} />',
664    type: 'JSXElement'
665    openingElement:
666      type: 'JSXOpeningElement'
667      attributes: [
668        type: 'JSXSpreadAttribute'
669        argument:
670          type: 'Identifier'
671          name: 'f'
672        postfix: yes
673      ]
674
675  testExpression '<div>abc</div>',
676    type: 'JSXElement'
677    openingElement:
678      type: 'JSXOpeningElement'
679      name:
680        type: 'JSXIdentifier'
681        name: 'div'
682      attributes: []
683      selfClosing: no
684    closingElement:
685      type: 'JSXClosingElement'
686      name:
687        type: 'JSXIdentifier'
688        name: 'div'
689    children: [
690      type: 'JSXText'
691      extra:
692        raw: 'abc'
693      value: 'abc'
694    ]
695
696  testExpression '''
697    <a>
698      {b}
699      <c />
700    </a>
701  ''',
702    type: 'JSXElement'
703    openingElement:
704      type: 'JSXOpeningElement'
705      name:
706        type: 'JSXIdentifier'
707        name: 'a'
708      attributes: []
709      selfClosing: no
710    closingElement:
711      type: 'JSXClosingElement'
712      name:
713        type: 'JSXIdentifier'
714        name: 'a'
715    children: [
716      type: 'JSXText'
717      extra:
718        raw: '\n  '
719      value: '\n  '
720    ,
721      type: 'JSXExpressionContainer'
722      expression: ID 'b'
723    ,
724      type: 'JSXText'
725      extra:
726        raw: '\n  '
727      value: '\n  '
728    ,
729      type: 'JSXElement'
730      openingElement:
731        type: 'JSXOpeningElement'
732        name:
733          type: 'JSXIdentifier'
734          name: 'c'
735        selfClosing: true
736      closingElement: null
737      children: []
738    ,
739      type: 'JSXText'
740      extra:
741        raw: '\n'
742      value: '\n'
743    ]
744
745  testExpression '<>abc{}</>',
746    type: 'JSXFragment'
747    openingFragment:
748      type: 'JSXOpeningFragment'
749    closingFragment:
750      type: 'JSXClosingFragment'
751    children: [
752      type: 'JSXText'
753      extra:
754        raw: 'abc'
755      value: 'abc'
756    ,
757      type: 'JSXExpressionContainer'
758      expression:
759        type: 'JSXEmptyExpression'
760    ]
761
762  testExpression '''
763    <a>{<b />}</a>
764  ''',
765    type: 'JSXElement'
766    openingElement:
767      type: 'JSXOpeningElement'
768      name:
769        type: 'JSXIdentifier'
770        name: 'a'
771      attributes: []
772      selfClosing: no
773    closingElement:
774      type: 'JSXClosingElement'
775      name:
776        type: 'JSXIdentifier'
777        name: 'a'
778    children: [
779      type: 'JSXExpressionContainer'
780      expression:
781        type: 'JSXElement'
782        openingElement:
783          type: 'JSXOpeningElement'
784          name:
785            type: 'JSXIdentifier'
786            name: 'b'
787          selfClosing: true
788        closingElement: null
789        children: []
790    ]
791
792  testExpression '''
793    <div>{
794      # comment
795    }</div>
796  ''',
797    type: 'JSXElement'
798    openingElement:
799      type: 'JSXOpeningElement'
800      name:
801        type: 'JSXIdentifier'
802        name: 'div'
803      attributes: []
804      selfClosing: no
805    closingElement:
806      type: 'JSXClosingElement'
807      name:
808        type: 'JSXIdentifier'
809        name: 'div'
810    children: [
811      type: 'JSXExpressionContainer'
812      expression:
813        type: 'JSXEmptyExpression'
814    ]
815
816  testExpression '''
817    <div>{### here ###}</div>
818  ''',
819    type: 'JSXElement'
820    openingElement:
821      type: 'JSXOpeningElement'
822      name:
823        type: 'JSXIdentifier'
824        name: 'div'
825      attributes: []
826      selfClosing: no
827    closingElement:
828      type: 'JSXClosingElement'
829      name:
830        type: 'JSXIdentifier'
831        name: 'div'
832    children: [
833      type: 'JSXExpressionContainer'
834      expression:
835        type: 'JSXEmptyExpression'
836    ]
837
838  testExpression '<div:a b:c />',
839    type: 'JSXElement'
840    openingElement:
841      type: 'JSXOpeningElement'
842      name:
843        type: 'JSXNamespacedName'
844        namespace:
845          type: 'JSXIdentifier'
846          name: 'div'
847        name:
848          type: 'JSXIdentifier'
849          name: 'a'
850      attributes: [
851        type: 'JSXAttribute'
852        name:
853          type: 'JSXNamespacedName'
854          namespace:
855            type: 'JSXIdentifier'
856            name: 'b'
857          name:
858            type: 'JSXIdentifier'
859            name: 'c'
860      ]
861      selfClosing: yes
862
863  testExpression '''
864    <div:a>
865      {b}
866    </div:a>
867  ''',
868    type: 'JSXElement'
869    openingElement:
870      type: 'JSXOpeningElement'
871      name:
872        type: 'JSXNamespacedName'
873        namespace:
874          type: 'JSXIdentifier'
875          name: 'div'
876        name:
877          type: 'JSXIdentifier'
878          name: 'a'
879    closingElement:
880      type: 'JSXClosingElement'
881      name:
882        type: 'JSXNamespacedName'
883        namespace:
884          type: 'JSXIdentifier'
885          name: 'div'
886        name:
887          type: 'JSXIdentifier'
888          name: 'a'
889
890  testExpression '''
891    <div b={
892      c
893      d
894    } />
895  ''',
896    type: 'JSXElement'
897    openingElement:
898      attributes: [
899        value:
900          type: 'JSXExpressionContainer'
901          expression:
902            type: 'BlockStatement'
903            body: [
904              type: 'ExpressionStatement'
905            ,
906              type: 'ExpressionStatement'
907              expression:
908                returns: yes
909            ]
910      ]
911
912test "AST as expected for ComputedPropertyName node", ->
913  testExpression '[fn]: ->',
914    type: 'ObjectExpression'
915    properties: [
916      type: 'ObjectProperty'
917      key:
918        type: 'Identifier'
919        name: 'fn'
920      value:
921        type: 'FunctionExpression'
922      computed: yes
923      shorthand: no
924      method: no
925    ]
926    implicit: yes
927
928  testExpression '[a]: b',
929    type: 'ObjectExpression'
930    properties: [
931      type: 'ObjectProperty'
932      key:
933        type: 'Identifier'
934        name: 'a'
935      value:
936        type: 'Identifier'
937        name: 'b'
938      computed: yes
939      shorthand: no
940      method: no
941    ]
942    implicit: yes
943
944test "AST as expected for StatementLiteral node", ->
945  testStatement 'break',
946    type: 'BreakStatement'
947
948  testStatement 'continue',
949    type: 'ContinueStatement'
950
951  testStatement 'debugger',
952    type: 'DebuggerStatement'
953
954test "AST as expected for ThisLiteral node", ->
955  testExpression 'this',
956    type: 'ThisExpression'
957    shorthand: no
958
959  testExpression '@',
960    type: 'ThisExpression'
961    shorthand: yes
962
963  testExpression '@b',
964    type: 'MemberExpression'
965    object:
966      type: 'ThisExpression'
967      shorthand: yes
968    property: ID 'b'
969
970  testExpression 'this.b',
971    type: 'MemberExpression'
972    object:
973      type: 'ThisExpression'
974      shorthand: no
975    property: ID 'b'
976
977test "AST as expected for UndefinedLiteral node", ->
978  testExpression 'undefined',
979    type: 'Identifier'
980    name: 'undefined'
981
982test "AST as expected for NullLiteral node", ->
983  testExpression 'null',
984    type: 'NullLiteral'
985
986test "AST as expected for BooleanLiteral node", ->
987  testExpression 'true',
988    type: 'BooleanLiteral'
989    value: true
990    name: 'true'
991
992  testExpression 'off',
993    type: 'BooleanLiteral'
994    value: false
995    name: 'off'
996
997  testExpression 'yes',
998    type: 'BooleanLiteral'
999    value: true
1000    name: 'yes'
1001
1002test "AST as expected for Return node", ->
1003  testStatement 'return no',
1004    type: 'ReturnStatement'
1005    argument:
1006      type: 'BooleanLiteral'
1007
1008  testExpression '''
1009    (a, b) ->
1010      return a + b
1011  ''',
1012    type: 'FunctionExpression'
1013    body:
1014      type: 'BlockStatement'
1015      body: [
1016        type: 'ReturnStatement'
1017        argument:
1018          type: 'BinaryExpression'
1019      ]
1020
1021  testExpression '-> return',
1022    type: 'FunctionExpression'
1023    body:
1024      type: 'BlockStatement'
1025      body: [
1026        type: 'ReturnStatement'
1027        argument: null
1028      ]
1029
1030test "AST as expected for YieldReturn node", ->
1031  testExpression '-> yield return 1',
1032    type: 'FunctionExpression'
1033    body:
1034      type: 'BlockStatement'
1035      body: [
1036        type: 'ExpressionStatement'
1037        expression:
1038          type: 'YieldExpression'
1039          argument:
1040            type: 'ReturnStatement'
1041            argument: NUMBER 1
1042          delegate: no
1043      ]
1044
1045test "AST as expected for AwaitReturn node", ->
1046  testExpression '-> await return 2',
1047    type: 'FunctionExpression'
1048    body:
1049      type: 'BlockStatement'
1050      body: [
1051        type: 'ExpressionStatement'
1052        expression:
1053          type: 'AwaitExpression'
1054          argument:
1055            type: 'ReturnStatement'
1056            argument: NUMBER 2
1057      ]
1058
1059test "AST as expected for Call node", ->
1060  testExpression 'fn()',
1061    type: 'CallExpression'
1062    callee:
1063      type: 'Identifier'
1064      name: 'fn'
1065    arguments: []
1066    optional: no
1067    implicit: no
1068    returns: undefined
1069
1070  testExpression 'new Date()',
1071    type: 'NewExpression'
1072    callee:
1073      type: 'Identifier'
1074      name: 'Date'
1075    arguments: []
1076    optional: no
1077    implicit: no
1078
1079  testExpression 'new Date?()',
1080    type: 'NewExpression'
1081    callee:
1082      type: 'Identifier'
1083      name: 'Date'
1084    arguments: []
1085    optional: yes
1086    implicit: no
1087
1088  testExpression 'new Old',
1089    type: 'NewExpression'
1090    callee:
1091      type: 'Identifier'
1092      name: 'Old'
1093    arguments: []
1094    optional: no
1095    implicit: no
1096
1097  testExpression 'new Old(1)',
1098    type: 'NewExpression'
1099    callee:
1100      type: 'Identifier'
1101      name: 'Old'
1102    arguments: [
1103      type: 'NumericLiteral'
1104      value: 1
1105    ]
1106    optional: no
1107    implicit: no
1108
1109  testExpression 'new Old 1',
1110    type: 'NewExpression'
1111    callee:
1112      type: 'Identifier'
1113      name: 'Old'
1114    arguments: [
1115      type: 'NumericLiteral'
1116      value: 1
1117    ]
1118    optional: no
1119    implicit: yes
1120
1121  testExpression 'maybe?()',
1122    type: 'OptionalCallExpression'
1123    optional: yes
1124    implicit: no
1125
1126  testExpression 'maybe?(1 + 1)',
1127    type: 'OptionalCallExpression'
1128    arguments: [
1129      type: 'BinaryExpression'
1130    ]
1131    optional: yes
1132    implicit: no
1133
1134  testExpression 'maybe? 1 + 1',
1135    type: 'OptionalCallExpression'
1136    arguments: [
1137      type: 'BinaryExpression'
1138    ]
1139    optional: yes
1140    implicit: yes
1141
1142  testExpression 'goDo this, that',
1143    type: 'CallExpression'
1144    arguments: [
1145      type: 'ThisExpression'
1146    ,
1147      type: 'Identifier'
1148      name: 'that'
1149    ]
1150    implicit: yes
1151    optional: no
1152
1153  testExpression 'a?().b',
1154    type: 'OptionalMemberExpression'
1155    object:
1156      type: 'OptionalCallExpression'
1157      optional: yes
1158    optional: no
1159
1160  testExpression 'a?.b.c()',
1161    type: 'OptionalCallExpression'
1162    callee:
1163      type: 'OptionalMemberExpression'
1164      object:
1165        type: 'OptionalMemberExpression'
1166        optional: yes
1167      optional: no
1168    optional: no
1169
1170  testExpression 'a?.b?()',
1171    type: 'OptionalCallExpression'
1172    callee:
1173      type: 'OptionalMemberExpression'
1174      optional: yes
1175    optional: yes
1176
1177  testExpression 'a?().b?()',
1178    type: 'OptionalCallExpression'
1179    callee:
1180      type: 'OptionalMemberExpression'
1181      optional: no
1182      object:
1183        type: 'OptionalCallExpression'
1184        optional: yes
1185    optional: yes
1186
1187  testExpression 'a().b?()',
1188    type: 'OptionalCallExpression'
1189    callee:
1190      type: 'MemberExpression'
1191      optional: no
1192      object:
1193        type: 'CallExpression'
1194        optional: no
1195    optional: yes
1196
1197  testExpression 'a?().b()',
1198    type: 'OptionalCallExpression'
1199    callee:
1200      type: 'OptionalMemberExpression'
1201      optional: no
1202      object:
1203        type: 'OptionalCallExpression'
1204        optional: yes
1205    optional: no
1206
1207test "AST as expected for SuperCall node", ->
1208  testStatement 'class child extends parent then constructor: -> super()',
1209    type: 'ClassDeclaration'
1210    body:
1211      type: 'ClassBody'
1212      body: [
1213        body:
1214          type: 'BlockStatement'
1215          body: [
1216            type: 'ExpressionStatement'
1217            expression:
1218              type: 'CallExpression'
1219              callee:
1220                type: 'Super'
1221          ]
1222      ]
1223
1224test "AST as expected for Super node", ->
1225  testStatement 'class child extends parent then func: -> super.prop',
1226    type: 'ClassDeclaration'
1227    body:
1228      type: 'ClassBody'
1229      body: [
1230        body:
1231          type: 'BlockStatement'
1232          body: [
1233            type: 'ExpressionStatement'
1234            expression:
1235              type: 'MemberExpression'
1236              object:
1237                type: 'Super'
1238              property: ID 'prop'
1239              computed: no
1240          ]
1241      ]
1242
1243  testStatement '''
1244    class child extends parent
1245      func: ->
1246        super[prop]()
1247  ''',
1248    type: 'ClassDeclaration'
1249    body:
1250      type: 'ClassBody'
1251      body: [
1252        body:
1253          type: 'BlockStatement'
1254          body: [
1255            type: 'ExpressionStatement'
1256            expression:
1257              type: 'CallExpression'
1258              callee:
1259                type: 'MemberExpression'
1260                object:
1261                  type: 'Super'
1262                property: ID 'prop'
1263                computed: yes
1264          ]
1265      ]
1266
1267test "AST as expected for RegexWithInterpolations node", ->
1268  testExpression '///^#{flavor}script$///',
1269    type: 'InterpolatedRegExpLiteral'
1270    interpolatedPattern:
1271      type: 'TemplateLiteral'
1272      expressions: [
1273        ID 'flavor'
1274      ]
1275      quasis: [
1276        type: 'TemplateElement'
1277        value:
1278          raw: '^'
1279        tail: no
1280      ,
1281        type: 'TemplateElement'
1282        value:
1283          raw: 'script$'
1284        tail: yes
1285      ]
1286      quote: '///'
1287    flags: ''
1288
1289  testExpression '''
1290    ///
1291      a
1292      #{b}///ig
1293  ''',
1294    type: 'InterpolatedRegExpLiteral'
1295    interpolatedPattern:
1296      type: 'TemplateLiteral'
1297      expressions: [
1298        ID 'b'
1299      ]
1300      quasis: [
1301        type: 'TemplateElement'
1302        value:
1303          raw: '\n  a\n  '
1304        tail: no
1305      ,
1306        type: 'TemplateElement'
1307        value:
1308          raw: ''
1309        tail: yes
1310      ]
1311      quote: '///'
1312    flags: 'ig'
1313
1314  testExpression '''
1315    ///
1316      a # first
1317      #{b} ### second ###
1318    ///ig
1319  ''',
1320    type: 'InterpolatedRegExpLiteral'
1321    interpolatedPattern:
1322      type: 'TemplateLiteral'
1323      expressions: [
1324        ID 'b'
1325      ]
1326      quasis: [
1327        type: 'TemplateElement'
1328        value:
1329          raw: '\n  a # first\n  '
1330        tail: no
1331      ,
1332        type: 'TemplateElement'
1333        value:
1334          raw: ' ### second ###\n'
1335        tail: yes
1336      ]
1337      quote: '///'
1338    flags: 'ig'
1339    comments: [
1340      type: 'CommentLine'
1341      value: ' first'
1342    ,
1343      type: 'CommentBlock'
1344      value: ' second '
1345    ]
1346
1347test "AST as expected for TaggedTemplateCall node", ->
1348  testExpression 'func"tagged"',
1349    type: 'TaggedTemplateExpression'
1350    tag: ID 'func'
1351    quasi:
1352      type: 'TemplateLiteral'
1353      expressions: []
1354      quasis: [
1355        type: 'TemplateElement'
1356        value:
1357          raw: 'tagged'
1358        tail: yes
1359      ]
1360
1361  testExpression 'a"b#{c}"',
1362    type: 'TaggedTemplateExpression'
1363    tag: ID 'a'
1364    quasi:
1365      type: 'TemplateLiteral'
1366      expressions: [
1367        ID 'c'
1368      ]
1369      quasis: [
1370        type: 'TemplateElement'
1371        value:
1372          raw: 'b'
1373        tail: no
1374      ,
1375        type: 'TemplateElement'
1376        value:
1377          raw: ''
1378        tail: yes
1379      ]
1380
1381  testExpression '''
1382    a"""
1383      b#{c}
1384    """
1385  ''',
1386    type: 'TaggedTemplateExpression'
1387    tag: ID 'a'
1388    quasi:
1389      type: 'TemplateLiteral'
1390      expressions: [
1391        ID 'c'
1392      ]
1393      quasis: [
1394        type: 'TemplateElement'
1395        value:
1396          raw: '\n  b'
1397        tail: no
1398      ,
1399        type: 'TemplateElement'
1400        value:
1401          raw: '\n'
1402        tail: yes
1403      ]
1404
1405  testExpression """
1406    a'''
1407      b
1408    '''
1409  """,
1410    type: 'TaggedTemplateExpression'
1411    tag: ID 'a'
1412    quasi:
1413      type: 'TemplateLiteral'
1414      expressions: []
1415      quasis: [
1416        type: 'TemplateElement'
1417        value:
1418          raw: '\n  b\n'
1419        tail: yes
1420      ]
1421
1422test "AST as expected for Access node", ->
1423  testExpression 'obj.prop',
1424    type: 'MemberExpression'
1425    object:
1426      type: 'Identifier'
1427      name: 'obj'
1428    property:
1429      type: 'Identifier'
1430      name: 'prop'
1431    computed: no
1432    optional: no
1433    shorthand: no
1434
1435  testExpression 'obj?.prop',
1436    type: 'OptionalMemberExpression'
1437    object:
1438      type: 'Identifier'
1439      name: 'obj'
1440    property:
1441      type: 'Identifier'
1442      name: 'prop'
1443    computed: no
1444    optional: yes
1445    shorthand: no
1446
1447  testExpression 'a::b',
1448    type: 'MemberExpression'
1449    object:
1450      type: 'MemberExpression'
1451      object:
1452        type: 'Identifier'
1453        name: 'a'
1454      property:
1455        type: 'Identifier'
1456        name: 'prototype'
1457      computed: no
1458      optional: no
1459      shorthand: yes
1460    property:
1461      type: 'Identifier'
1462      name: 'b'
1463    computed: no
1464    optional: no
1465    shorthand: no
1466
1467  testExpression 'a.prototype.b',
1468    type: 'MemberExpression'
1469    object:
1470      type: 'MemberExpression'
1471      object:
1472        type: 'Identifier'
1473        name: 'a'
1474      property:
1475        type: 'Identifier'
1476        name: 'prototype'
1477      computed: no
1478      optional: no
1479      shorthand: no
1480    property:
1481      type: 'Identifier'
1482      name: 'b'
1483    computed: no
1484    optional: no
1485    shorthand: no
1486
1487  testExpression 'a?.b.c',
1488    type: 'OptionalMemberExpression'
1489    object:
1490      type: 'OptionalMemberExpression'
1491      object:
1492        type: 'Identifier'
1493        name: 'a'
1494      property:
1495        type: 'Identifier'
1496        name: 'b'
1497      computed: no
1498      optional: yes
1499      shorthand: no
1500    property:
1501      type: 'Identifier'
1502      name: 'c'
1503    computed: no
1504    optional: no
1505    shorthand: no
1506
1507test "AST as expected for Index node", ->
1508  testExpression 'a[b]',
1509    type: 'MemberExpression'
1510    object:
1511      type: 'Identifier'
1512      name: 'a'
1513    property:
1514      type: 'Identifier'
1515      name: 'b'
1516    computed: yes
1517    optional: no
1518    shorthand: no
1519
1520  testExpression 'a?[b]',
1521    type: 'OptionalMemberExpression'
1522    object:
1523      type: 'Identifier'
1524      name: 'a'
1525    property:
1526      type: 'Identifier'
1527      name: 'b'
1528    computed: yes
1529    optional: yes
1530    shorthand: no
1531
1532  testExpression 'a::[b]',
1533    type: 'MemberExpression'
1534    object:
1535      type: 'MemberExpression'
1536      object:
1537        type: 'Identifier'
1538        name: 'a'
1539      property:
1540        type: 'Identifier'
1541        name: 'prototype'
1542      computed: no
1543      optional: no
1544      shorthand: yes
1545    property:
1546      type: 'Identifier'
1547      name: 'b'
1548    computed: yes
1549    optional: no
1550    shorthand: no
1551
1552  testExpression 'a[b][3]',
1553    type: 'MemberExpression'
1554    object:
1555      type: 'MemberExpression'
1556      object:
1557        type: 'Identifier'
1558        name: 'a'
1559      property:
1560        type: 'Identifier'
1561        name: 'b'
1562      computed: yes
1563      optional: no
1564      shorthand: no
1565    property:
1566      type: 'NumericLiteral'
1567      value: 3
1568    computed: yes
1569    optional: no
1570    shorthand: no
1571
1572  testExpression 'a[if b then c]',
1573    type: 'MemberExpression'
1574    object: ID 'a'
1575    property:
1576      type: 'ConditionalExpression'
1577      test: ID 'b'
1578      consequent: ID 'c'
1579    computed: yes
1580    optional: no
1581    shorthand: no
1582
1583test "AST as expected for Range node", ->
1584  testExpression '[x..y]',
1585    type: 'Range'
1586    exclusive: no
1587    from:
1588      name: 'x'
1589    to:
1590      name: 'y'
1591
1592  testExpression '[4...2]',
1593    type: 'Range'
1594    exclusive: yes
1595    from:
1596      value: 4
1597    to:
1598      value: 2
1599
1600test "AST as expected for Slice node", ->
1601  testExpression 'x[..y]',
1602    property:
1603      type: 'Range'
1604      exclusive: no
1605      from: null
1606      to:
1607        name: 'y'
1608
1609  testExpression 'x[y...]',
1610    property:
1611      type: 'Range'
1612      exclusive: yes
1613      from:
1614        name: 'y'
1615      to: null
1616
1617  testExpression 'x[...]',
1618    property:
1619      type: 'Range'
1620      exclusive: yes
1621      from: null
1622      to: null
1623
1624  testExpression '"abc"[...2]',
1625    type: 'MemberExpression'
1626    property:
1627      type: 'Range'
1628      from: null
1629      to:
1630        type: 'NumericLiteral'
1631        value: 2
1632      exclusive: yes
1633    computed: yes
1634    optional: no
1635    shorthand: no
1636
1637  testExpression 'x[...][a..][b...][..c][...d]',
1638    type: 'MemberExpression'
1639    object:
1640      type: 'MemberExpression'
1641      object:
1642        type: 'MemberExpression'
1643        object:
1644          type: 'MemberExpression'
1645          object:
1646            type: 'MemberExpression'
1647            property:
1648              type: 'Range'
1649              from: null
1650              to: null
1651              exclusive: yes
1652          property:
1653            type: 'Range'
1654            from:
1655              name: 'a'
1656            to: null
1657            exclusive: no
1658        property:
1659          type: 'Range'
1660          from:
1661            name: 'b'
1662          to: null
1663          exclusive: yes
1664      property:
1665        type: 'Range'
1666        from: null
1667        to:
1668          name: 'c'
1669        exclusive: no
1670    property:
1671      type: 'Range'
1672      from: null
1673      to:
1674        name: 'd'
1675      exclusive: yes
1676
1677test "AST as expected for Obj node", ->
1678  testExpression "{a: 1, b, [c], @d, [e()]: f, 'g': 2, ...h, i...}",
1679    type: 'ObjectExpression'
1680    properties: [
1681      type: 'ObjectProperty'
1682      key:
1683        type: 'Identifier'
1684        name: 'a'
1685      value:
1686        type: 'NumericLiteral'
1687        value: 1
1688      computed: no
1689      shorthand: no
1690    ,
1691      type: 'ObjectProperty'
1692      key:
1693        type: 'Identifier'
1694        name: 'b'
1695      value:
1696        type: 'Identifier'
1697        name: 'b'
1698      computed: no
1699      shorthand: yes
1700    ,
1701      type: 'ObjectProperty'
1702      key:
1703        type: 'Identifier'
1704        name: 'c'
1705      value:
1706        type: 'Identifier'
1707        name: 'c'
1708      computed: yes
1709      shorthand: yes
1710    ,
1711      type: 'ObjectProperty'
1712      key:
1713        type: 'MemberExpression'
1714        object:
1715          type: 'ThisExpression'
1716        property:
1717          type: 'Identifier'
1718          name: 'd'
1719      value:
1720        type: 'MemberExpression'
1721        object:
1722          type: 'ThisExpression'
1723        property:
1724          type: 'Identifier'
1725          name: 'd'
1726      computed: no
1727      shorthand: yes
1728    ,
1729      type: 'ObjectProperty'
1730      key:
1731        type: 'CallExpression'
1732        callee:
1733          type: 'Identifier'
1734          name: 'e'
1735        arguments: []
1736      value:
1737        type: 'Identifier'
1738        name: 'f'
1739      computed: yes
1740      shorthand: no
1741    ,
1742      type: 'ObjectProperty'
1743      key:
1744        type: 'StringLiteral'
1745        value: 'g'
1746      value:
1747        type: 'NumericLiteral'
1748        value: 2
1749      computed: no
1750      shorthand: no
1751    ,
1752      type: 'SpreadElement'
1753      argument:
1754        type: 'Identifier'
1755        name: 'h'
1756      postfix: no
1757    ,
1758      type: 'SpreadElement'
1759      argument:
1760        type: 'Identifier'
1761        name: 'i'
1762      postfix: yes
1763    ]
1764    implicit: no
1765
1766  testExpression 'a: 1',
1767    type: 'ObjectExpression'
1768    properties: [
1769      type: 'ObjectProperty'
1770      key:
1771        type: 'Identifier'
1772        name: 'a'
1773      value:
1774        type: 'NumericLiteral'
1775        value: 1
1776      shorthand: no
1777      computed: no
1778    ]
1779    implicit: yes
1780
1781  testExpression '''
1782    a:
1783      if b then c
1784  ''',
1785    type: 'ObjectExpression'
1786    properties: [
1787      type: 'ObjectProperty'
1788      key: ID 'a'
1789      value:
1790        type: 'ConditionalExpression'
1791        test: ID 'b'
1792        consequent: ID 'c'
1793    ]
1794    implicit: yes
1795
1796  testExpression '''
1797    a:
1798      c if b
1799  ''',
1800    type: 'ObjectExpression'
1801    properties: [
1802      type: 'ObjectProperty'
1803      key: ID 'a'
1804      value:
1805        type: 'ConditionalExpression'
1806        test: ID 'b'
1807        consequent: ID 'c'
1808    ]
1809    implicit: yes
1810
1811  testExpression '"#{a}": 1',
1812    type: 'ObjectExpression'
1813    properties: [
1814      type: 'ObjectProperty'
1815      key:
1816        type: 'TemplateLiteral'
1817        expressions: [
1818          ID 'a'
1819        ]
1820      value:
1821        type: 'NumericLiteral'
1822        value: 1
1823      shorthand: no
1824      computed: yes
1825    ]
1826    implicit: yes
1827
1828test "AST as expected for Arr node", ->
1829  testExpression '[]',
1830    type: 'ArrayExpression'
1831    elements: []
1832
1833  testExpression '[3, tables, !1]',
1834    type: 'ArrayExpression'
1835    elements: [
1836      {value: 3}
1837      {name: 'tables'}
1838      {operator: '!'}
1839    ]
1840
1841test "AST as expected for Class node", ->
1842  testStatement 'class Klass',
1843    type: 'ClassDeclaration'
1844    id: ID 'Klass', declaration: yes
1845    superClass: null
1846    body:
1847      type: 'ClassBody'
1848      body: []
1849
1850  testStatement 'class child extends parent',
1851    type: 'ClassDeclaration'
1852    id: ID 'child', declaration: yes
1853    superClass: ID 'parent', declaration: no
1854    body:
1855      type: 'ClassBody'
1856      body: []
1857
1858  testStatement 'class Klass then constructor: -> @a = 1',
1859    type: 'ClassDeclaration'
1860    id: ID 'Klass', declaration: yes
1861    superClass: null
1862    body:
1863      type: 'ClassBody'
1864      body: [
1865        type: 'ClassMethod'
1866        static: no
1867        key: ID 'constructor', declaration: no
1868        computed: no
1869        kind: 'constructor'
1870        id: null
1871        generator: no
1872        async: no
1873        params: []
1874        body:
1875          type: 'BlockStatement'
1876          body: [
1877            type: 'ExpressionStatement'
1878            expression:
1879              type: 'AssignmentExpression'
1880              returns: undefined
1881          ]
1882        bound: no
1883      ]
1884
1885  testExpression '''
1886    a = class A
1887      b: ->
1888        c
1889      d: =>
1890        e
1891  ''',
1892    type: 'AssignmentExpression'
1893    right:
1894      type: 'ClassExpression'
1895      id: ID 'A', declaration: yes
1896      superClass: null
1897      body:
1898        type: 'ClassBody'
1899        body: [
1900          type: 'ClassMethod'
1901          static: no
1902          key: ID 'b'
1903          computed: no
1904          kind: 'method'
1905          id: null
1906          generator: no
1907          async: no
1908          params: []
1909          body:
1910            type: 'BlockStatement'
1911            body: [
1912              type: 'ExpressionStatement'
1913              expression: ID 'c', returns: yes
1914            ]
1915          operator: ':'
1916          bound: no
1917        ,
1918          type: 'ClassMethod'
1919          static: no
1920          key: ID 'd'
1921          computed: no
1922          kind: 'method'
1923          id: null
1924          generator: no
1925          async: no
1926          params: []
1927          body:
1928            type: 'BlockStatement'
1929            body: [
1930              type: 'ExpressionStatement'
1931              expression: ID 'e'
1932            ]
1933          operator: ':'
1934          bound: yes
1935        ]
1936
1937  testStatement '''
1938    class A
1939      @b: ->
1940      @c = =>
1941      @d: 1
1942      @e = 2
1943      j = 5
1944      A.f = 3
1945      A.g = ->
1946      this.h = ->
1947      this.i = 4
1948  ''',
1949    type: 'ClassDeclaration'
1950    id: ID 'A', declaration: yes
1951    superClass: null
1952    body:
1953      type: 'ClassBody'
1954      body: [
1955        type: 'ClassMethod'
1956        static: yes
1957        key: ID 'b'
1958        computed: no
1959        kind: 'method'
1960        id: null
1961        generator: no
1962        async: no
1963        params: []
1964        body: EMPTY_BLOCK
1965        operator: ':'
1966        staticClassName:
1967          type: 'ThisExpression'
1968          shorthand: yes
1969        bound: no
1970      ,
1971        type: 'ClassMethod'
1972        static: yes
1973        key: ID 'c'
1974        computed: no
1975        kind: 'method'
1976        id: null
1977        generator: no
1978        async: no
1979        params: []
1980        body: EMPTY_BLOCK
1981        operator: '='
1982        staticClassName:
1983          type: 'ThisExpression'
1984          shorthand: yes
1985        bound: yes
1986      ,
1987        type: 'ClassProperty'
1988        static: yes
1989        key: ID 'd'
1990        computed: no
1991        value: NUMBER 1
1992        operator: ':'
1993        staticClassName:
1994          type: 'ThisExpression'
1995          shorthand: yes
1996      ,
1997        type: 'ClassProperty'
1998        static: yes
1999        key: ID 'e'
2000        computed: no
2001        value: NUMBER 2
2002        operator: '='
2003        staticClassName:
2004          type: 'ThisExpression'
2005          shorthand: yes
2006      ,
2007        type: 'ExpressionStatement'
2008        expression:
2009          type: 'AssignmentExpression'
2010          left: ID 'j', declaration: yes
2011          right: NUMBER 5
2012      ,
2013        type: 'ClassProperty'
2014        static: yes
2015        key: ID 'f'
2016        computed: no
2017        value: NUMBER 3
2018        operator: '='
2019        staticClassName: ID 'A'
2020      ,
2021        type: 'ClassMethod'
2022        static: yes
2023        key: ID 'g'
2024        computed: no
2025        kind: 'method'
2026        id: null
2027        generator: no
2028        async: no
2029        params: []
2030        body: EMPTY_BLOCK
2031        operator: '='
2032        staticClassName: ID 'A'
2033        bound: no
2034      ,
2035        type: 'ClassMethod'
2036        static: yes
2037        key: ID 'h'
2038        computed: no
2039        kind: 'method'
2040        id: null
2041        generator: no
2042        async: no
2043        params: []
2044        body: EMPTY_BLOCK
2045        operator: '='
2046        staticClassName:
2047          type: 'ThisExpression'
2048          shorthand: no
2049        bound: no
2050      ,
2051        type: 'ClassProperty'
2052        static: yes
2053        key: ID 'i'
2054        computed: no
2055        value: NUMBER 4
2056        operator: '='
2057        staticClassName:
2058          type: 'ThisExpression'
2059          shorthand: no
2060      ]
2061
2062  testStatement '''
2063    class A
2064      b: 1
2065      [c]: 2
2066      [d]: ->
2067      @[e]: ->
2068      @[f]: 3
2069  ''',
2070    type: 'ClassDeclaration'
2071    id: ID 'A', declaration: yes
2072    superClass: null
2073    body:
2074      type: 'ClassBody'
2075      body: [
2076        type: 'ClassPrototypeProperty'
2077        key: ID 'b', declaration: no
2078        value: NUMBER 1
2079        computed: no
2080      ,
2081        type: 'ClassPrototypeProperty'
2082        key: ID 'c'
2083        value: NUMBER 2
2084        computed: yes
2085      ,
2086        type: 'ClassMethod'
2087        static: no
2088        key: ID 'd'
2089        computed: yes
2090        kind: 'method'
2091        id: null
2092        generator: no
2093        async: no
2094        params: []
2095        body: EMPTY_BLOCK
2096        operator: ':'
2097        bound: no
2098      ,
2099        type: 'ClassMethod'
2100        static: yes
2101        key: ID 'e'
2102        computed: yes
2103        kind: 'method'
2104        id: null
2105        generator: no
2106        async: no
2107        params: []
2108        body: EMPTY_BLOCK
2109        operator: ':'
2110        bound: no
2111        staticClassName:
2112          type: 'ThisExpression'
2113          shorthand: yes
2114      ,
2115        type: 'ClassProperty'
2116        static: yes
2117        key: ID 'f'
2118        computed: yes
2119        value: NUMBER 3
2120        operator: ':'
2121        staticClassName:
2122          type: 'ThisExpression'
2123          shorthand: yes
2124      ]
2125
2126  testStatement '''
2127    class A
2128      @[b] = ->
2129      "#{c}": ->
2130      @[d] = 1
2131      [e]: 2
2132      "#{f}": 3
2133      @[g]: 4
2134  ''',
2135    type: 'ClassDeclaration'
2136    body:
2137      body: [
2138        type: 'ClassMethod'
2139        computed: yes
2140      ,
2141        type: 'ClassMethod'
2142        computed: yes
2143      ,
2144        type: 'ClassProperty'
2145        computed: yes
2146      ,
2147        type: 'ClassPrototypeProperty'
2148        computed: yes
2149      ,
2150        type: 'ClassPrototypeProperty'
2151        computed: yes
2152      ,
2153        type: 'ClassProperty'
2154        computed: yes
2155      ]
2156
2157  testStatement '''
2158    class A.b
2159  ''',
2160    type: 'ClassDeclaration'
2161    id:
2162      type: 'MemberExpression'
2163      object: ID 'A', declaration: no
2164      property: ID 'b', declaration: no
2165
2166  testStatement '''
2167    class A
2168      'constructor': ->
2169  ''',
2170    type: 'ClassDeclaration'
2171    body:
2172      type: 'ClassBody'
2173      body: [
2174        type: 'ClassMethod'
2175        static: no
2176        key:
2177          type: 'StringLiteral'
2178        computed: no
2179        kind: 'constructor'
2180        id: null
2181        generator: no
2182        async: no
2183        params: []
2184        body: EMPTY_BLOCK
2185        bound: no
2186      ]
2187
2188
2189test "AST as expected for ModuleDeclaration node", ->
2190  testStatement 'export {X}',
2191    type: 'ExportNamedDeclaration'
2192    declaration: null
2193    specifiers: [
2194      type: 'ExportSpecifier'
2195      local:
2196        type: 'Identifier'
2197        name: 'X'
2198        declaration: no
2199      exported:
2200        type: 'Identifier'
2201        name: 'X'
2202        declaration: no
2203    ]
2204    source: null
2205    exportKind: 'value'
2206
2207  testStatement 'import X from "."',
2208    type: 'ImportDeclaration'
2209    specifiers: [
2210      type: 'ImportDefaultSpecifier'
2211      local:
2212        type: 'Identifier'
2213        name: 'X'
2214        declaration: no
2215    ]
2216    importKind: 'value'
2217    source:
2218      type: 'StringLiteral'
2219      value: '.'
2220
2221  testStatement 'import X from "." assert { type: "json" }',
2222    type: 'ImportDeclaration'
2223    specifiers: [
2224      type: 'ImportDefaultSpecifier'
2225      local:
2226        type: 'Identifier'
2227        name: 'X'
2228        declaration: no
2229    ]
2230    importKind: 'value'
2231    source:
2232      type: 'StringLiteral'
2233      value: '.'
2234    assertions: [
2235      type: 'ImportAttribute'
2236      key:
2237        type: 'Identifier'
2238        name: 'type'
2239      value:
2240        type: 'StringLiteral'
2241        value: 'json'
2242        extra:
2243          raw: '"json"'
2244    ]
2245
2246test "AST as expected for ImportDeclaration node", ->
2247  testStatement 'import React, {Component} from "react"',
2248    type: 'ImportDeclaration'
2249    specifiers: [
2250      type: 'ImportDefaultSpecifier'
2251      local:
2252        type: 'Identifier'
2253        name: 'React'
2254        declaration: no
2255    ,
2256      type: 'ImportSpecifier'
2257      imported:
2258        type: 'Identifier'
2259        name: 'Component'
2260        declaration: no
2261      importKind: null
2262      local:
2263        type: 'Identifier'
2264        name: 'Component'
2265        declaration: no
2266    ]
2267    importKind: 'value'
2268    source:
2269      type: 'StringLiteral'
2270      value: 'react'
2271      extra:
2272        raw: '"react"'
2273
2274test "AST as expected for ExportNamedDeclaration node", ->
2275  testStatement 'export {}',
2276    type: 'ExportNamedDeclaration'
2277    declaration: null
2278    specifiers: []
2279    source: null
2280    exportKind: 'value'
2281
2282  testStatement 'export fn = ->',
2283    type: 'ExportNamedDeclaration'
2284    declaration:
2285      type: 'AssignmentExpression'
2286      left:
2287        type: 'Identifier'
2288        declaration: yes
2289      right:
2290        type: 'FunctionExpression'
2291    specifiers: []
2292    source: null
2293    exportKind: 'value'
2294
2295  testStatement 'export class A',
2296    type: 'ExportNamedDeclaration'
2297    declaration:
2298      type: 'ClassDeclaration'
2299      id: ID 'A', declaration: yes
2300      superClass: null
2301      body:
2302        type: 'ClassBody'
2303        body: []
2304    specifiers: []
2305    source: null
2306    exportKind: 'value'
2307
2308  testStatement 'export {x as y, z as default}',
2309    type: 'ExportNamedDeclaration'
2310    declaration: null
2311    specifiers: [
2312      type: 'ExportSpecifier'
2313      local:
2314        type: 'Identifier'
2315        name: 'x'
2316        declaration: no
2317      exported:
2318        type: 'Identifier'
2319        name: 'y'
2320        declaration: no
2321    ,
2322      type: 'ExportSpecifier'
2323      local:
2324        type: 'Identifier'
2325        name: 'z'
2326        declaration: no
2327      exported:
2328        type: 'Identifier'
2329        name: 'default'
2330        declaration: no
2331    ]
2332    source: null
2333    exportKind: 'value'
2334
2335  testStatement 'export {default, default as b} from "./abc"',
2336    type: 'ExportNamedDeclaration'
2337    declaration: null
2338    specifiers: [
2339      type: 'ExportSpecifier'
2340      local:
2341        type: 'Identifier'
2342        name: 'default'
2343        declaration: no
2344      exported:
2345        type: 'Identifier'
2346        name: 'default'
2347        declaration: no
2348    ,
2349      type: 'ExportSpecifier'
2350      local:
2351        type: 'Identifier'
2352        name: 'default'
2353        declaration: no
2354      exported:
2355        type: 'Identifier'
2356        name: 'b'
2357        declaration: no
2358    ]
2359    source:
2360      type: 'StringLiteral'
2361      value: './abc'
2362      extra:
2363        raw: '"./abc"'
2364    exportKind: 'value'
2365
2366test "AST as expected for ExportDefaultDeclaration node", ->
2367  testStatement 'export default class',
2368    type: 'ExportDefaultDeclaration'
2369    declaration:
2370      type: 'ClassDeclaration'
2371
2372  testStatement 'export default "abc"',
2373    type: 'ExportDefaultDeclaration'
2374    declaration:
2375      type: 'StringLiteral'
2376      value: 'abc'
2377      extra:
2378        raw: '"abc"'
2379
2380  testStatement 'export default a = b',
2381    type: 'ExportDefaultDeclaration'
2382    declaration:
2383      type: 'AssignmentExpression'
2384      left: ID 'a', declaration: yes
2385      right: ID 'b', declaration: no
2386
2387test "AST as expected for ExportAllDeclaration node", ->
2388  testStatement 'export * from "module-name"',
2389    type: 'ExportAllDeclaration'
2390    source:
2391      type: 'StringLiteral'
2392      value: 'module-name'
2393      extra:
2394        raw: '"module-name"'
2395    exportKind: 'value'
2396
2397  testStatement 'export * from "module-name" assert { type: "json" }',
2398    type: 'ExportAllDeclaration'
2399    source:
2400      type: 'StringLiteral'
2401      value: 'module-name'
2402      extra:
2403        raw: '"module-name"'
2404    assertions: [
2405      type: 'ImportAttribute'
2406      key:
2407        type: 'Identifier'
2408        name: 'type'
2409      value:
2410        type: 'StringLiteral'
2411        value: 'json'
2412        extra:
2413          raw: '"json"'
2414    ]
2415    exportKind: 'value'
2416
2417test "AST as expected for ExportSpecifierList node", ->
2418  testStatement 'export {a, b, c}',
2419    type: 'ExportNamedDeclaration'
2420    declaration: null
2421    specifiers: [
2422      type: 'ExportSpecifier'
2423      local:
2424        type: 'Identifier'
2425        name: 'a'
2426        declaration: no
2427      exported:
2428        type: 'Identifier'
2429        name: 'a'
2430        declaration: no
2431    ,
2432      type: 'ExportSpecifier'
2433      local:
2434        type: 'Identifier'
2435        name: 'b'
2436        declaration: no
2437      exported:
2438        type: 'Identifier'
2439        name: 'b'
2440        declaration: no
2441    ,
2442      type: 'ExportSpecifier'
2443      local:
2444        type: 'Identifier'
2445        name: 'c'
2446        declaration: no
2447      exported:
2448        type: 'Identifier'
2449        name: 'c'
2450        declaration: no
2451    ]
2452
2453test "AST as expected for ImportDefaultSpecifier node", ->
2454  testStatement 'import React from "react"',
2455    type: 'ImportDeclaration'
2456    specifiers: [
2457      type: 'ImportDefaultSpecifier'
2458      local:
2459        type: 'Identifier'
2460        name: 'React'
2461        declaration: no
2462    ]
2463    importKind: 'value'
2464    source:
2465      type: 'StringLiteral'
2466      value: 'react'
2467
2468test "AST as expected for ImportNamespaceSpecifier node", ->
2469  testStatement 'import * as React from "react"',
2470    type: 'ImportDeclaration'
2471    specifiers: [
2472      type: 'ImportNamespaceSpecifier'
2473      local:
2474        type: 'Identifier'
2475        name: 'React'
2476        declaration: no
2477    ]
2478    importKind: 'value'
2479    source:
2480      type: 'StringLiteral'
2481      value: 'react'
2482
2483  testStatement 'import React, * as ReactStar from "react"',
2484    type: 'ImportDeclaration'
2485    specifiers: [
2486      type: 'ImportDefaultSpecifier'
2487      local:
2488        type: 'Identifier'
2489        name: 'React'
2490        declaration: no
2491    ,
2492      type: 'ImportNamespaceSpecifier'
2493      local:
2494        type: 'Identifier'
2495        name: 'ReactStar'
2496        declaration: no
2497    ]
2498    importKind: 'value'
2499    source:
2500      type: 'StringLiteral'
2501      value: 'react'
2502
2503test "AST as expected for Assign node", ->
2504  testExpression 'a = b',
2505    type: 'AssignmentExpression'
2506    left:
2507      type: 'Identifier'
2508      name: 'a'
2509      declaration: yes
2510    right:
2511      type: 'Identifier'
2512      name: 'b'
2513      declaration: no
2514    operator: '='
2515
2516  testExpression 'a += b',
2517    type: 'AssignmentExpression'
2518    left:
2519      type: 'Identifier'
2520      name: 'a'
2521      declaration: no
2522    right:
2523      type: 'Identifier'
2524      name: 'b'
2525      declaration: no
2526    operator: '+='
2527
2528  testExpression '[@a = 2, {b: {c = 3} = {}, d...}, ...e] = f',
2529    type: 'AssignmentExpression'
2530    left:
2531      type: 'ArrayPattern'
2532      elements: [
2533        type: 'AssignmentPattern'
2534        left:
2535          type: 'MemberExpression'
2536          object:
2537            type: 'ThisExpression'
2538          property:
2539            name: 'a'
2540            declaration: no
2541        right:
2542          type: 'NumericLiteral'
2543      ,
2544        type: 'ObjectPattern'
2545        properties: [
2546          type: 'ObjectProperty'
2547          key:
2548            name: 'b'
2549            declaration: no
2550          value:
2551            type: 'AssignmentPattern'
2552            left:
2553              type: 'ObjectPattern'
2554              properties: [
2555                type: 'ObjectProperty'
2556                key:
2557                  name: 'c'
2558                value:
2559                  type: 'AssignmentPattern'
2560                  left:
2561                    name: 'c'
2562                    declaration: yes
2563                  right:
2564                    value: 3
2565                shorthand: yes
2566              ]
2567            right:
2568              type: 'ObjectExpression'
2569              properties: []
2570        ,
2571          type: 'RestElement'
2572          argument:
2573            name: 'd'
2574            declaration: yes
2575          postfix: yes
2576        ]
2577      ,
2578        type: 'RestElement'
2579        argument:
2580          name: 'e'
2581          declaration: yes
2582        postfix: no
2583      ]
2584    right:
2585      name: 'f'
2586
2587  testExpression '{a: [...b]} = c',
2588    type: 'AssignmentExpression'
2589    left:
2590      type: 'ObjectPattern'
2591      properties: [
2592        type: 'ObjectProperty'
2593        key:
2594          name: 'a'
2595          declaration: no
2596        value:
2597          type: 'ArrayPattern'
2598          elements: [
2599            type: 'RestElement'
2600            argument:
2601              name: 'b'
2602              declaration: yes
2603          ]
2604      ]
2605    right:
2606      name: 'c'
2607      declaration: no
2608
2609  testExpression '(a = 1; a ?= b)',
2610    type: 'SequenceExpression'
2611    expressions: [
2612      type: 'AssignmentExpression'
2613    ,
2614      type: 'AssignmentExpression'
2615      left:
2616        type: 'Identifier'
2617        name: 'a'
2618        declaration: no
2619      right:
2620        type: 'Identifier'
2621        name: 'b'
2622        declaration: no
2623      operator: '?='
2624    ]
2625
2626  testExpression '[a..., b] = c',
2627    type: 'AssignmentExpression'
2628    left:
2629      type: 'ArrayPattern'
2630      elements: [
2631        type: 'RestElement'
2632        argument: ID 'a', declaration: yes
2633        postfix: yes
2634      ,
2635        ID 'b'
2636      ]
2637    right:
2638      ID 'c'
2639
2640  testExpression '[] = c',
2641    type: 'AssignmentExpression'
2642    left:
2643      type: 'ArrayPattern'
2644      elements: []
2645    right:
2646      ID 'c'
2647
2648  testExpression '{{a...}...} = b',
2649    type: 'AssignmentExpression'
2650    left:
2651      type: 'ObjectPattern'
2652      properties: [
2653        type: 'RestElement'
2654        argument:
2655          type: 'ObjectPattern'
2656          properties: [
2657            type: 'RestElement'
2658            argument: ID 'a'
2659          ]
2660        postfix: yes
2661      ]
2662    right: ID 'b'
2663
2664  testExpression '{a..., b} = c',
2665    type: 'AssignmentExpression'
2666    left:
2667      type: 'ObjectPattern'
2668      properties: [
2669        type: 'RestElement'
2670        argument: ID 'a'
2671        postfix: yes
2672      ,
2673        type: 'ObjectProperty'
2674      ]
2675    right: ID 'c'
2676
2677  testExpression '{a.b...} = c',
2678    type: 'AssignmentExpression'
2679    left:
2680      type: 'ObjectPattern'
2681      properties: [
2682        type: 'RestElement'
2683        argument:
2684          type: 'MemberExpression'
2685        postfix: yes
2686      ]
2687    right: ID 'c'
2688
2689  testExpression '{{a}...} = b',
2690    type: 'AssignmentExpression'
2691    left:
2692      type: 'ObjectPattern'
2693      properties: [
2694        type: 'RestElement'
2695        argument:
2696          type: 'ObjectPattern'
2697          properties: [
2698            type: 'ObjectProperty'
2699            shorthand: yes
2700          ]
2701        postfix: yes
2702      ]
2703    right: ID 'b'
2704
2705  testExpression '[u, [v, ...w, x], ...{...y}, z] = a',
2706    left:
2707      type: 'ArrayPattern'
2708
2709  testExpression '{...{a: [...b, c]}} = d',
2710    left:
2711      type: 'ObjectPattern'
2712
2713  testExpression '{"#{a}": b} = c',
2714    left:
2715      type: 'ObjectPattern'
2716      properties: [
2717        type: 'ObjectProperty'
2718        key:
2719          type: 'TemplateLiteral'
2720          expressions: [
2721            ID 'a'
2722          ]
2723        computed: yes
2724      ]
2725
2726test "AST as expected for Code node", ->
2727  testExpression '=>',
2728    type: 'ArrowFunctionExpression'
2729    params: []
2730    body: EMPTY_BLOCK
2731    generator: no
2732    async: no
2733    id: null
2734    hasIndentedBody: no
2735
2736  testExpression '''
2737    (a, b = 1) ->
2738      c
2739      d()
2740  ''',
2741    type: 'FunctionExpression'
2742    params: [
2743      type: 'Identifier'
2744      name: 'a'
2745      declaration: no
2746    ,
2747      type: 'AssignmentPattern'
2748      left:
2749        type: 'Identifier'
2750        name: 'b'
2751        declaration: no
2752      right:
2753        type: 'NumericLiteral'
2754        value: 1
2755    ]
2756    body:
2757      type: 'BlockStatement'
2758      body: [
2759        type: 'ExpressionStatement'
2760        expression:
2761          type: 'Identifier'
2762          name: 'c'
2763      ,
2764        type: 'ExpressionStatement'
2765        expression:
2766          type: 'CallExpression'
2767          returns: yes
2768      ]
2769      directives: []
2770    generator: no
2771    async: no
2772    id: null
2773    hasIndentedBody: yes
2774
2775  testExpression '({a}) ->',
2776    type: 'FunctionExpression'
2777    params: [
2778      type: 'ObjectPattern'
2779      properties: [
2780        type: 'ObjectProperty'
2781        key: ID 'a', declaration: no
2782        value: ID 'a', declaration: no
2783        shorthand: yes
2784      ]
2785    ]
2786    body: EMPTY_BLOCK
2787    generator: no
2788    async: no
2789    id: null
2790
2791  testExpression '([a]) ->',
2792    type: 'FunctionExpression'
2793    params: [
2794      type: 'ArrayPattern'
2795      elements: [
2796        ID 'a', declaration: no
2797      ]
2798    ]
2799    body: EMPTY_BLOCK
2800    generator: no
2801    async: no
2802    id: null
2803
2804  testExpression '({a = 1} = {}) ->',
2805    type: 'FunctionExpression'
2806    params: [
2807      type: 'AssignmentPattern'
2808      left:
2809        type: 'ObjectPattern'
2810        properties: [
2811          type: 'ObjectProperty'
2812          key: ID 'a', declaration: no
2813          value:
2814            type: 'AssignmentPattern'
2815            left: ID 'a', declaration: no
2816            right: NUMBER(1)
2817          shorthand: yes
2818        ]
2819      right:
2820        type: 'ObjectExpression'
2821        properties: []
2822    ]
2823    body: EMPTY_BLOCK
2824    generator: no
2825    async: no
2826    id: null
2827
2828  testExpression '([a = 1] = []) ->',
2829    type: 'FunctionExpression'
2830    params: [
2831      type: 'AssignmentPattern'
2832      left:
2833        type: 'ArrayPattern'
2834        elements: [
2835          type: 'AssignmentPattern'
2836          left: ID 'a', declaration: no
2837          right: NUMBER(1)
2838        ]
2839      right:
2840        type: 'ArrayExpression'
2841        elements: []
2842    ]
2843    body: EMPTY_BLOCK
2844    generator: no
2845    async: no
2846    id: null
2847
2848  testExpression '() ->',
2849    type: 'FunctionExpression'
2850    params: []
2851    body: EMPTY_BLOCK
2852    generator: no
2853    async: no
2854    id: null
2855
2856  testExpression '(@a) ->',
2857    type: 'FunctionExpression'
2858    params: [
2859      type: 'MemberExpression'
2860      object:
2861        type: 'ThisExpression'
2862        shorthand: yes
2863      property: ID 'a', declaration: no
2864    ]
2865    body: EMPTY_BLOCK
2866    generator: no
2867    async: no
2868    id: null
2869
2870  testExpression '(@a = 1) ->',
2871    type: 'FunctionExpression'
2872    params: [
2873      type: 'AssignmentPattern'
2874      left:
2875        type: 'MemberExpression'
2876      right: NUMBER 1
2877    ]
2878    body: EMPTY_BLOCK
2879    generator: no
2880    async: no
2881    id: null
2882
2883  testExpression '({@a}) ->',
2884    type: 'FunctionExpression'
2885    params: [
2886      type: 'ObjectPattern'
2887      properties: [
2888        type: 'ObjectProperty'
2889        key:
2890          type: 'MemberExpression'
2891        value:
2892          type: 'MemberExpression'
2893        shorthand: yes
2894        computed: no
2895      ]
2896    ]
2897    body: EMPTY_BLOCK
2898    generator: no
2899    async: no
2900    id: null
2901
2902  testExpression '({[a]}) ->',
2903    type: 'FunctionExpression'
2904    params: [
2905      type: 'ObjectPattern'
2906      properties: [
2907        type: 'ObjectProperty'
2908        key:   ID 'a', declaration: no
2909        value: ID 'a', declaration: no
2910        shorthand: yes
2911        computed: yes
2912      ]
2913    ]
2914    body: EMPTY_BLOCK
2915    generator: no
2916    async: no
2917    id: null
2918
2919  testExpression '(...a) ->',
2920    type: 'FunctionExpression'
2921    params: [
2922      type: 'RestElement'
2923      argument: ID 'a', declaration: no
2924      postfix: no
2925    ]
2926    body: EMPTY_BLOCK
2927    generator: no
2928    async: no
2929    id: null
2930
2931  testExpression '(a...) ->',
2932    type: 'FunctionExpression'
2933    params: [
2934      type: 'RestElement'
2935      argument: ID 'a'
2936      postfix: yes
2937    ]
2938    body: EMPTY_BLOCK
2939    generator: no
2940    async: no
2941    id: null
2942
2943  testExpression '(..., a) ->',
2944    type: 'FunctionExpression'
2945    params: [
2946      type: 'RestElement'
2947      argument: null
2948    ,
2949      ID 'a'
2950    ]
2951    body: EMPTY_BLOCK
2952    generator: no
2953    async: no
2954    id: null
2955
2956  testExpression '-> a',
2957    type: 'FunctionExpression'
2958    params: []
2959    body:
2960      type: 'BlockStatement'
2961      body: [
2962        type: 'ExpressionStatement'
2963        expression: ID 'a', returns: yes
2964      ]
2965    generator: no
2966    async: no
2967    id: null
2968    hasIndentedBody: no
2969
2970  testExpression '-> await 3',
2971    type: 'FunctionExpression'
2972    params: []
2973    body:
2974      type: 'BlockStatement'
2975      body: [
2976        type: 'ExpressionStatement'
2977        expression:
2978          type: 'AwaitExpression'
2979          argument: NUMBER 3
2980          returns: yes
2981      ]
2982    generator: no
2983    async: yes
2984    id: null
2985
2986  testExpression '-> yield 4',
2987    type: 'FunctionExpression'
2988    params: []
2989    body:
2990      type: 'BlockStatement'
2991      body: [
2992        type: 'ExpressionStatement'
2993        expression:
2994          type: 'YieldExpression'
2995          argument: NUMBER 4
2996          delegate: no
2997      ]
2998    generator: yes
2999    async: no
3000    id: null
3001
3002  testExpression '-> yield',
3003    type: 'FunctionExpression'
3004    params: []
3005    body:
3006      type: 'BlockStatement'
3007      body: [
3008        type: 'ExpressionStatement'
3009        expression:
3010          type: 'YieldExpression'
3011          argument: null
3012          delegate: no
3013      ]
3014    generator: yes
3015    async: no
3016    id: null
3017
3018  testExpression '(a) -> a = 1',
3019    type: 'FunctionExpression'
3020    body:
3021      type: 'BlockStatement'
3022      body: [
3023        type: 'ExpressionStatement'
3024        expression:
3025          type: 'AssignmentExpression'
3026          left:
3027            ID 'a', declaration: no
3028      ]
3029
3030  testExpression '(...a) -> a = 1',
3031    type: 'FunctionExpression'
3032    body:
3033      type: 'BlockStatement'
3034      body: [
3035        type: 'ExpressionStatement'
3036        expression:
3037          type: 'AssignmentExpression'
3038          left:
3039            ID 'a', declaration: no
3040      ]
3041
3042  testExpression '({a}) -> a = 1',
3043    type: 'FunctionExpression'
3044    body:
3045      type: 'BlockStatement'
3046      body: [
3047        type: 'ExpressionStatement'
3048        expression:
3049          type: 'AssignmentExpression'
3050          left:
3051            ID 'a', declaration: no
3052      ]
3053
3054  testExpression '([a]) -> a = 1',
3055    type: 'FunctionExpression'
3056    body:
3057      type: 'BlockStatement'
3058      body: [
3059        type: 'ExpressionStatement'
3060        expression:
3061          type: 'AssignmentExpression'
3062          left:
3063            ID 'a', declaration: no
3064      ]
3065
3066  testExpression '(a = 1) -> a = 1',
3067    type: 'FunctionExpression'
3068    body:
3069      type: 'BlockStatement'
3070      body: [
3071        type: 'ExpressionStatement'
3072        expression:
3073          type: 'AssignmentExpression'
3074          left:
3075            ID 'a', declaration: no
3076      ]
3077    generator: no
3078    async: no
3079    id: null
3080
3081  testExpression '({a} = 1) -> a = 1',
3082    type: 'FunctionExpression'
3083    body:
3084      type: 'BlockStatement'
3085      body: [
3086        type: 'ExpressionStatement'
3087        expression:
3088          type: 'AssignmentExpression'
3089          left:
3090            ID 'a', declaration: no
3091      ]
3092    generator: no
3093    async: no
3094    id: null
3095
3096test "AST as expected for Splat node", ->
3097  testExpression '[a...]',
3098    type: 'ArrayExpression'
3099    elements: [
3100      type: 'SpreadElement'
3101      argument:
3102        type: 'Identifier'
3103        name: 'a'
3104        declaration: no
3105      postfix: yes
3106    ]
3107
3108  testExpression '[b, ...c]',
3109    type: 'ArrayExpression'
3110    elements: [
3111      name: 'b'
3112      declaration: no
3113    ,
3114      type: 'SpreadElement'
3115      argument:
3116        type: 'Identifier'
3117        name: 'c'
3118        declaration: no
3119      postfix: no
3120    ]
3121
3122test "AST as expected for Expansion node", ->
3123  testExpression '(..., b) ->',
3124    type: 'FunctionExpression'
3125    params: [
3126      type: 'RestElement'
3127      argument: null
3128    ,
3129      ID 'b'
3130    ]
3131
3132  testExpression '[..., b] = c',
3133    type: 'AssignmentExpression'
3134    left:
3135      type: 'ArrayPattern'
3136      elements: [
3137        type: 'RestElement'
3138        argument: null
3139      ,
3140        type: 'Identifier'
3141      ]
3142
3143test "AST as expected for Elision node", ->
3144  testExpression '[,,,a,,,b]',
3145    type: 'ArrayExpression'
3146    elements: [
3147      null, null, null
3148      name: 'a'
3149      null, null
3150      name: 'b'
3151    ]
3152
3153  testExpression '[,,,a,,,b] = "asdfqwer"',
3154    type: 'AssignmentExpression'
3155    left:
3156      type: 'ArrayPattern'
3157      elements: [
3158        null, null, null
3159      ,
3160        type: 'Identifier'
3161        name: 'a'
3162      ,
3163        null, null
3164      ,
3165        type: 'Identifier'
3166        name: 'b'
3167      ]
3168    right:
3169      type: 'StringLiteral'
3170      value: 'asdfqwer'
3171
3172test "AST as expected for While node", ->
3173  testStatement '
3173loop 1',
3174    type: 'WhileStatement'
3175    test:
3176      type: 'BooleanLiteral'
3177      value: true
3178    body:
3179      type: 'BlockStatement'
3180      body: [
3181        type: 'ExpressionStatement'
3182        expression: NUMBER 1
3183      ]
3184    guard: null
3185    inverted: no
3186    postfix: no
3187    loop: yes
3188
3189  testStatement 'while 1 < 2 then',
3190    type: 'WhileStatement'
3191    test:
3192      type: 'BinaryExpression'
3193    body:
3194      type: 'BlockStatement'
3195      body: []
3196    guard: null
3197    inverted: no
3198    postfix: no
3199    loop: no
3200
3201  testStatement 'while 1 < 2 then fn()',
3202    type: 'WhileStatement'
3203    test:
3204      type: 'BinaryExpression'
3205    body:
3206      type: 'BlockStatement'
3207      body: [
3208        type: 'ExpressionStatement'
3209        expression:
3210          type: 'CallExpression'
3211      ]
3212    guard: null
3213    inverted: no
3214    postfix: no
3215    loop: no
3216
3217  testStatement '''
3218    x() until y
3219  ''',
3220    type: 'WhileStatement'
3221    test: ID 'y'
3222    body:
3223      type: 'BlockStatement'
3224      body: [
3225        type: 'ExpressionStatement'
3226        expression:
3227          type: 'CallExpression'
3228          returns: undefined
3229      ]
3230    guard: null
3231    inverted: yes
3232    postfix: yes
3233    loop: no
3234
3235  testStatement '''
3236    until x when y
3237      z++
3238  ''',
3239    type: 'WhileStatement'
3240    test: ID 'x'
3241    body:
3242      type: 'BlockStatement'
3243      body: [
3244        type: 'ExpressionStatement'
3245        expression:
3246          type: 'UpdateExpression'
3247      ]
3248    guard: ID 'y'
3249    inverted: yes
3250    postfix: no
3251    loop: no
3252
3253  testStatement '''
3254    x while y when z
3255  ''',
3256    type: 'WhileStatement'
3257    test: ID 'y'
3258    body:
3259      type: 'BlockStatement'
3260      body: [
3261        type: 'ExpressionStatement'
3262        expression: ID 'x'
3263      ]
3264    guard: ID 'z'
3265    inverted: no
3266    postfix: yes
3267    loop: no
3268
3269  testStatement '''
3270    loop
3271      a()
3272      b++
3273  ''',
3274    type: 'WhileStatement'
3275    test:
3276      type: 'BooleanLiteral'
3277    body:
3278      type: 'BlockStatement'
3279      body: [
3280        type: 'ExpressionStatement'
3281        expression:
3282          type: 'CallExpression'
3283      ,
3284        type: 'ExpressionStatement'
3285        expression:
3286          type: 'UpdateExpression'
3287      ]
3288    guard: null
3289    inverted: no
3290    postfix: no
3291    loop: yes
3292
3293  testExpression '''
3294    x = (z() while y)
3295  ''',
3296    type: 'AssignmentExpression'
3297    right:
3298      type: 'WhileStatement'
3299      body:
3300        type: 'BlockStatement'
3301        body: [
3302          type: 'ExpressionStatement'
3303          expression:
3304            type: 'CallExpression'
3305            returns: yes
3306        ]
3307
3308test "AST as expected for Op node", ->
3309  testExpression 'a <= 2',
3310    type: 'BinaryExpression'
3311    operator: '<='
3312    left:
3313      type: 'Identifier'
3314      name: 'a'
3315    right:
3316      type: 'NumericLiteral'
3317      value: 2
3318
3319  testExpression 'a is 2',
3320    type: 'BinaryExpression'
3321    operator: 'is'
3322    left:
3323      type: 'Identifier'
3324      name: 'a'
3325    right:
3326      type: 'NumericLiteral'
3327      value: 2
3328
3329  testExpression 'a // 2',
3330    type: 'BinaryExpression'
3331    operator: '//'
3332    left:
3333      type: 'Identifier'
3334      name: 'a'
3335    right:
3336      type: 'NumericLiteral'
3337      value: 2
3338
3339  testExpression 'a << 2',
3340    type: 'BinaryExpression'
3341    operator: '<<'
3342    left:
3343      type: 'Identifier'
3344      name: 'a'
3345    right:
3346      type: 'NumericLiteral'
3347      value: 2
3348
3349  testExpression 'typeof x',
3350    type: 'UnaryExpression'
3351    operator: 'typeof'
3352    prefix: yes
3353    argument:
3354      type: 'Identifier'
3355      name: 'x'
3356
3357  testExpression 'delete x.y',
3358    type: 'UnaryExpression'
3359    operator: 'delete'
3360    prefix: yes
3361    argument:
3362      type: 'MemberExpression'
3363
3364  testExpression 'do x',
3365    type: 'UnaryExpression'
3366    operator: 'do'
3367    prefix: yes
3368    argument:
3369      type: 'Identifier'
3370      name: 'x'
3371
3372  testExpression 'do ->',
3373    type: 'UnaryExpression'
3374    operator: 'do'
3375    prefix: yes
3376    argument:
3377      type: 'FunctionExpression'
3378
3379  testExpression '!x',
3380    type: 'UnaryExpression'
3381    operator: '!'
3382    prefix: yes
3383    argument:
3384      type: 'Identifier'
3385      name: 'x'
3386
3387  testExpression 'not x',
3388    type: 'UnaryExpression'
3389    operator: 'not'
3390    prefix: yes
3391    argument:
3392      type: 'Identifier'
3393      name: 'x'
3394
3395  testExpression '--x',
3396    type: 'UpdateExpression'
3397    operator: '--'
3398    prefix: yes
3399    argument:
3400      type: 'Identifier'
3401      name: 'x'
3402
3403  testExpression 'x++',
3404    type: 'UpdateExpression'
3405    operator: '++'
3406    prefix: no
3407    argument:
3408      type: 'Identifier'
3409      name: 'x'
3410
3411  testExpression 'x && y',
3412    type: 'LogicalExpression'
3413    operator: '&&'
3414    left:
3415      type: 'Identifier'
3416      name: 'x'
3417    right:
3418      type: 'Identifier'
3419      name: 'y'
3420
3421  testExpression 'x or y',
3422    type: 'LogicalExpression'
3423    operator: 'or'
3424    left:
3425      type: 'Identifier'
3426      name: 'x'
3427    right:
3428      type: 'Identifier'
3429      name: 'y'
3430
3431  testExpression 'x ? y',
3432    type: 'LogicalExpression'
3433    operator: '?'
3434    left:
3435      type: 'Identifier'
3436      name: 'x'
3437    right:
3438      type: 'Identifier'
3439      name: 'y'
3440
3441  testExpression 'x in y',
3442    type: 'BinaryExpression'
3443    operator: 'in'
3444    left:
3445      type: 'Identifier'
3446      name: 'x'
3447    right:
3448      type: 'Identifier'
3449      name: 'y'
3450
3451  testExpression 'x not in y',
3452    type: 'BinaryExpression'
3453    operator: 'not in'
3454    left:
3455      type: 'Identifier'
3456      name: 'x'
3457    right:
3458      type: 'Identifier'
3459      name: 'y'
3460
3461  testExpression 'x + y * z',
3462    type: 'BinaryExpression'
3463    operator: '+'
3464    left:
3465      type: 'Identifier'
3466      name: 'x'
3467    right:
3468      type: 'BinaryExpression'
3469      operator: '*'
3470      left:
3471        type: 'Identifier'
3472        name: 'y'
3473      right:
3474        type: 'Identifier'
3475        name: 'z'
3476
3477  testExpression '(x + y) * z',
3478    type: 'BinaryExpression'
3479    operator: '*'
3480    left:
3481      type: 'BinaryExpression'
3482      operator: '+'
3483      left:
3484        type: 'Identifier'
3485        name: 'x'
3486      right:
3487        type: 'Identifier'
3488        name: 'y'
3489    right:
3490      type: 'Identifier'
3491      name: 'z'
3492
3493test "AST as expected for Try node", ->
3494  testStatement 'try cappuccino',
3495    type: 'TryStatement'
3496    block:
3497      type: 'BlockStatement'
3498      body: [
3499        type: 'ExpressionStatement'
3500        expression:
3501          type: 'Identifier'
3502          name: 'cappuccino'
3503      ]
3504    handler: null
3505    finalizer: null
3506
3507  testStatement '''
3508    try
3509      x = 1
3510      y()
3511    catch e
3512      d()
3513    finally
3514      f + g
3515  ''',
3516    type: 'TryStatement'
3517    block:
3518      type: 'BlockStatement'
3519      body: [
3520        type: 'ExpressionStatement'
3521        expression:
3522          type: 'AssignmentExpression'
3523      ,
3524        type: 'ExpressionStatement'
3525        expression:
3526          type: 'CallExpression'
3527      ]
3528    handler:
3529      type: 'CatchClause'
3530      param:
3531        type: 'Identifier'
3532        name: 'e'
3533        declaration: yes
3534      body:
3535        type: 'BlockStatement'
3536        body: [
3537          type: 'ExpressionStatement'
3538          expression:
3539            type: 'CallExpression'
3540        ]
3541    finalizer:
3542      type: 'BlockStatement'
3543      body: [
3544        type: 'ExpressionStatement'
3545        expression:
3546          type: 'BinaryExpression'
3547      ]
3548
3549  testStatement '''
3550    try
3551    catch
3552    finally
3553  ''',
3554    type: 'TryStatement'
3555    block:
3556      type: 'BlockStatement'
3557      body: []
3558    handler:
3559      type: 'CatchClause'
3560      param: null
3561      body:
3562        type: 'BlockStatement'
3563        body: []
3564    finalizer:
3565      type: 'BlockStatement'
3566      body: []
3567
3568  testStatement '''
3569    try
3570    catch {e}
3571      f
3572  ''',
3573    type: 'TryStatement'
3574    block:
3575      type: 'BlockStatement'
3576      body: []
3577    handler:
3578      type: 'CatchClause'
3579      param:
3580        type: 'ObjectPattern'
3581        properties: [
3582          type: 'ObjectProperty'
3583          key: ID 'e', declaration: no
3584          value: ID 'e', declaration: yes
3585        ]
3586      body:
3587        type: 'BlockStatement'
3588        body: [
3589          type: 'ExpressionStatement'
3590        ]
3591    finalizer: null
3592
3593test "AST as expected for Throw node", ->
3594  testStatement 'throw new BallError "catch"',
3595    type: 'ThrowStatement'
3596    argument:
3597      type: 'NewExpression'
3598
3599test "AST as expected for Existence node", ->
3600  testExpression 'Ghosts?',
3601    type: 'UnaryExpression',
3602    argument:
3603      name: 'Ghosts'
3604    operator: '?'
3605    prefix: no
3606
3607test "AST as expected for Parens node", ->
3608  testExpression '(hmmmmm)',
3609    type: 'Identifier'
3610    name: 'hmmmmm'
3611
3612  testExpression '(a + b) / c',
3613    type: 'BinaryExpression'
3614    operator: '/'
3615    left:
3616      type: 'BinaryExpression'
3617      operator: '+'
3618      left: ID 'a'
3619      right: ID 'b'
3620    right: ID 'c'
3621
3622  testExpression '(((1)))',
3623    type: 'NumericLiteral'
3624    value: 1
3625
3626test "AST as expected for StringWithInterpolations node", ->
3627  testExpression '"a#{b}c"',
3628    type: 'TemplateLiteral'
3629    expressions: [
3630      ID 'b'
3631    ]
3632    quasis: [
3633      type: 'TemplateElement'
3634      value:
3635        raw: 'a'
3636      tail: no
3637    ,
3638      type: 'TemplateElement'
3639      value:
3640        raw: 'c'
3641      tail: yes
3642    ]
3643    quote: '"'
3644
3645  testExpression '"""a#{b}c"""',
3646    type: 'TemplateLiteral'
3647    expressions: [
3648      ID 'b'
3649    ]
3650    quasis: [
3651      type: 'TemplateElement'
3652      value:
3653        raw: 'a'
3654      tail: no
3655    ,
3656      type: 'TemplateElement'
3657      value:
3658        raw: 'c'
3659      tail: yes
3660    ]
3661    quote: '"""'
3662
3663  testExpression '"#{b}"',
3664    type: 'TemplateLiteral'
3665    expressions: [
3666      ID 'b'
3667    ]
3668    quasis: [
3669      type: 'TemplateElement'
3670      value:
3671        raw: ''
3672      tail: no
3673    ,
3674      type: 'TemplateElement'
3675      value:
3676        raw: ''
3677      tail: yes
3678    ]
3679    quote: '"'
3680
3681  testExpression '''
3682    " a
3683      #{b}
3684      c
3685    "
3686  ''',
3687    type: 'TemplateLiteral'
3688    expressions: [
3689      ID 'b'
3690    ]
3691    quasis: [
3692      type: 'TemplateElement'
3693      value:
3694        raw: ' a\n  '
3695      tail: no
3696    ,
3697      type: 'TemplateElement'
3698      value:
3699        raw: '\n  c\n'
3700      tail: yes
3701    ]
3702    quote: '"'
3703
3704  testExpression '''
3705    """
3706      a
3707        b#{
3708        c
3709      }d
3710    """
3711  ''',
3712    type: 'TemplateLiteral'
3713    expressions: [
3714      ID 'c'
3715    ]
3716    quasis: [
3717      type: 'TemplateElement'
3718      value:
3719        raw: '\n  a\n    b'
3720      tail: no
3721    ,
3722      type: 'TemplateElement'
3723      value:
3724        raw: 'd\n'
3725      tail: yes
3726    ]
3727    quote: '"""'
3728
3729  # empty interpolation
3730  testExpression '"#{}"',
3731    type: 'TemplateLiteral'
3732    expressions: [
3733      type: 'EmptyInterpolation'
3734    ]
3735    quasis: [
3736      type: 'TemplateElement'
3737      value:
3738        raw: ''
3739      tail: no
3740    ,
3741      type: 'TemplateElement'
3742      value:
3743        raw: ''
3744      tail: yes
3745    ]
3746    quote: '"'
3747
3748  testExpression '''
3749    "#{
3750      # comment
3751     }"
3752    ''',
3753    type: 'TemplateLiteral'
3754    expressions: [
3755      type: 'EmptyInterpolation'
3756    ]
3757    quasis: [
3758      type: 'TemplateElement'
3759      value:
3760        raw: ''
3761      tail: no
3762    ,
3763      type: 'TemplateElement'
3764      value:
3765        raw: ''
3766      tail: yes
3767    ]
3768    quote: '"'
3769
3770  testExpression '"#{ ### here ### }"',
3771    type: 'TemplateLiteral'
3772    expressions: [
3773      type: 'EmptyInterpolation'
3774    ]
3775    quasis: [
3776      type: 'TemplateElement'
3777      value:
3778        raw: ''
3779      tail: no
3780    ,
3781      type: 'TemplateElement'
3782      value:
3783        raw: ''
3784      tail: yes
3785    ]
3786    quote: '"'
3787
3788  testExpression '''
3789    a "#{
3790      b
3791      c
3792    }"
3793  ''',
3794    type: 'CallExpression'
3795    arguments: [
3796      type: 'TemplateLiteral'
3797      expressions: [
3798        type: 'BlockStatement'
3799        body: [
3800          type: 'ExpressionStatement'
3801        ,
3802          type: 'ExpressionStatement'
3803          expression:
3804            returns: yes
3805        ]
3806      ]
3807    ]
3808
3809test "AST as expected for For node", ->
3810  testStatement 'for x, i in arr when x? then return',
3811    type: 'For'
3812    name: ID 'x', declaration: yes
3813    index: ID 'i', declaration: yes
3814    guard:
3815      type: 'UnaryExpression'
3816    source: ID 'arr', declaration: no
3817    body:
3818      type: 'BlockStatement'
3819      body: [
3820        type: 'ReturnStatement'
3821      ]
3822    style: 'in'
3823    own: no
3824    postfix: no
3825    await: no
3826    step: null
3827
3828  testStatement 'for k, v of obj then return',
3829    type: 'For'
3830    name: ID 'v', declaration: yes
3831    index: ID 'k', declaration: yes
3832    guard: null
3833    source: ID 'obj', declaration: no
3834    body:
3835      type: 'BlockStatement'
3836      body: [
3837        type: 'ReturnStatement'
3838      ]
3839    style: 'of'
3840    own: no
3841    postfix: no
3842    await: no
3843    step: null
3844
3845  testStatement 'for x from iterable then',
3846    type: 'For'
3847    name: ID 'x', declaration: yes
3848    index: null
3849    guard: null
3850    body: EMPTY_BLOCK
3851    source: ID 'iterable', declaration: no
3852    style: 'from'
3853    own: no
3854    postfix: no
3855    await: no
3856    step: null
3857
3858  testStatement 'for i in [0...42] by step when not (i % 2) then',
3859    type: 'For'
3860    name: ID 'i', declaration: yes
3861    index: null
3862    body: EMPTY_BLOCK
3863    source:
3864      type: 'Range'
3865    guard:
3866      type: 'UnaryExpression'
3867    step: ID 'step', declaration: no
3868    style: 'in'
3869    own: no
3870    postfix: no
3871    await: no
3872
3873  testExpression 'a = (x for x in y)',
3874    type: 'AssignmentExpression'
3875    right:
3876      type: 'For'
3877      name: ID 'x', declaration: yes
3878      index: null
3879      body:
3880        type: 'BlockStatement'
3881        body: [
3882          type: 'ExpressionStatement'
3883          expression: ID 'x', declaration: no, returns: yes
3884        ]
3885      source: ID 'y', declaration: no
3886      guard: null
3887      step: null
3888      style: 'in'
3889      own: no
3890      postfix: yes
3891      await: no
3892
3893  testStatement 'x for [0...1]',
3894    type: 'For'
3895    name: null
3896    index: null
3897    body:
3898      type: 'BlockStatement'
3899      body: [
3900        type: 'ExpressionStatement'
3901        expression: ID 'x', declaration: no, returns: undefined
3902      ]
3903    source:
3904      type: 'Range'
3905    guard: null
3906    step: null
3907    style: 'range'
3908    own: no
3909    postfix: yes
3910    await: no
3911
3912  testStatement '''
3913    for own x, y of z
3914      c()
3915      d
3916  ''',
3917    type: 'For'
3918    name: ID 'y', declaration: yes
3919    index: ID 'x', declaration: yes
3920    body:
3921      type: 'BlockStatement'
3922      body: [
3923        type: 'ExpressionStatement'
3924        expression:
3925          type: 'CallExpression'
3926          returns: undefined
3927      ,
3928        type: 'ExpressionStatement'
3929        expression: ID 'd', declaration: no, returns: undefined
3930      ]
3931    source: ID 'z', declaration: no
3932    guard: null
3933    step: null
3934    style: 'of'
3935    own: yes
3936    postfix: no
3937    await: no
3938
3939  testExpression '''
3940    ->
3941      for await x from y
3942        z
3943  ''',
3944    type: 'FunctionExpression'
3945    body:
3946      type: 'BlockStatement'
3947      body: [
3948        type: 'For'
3949        name: ID 'x', declaration: yes
3950        index: null
3951        body:
3952          type: 'BlockStatement'
3953          body: [
3954            type: 'ExpressionStatement'
3955            expression: ID 'z', declaration: no, returns: yes
3956          ]
3957        source: ID 'y', declaration: no
3958        guard: null
3959        step: null
3960        style: 'from'
3961        own: no
3962        postfix: no
3963        await: yes
3964      ]
3965
3966  testStatement '''
3967    for {x} in y
3968      z
3969  ''',
3970    type: 'For'
3971    name:
3972      type: 'ObjectPattern'
3973      properties: [
3974        type: 'ObjectProperty'
3975        key: ID 'x', declaration: no
3976        value: ID 'x', declaration: yes
3977        shorthand: yes
3978        computed: no
3979      ]
3980    index: null
3981    body:
3982      type: 'BlockStatement'
3983      body: [
3984        type: 'ExpressionStatement'
3985        expression: ID 'z'
3986      ]
3987    source: ID 'y'
3988    guard: null
3989    step: null
3990    style: 'in'
3991    postfix: no
3992    await: no
3993
3994  testStatement '''
3995    for [x] in y
3996      z
3997  ''',
3998    type: 'For'
3999    name:
4000      type: 'ArrayPattern'
4001      elements: [
4002        ID 'x', declaration: yes
4003      ]
4004    index: null
4005    body:
4006      type: 'BlockStatement'
4007      body: [
4008        type: 'ExpressionStatement'
4009        expression: ID 'z'
4010      ]
4011    source: ID 'y'
4012    guard: null
4013    step: null
4014    style: 'in'
4015    postfix: no
4016    await: no
4017
4018  testStatement '''
4019    for [x..., y] in z
4020      y()
4021  ''',
4022    type: 'For'
4023    name:
4024      type: 'ArrayPattern'
4025
4026test "AST as expected for Switch node", ->
4027  testStatement '''
4028    switch x
4029      when a then a
4030      when b, c then c
4031      else 42
4032  ''',
4033    type: 'SwitchStatement'
4034    discriminant:
4035      type: 'Identifier'
4036      name: 'x'
4037    cases: [
4038      type: 'SwitchCase'
4039      test:
4040        type: 'Identifier'
4041        name: 'a'
4042      consequent: [
4043        type: 'ExpressionStatement'
4044        expression:
4045          type: 'Identifier'
4046          name: 'a'
4047      ]
4048      trailing: yes
4049    ,
4050      type: 'SwitchCase'
4051      test:
4052        type: 'Identifier'
4053        name: 'b'
4054      consequent: []
4055      trailing: no
4056    ,
4057      type: 'SwitchCase'
4058      test:
4059        type: 'Identifier'
4060        name: 'c'
4061      consequent: [
4062        type: 'ExpressionStatement'
4063        expression:
4064          type: 'Identifier'
4065          name: 'c'
4066      ]
4067      trailing: yes
4068    ,
4069      type: 'SwitchCase'
4070      test: null
4071      consequent: [
4072        type: 'ExpressionStatement'
4073        expression:
4074          type: 'NumericLiteral'
4075          value: 42
4076      ]
4077    ]
4078
4079  testStatement '''
4080    switch
4081      when some(condition)
4082        doSomething()
4083        andThenSomethingElse
4084  ''',
4085    type: 'SwitchStatement'
4086    discriminant: null
4087    cases: [
4088      type: 'SwitchCase'
4089      test:
4090        type: 'CallExpression'
4091      consequent: [
4092        type: 'ExpressionStatement'
4093        expression:
4094          type: 'CallExpression'
4095      ,
4096        type: 'ExpressionStatement'
4097        expression:
4098          type: 'Identifier'
4099      ]
4100      trailing: yes
4101    ]
4102
4103  testStatement '''
4104    switch a
4105      when 1, 2, 3, 4
4106        b
4107      else
4108        c
4109        d
4110  ''',
4111    type: 'SwitchStatement'
4112    discriminant:
4113      type: 'Identifier'
4114    cases: [
4115      type: 'SwitchCase'
4116      test:
4117        type: 'NumericLiteral'
4118        value: 1
4119      consequent: []
4120      trailing: no
4121    ,
4122      type: 'SwitchCase'
4123      test:
4124        type: 'NumericLiteral'
4125        value: 2
4126      consequent: []
4127      trailing: no
4128    ,
4129      type: 'SwitchCase'
4130      test:
4131        type: 'NumericLiteral'
4132        value: 3
4133      consequent: []
4134      trailing: no
4135    ,
4136      type: 'SwitchCase'
4137      test:
4138        type: 'NumericLiteral'
4139        value: 4
4140      consequent: [
4141        type: 'ExpressionStatement'
4142        expression:
4143          type: 'Identifier'
4144      ]
4145      trailing: yes
4146    ,
4147      type: 'SwitchCase'
4148      test: null
4149      consequent: [
4150        type: 'ExpressionStatement'
4151        expression:
4152          type: 'Identifier'
4153      ,
4154        type: 'ExpressionStatement'
4155        expression:
4156          type: 'Identifier'
4157      ]
4158    ]
4159
4160test "AST as expected for If node", ->
4161  testStatement 'if maybe then yes',
4162    type: 'IfStatement'
4163    test: ID 'maybe'
4164    consequent:
4165      type: 'BlockStatement'
4166      body: [
4167        type: 'ExpressionStatement'
4168        expression:
4169          type: 'BooleanLiteral'
4170      ]
4171    alternate: null
4172    postfix: no
4173    inverted: no
4174
4175  testStatement 'yes if maybe',
4176    type: 'IfStatement'
4177    test: ID 'maybe'
4178    consequent:
4179      type: 'BlockStatement'
4180      body: [
4181        type: 'ExpressionStatement'
4182        expression:
4183          type: 'BooleanLiteral'
4184      ]
4185    alternate: null
4186    postfix: yes
4187    inverted: no
4188
4189  testStatement 'unless x then x else if y then y else z',
4190    type: 'IfStatement'
4191    test: ID 'x'
4192    consequent:
4193      type: 'BlockStatement'
4194      body: [
4195        type: 'ExpressionStatement'
4196        expression: ID 'x'
4197      ]
4198    alternate:
4199      type: 'IfStatement'
4200      test: ID 'y'
4201      consequent:
4202        type: 'BlockStatement'
4203        body: [
4204          type: 'ExpressionStatement'
4205          expression: ID 'y'
4206        ]
4207      alternate:
4208        type: 'BlockStatement'
4209        body: [
4210          type: 'ExpressionStatement'
4211          expression: ID 'z'
4212        ]
4213      postfix: no
4214      inverted: no
4215    postfix: no
4216    inverted: yes
4217
4218  testStatement '''
4219    if a
4220      b
4221    else
4222      if c
4223        d
4224  ''',
4225    type: 'IfStatement'
4226    test: ID 'a'
4227    consequent:
4228      type: 'BlockStatement'
4229      body: [
4230        type: 'ExpressionStatement'
4231        expression: ID 'b'
4232      ]
4233    alternate:
4234      type: 'BlockStatement'
4235      body: [
4236        type: 'IfStatement'
4237        test: ID 'c'
4238        consequent:
4239          type: 'BlockStatement'
4240          body: [
4241            type: 'ExpressionStatement'
4242            expression: ID 'd'
4243          ]
4244        alternate: null
4245        postfix: no
4246        inverted: no
4247      ]
4248    postfix: no
4249    inverted: no
4250
4251  testExpression '''
4252    a =
4253      if b then c else if d then e
4254  ''',
4255    type: 'AssignmentExpression'
4256    right:
4257      type: 'ConditionalExpression'
4258      test: ID 'b'
4259      consequent: ID 'c'
4260      alternate:
4261        type: 'ConditionalExpression'
4262        test: ID 'd'
4263        consequent: ID 'e'
4264        alternate: null
4265        postfix: no
4266        inverted: no
4267      postfix: no
4268      inverted: no
4269
4270  testExpression '''
4271    f(
4272      if b
4273        c
4274        d
4275    )
4276  ''',
4277    type: 'CallExpression'
4278    arguments: [
4279      type: 'ConditionalExpression'
4280      test: ID 'b'
4281      consequent:
4282        type: 'BlockStatement'
4283        body: [
4284          type: 'ExpressionStatement'
4285          expression:
4286            ID 'c'
4287        ,
4288          type: 'ExpressionStatement'
4289          expression:
4290            ID 'd'
4291        ]
4292      alternate: null
4293      postfix: no
4294      inverted: no
4295    ]
4296
4297  testStatement 'a unless b',
4298    type: 'IfStatement'
4299    test: ID 'b'
4300    consequent:
4301      type: 'BlockStatement'
4302      body: [
4303        type: 'ExpressionStatement'
4304        expression: ID 'a'
4305      ]
4306    alternate: null
4307    postfix: yes
4308    inverted: yes
4309
4310  testExpression '''
4311    f(
4312      if b
4313        c
4314      else
4315        d
4316    )
4317  ''',
4318      type: 'CallExpression'
4319      arguments: [
4320        type: 'ConditionalExpression'
4321        test: ID 'b'
4322        consequent: ID 'c'
4323        alternate: ID 'd'
4324        postfix: no
4325        inverted: no
4326      ]
4327
4328test "AST as expected for `new.target` MetaProperty node", ->
4329  testExpression '''
4330    -> new.target
4331  ''',
4332    type: 'FunctionExpression'
4333    body:
4334      type: 'BlockStatement'
4335      body: [
4336        type: 'ExpressionStatement'
4337        expression:
4338          type: 'MetaProperty'
4339          meta: ID 'new'
4340          property: ID 'target'
4341      ]
4342
4343  testExpression '''
4344    -> new.target.name
4345  ''',
4346    type: 'FunctionExpression'
4347    body:
4348      type: 'BlockStatement'
4349      body: [
4350        type: 'ExpressionStatement'
4351        expression:
4352          type: 'MemberExpression'
4353          object:
4354            type: 'MetaProperty'
4355            meta: ID 'new'
4356            property: ID 'target'
4357          property: ID 'name'
4358          computed: no
4359      ]
4360
4361test "AST as expected for `import.meta` MetaProperty node", ->
4362  testExpression '''
4363    import.meta
4364  ''',
4365    type: 'MetaProperty'
4366    meta: ID 'import'
4367    property: ID 'meta'
4368
4369  testExpression '''
4370    import.meta.name
4371  ''',
4372    type: 'MemberExpression'
4373    object:
4374      type: 'MetaProperty'
4375      meta: ID 'import'
4376      property: ID 'meta'
4377    property: ID 'name'
4378    computed: no
4379
4380test "AST as expected for dynamic import", ->
4381  testExpression '''
4382    import('a')
4383  ''',
4384    type: 'CallExpression'
4385    callee:
4386      type: 'Import'
4387    arguments: [STRING 'a']
4388
4389test "AST as expected for RegexLiteral node", ->
4390  testExpression '/a/ig',
4391    type: 'RegExpLiteral'
4392    pattern: 'a'
4393    originalPattern: 'a'
4394    flags: 'ig'
4395    delimiter: '/'
4396    value: undefined
4397    extra:
4398      raw: "/a/ig"
4399      originalRaw: "/a/ig"
4400      rawValue: undefined
4401
4402  testExpression '''
4403    ///
4404      a
4405    ///i
4406  ''',
4407    type: 'RegExpLiteral'
4408    pattern: 'a'
4409    originalPattern: '\n  a\n'
4410    flags: 'i'
4411    delimiter: '///'
4412    value: undefined
4413    extra:
4414      raw: "/a/i"
4415      originalRaw: "///\n  a\n///i"
4416      rawValue: undefined
4417
4418  testExpression '/a\\w\\u1111\\u{11111}/',
4419    type: 'RegExpLiteral'
4420    pattern: 'a\\w\\u1111\\ud804\\udd11'
4421    originalPattern: 'a\\w\\u1111\\u{11111}'
4422    flags: ''
4423    delimiter: '/'
4424    value: undefined
4425    extra:
4426      raw: "/a\\w\\u1111\\ud804\\udd11/"
4427      originalRaw: "/a\\w\\u1111\\u{11111}/"
4428      rawValue: undefined
4429
4430  testExpression '''
4431    ///
4432      a
4433      \\w\\u1111\\u{11111}
4434    ///
4435  ''',
4436    type: 'RegExpLiteral'
4437    pattern: 'a\\w\\u1111\\ud804\\udd11'
4438    originalPattern: '\n  a\n  \\w\\u1111\\u{11111}\n'
4439    flags: ''
4440    delimiter: '///'
4441    value: undefined
4442    extra:
4443      raw: "/a\\w\\u1111\\ud804\\udd11/"
4444      originalRaw: "///\n  a\n  \\w\\u1111\\u{11111}\n///"
4445      rawValue: undefined
4446
4447  testExpression '''
4448    ///
4449      /
4450      (.+)
4451      /
4452    ///
4453  ''',
4454    type: 'RegExpLiteral'
4455    pattern: '\\/(.+)\\/'
4456    originalPattern: '\n  /\n  (.+)\n  /\n'
4457    flags: ''
4458    delimiter: '///'
4459    value: undefined
4460    extra:
4461      raw: "/\\/(.+)\\//"
4462      originalRaw: "///\n  /\n  (.+)\n  /\n///"
4463      rawValue: undefined
4464
4465  testExpression '''
4466    ///
4467      a # first
4468      b ### second ###
4469    ///
4470  ''',
4471    type: 'RegExpLiteral'
4472    pattern: 'ab'
4473    originalPattern: '\n  a # first\n  b ### second ###\n'
4474    comments: [
4475      type: 'CommentLine'
4476      value: ' first'
4477    ,
4478      type: 'CommentBlock'
4479      value: ' second '
4480    ]
4481
4482test "AST as expected for directives", ->
4483  deepStrictIncludeExpectedProperties CoffeeScript.compile('''
4484    'directive 1'
4485    'use strict'
4486    f()
4487  ''', ast: yes),
4488    type: 'File'
4489    program:
4490      type: 'Program'
4491      body: [
4492        type: 'ExpressionStatement'
4493        expression:
4494          type: 'CallExpression'
4495      ]
4496      directives: [
4497        type: 'Directive'
4498        value:
4499          type: 'DirectiveLiteral'
4500          value: 'directive 1'
4501          extra:
4502            raw: "'directive 1'"
4503      ,
4504        type: 'Directive'
4505        value:
4506          type: 'DirectiveLiteral'
4507          value: 'use strict'
4508          extra:
4509            raw: "'use strict'"
4510      ]
4511
4512  testExpression '''
4513    ->
4514      'use strict'
4515      f()
4516      'not a directive'
4517      g
4518  ''',
4519    type: 'FunctionExpression'
4520    body:
4521      type: 'BlockStatement'
4522      body: [
4523        type: 'ExpressionStatement'
4524        expression:
4525          type: 'CallExpression'
4526      ,
4527        type: 'ExpressionStatement'
4528        expression: STRING 'not a directive'
4529      ,
4530        type: 'ExpressionStatement'
4531        expression: ID 'g'
4532      ]
4533      directives: [
4534        type: 'Directive'
4535        value:
4536          type: 'DirectiveLiteral'
4537          value: 'use strict'
4538          extra:
4539            raw: "'use strict'"
4540      ]
4541
4542  testExpression '''
4543    ->
4544      "not a directive because it's implicitly returned"
4545  ''',
4546    type: 'FunctionExpression'
4547    body:
4548      type: 'BlockStatement'
4549      body: [
4550        type: 'ExpressionStatement'
4551        expression: STRING "not a directive because it's implicitly returned"
4552      ]
4553      directives: []
4554
4555  deepStrictIncludeExpectedProperties CoffeeScript.compile('''
4556    'use strict'
4557  ''', ast: yes),
4558    type: 'File'
4559    program:
4560      type: 'Program'
4561      body: []
4562      directives: [
4563        type: 'Directive'
4564        value:
4565          type: 'DirectiveLiteral'
4566          value: 'use strict'
4567          extra:
4568            raw: "'use strict'"
4569      ]
4570
4571  testStatement '''
4572    class A
4573      'classes can have directives too'
4574      a: ->
4575  ''',
4576    type: 'ClassDeclaration'
4577    body:
4578      type: 'ClassBody'
4579      body: [
4580        type: 'ClassMethod'
4581      ]
4582      directives: [
4583        type: 'Directive'
4584        value:
4585          type: 'DirectiveLiteral'
4586          value: 'classes can have directives too'
4587      ]
4588
4589  testStatement '''
4590    if a
4591      "but other blocks can't"
4592      b
4593  ''',
4594    type: 'IfStatement'
4595    consequent:
4596      type: 'BlockStatement'
4597      body: [
4598        type: 'ExpressionStatement'
4599        expression: STRING "but other blocks can't"
4600      ,
4601        type: 'ExpressionStatement'
4602        expression: ID 'b'
4603      ]
4604      directives: []
4605
4606  testExpression '''
4607    ->
4608      """not a directive"""
4609      b
4610  ''',
4611    type: 'FunctionExpression'
4612    body:
4613      type: 'BlockStatement'
4614      body: [
4615        type: 'ExpressionStatement'
4616        expression:
4617          type: 'TemplateLiteral'
4618      ,
4619        type: 'ExpressionStatement'
4620        expression: ID 'b'
4621      ]
4622      directives: []
4623
4624  testExpression '''
4625    ->
4626      # leading comment
4627      'use strict'
4628      b
4629  ''',
4630    type: 'FunctionExpression'
4631    body:
4632      type: 'BlockStatement'
4633      body: [
4634        type: 'ExpressionStatement'
4635        expression: ID 'b'
4636      ]
4637      directives: [
4638        type: 'Directive'
4639        value:
4640          type: 'DirectiveLiteral'
4641          value: 'use strict'
4642          extra:
4643            raw: "'use strict'"
4644      ]
4645
4646test "AST as expected for comments", ->
4647  testComments '''
4648    a # simple line comment
4649  ''', [
4650    type: 'CommentLine'
4651    value: ' simple line comment'
4652  ]
4653
4654  testComments '''
4655    a ### simple here comment ###
4656  ''', [
4657    type: 'CommentBlock'
4658    value: ' simple here comment '
4659  ]
4660
4661  testComments '''
4662    # just a line comment
4663  ''', [
4664    type: 'CommentLine'
4665    value: ' just a line comment'
4666  ]
4667
4668  testComments '''
4669    ### just a here comment ###
4670  ''', [
4671    type: 'CommentBlock'
4672    value: ' just a here comment '
4673  ]
4674
4675  testComments '''
4676    "#{
4677      # empty interpolation line comment
4678     }"
4679  ''', [
4680    type: 'CommentLine'
4681    value: ' empty interpolation line comment'
4682  ]
4683
4684  testComments '''
4685    "#{
4686      ### empty interpolation block comment ###
4687     }"
4688  ''', [
4689    type: 'CommentBlock'
4690    value: ' empty interpolation block comment '
4691  ]
4692
4693  testComments '''
4694    # multiple line comments
4695    # on consecutive lines
4696  ''', [
4697    type: 'CommentLine'
4698    value: ' multiple line comments'
4699  ,
4700    type: 'CommentLine'
4701    value: ' on consecutive lines'
4702  ]
4703
4704  testComments '''
4705    # multiple line comments
4706
4707    # with blank line
4708  ''', [
4709    type: 'CommentLine'
4710    value: ' multiple line comments'
4711  ,
4712    type: 'CommentLine'
4713    value: ' with blank line'
4714  ]
4715
4716  testComments '''
4717    #no whitespace line comment
4718  ''', [
4719    type: 'CommentLine'
4720    value: 'no whitespace line comment'
4721  ]
4722
4723  testComments '''
4724    ###no whitespace here comment###
4725  ''', [
4726    type: 'CommentBlock'
4727    value: 'no whitespace here comment'
4728  ]
4729
4730  testComments '''
4731    ###
4732    # multiline
4733    # here comment
4734    ###
4735  ''', [
4736    type: 'CommentBlock'
4737    value: '\n# multiline\n# here comment\n'
4738  ]
4739
4740  testComments '''
4741    if b
4742      ###
4743      # multiline
4744      # indented here comment
4745      ###
4746      c
4747  ''', [
4748    type: 'CommentBlock'
4749    value: '\n  # multiline\n  # indented here comment\n  '
4750  ]
4751
4752  testComments '''
4753    if foo
4754      ;
4755      ### empty ###
4756  ''', [
4757    type: 'CommentBlock'
4758    value: ' empty '
4759  ]
4760
4761test "AST as expected for chained comparisons", ->
4762  testExpression '''
4763    a < b < c
4764  ''',
4765    type: 'ChainedComparison'
4766    operands: [
4767      ID 'a'
4768      ID 'b'
4769      ID 'c'
4770    ]
4771    operators: [
4772      '<'
4773      '<'
4774    ]
4775
4776  testExpression '''
4777    a isnt b is c isnt d
4778  ''',
4779    type: 'ChainedComparison'
4780    operands: [
4781      ID 'a'
4782      ID 'b'
4783      ID 'c'
4784      ID 'd'
4785    ]
4786    operators: [
4787      'isnt'
4788      'is'
4789      'isnt'
4790    ]
4791
4792  testExpression '''
4793    a >= b < c
4794  ''',
4795    type: 'ChainedComparison'
4796    operands: [
4797      ID 'a'
4798      ID 'b'
4799      ID 'c'
4800    ]
4801    operators: [
4802      '>='
4803      '<'
4804    ]
4805
4806test "AST as expected for Sequence", ->
4807  testExpression '''
4808    (a; b)
4809  ''',
4810    type: 'SequenceExpression'
4811    expressions: [
4812      ID 'a'
4813      ID 'b'
4814    ]
4815
4816  testExpression '''
4817    (a; b)""
4818  ''',
4819    type: 'TaggedTemplateExpression'
4820    tag:
4821      type: 'SequenceExpression'
4822      expressions: [
4823        ID 'a'
4824        ID 'b'
4825      ]
4826
4827</script>
vendor: 1 bytes, line 4827
4827
4828<script type="text/x-coffeescript" class="test" id="abstract_syntax_tree_location_data">
4829# Astract Syntax Tree location data
4830# ---------------------------------
4831
4832testAstLocationData = (code, expected) ->
4833  testAstNodeLocationData getAstExpressionOrStatement(code), expected
4834
4835testAstRootLocationData = (code, expected) ->
4836  testAstNodeLocationData getAstRoot(code), expected
4837
4838testAstNodeLocationData = (node, expected, path = '') ->
4839  extendPath = (additionalPath) ->
4840    return additionalPath unless path
4841    "#{path}.#{additionalPath}"
4842  ok node?, "Missing expected node at '#{path}'"
4843  testSingleNodeLocationData node, expected, path if expected.range?
4844  for own key, expectedChild of expected when key not in ['start', 'end', 'range', 'loc']
4845    if Array.isArray expectedChild
4846      ok Array.isArray(node[key]), "Missing expected array at '#{extendPath key}'"
4847      for expectedItem, index in expectedChild when expectedItem?
4848        testAstNodeLocationData node[key][index], expectedItem, extendPath "#{key}[#{index}]"
4849    else if typeof expectedChild is 'object'
4850      testAstNodeLocationData node[key], expectedChild, extendPath(key)
4851
4852testSingleNodeLocationData = (node, expected, path = '') ->
4853  # Even though it’s not part of the location data, check the type to ensure
4854  # that we’re testing the node we think we are.
4855  if expected.type?
4856    eq node.type, expected.type, \
4857      "Expected AST node type #{reset}#{node.type}#{red} to equal #{reset}#{expected.type}#{red}"
4858
4859  eq node.start, expected.start, \
4860    "Expected #{path}.start: #{reset}#{node.start}#{red} to equal #{reset}#{expected.start}#{red}"
4861  eq node.end, expected.end, \
4862    "Expected #{path}.end: #{reset}#{node.end}#{red} to equal #{reset}#{expected.end}#{red}"
4863  arrayEq node.range, expected.range, \
4864    "Expected #{path}.range: #{reset}#{JSON.stringify node.range}#{red} to equal #{reset}#{JSON.stringify expected.range}#{red}"
4865  eq node.loc.start.line, expected.loc.start.line, \
4866    "Expected #{path}.loc.start.line: #{reset}#{node.loc.start.line}#{red} to equal #{reset}#{expected.loc.start.line}#{red}"
4867  eq node.loc.start.column, expected.loc.start.column, \
4868    "Expected #{path}.loc.start.column: #{reset}#{node.loc.start.column}#{red} to equal #{reset}#{expected.loc.start.column}#{red}"
4869  eq node.loc.end.line, expected.loc.end.line, \
4870    "Expected #{path}.loc.end.line: #{reset}#{node.loc.end.line}#{red} to equal #{reset}#{expected.loc.end.line}#{red}"
4871  eq node.loc.end.column, expected.loc.end.column, \
4872    "Expected #{path}.loc.end.column: #{reset}#{node.loc.end.column}#{red} to equal #{reset}#{expected.loc.end.column}#{red}"
4873
4874testAstCommentsLocationData = (code, expected) ->
4875  testAstNodeLocationData getAstRoot(code).comments, expected
4876
4877if require?
4878  {mergeAstLocationData, mergeLocationData} = require './../lib/coffeescript/nodes'
4879
4880  test "the `mergeAstLocationData` helper accepts `justLeading` and `justEnding` options", ->
4881    first =
4882      range: [4, 5]
4883      start: 4
4884      end: 5
4885      loc:
4886        start:
4887          line: 1
4888          column: 4
4889        end:
4890          line: 1
4891          column: 5
4892    second =
4893      range: [1, 10]
4894      start: 1
4895      end: 10
4896      loc:
4897        start:
4898          line: 1
4899          column: 1
4900        end:
4901          line: 2
4902          column: 2
4903    testSingleNodeLocationData mergeAstLocationData(first, second), second
4904    testSingleNodeLocationData mergeAstLocationData(first, second, justLeading: yes),
4905      range: [1, 5]
4906      start: 1
4907      end: 5
4908      loc:
4909        start:
4910          line: 1
4911          column: 1
4912        end:
4913          line: 1
4914          column: 5
4915    testSingleNodeLocationData mergeAstLocationData(first, second, justEnding: yes),
4916      range: [4, 10]
4917      start: 4
4918      end: 10
4919      loc:
4920        start:
4921          line: 1
4922          column: 4
4923        end:
4924          line: 2
4925          column: 2
4926
4927  test "the `mergeLocationData` helper accepts `justLeading` and `justEnding` options", ->
4928    testLocationData = (node, expected) ->
4929      arrayEq node.range, expected.range
4930      for field in ['first_line', 'first_column', 'last_line', 'last_column']
4931        eq node[field], expected[field]
4932
4933    first =
4934      range: [4, 5]
4935      first_line: 0
4936      first_column: 4
4937      last_line: 0
4938      last_column: 4
4939    second =
4940      range: [1, 10]
4941      first_line: 0
4942      first_column: 1
4943      last_line: 1
4944      last_column: 2
4945
4946    testLocationData mergeLocationData(first, second), second
4947    testLocationData mergeLocationData(first, second, justLeading: yes),
4948      range: [1, 5]
4949      first_line: 0
4950      first_column: 1
4951      last_line: 0
4952      last_column: 4
4953    testLocationData mergeLocationData(first, second, justEnding: yes),
4954      range: [4, 10]
4955      first_line: 0
4956      first_column: 4
4957      last_line: 1
4958      last_column: 2
4959
4960test "AST location data as expected for NumberLiteral node", ->
4961  testAstLocationData '42',
4962    type: 'NumericLiteral'
4963    start: 0
4964    end: 2
4965    range: [0, 2]
4966    loc:
4967      start:
4968        line: 1
4969        column: 0
4970      end:
4971        line: 1
4972        column: 2
4973
4974test "AST location data as expected for InfinityLiteral node", ->
4975  testAstLocationData 'Infinity',
4976    type: 'Identifier'
4977    start: 0
4978    end: 8
4979    range: [0, 8]
4980    loc:
4981      start:
4982        line: 1
4983        column: 0
4984      end:
4985        line: 1
4986        column: 8
4987
4988  testAstLocationData '2e308',
4989    type: 'NumericLiteral'
4990    start: 0
4991    end: 5
4992    range: [0, 5]
4993    loc:
4994      start:
4995        line: 1
4996        column: 0
4997      end:
4998        line: 1
4999        column: 5
5000
5001test "AST location data as expected for NaNLiteral node", ->
5002  testAstLocationData 'NaN',
5003    type: 'Identifier'
5004    start: 0
5005    end: 3
5006    range: [0, 3]
5007    loc:
5008      start:
5009        line: 1
5010        column: 0
5011      end:
5012        line: 1
5013        column: 3
5014
5015test "AST location data as expected for IdentifierLiteral node", ->
5016  testAstLocationData 'id',
5017    type: 'Identifier'
5018    start: 0
5019    end: 2
5020    range: [0, 2]
5021    loc:
5022      start:
5023        line: 1
5024        column: 0
5025      end:
5026        line: 1
5027        column: 2
5028
5029test "AST location data as expected for StatementLiteral node", ->
5030  testAstLocationData 'break',
5031    type: 'BreakStatement'
5032    start: 0
5033    end: 5
5034    range: [0, 5]
5035    loc:
5036      start:
5037        line: 1
5038        column: 0
5039      end:
5040        line: 1
5041        column: 5
5042
5043  testAstLocationData 'continue',
5044    type: 'ContinueStatement'
5045    start: 0
5046    end: 8
5047    range: [0, 8]
5048    loc:
5049      start:
5050        line: 1
5051        column: 0
5052      end:
5053        line: 1
5054        column: 8
5055
5056  testAstLocationData 'debugger',
5057    type: 'DebuggerStatement'
5058    start: 0
5059    end: 8
5060    range: [0, 8]
5061    loc:
5062      start:
5063        line: 1
5064        column: 0
5065      end:
5066        line: 1
5067        column: 8
5068
5069test "AST location data as expected for ThisLiteral node", ->
5070  testAstLocationData 'this',
5071    type: 'ThisExpression'
5072    start: 0
5073    end: 4
5074    range: [0, 4]
5075    loc:
5076      start:
5077        line: 1
5078        column: 0
5079      end:
5080        line: 1
5081        column: 4
5082
5083test "AST location data as expected for UndefinedLiteral node", ->
5084  testAstLocationData 'undefined',
5085    type: 'Identifier'
5086    start: 0
5087    end: 9
5088    range: [0, 9]
5089    loc:
5090      start:
5091        line: 1
5092        column: 0
5093      end:
5094        line: 1
5095        column: 9
5096
5097test "AST location data as expected for NullLiteral node", ->
5098  testAstLocationData 'null',
5099    type: 'NullLiteral'
5100    start: 0
5101    end: 4
5102    range: [0, 4]
5103    loc:
5104      start:
5105        line: 1
5106        column: 0
5107      end:
5108        line: 1
5109        column: 4
5110
5111test "AST location data as expected for BooleanLiteral node", ->
5112  testAstLocationData 'true',
5113    type: 'BooleanLiteral'
5114    start: 0
5115    end: 4
5116    range: [0, 4]
5117    loc:
5118      start:
5119        line: 1
5120        column: 0
5121      end:
5122        line: 1
5123        column: 4
5124
5125test "AST location data as expected for Access node", ->
5126  testAstLocationData 'obj.prop',
5127    type: 'MemberExpression'
5128    object:
5129      start: 0
5130      end: 3
5131      range: [0, 3]
5132      loc:
5133        start:
5134          line: 1
5135          column: 0
5136        end:
5137          line: 1
5138          column: 3
5139    property:
5140      start: 4
5141      end: 8
5142      range: [4, 8]
5143      loc:
5144        start:
5145          line: 1
5146          column: 4
5147        end:
5148          line: 1
5149          column: 8
5150    start: 0
5151    end: 8
5152    range: [0, 8]
5153    loc:
5154      start:
5155        line: 1
5156        column: 0
5157      end:
5158        line: 1
5159        column: 8
5160
5161  testAstLocationData 'a::b',
5162    type: 'MemberExpression'
5163    object:
5164      object:
5165        start: 0
5166        end: 1
5167        range: [0, 1]
5168        loc:
5169          start:
5170            line: 1
5171            column: 0
5172          end:
5173            line: 1
5174            column: 1
5175      property:
5176        start: 1
5177        end: 3
5178        range: [1, 3]
5179        loc:
5180          start:
5181            line: 1
5182            column: 1
5183          end:
5184            line: 1
5185            column: 3
5186    property:
5187      start: 3
5188      end: 4
5189      range: [3, 4]
5190      loc:
5191        start:
5192          line: 1
5193          column: 3
5194        end:
5195          line: 1
5196          column: 4
5197    start: 0
5198    end: 4
5199    range: [0, 4]
5200    loc:
5201      start:
5202        line: 1
5203        column: 0
5204      end:
5205        line: 1
5206        column: 4
5207
5208  testAstLocationData '''
5209    (
5210      obj
5211    ).prop
5212  ''',
5213    type: 'MemberExpression'
5214    object:
5215      start: 4
5216      end: 7
5217      range: [4, 7]
5218      loc:
5219        start:
5220          line: 2
5221          column: 2
5222        end:
5223          line: 2
5224          column: 5
5225    property:
5226      start: 10
5227      end: 14
5228      range: [10, 14]
5229      loc:
5230        start:
5231          line: 3
5232          column: 2
5233        end:
5234          line: 3
5235          column: 6
5236    start: 0
5237    end: 14
5238    range: [0, 14]
5239    loc:
5240      start:
5241        line: 1
5242        column: 0
5243      end:
5244        line: 3
5245        column: 6
5246
5247test "AST location data as expected for Index node", ->
5248  testAstLocationData 'a[b]',
5249    type: 'MemberExpression'
5250    object:
5251      start: 0
5252      end: 1
5253      range: [0, 1]
5254      loc:
5255        start:
5256          line: 1
5257          column: 0
5258        end:
5259          line: 1
5260          column: 1
5261    property:
5262      start: 2
5263      end: 3
5264      range: [2, 3]
5265      loc:
5266        start:
5267          line: 1
5268          column: 2
5269        end:
5270          line: 1
5271          column: 3
5272    start: 0
5273    end: 4
5274    range: [0, 4]
5275    loc:
5276      start:
5277        line: 1
5278        column: 0
5279      end:
5280        line: 1
5281        column: 4
5282
5283  testAstLocationData 'a?[b][3]',
5284    type: 'OptionalMemberExpression'
5285    object:
5286      object:
5287        start: 0
5288        end: 1
5289        range: [0, 1]
5290        loc:
5291          start:
5292            line: 1
5293            column: 0
5294          end:
5295            line: 1
5296            column: 1
5297      property:
5298        start: 3
5299        end: 4
5300        range: [3, 4]
5301        loc:
5302          start:
5303            line: 1
5304            column: 3
5305          end:
5306            line: 1
5307            column: 4
5308      start: 0
5309      end: 5
5310      range: [0, 5]
5311      loc:
5312        start:
5313          line: 1
5314          column: 0
5315        end:
5316          line: 1
5317          column: 5
5318    property:
5319      start: 6
5320      end: 7
5321      range: [6, 7]
5322      loc:
5323        start:
5324          line: 1
5325          column: 6
5326        end:
5327          line: 1
5328          column: 7
5329    start: 0
5330    end: 8
5331    range: [0, 8]
5332    loc:
5333      start:
5334        line: 1
5335        column: 0
5336      end:
5337        line: 1
5338        column: 8
5339
5340test "AST location data as expected for Parens node", ->
5341  testAstLocationData '(hmmmmm)',
5342    type: 'Identifier'
5343    start: 1
5344    end: 7
5345    range: [1, 7]
5346    loc:
5347      start:
5348        line: 1
5349        column: 1
5350      end:
5351        line: 1
5352        column: 7
5353
5354  testAstLocationData '(((1)))',
5355    type: 'NumericLiteral'
5356    start: 3
5357    end: 4
5358    range: [3, 4]
5359    loc:
5360      start:
5361        line: 1
5362        column: 3
5363      end:
5364        line: 1
5365        column: 4
5366
5367test "AST location data as expected for Op node", ->
5368  testAstLocationData '1 <= 2',
5369    type: 'BinaryExpression'
5370    left:
5371      start: 0
5372      end: 1
5373      range: [0, 1]
5374      loc:
5375        start:
5376          line: 1
5377          column: 0
5378        end:
5379          line: 1
5380          column: 1
5381    right:
5382      start: 5
5383      end: 6
5384      range: [5, 6]
5385      loc:
5386        start:
5387          line: 1
5388          column: 5
5389        end:
5390          line: 1
5391          column: 6
5392    start: 0
5393    end: 6
5394    range: [0, 6]
5395    loc:
5396      start:
5397        line: 1
5398        column: 0
5399      end:
5400        line: 1
5401        column: 6
5402
5403  testAstLocationData '!x',
5404    type: 'UnaryExpression'
5405    argument:
5406      start: 1
5407      end: 2
5408      range: [1, 2]
5409      loc:
5410        start:
5411          line: 1
5412          column: 1
5413        end:
5414          line: 1
5415          column: 2
5416    start: 0
5417    end: 2
5418    range: [0, 2]
5419    loc:
5420      start:
5421        line: 1
5422        column: 0
5423      end:
5424        line: 1
5425        column: 2
5426
5427  testAstLocationData 'not x',
5428    type: 'UnaryExpression'
5429    argument:
5430      start: 4
5431      end: 5
5432      range: [4, 5]
5433      loc:
5434        start:
5435          line: 1
5436          column: 4
5437        end:
5438          line: 1
5439          column: 5
5440    start: 0
5441    end: 5
5442    range: [0, 5]
5443    loc:
5444      start:
5445        line: 1
5446        column: 0
5447      end:
5448        line: 1
5449        column: 5
5450
5451  testAstLocationData 'x++',
5452    type: 'UpdateExpression'
5453    argument:
5454      start: 0
5455      end: 1
5456      range: [0, 1]
5457      loc:
5458        start:
5459          line: 1
5460          column: 0
5461        end:
5462          line: 1
5463          column: 1
5464    start: 0
5465    end: 3
5466    range: [0, 3]
5467    loc:
5468      start:
5469        line: 1
5470        column: 0
5471      end:
5472        line: 1
5473        column: 3
5474
5475  testAstLocationData '(x + y) * z',
5476    type: 'BinaryExpression'
5477    left:
5478      left:
5479        start: 1
5480        end: 2
5481        range: [1, 2]
5482        loc:
5483          start:
5484            line: 1
5485            column: 1
5486          end:
5487            line: 1
5488            column: 2
5489      right:
5490        start: 5
5491        end: 6
5492        range: [5, 6]
5493        loc:
5494          start:
5495            line: 1
5496            column: 5
5497          end:
5498            line: 1
5499            column: 6
5500      start: 1
5501      end: 6
5502      range: [1, 6]
5503      loc:
5504        start:
5505          line: 1
5506          column: 1
5507        end:
5508          line: 1
5509          column: 6
5510    right:
5511      start: 10
5512      end: 11
5513      range: [10, 11]
5514      loc:
5515        start:
5516          line: 1
5517          column: 10
5518        end:
5519          line: 1
5520          column: 11
5521    start: 0
5522    end: 11
5523    range: [0, 11]
5524    loc:
5525      start:
5526        line: 1
5527        column: 0
5528      end:
5529        line: 1
5530        column: 11
5531
5532test "AST location data as expected for Call node", ->
5533  testAstLocationData 'fn()',
5534    type: 'CallExpression'
5535    start: 0
5536    end: 4
5537    range: [0, 4]
5538    loc:
5539      start:
5540        line: 1
5541        column: 0
5542      end:
5543        line: 1
5544        column: 4
5545    callee:
5546      start: 0
5547      end: 2
5548      range: [0, 2]
5549      loc:
5550        start:
5551          line: 1
5552          column: 0
5553        end:
5554          line: 1
5555          column: 2
5556
5557  testAstLocationData 'new Date()',
5558    type: 'NewExpression'
5559    start: 0
5560    end: 10
5561    range: [0, 10]
5562    loc:
5563      start:
5564        line: 1
5565        column: 0
5566      end:
5567        line: 1
5568        column: 10
5569    callee:
5570      start: 4
5571      end: 8
5572      range: [4, 8]
5573      loc:
5574        start:
5575          line: 1
5576          column: 4
5577        end:
5578          line: 1
5579          column: 8
5580
5581  testAstLocationData '''
5582    new Old(
5583      1
5584    )
5585  ''',
5586    start: 0
5587    end: 14
5588    range: [0, 14]
5589    loc:
5590      start:
5591        line: 1
5592        column: 0
5593      end:
5594        line: 3
5595        column: 1
5596    type: 'NewExpression'
5597    arguments: [
5598      start: 11
5599      end: 12
5600      range: [11, 12]
5601      loc:
5602        start:
5603          line: 2
5604          column: 2
5605        end:
5606          line: 2
5607          column: 3
5608    ]
5609
5610  testAstLocationData 'maybe? 1 + 1',
5611    type: 'OptionalCallExpression'
5612    start: 0
5613    end: 12
5614    range: [0, 12]
5615    loc:
5616      start:
5617        line: 1
5618        column: 0
5619      end:
5620        line: 1
5621        column: 12
5622    arguments: [
5623      start: 7
5624      end: 12
5625      range: [7, 12]
5626      loc:
5627        start:
5628          line: 1
5629          column: 7
5630        end:
5631          line: 1
5632          column: 12
5633    ]
5634
5635  testAstLocationData '''
5636    goDo(this,
5637      that)
5638  ''',
5639    type: 'CallExpression'
5640    start: 0
5641    end: 18
5642    range: [0, 18]
5643    loc:
5644      start:
5645        line: 1
5646        column: 0
5647      end:
5648        line: 2
5649        column: 7
5650    arguments: [
5651      start: 5
5652      end: 9
5653      range: [5, 9]
5654      loc:
5655        start:
5656          line: 1
5657          column: 5
5658        end:
5659          line: 1
5660          column: 9
5661    ,
5662      start: 13
5663      end: 17
5664      range: [13, 17]
5665      loc:
5666        start:
5667          line: 2
5668          column: 2
5669        end:
5670          line: 2
5671          column: 6
5672    ]
5673
5674  testAstLocationData 'new Old',
5675    type: 'NewExpression'
5676    callee:
5677      start: 4
5678      end: 7
5679      range: [4, 7]
5680      loc:
5681        start:
5682          line: 1
5683          column: 4
5684        end:
5685          line: 1
5686          column: 7
5687    start: 0
5688    end: 7
5689    range: [0, 7]
5690    loc:
5691      start:
5692        line: 1
5693        column: 0
5694      end:
5695        line: 1
5696        column: 7
5697
5698test "AST location data as expected for SuperCall node", ->
5699  testAstLocationData 'class child extends parent then constructor: -> super()',
5700    type: 'ClassDeclaration'
5701    body:
5702      body: [
5703        body:
5704          body: [
5705            expression:
5706              callee:
5707                start: 48
5708                end: 53
5709                range: [48, 53]
5710                loc:
5711                  start:
5712                    line: 1
5713                    column: 48
5714                  end:
5715                    line: 1
5716                    column: 53
5717              start: 48
5718              end: 55
5719              range: [48, 55]
5720              loc:
5721                start:
5722                  line: 1
5723                  column: 48
5724                end:
5725                  line: 1
5726                  column: 55
5727          ]
5728      ]
5729    start: 0
5730    end: 55
5731    range: [0, 55]
5732    loc:
5733      start:
5734        line: 1
5735        column: 0
5736      end:
5737        line: 1
5738        column: 55
5739
5740test "AST location data as expected for Super node", ->
5741  testAstLocationData '''
5742    class child extends parent
5743      func: ->
5744        super[prop]()
5745  ''',
5746    type: 'ClassDeclaration'
5747    body:
5748      body: [
5749        body:
5750          body: [
5751            expression:
5752              callee:
5753                object:
5754                  start: 42
5755                  end: 47
5756                  range: [42, 47]
5757                  loc:
5758                    start:
5759                      line: 3
5760                      column: 4
5761                    end:
5762                      line: 3
5763                      column: 9
5764                property:
5765                  start: 48
5766                  end: 52
5767                  range: [48, 52]
5768                  loc:
5769                    start:
5770                      line: 3
5771                      column: 10
5772                    end:
5773                      line: 3
5774                      column: 14
5775                start: 42
5776                end: 53
5777                range: [42, 53]
5778                loc:
5779                  start:
5780                    line: 3
5781                    column: 4
5782                  end:
5783                    line: 3
5784                    column: 15
5785              start: 42
5786              end: 55
5787              range: [42, 55]
5788              loc:
5789                start:
5790                  line: 3
5791                  column: 4
5792                end:
5793                  line: 3
5794                  column: 17
5795          ]
5796      ]
5797    start: 0
5798    end: 55
5799    range: [0, 55]
5800    loc:
5801      start:
5802        line: 1
5803        column: 0
5804      end:
5805        line: 3
5806        column: 17
5807
5808test "AST location data as expected for Range node", ->
5809  testAstLocationData '[x..y]',
5810    type: 'Range'
5811    from:
5812      start: 1
5813      end: 2
5814      range: [1, 2]
5815      loc:
5816        start:
5817          line: 1
5818          column: 1
5819        end:
5820          line: 1
5821          column: 2
5822    to:
5823      start: 4
5824      end: 5
5825      range: [4, 5]
5826      loc:
5827        start:
5828          line: 1
5829          column: 4
5830        end:
5831          line: 1
5832          column: 5
5833    start: 0
5834    end: 6
5835    range: [0, 6]
5836    loc:
5837      start:
5838        line: 1
5839        column: 0
5840      end:
5841        line: 1
5842        column: 6
5843
5844  testAstLocationData '[4...2]',
5845    type: 'Range'
5846    from:
5847      start: 1
5848      end: 2
5849      range: [1, 2]
5850      loc:
5851        start:
5852          line: 1
5853          column: 1
5854        end:
5855          line: 1
5856          column: 2
5857    to:
5858      start: 5
5859      end: 6
5860      range: [5, 6]
5861      loc:
5862        start:
5863          line: 1
5864          column: 5
5865        end:
5866          line: 1
5867          column: 6
5868    start: 0
5869    end: 7
5870    range: [0, 7]
5871    loc:
5872      start:
5873        line: 1
5874        column: 0
5875      end:
5876        line: 1
5877        column: 7
5878
5879test "AST location data as expected for Slice node", ->
5880  testAstLocationData 'x[..y]',
5881    property:
5882      to:
5883        start: 4
5884        end: 5
5885        range: [4, 5]
5886        loc:
5887          start:
5888            line: 1
5889            column: 4
5890          end:
5891            line: 1
5892            column: 5
5893      start: 2
5894      end: 5
5895      range: [2, 5]
5896      loc:
5897        start:
5898          line: 1
5899          column: 2
5900        end:
5901          line: 1
5902          column: 5
5903    start: 0
5904    end: 6
5905    range: [0, 6]
5906    loc:
5907      start:
5908        line: 1
5909        column: 0
5910      end:
5911        line: 1
5912        column: 6
5913
5914  testAstLocationData 'x[y...z]',
5915    property:
5916      start: 2
5917      end: 7
5918      range: [2, 7]
5919      loc:
5920        start:
5921          line: 1
5922          column: 2
5923        end:
5924          line: 1
5925          column: 7
5926    start: 0
5927    end: 8
5928    range: [0, 8]
5929    loc:
5930      start:
5931        line: 1
5932        column: 0
5933      end:
5934        line: 1
5935        column: 8
5936
5937  testAstLocationData 'x[...]',
5938    property:
5939      start: 2
5940      end: 5
5941      range: [2, 5]
5942      loc:
5943        start:
5944          line: 1
5945          column: 2
5946        end:
5947          line: 1
5948          column: 5
5949    start: 0
5950    end: 6
5951    range: [0, 6]
5952    loc:
5953      start:
5954        line: 1
5955        column: 0
5956      end:
5957        line: 1
5958        column: 6
5959
5960test "AST location data as expected for Splat node", ->
5961  testAstLocationData '[a...]',
5962    type: 'ArrayExpression'
5963    elements: [
5964      argument:
5965        start: 1
5966        end: 2
5967        range: [1, 2]
5968        loc:
5969          start:
5970            line: 1
5971            column: 1
5972          end:
5973            line: 1
5974            column: 2
5975      start: 1
5976      end: 5
5977      range: [1, 5]
5978      loc:
5979        start:
5980          line: 1
5981          column: 1
5982        end:
5983          line: 1
5984          column: 5
5985    ]
5986    start: 0
5987    end: 6
5988    range: [0, 6]
5989    loc:
5990      start:
5991        line: 1
5992        column: 0
5993      end:
5994        line: 1
5995        column: 6
5996
5997  testAstLocationData '[b, ...c]',
5998    type: 'ArrayExpression'
5999    elements: [
6000      {}
6001    ,
6002      argument:
6003        start: 7
6004        end: 8
6005        range: [7, 8]
6006        loc:
6007          start:
6008            line: 1
6009            column: 7
6010          end:
6011            line: 1
6012            column: 8
6013      start: 4
6014      end: 8
6015      range: [4, 8]
6016      loc:
6017        start:
6018          line: 1
6019          column: 4
6020        end:
6021          line: 1
6022          column: 8
6023    ]
6024    start: 0
6025    end: 9
6026    range: [0, 9]
6027    loc:
6028      start:
6029        line: 1
6030        column: 0
6031      end:
6032        line: 1
6033        column: 
60339
6034
6035test "AST location data as expected for Elision node", ->
6036  testAstLocationData '[,,,a,, ,b]',
6037    type: 'ArrayExpression'
6038    elements: [
6039      null,,,
6040      start: 4
6041      end: 5
6042      range: [4, 5]
6043      loc:
6044        start:
6045          line: 1
6046          column: 4
6047        end:
6048          line: 1
6049          column: 5
6050    ,,,
6051      start: 9
6052      end: 10
6053      range: [9, 10]
6054      loc:
6055        start:
6056          line: 1
6057          column: 9
6058        end:
6059          line: 1
6060          column: 10
6061    ]
6062    start: 0
6063    end: 11
6064    range: [0, 11]
6065    loc:
6066      start:
6067        line: 1
6068        column: 0
6069      end:
6070        line: 1
6071        column: 11
6072
6073test "AST location data as expected for ModuleDeclaration node", ->
6074  testAstLocationData 'export {X}',
6075    type: 'ExportNamedDeclaration'
6076    specifiers: [
6077      local:
6078        start: 8
6079        end: 9
6080        range: [8, 9]
6081        loc:
6082          start:
6083            line: 1
6084            column: 8
6085          end:
6086            line: 1
6087            column: 9
6088      exported:
6089        start: 8
6090        end: 9
6091        range: [8, 9]
6092        loc:
6093          start:
6094            line: 1
6095            column: 8
6096          end:
6097            line: 1
6098            column: 9
6099      start: 8
6100      end: 9
6101      range: [8, 9]
6102      loc:
6103        start:
6104          line: 1
6105          column: 8
6106        end:
6107          line: 1
6108          column: 9
6109    ]
6110    start: 0
6111    end: 10
6112    range: [0, 10]
6113    loc:
6114      start:
6115        line: 1
6116        column: 0
6117      end:
6118        line: 1
6119        column: 10
6120
6121  testAstLocationData 'import X from "."',
6122    type: 'ImportDeclaration'
6123    specifiers: [
6124      start: 7
6125      end: 8
6126      range: [7, 8]
6127      loc:
6128        start:
6129          line: 1
6130          column: 7
6131        end:
6132          line: 1
6133          column: 8
6134    ]
6135    source:
6136      start: 14
6137      end: 17
6138      range: [14, 17]
6139      loc:
6140        start:
6141          line: 1
6142          column: 14
6143        end:
6144          line: 1
6145          column: 17
6146    start: 0
6147    end: 17
6148    range: [0, 17]
6149    loc:
6150      start:
6151        line: 1
6152        column: 0
6153      end:
6154        line: 1
6155        column: 17
6156
6157test "AST location data as expected for ImportDeclaration node", ->
6158  testAstLocationData '''
6159    import React, {
6160      Component
6161    } from "react"
6162  ''',
6163    type: 'ImportDeclaration'
6164    specifiers: [
6165      start: 7
6166      end: 12
6167      range: [7, 12]
6168      loc:
6169        start:
6170          line: 1
6171          column: 7
6172        end:
6173          line: 1
6174          column: 12
6175    ,
6176      imported:
6177        start: 18
6178        end: 27
6179        range: [18, 27]
6180        loc:
6181          start:
6182            line: 2
6183            column: 2
6184          end:
6185            line: 2
6186            column: 11
6187      start: 18
6188      end: 27
6189      range: [18, 27]
6190      loc:
6191        start:
6192          line: 2
6193          column: 2
6194        end:
6195          line: 2
6196          column: 11
6197    ]
6198    source:
6199      start: 35
6200      end: 42
6201      range: [35, 42]
6202      loc:
6203        start:
6204          line: 3
6205          column: 7
6206        end:
6207          line: 3
6208          column: 14
6209    start: 0
6210    end: 42
6211    range: [0, 42]
6212    loc:
6213      start:
6214        line: 1
6215        column: 0
6216      end:
6217        line: 3
6218        column: 14
6219
6220test "AST location data as expected for ExportNamedDeclaration node", ->
6221  testAstLocationData 'export {}',
6222    type: 'ExportNamedDeclaration'
6223    start: 0
6224    end: 9
6225    range: [0, 9]
6226    loc:
6227      start:
6228        line: 1
6229        column: 0
6230      end:
6231        line: 1
6232        column: 9
6233
6234  testAstLocationData 'export fn = ->',
6235    type: 'ExportNamedDeclaration'
6236    declaration:
6237      left:
6238        start: 7
6239        end: 9
6240        range: [7, 9]
6241        loc:
6242          start:
6243            line: 1
6244            column: 7
6245          end:
6246            line: 1
6247            column: 9
6248      right:
6249        start: 12
6250        end: 14
6251        range: [12, 14]
6252        loc:
6253          start:
6254            line: 1
6255            column: 12
6256          end:
6257            line: 1
6258            column: 14
6259      start: 7
6260      end: 14
6261      range: [7, 14]
6262      loc:
6263        start:
6264          line: 1
6265          column: 7
6266        end:
6267          line: 1
6268          column: 14
6269    start: 0
6270    end: 14
6271    range: [0, 14]
6272    loc:
6273      start:
6274        line: 1
6275        column: 0
6276      end:
6277        line: 1
6278        column: 14
6279
6280  testAstLocationData 'export class A',
6281    type: 'ExportNamedDeclaration'
6282    declaration:
6283      id:
6284        start: 13
6285        end: 14
6286        range: [13, 14]
6287        loc:
6288          start:
6289            line: 1
6290            column: 13
6291          end:
6292            line: 1
6293            column: 14
6294      start: 7
6295      end: 14
6296      range: [7, 14]
6297      loc:
6298        start:
6299          line: 1
6300          column: 7
6301        end:
6302          line: 1
6303          column: 14
6304    start: 0
6305    end: 14
6306    range: [0, 14]
6307    loc:
6308      start:
6309        line: 1
6310        column: 0
6311      end:
6312        line: 1
6313        column: 14
6314
6315  testAstLocationData '''
6316    export {
6317      x as y
6318      z as default
6319      }
6320  ''',
6321    type: 'ExportNamedDeclaration'
6322    specifiers: [
6323      local:
6324        start: 11
6325        end: 12
6326        range: [11, 12]
6327        loc:
6328          start:
6329            line: 2
6330            column: 2
6331          end:
6332            line: 2
6333            column: 3
6334      exported:
6335        start: 16
6336        end: 17
6337        range: [16, 17]
6338        loc:
6339          start:
6340            line: 2
6341            column: 7
6342          end:
6343            line: 2
6344            column: 8
6345      start: 11
6346      end: 17
6347      range: [11, 17]
6348      loc:
6349        start:
6350          line: 2
6351          column: 2
6352        end:
6353          line: 2
6354          column: 8
6355    ,
6356      local:
6357        start: 20
6358        end: 21
6359        range: [20, 21]
6360        loc:
6361          start:
6362            line: 3
6363            column: 2
6364          end:
6365            line: 3
6366            column: 3
6367      exported:
6368        start: 25
6369        end: 32
6370        range: [25, 32]
6371        loc:
6372          start:
6373            line: 3
6374            column: 7
6375          end:
6376            line: 3
6377            column: 14
6378      start: 20
6379      end: 32
6380      range: [20, 32]
6381      loc:
6382        start:
6383          line: 3
6384          column: 2
6385        end:
6386          line: 3
6387          column: 14
6388    ]
6389    start: 0
6390    end: 36
6391    range: [0, 36]
6392    loc:
6393      start:
6394        line: 1
6395        column: 0
6396      end:
6397        line: 4
6398        column: 3
6399
6400  testAstLocationData 'export {default, default as b} from "./abc"',
6401    type: 'ExportNamedDeclaration'
6402    specifiers: [
6403      local:
6404        start: 8
6405        end: 15
6406        range: [8, 15]
6407        loc:
6408          start:
6409            line: 1
6410            column: 8
6411          end:
6412            line: 1
6413            column: 15
6414      start: 8
6415      end: 15
6416      range: [8, 15]
6417      loc:
6418        start:
6419          line: 1
6420          column: 8
6421        end:
6422          line: 1
6423          column: 15
6424    ,
6425      local:
6426        start: 17
6427        end: 24
6428        range: [17, 24]
6429        loc:
6430          start:
6431            line: 1
6432            column: 17
6433          end:
6434            line: 1
6435            column: 24
6436      exported:
6437        start: 28
6438        end: 29
6439        range: [28, 29]
6440        loc:
6441          start:
6442            line: 1
6443            column: 28
6444          end:
6445            line: 1
6446            column: 29
6447      start: 17
6448      end: 29
6449      range: [17, 29]
6450      loc:
6451        start:
6452          line: 1
6453          column: 17
6454        end:
6455          line: 1
6456          column: 29
6457    ]
6458    source:
6459      start: 36
6460      end: 43
6461      range: [36, 43]
6462      loc:
6463        start:
6464          line: 1
6465          column: 36
6466        end:
6467          line: 1
6468          column: 43
6469    start: 0
6470    end: 43
6471    range: [0, 43]
6472    loc:
6473      start:
6474        line: 1
6475        column: 0
6476      end:
6477        line: 1
6478        column: 43
6479
6480test "AST location data as expected for ExportDefaultDeclaration node", ->
6481  testAstLocationData 'export default class',
6482    type: 'ExportDefaultDeclaration'
6483    declaration:
6484      start: 15
6485      end: 20
6486      range: [15, 20]
6487      loc:
6488        start:
6489          line: 1
6490          column: 15
6491        end:
6492          line: 1
6493          column: 20
6494    start: 0
6495    end: 20
6496    range: [0, 20]
6497    loc:
6498      start:
6499        line: 1
6500        column: 0
6501      end:
6502        line: 1
6503        column: 20
6504
6505  testAstLocationData 'export default "abc"',
6506    type: 'ExportDefaultDeclaration'
6507    declaration:
6508      start: 15
6509      end: 20
6510      range: [15, 20]
6511      loc:
6512        start:
6513          line: 1
6514          column: 15
6515        end:
6516          line: 1
6517          column: 20
6518    start: 0
6519    end: 20
6520    range: [0, 20]
6521    loc:
6522      start:
6523        line: 1
6524        column: 0
6525      end:
6526        line: 1
6527        column: 20
6528
6529test "AST location data as expected for ExportAllDeclaration node", ->
6530  testAstLocationData 'export * from "module-name"',
6531    type: 'ExportAllDeclaration'
6532    source:
6533      start: 14
6534      end: 27
6535      range: [14, 27]
6536      loc:
6537        start:
6538          line: 1
6539          column: 14
6540        end:
6541          line: 1
6542          column: 27
6543    start: 0
6544    end: 27
6545    range: [0, 27]
6546    loc:
6547      start:
6548        line: 1
6549        column: 0
6550      end:
6551        line: 1
6552        column: 27
6553
6554test "AST location data as expected for ImportDefaultSpecifier node", ->
6555  testAstLocationData 'import React from "react"',
6556    type: 'ImportDeclaration'
6557    specifiers: [
6558      start: 7
6559      end: 12
6560      range: [7, 12]
6561      loc:
6562        start:
6563          line: 1
6564          column: 7
6565        end:
6566          line: 1
6567          column: 12
6568    ]
6569    source:
6570      start: 18
6571      end: 25
6572      range: [18, 25]
6573      loc:
6574        start:
6575          line: 1
6576          column: 18
6577        end:
6578          line: 1
6579          column: 25
6580    start: 0
6581    end: 25
6582    range: [0, 25]
6583    loc:
6584      start:
6585        line: 1
6586        column: 0
6587      end:
6588        line: 1
6589        column: 25
6590
6591test "AST location data as expected for ImportNamespaceSpecifier node", ->
6592  testAstLocationData 'import * as React from "react"',
6593    type: 'ImportDeclaration'
6594    specifiers: [
6595      start: 7
6596      end: 17
6597      range: [7, 17]
6598      loc:
6599        start:
6600          line: 1
6601          column: 7
6602        end:
6603          line: 1
6604          column: 17
6605    ]
6606    source:
6607      start: 23
6608      end: 30
6609      range: [23, 30]
6610      loc:
6611        start:
6612          line: 1
6613          column: 23
6614        end:
6615          line: 1
6616          column: 30
6617    start: 0
6618    end: 30
6619    range: [0, 30]
6620    loc:
6621      start:
6622        line: 1
6623        column: 0
6624      end:
6625        line: 1
6626        column: 30
6627
6628  testAstLocationData 'import React, * as ReactStar from "react"',
6629    type: 'ImportDeclaration'
6630    specifiers: [
6631      start: 7
6632      end: 12
6633      range: [7, 12]
6634      loc:
6635        start:
6636          line: 1
6637          column: 7
6638        end:
6639          line: 1
6640          column: 12
6641    ,
6642      local:
6643        start: 19
6644        end: 28
6645        range: [19, 28]
6646        loc:
6647          start:
6648            line: 1
6649            column: 19
6650          end:
6651            line: 1
6652            column: 28
6653      start: 14
6654      end: 28
6655      range: [14, 28]
6656      loc:
6657        start:
6658          line: 1
6659          column: 14
6660        end:
6661          line: 1
6662          column: 28
6663    ]
6664    source:
6665      start: 34
6666      end: 41
6667      range: [34, 41]
6668      loc:
6669        start:
6670          line: 1
6671          column: 34
6672        end:
6673          line: 1
6674          column: 41
6675    start: 0
6676    end: 41
6677    range: [0, 41]
6678    loc:
6679      start:
6680        line: 1
6681        column: 0
6682      end:
6683        line: 1
6684        column: 41
6685
6686test "AST location data as expected for Obj node", ->
6687  testAstLocationData "{a: 1, b, [c], @d, [e()]: f, 'g': 2, ...h, i...}",
6688    type: 'ObjectExpression'
6689    properties: [
6690      key:
6691        start: 1
6692        end: 2
6693        range: [1, 2]
6694        loc:
6695          start:
6696            line: 1
6697            column: 1
6698          end:
6699            line: 1
6700            column: 2
6701      value:
6702        start: 4
6703        end: 5
6704        range: [4, 5]
6705        loc:
6706          start:
6707            line: 1
6708            column: 4
6709          end:
6710            line: 1
6711            column: 5
6712      start: 1
6713      end: 5
6714      range: [1, 5]
6715      loc:
6716        start:
6717          line: 1
6718          column: 1
6719        end:
6720          line: 1
6721          column: 5
6722    ,
6723      key:
6724        start: 7
6725        end: 8
6726        range: [7, 8]
6727        loc:
6728          start:
6729            line: 1
6730            column: 7
6731          end:
6732            line: 1
6733            column: 8
6734      value:
6735        start: 7
6736        end: 8
6737        range: [7, 8]
6738        loc:
6739          start:
6740            line: 1
6741            column: 7
6742          end:
6743            line: 1
6744            column: 8
6745      start: 7
6746      end: 8
6747      range: [7, 8]
6748      loc:
6749        start:
6750          line: 1
6751          column: 7
6752        end:
6753          line: 1
6754          column: 8
6755    ,
6756      key:
6757        start: 11
6758        end: 12
6759        range: [11, 12]
6760        loc:
6761          start:
6762            line: 1
6763            column: 11
6764          end:
6765            line: 1
6766            column: 12
6767      value:
6768        start: 11
6769        end: 12
6770        range: [11, 12]
6771        loc:
6772          start:
6773            line: 1
6774            column: 11
6775          end:
6776            line: 1
6777            column: 12
6778      start: 10
6779      end: 13
6780      range: [10, 13]
6781      loc:
6782        start:
6783          line: 1
6784          column: 10
6785        end:
6786          line: 1
6787          column: 13
6788    ,
6789      key:
6790        object:
6791          start: 15
6792          end: 16
6793          range: [15, 16]
6794          loc:
6795            start:
6796              line: 1
6797              column: 15
6798            end:
6799              line: 1
6800              column: 16
6801        property:
6802          start: 16
6803          end: 17
6804          range: [16, 17]
6805          loc:
6806            start:
6807              line: 1
6808              column: 16
6809            end:
6810              line: 1
6811              column: 17
6812        start: 15
6813        end: 17
6814        range: [15, 17]
6815        loc:
6816          start:
6817            line: 1
6818            column: 15
6819          end:
6820            line: 1
6821            column: 17
6822      value:
6823        object:
6824          start: 15
6825          end: 16
6826          range: [15, 16]
6827          loc:
6828            start:
6829              line: 1
6830              column: 15
6831            end:
6832              line: 1
6833              column: 16
6834        property:
6835          start: 16
6836          end: 17
6837          range: [16, 17]
6838          loc:
6839            start:
6840              line: 1
6841              column: 16
6842            end:
6843              line: 1
6844              column: 17
6845        start: 15
6846        end: 17
6847        range: [15, 17]
6848        loc:
6849          start:
6850            line: 1
6851            column: 15
6852          end:
6853            line: 1
6854            column: 17
6855      start: 15
6856      end: 17
6857      range: [15, 17]
6858      loc:
6859        start:
6860          line: 1
6861          column: 15
6862        end:
6863          line: 1
6864          column: 17
6865    ,
6866      key:
6867        start: 20
6868        end: 23
6869        range: [20, 23]
6870        loc:
6871          start:
6872            line: 1
6873            column: 20
6874          end:
6875            line: 1
6876            column: 23
6877      value:
6878        start: 26
6879        end: 27
6880        range: [26, 27]
6881        loc:
6882          start:
6883            line: 1
6884            column: 26
6885          end:
6886            line: 1
6887            column: 27
6888      start: 19
6889      end: 27
6890      range: [19, 27]
6891      loc:
6892        start:
6893          line: 1
6894          column: 19
6895        end:
6896          line: 1
6897          column: 27
6898    ,
6899      key:
6900        start: 29
6901        end: 32
6902        range: [29, 32]
6903        loc:
6904          start:
6905            line: 1
6906            column: 29
6907          end:
6908            line: 1
6909            column: 32
6910      value:
6911        start: 34
6912        end: 35
6913        range: [34, 35]
6914        loc:
6915          start:
6916            line: 1
6917            column: 34
6918          end:
6919            line: 1
6920            column: 35
6921      start: 29
6922      end: 35
6923      range: [29, 35]
6924      loc:
6925        start:
6926          line: 1
6927          column: 29
6928        end:
6929          line: 1
6930          column: 35
6931    ,
6932      argument:
6933        start: 40
6934        end: 41
6935        range: [40, 41]
6936        loc:
6937          start:
6938            line: 1
6939            column: 40
6940          end:
6941            line: 1
6942            column: 41
6943      start: 37
6944      end: 41
6945      range: [37, 41]
6946      loc:
6947        start:
6948          line: 1
6949          column: 37
6950        end:
6951          line: 1
6952          column: 41
6953    ,
6954      argument:
6955        start: 43
6956        end: 44
6957        range: [43, 44]
6958        loc:
6959          start:
6960            line: 1
6961            column: 43
6962          end:
6963            line: 1
6964            column: 44
6965      start: 43
6966      end: 47
6967      range: [43, 47]
6968      loc:
6969        start:
6970          line: 1
6971          column: 43
6972        end:
6973          line: 1
6974          column: 47
6975    ]
6976    start: 0
6977    end: 48
6978    range: [0, 48]
6979    loc:
6980      start:
6981        line: 1
6982        column: 0
6983      end:
6984        line: 1
6985        column: 48
6986
6987  testAstLocationData 'a: 1',
6988    type: 'ObjectExpression'
6989    properties: [
6990      key:
6991        start: 0
6992        end: 1
6993        range: [0, 1]
6994        loc:
6995          start:
6996            line: 1
6997            column: 0
6998          end:
6999            line: 1
7000            column: 1
7001      value:
7002        start: 3
7003        end: 4
7004        range: [3, 4]
7005        loc:
7006          start:
7007            line: 1
7008            column: 3
7009          end:
7010            line: 1
7011            column: 4
7012      start: 0
7013      end: 4
7014      range: [0, 4]
7015      loc:
7016        start:
7017          line: 1
7018          column: 0
7019        end:
7020          line: 1
7021          column: 4
7022    ]
7023    start: 0
7024    end: 4
7025    range: [0, 4]
7026    loc:
7027      start:
7028        line: 1
7029        column: 0
7030      end:
7031        line: 1
7032        column: 4
7033
7034test "AST location data as expected for Assign node", ->
7035  testAstLocationData 'a = b',
7036    type: 'AssignmentExpression'
7037    left:
7038      start: 0
7039      end: 1
7040      range: [0, 1]
7041      loc:
7042        start:
7043          line: 1
7044          column: 0
7045        end:
7046          line: 1
7047          column: 1
7048    right:
7049      start: 4
7050      end: 5
7051      range: [4, 5]
7052      loc:
7053        start:
7054          line: 1
7055          column: 4
7056        end:
7057          line: 1
7058          column: 5
7059    start: 0
7060    end: 5
7061    range: [0, 5]
7062    loc:
7063      start:
7064        line: 1
7065        column: 0
7066      end:
7067        line: 1
7068        column: 5
7069
7070  testAstLocationData 'a += b',
7071    type: 'AssignmentExpression'
7072    left:
7073      start: 0
7074      end: 1
7075      range: [0, 1]
7076      loc:
7077        start:
7078          line: 1
7079          column: 0
7080        end:
7081          line: 1
7082          column: 1
7083    right:
7084      start: 5
7085      end: 6
7086      range: [5, 6]
7087      loc:
7088        start:
7089          line: 1
7090          column: 5
7091        end:
7092          line: 1
7093          column: 6
7094    start: 0
7095    end: 6
7096    range: [0, 6]
7097    loc:
7098      start:
7099        line: 1
7100        column: 0
7101      end:
7102        line: 1
7103        column: 6
7104
7105  testAstLocationData '{a: [...b]} = c',
7106    type: 'AssignmentExpression'
7107    left:
7108      properties: [
7109        type: 'ObjectProperty'
7110        key:
7111          start: 1
7112          end: 2
7113          range: [1, 2]
7114          loc:
7115            start:
7116              line: 1
7117              column: 1
7118            end:
7119              line: 1
7120              column: 2
7121        value:
7122          elements: [
7123            start: 5
7124            end: 9
7125            range: [5, 9]
7126            loc:
7127              start:
7128                line: 1
7129                column: 5
7130              end:
7131                line: 1
7132                column: 9
7133          ]
7134          start: 4
7135          end: 10
7136          range: [4, 10]
7137          loc:
7138            start:
7139              line: 1
7140              column: 4
7141            end:
7142              line: 1
7143              column: 10
7144        start: 1
7145        end: 10
7146        range: [1, 10]
7147        loc:
7148          start:
7149            line: 1
7150            column: 1
7151          end:
7152            line: 1
7153            column: 10
7154      ]
7155      start: 0
7156      end: 11
7157      range: [0, 11]
7158      loc:
7159        start:
7160          line: 1
7161          column: 0
7162        end:
7163          line: 1
7164          column: 11
7165    right:
7166      start: 14
7167      end: 15
7168      range: [14, 15]
7169      loc:
7170        start:
7171          line: 1
7172          column: 14
7173        end:
7174          line: 1
7175          column: 15
7176    start: 0
7177    end: 15
7178    range: [0, 15]
7179    loc:
7180      start:
7181        line: 1
7182        column: 0
7183      end:
7184        line: 1
7185        column: 15
7186
7187test "AST location data as expected for Expansion node", ->
7188  testAstLocationData '[..., b] = c',
7189    type: 'AssignmentExpression'
7190    left:
7191      elements: [
7192        start: 1
7193        end: 4
7194        range: [1, 4]
7195        loc:
7196          start:
7197            line: 1
7198            column: 1
7199          end:
7200            line: 1
7201            column: 4
7202      ]
7203      start: 0
7204      end: 8
7205      range: [0, 8]
7206      loc:
7207        start:
7208          line: 1
7209          column: 0
7210        end:
7211          line: 1
7212          column: 8
7213    start: 0
7214    end: 12
7215    range: [0, 12]
7216    loc:
7217      start:
7218        line: 1
7219        column: 0
7220      end:
7221        line: 1
7222        column: 12
7223
7224test "AST location data as expected for Throw node", ->
7225  testAstLocationData 'throw new BallError "catch"',
7226    type: 'ThrowStatement'
7227    argument:
7228      start: 6
7229      end: 27
7230      range: [6, 27]
7231      loc:
7232        start:
7233          line: 1
7234          column: 6
7235        end:
7236          line: 1
7237          column: 27
7238    start: 0
7239    end: 27
7240    range: [0, 27]
7241    loc:
7242      start:
7243        line: 1
7244        column: 0
7245      end:
7246        line: 1
7247        column: 27
7248
7249test "AST location data as expected for Existence node", ->
7250  testAstLocationData 'Ghosts?',
7251    type: 'UnaryExpression'
7252    argument:
7253      start: 0
7254      end: 6
7255      range: [0, 6]
7256      loc:
7257        start:
7258          line: 1
7259          column: 0
7260        end:
7261          line: 1
7262          column: 6
7263    start: 0
7264    end: 7
7265    range: [0, 7]
7266    loc:
7267      start:
7268        line: 1
7269        column: 0
7270      end:
7271        line: 1
7272        column: 7
7273
7274test "AST location data as expected for JSXTag node", ->
7275  testAstLocationData '<CSXY />',
7276    type: 'JSXElement'
7277    openingElement:
7278      name:
7279        start: 1
7280        end: 5
7281        range: [1, 5]
7282        loc:
7283          start:
7284            line: 1
7285            column: 1
7286          end:
7287            line: 1
7288            column: 5
7289      start: 0
7290      end: 8
7291      range: [0, 8]
7292      loc:
7293        start:
7294          line: 1
7295          column: 0
7296        end:
7297          line: 1
7298          column: 8
7299    start: 0
7300    end: 8
7301    range: [0, 8]
7302    loc:
7303      start:
7304        line: 1
7305        column: 0
7306      end:
7307        line: 1
7308        column: 8
7309
7310  testAstLocationData '<div></div>',
7311    type: 'JSXElement'
7312    openingElement:
7313      name:
7314        start: 1
7315        end: 4
7316        range: [1, 4]
7317        loc:
7318          start:
7319            line: 1
7320            column: 1
7321          end:
7322            line: 1
7323            column: 4
7324      start: 0
7325      end: 5
7326      range: [0, 5]
7327      loc:
7328        start:
7329          line: 1
7330          column: 0
7331        end:
7332          line: 1
7333          column: 5
7334    closingElement:
7335      name:
7336        start: 7
7337        end: 10
7338        range: [7, 10]
7339        loc:
7340          start:
7341            line: 1
7342            column: 7
7343          end:
7344            line: 1
7345            column: 10
7346      start: 5
7347      end: 11
7348      range: [5, 11]
7349      loc:
7350        start:
7351          line: 1
7352          column: 5
7353        end:
7354          line: 1
7355          column: 11
7356    start: 0
7357    end: 11
7358    range: [0, 11]
7359    loc:
7360      start:
7361        line: 1
7362        column: 0
7363      end:
7364        line: 1
7365        column: 11
7366
7367  testAstLocationData '<A.B />',
7368    type: 'JSXElement'
7369    openingElement:
7370      name:
7371        object:
7372          start: 1
7373          end: 2
7374          range: [1, 2]
7375          loc:
7376            start:
7377              line: 1
7378              column: 1
7379            end:
7380              line: 1
7381              column: 2
7382        property:
7383          start: 3
7384          end: 4
7385          range: [3, 4]
7386          loc:
7387            start:
7388              line: 1
7389              column: 3
7390            end:
7391              line: 1
7392              column: 4
7393        start: 1
7394        end: 4
7395        range: [1, 4]
7396        loc:
7397          start:
7398            line: 1
7399            column: 1
7400          end:
7401            line: 1
7402            column: 4
7403      start: 0
7404      end: 7
7405      range: [0, 7]
7406      loc:
7407        start:
7408          line: 1
7409          column: 0
7410        end:
7411          line: 1
7412          column: 7
7413    start: 0
7414    end: 7
7415    range: [0, 7]
7416    loc:
7417      start:
7418        line: 1
7419        column: 0
7420      end:
7421        line: 1
7422        column: 7
7423
7424  testAstLocationData '<Tag.Name.Here></Tag.Name.Here>',
7425    type: 'JSXElement'
7426    openingElement:
7427      name:
7428        object:
7429          object:
7430            start: 1
7431            end: 4
7432            range: [1, 4]
7433            loc:
7434              start:
7435                line: 1
7436                column: 1
7437              end:
7438                line: 1
7439                column: 4
7440          property:
7441            start: 5
7442            end: 9
7443            range: [5, 9]
7444            loc:
7445              start:
7446                line: 1
7447                column: 5
7448              end:
7449                line: 1
7450                column: 9
7451          start: 1
7452          end: 9
7453          range: [1, 9]
7454          loc:
7455            start:
7456              line: 1
7457              column: 1
7458            end:
7459              line: 1
7460              column: 9
7461        property:
7462          start: 10
7463          end: 14
7464          range: [10, 14]
7465          loc:
7466            start:
7467              line: 1
7468              column: 10
7469            end:
7470              line: 1
7471              column: 14
7472        start: 1
7473        end: 14
7474        range: [1, 14]
7475        loc:
7476          start:
7477            line: 1
7478            column: 1
7479          end:
7480            line: 1
7481            column: 14
7482      start: 0
7483      end: 15
7484      range: [0, 15]
7485      loc:
7486        start:
7487          line: 1
7488          column: 0
7489        end:
7490          line: 1
7491          column: 15
7492    closingElement:
7493      name:
7494        object:
7495          object:
7496            start: 17
7497            end: 20
7498            range: [17, 20]
7499            loc:
7500              start:
7501                line: 1
7502                column: 17
7503              end:
7504                line: 1
7505                column: 20
7506          property:
7507            start: 21
7508            end: 25
7509            range: [21, 25]
7510            loc:
7511              start:
7512                line: 1
7513                column: 21
7514              end:
7515                line: 1
7516                column: 25
7517          start: 17
7518          end: 25
7519          range: [17, 25]
7520          loc:
7521            start:
7522              line: 1
7523              column: 17
7524            end:
7525              line: 1
7526              column: 25
7527        property:
7528          start: 26
7529          end: 30
7530          range: [26, 30]
7531          loc:
7532            start:
7533              line: 1
7534              column: 26
7535            end:
7536              line: 1
7537              column: 30
7538        start: 17
7539        end: 30
7540        range: [17, 30]
7541        loc:
7542          start:
7543            line: 1
7544            column: 17
7545          end:
7546            line: 1
7547            column: 30
7548      start: 15
7549      end: 31
7550      range: [15, 31]
7551      loc:
7552        start:
7553          line: 1
7554          column: 15
7555        end:
7556          line: 1
7557          column: 31
7558    start: 0
7559    end: 31
7560    range: [0, 31]
7561    loc:
7562      start:
7563        line: 1
7564        column: 0
7565      end:
7566        line: 1
7567        column: 31
7568
7569  testAstLocationData '<></>',
7570    type: 'JSXFragment'
7571    openingFragment:
7572      start: 0
7573      end: 2
7574      range: [0, 2]
7575      loc:
7576        start:
7577          line: 1
7578          column: 0
7579        end:
7580          line: 1
7581          column: 2
7582    closingFragment:
7583      start: 2
7584      end: 5
7585      range: [2, 5]
7586      loc:
7587        start:
7588          line: 1
7589          column: 2
7590        end:
7591          line: 1
7592          column: 5
7593    start: 0
7594    end: 5
7595    range: [0, 5]
7596    loc:
7597      start:
7598        line: 1
7599        column: 0
7600      end:
7601        line: 1
7602        column: 5
7603
7604  testAstLocationData '''
7605    <div
7606      a
7607      b="c"
7608      d={e}
7609      {...f}
7610    />
7611  ''',
7612    type: 'JSXElement'
7613    openingElement:
7614      name:
7615        start: 1
7616        end: 4
7617        range: [1, 4]
7618        loc:
7619          start:
7620            line: 1
7621            column: 1
7622          end:
7623            line: 1
7624            column: 4
7625      attributes: [
7626        name:
7627          start: 7
7628          end: 8
7629          range: [7, 8]
7630          loc:
7631            start:
7632              line: 2
7633              column: 2
7634            end:
7635              line: 2
7636              column: 3
7637        start: 7
7638        end: 8
7639        range: [7, 8]
7640        loc:
7641          start:
7642            line: 2
7643            column: 2
7644          end:
7645            line: 2
7646            column: 3
7647      ,
7648        name:
7649          start: 11
7650          end: 12
7651          range: [11, 12]
7652          loc:
7653            start:
7654              line: 3
7655              column: 2
7656            end:
7657              line: 3
7658              column: 3
7659        value:
7660          start: 13
7661          end: 16
7662          range: [13, 16]
7663          loc:
7664            start:
7665              line: 3
7666              column: 4
7667            end:
7668              line: 3
7669              column: 7
7670        start: 11
7671        end: 16
7672        range: [11, 16]
7673        loc:
7674          start:
7675            line: 3
7676            column: 2
7677          end:
7678            line: 3
7679            column: 7
7680      ,
7681        name:
7682          start: 19
7683          end: 20
7684          range: [19, 20]
7685          loc:
7686            start:
7687              line: 4
7688              column: 2
7689            end:
7690              line: 4
7691              column: 3
7692        value:
7693          expression:
7694            start: 22
7695            end: 23
7696            range: [22, 23]
7697            loc:
7698              start:
7699                line: 4
7700                column: 5
7701              end:
7702                line: 4
7703                column: 6
7704          start: 21
7705          end: 24
7706          range: [21, 24]
7707          loc:
7708            start:
7709              line: 4
7710              column: 4
7711            end:
7712              line: 4
7713              column: 7
7714        start: 19
7715        end: 24
7716        range: [19, 24]
7717        loc:
7718          start:
7719            line: 4
7720            column: 2
7721          end:
7722            line: 4
7723            column: 7
7724      ,
7725        argument:
7726          start: 31
7727          end: 32
7728          range: [31, 32]
7729          loc:
7730            start:
7731              line: 5
7732              column: 6
7733            end:
7734              line: 5
7735              column: 7
7736        start: 27
7737        end: 33
7738        range: [27, 33]
7739        loc:
7740          start:
7741            line: 5
7742            column: 2
7743          end:
7744            line: 5
7745            column: 8
7746      ]
7747      start: 0
7748      end: 36
7749      range: [0, 36]
7750      loc:
7751        start:
7752          line: 1
7753          column: 0
7754        end:
7755          line: 6
7756          column: 2
7757    start: 0
7758    end: 36
7759    range: [0, 36]
7760    loc:
7761      start:
7762        line: 1
7763        column: 0
7764      end:
7765        line: 6
7766        column: 2
7767
7768  testAstLocationData '<div {f...} />',
7769    type: 'JSXElement'
7770    openingElement:
7771      attributes: [
7772        argument:
7773          start: 6
7774          end: 7
7775          range: [6, 7]
7776          loc:
7777            start:
7778              line: 1
7779              column: 6
7780            end:
7781              line: 1
7782              column: 7
7783        start: 5
7784        end: 11
7785        range: [5, 11]
7786        loc:
7787          start:
7788            line: 1
7789            column: 5
7790          end:
7791            line: 1
7792            column: 11
7793      ]
7794
7795  testAstLocationData '<div>abc</div>',
7796    type: 'JSXElement'
7797    openingElement:
7798      name:
7799        start: 1
7800        end: 4
7801        range: [1, 4]
7802        loc:
7803          start:
7804            line: 1
7805            column: 1
7806          end:
7807            line: 1
7808            column: 4
7809      start: 0
7810      end: 5
7811      range: [0, 5]
7812      loc:
7813        start:
7814          line: 1
7815          column: 0
7816        end:
7817          line: 1
7818          column: 5
7819    closingElement:
7820      name:
7821        start: 10
7822        end: 13
7823        range: [10, 13]
7824        loc:
7825          start:
7826            line: 1
7827            column: 10
7828          end:
7829            line: 1
7830            column: 13
7831      start: 8
7832      end: 14
7833      range: [8, 14]
7834      loc:
7835        start:
7836          line: 1
7837          column: 8
7838        end:
7839          line: 1
7840          column: 14
7841    children: [
7842      start: 5
7843      end: 8
7844      range: [5, 8]
7845      loc:
7846        start:
7847          line: 1
7848          column: 5
7849        end:
7850          line: 1
7851          column: 8
7852    ]
7853    start: 0
7854    end: 14
7855    range: [0, 14]
7856    loc:
7857      start:
7858        line: 1
7859        column: 0
7860      end:
7861        line: 1
7862        column: 14
7863
7864  testAstLocationData '''
7865    <a>
7866      {b}
7867      <c />
7868    </a>
7869  ''',
7870    type: 'JSXElement'
7871   
7871 openingElement:
7872      name:
7873        start: 1
7874        end: 2
7875        range: [1, 2]
7876        loc:
7877          start:
7878            line: 1
7879            column: 1
7880          end:
7881            line: 1
7882            column: 2
7883      start: 0
7884      end: 3
7885      range: [0, 3]
7886      loc:
7887        start:
7888          line: 1
7889          column: 0
7890        end:
7891          line: 1
7892          column: 3
7893    closingElement:
7894      name:
7895        start: 20
7896        end: 21
7897        range: [20, 21]
7898        loc:
7899          start:
7900            line: 4
7901            column: 2
7902          end:
7903            line: 4
7904            column: 3
7905      start: 18
7906      end: 22
7907      range: [18, 22]
7908      loc:
7909        start:
7910          line: 4
7911          column: 0
7912        end:
7913          line: 4
7914          column: 4
7915    children: [
7916      start: 3
7917      end: 6
7918      range: [3, 6]
7919      loc:
7920        start:
7921          line: 1
7922          column: 3
7923        end:
7924          line: 2
7925          column: 2
7926    ,
7927      expression:
7928        start: 7
7929        end: 8
7930        range: [7, 8]
7931        loc:
7932          start:
7933            line: 2
7934            column: 3
7935          end:
7936            line: 2
7937            column: 4
7938      start: 6
7939      end: 9
7940      range: [6, 9]
7941      loc:
7942        start:
7943          line: 2
7944          column: 2
7945        end:
7946          line: 2
7947          column: 5
7948    ,
7949      start: 9
7950      end: 12
7951      range: [9, 12]
7952      loc:
7953        start:
7954          line: 2
7955          column: 5
7956        end:
7957          line: 3
7958          column: 2
7959    ,
7960      start: 12
7961      end: 17
7962      range: [12, 17]
7963      loc:
7964        start:
7965          line: 3
7966          column: 2
7967        end:
7968          line: 3
7969          column: 7
7970    ,
7971      start: 17
7972      end: 18
7973      range: [17, 18]
7974      loc:
7975        start:
7976          line: 3
7977          column: 7
7978        end:
7979          line: 4
7980          column: 0
7981    ]
7982    start: 0
7983    end: 22
7984    range: [0, 22]
7985    loc:
7986      start:
7987        line: 1
7988        column: 0
7989      end:
7990        line: 4
7991        column: 4
7992
7993  testAstLocationData '<>abc{}</>',
7994    type: 'JSXFragment'
7995    openingFragment:
7996      start: 0
7997      end: 2
7998      range: [0, 2]
7999      loc:
8000        start:
8001          line: 1
8002          column: 0
8003        end:
8004          line: 1
8005          column: 2
8006    closingFragment:
8007      start: 7
8008      end: 10
8009      range: [7, 10]
8010      loc:
8011        start:
8012          line: 1
8013          column: 7
8014        end:
8015          line: 1
8016          column: 10
8017    children: [
8018      start: 2
8019      end: 5
8020      range: [2, 5]
8021      loc:
8022        start:
8023          line: 1
8024          column: 2
8025        end:
8026          line: 1
8027          column: 5
8028    ,
8029      expression:
8030        start: 6
8031        end: 6
8032        range: [6, 6]
8033        loc:
8034          start:
8035            line: 1
8036            column: 6
8037          end:
8038            line: 1
8039            column: 6
8040      start: 5
8041      end: 7
8042      range: [5, 7]
8043      loc:
8044        start:
8045          line: 1
8046          column: 5
8047        end:
8048          line: 1
8049          column: 7
8050    ]
8051    start: 0
8052    end: 10
8053    range: [0, 10]
8054    loc:
8055      start:
8056        line: 1
8057        column: 0
8058      end:
8059        line: 1
8060        column: 10
8061
8062  testAstLocationData '''
8063    <a>{<b />}</a>
8064  ''',
8065    type: 'JSXElement'
8066    children: [
8067      expression:
8068        start: 4
8069        end: 9
8070        range: [4, 9]
8071        loc:
8072          start:
8073            line: 1
8074            column: 4
8075          end:
8076            line: 1
8077            column: 9
8078      start: 3
8079      end: 10
8080      range: [3, 10]
8081      loc:
8082        start:
8083          line: 1
8084          column: 3
8085        end:
8086          line: 1
8087          column: 10
8088    ]
8089    start: 0
8090    end: 14
8091    range: [0, 14]
8092    loc:
8093      start:
8094        line: 1
8095        column: 0
8096      end:
8097        line: 1
8098        column: 14
8099
8100  testAstLocationData '''
8101    <div>{
8102      # comment
8103    }</div>
8104  ''',
8105    type: 'JSXElement'
8106    children: [
8107      expression:
8108        start: 6
8109        end: 19
8110        range: [6, 19]
8111        loc:
8112          start:
8113            line: 1
8114            column: 6
8115          end:
8116            line: 3
8117            column: 0
8118      start: 5
8119      end: 20
8120      range: [5, 20]
8121      loc:
8122        start:
8123          line: 1
8124          column: 5
8125        end:
8126          line: 3
8127          column: 1
8128    ]
8129    start: 0
8130    end: 26
8131    range: [0, 26]
8132    loc:
8133      start:
8134        line: 1
8135        column: 0
8136      end:
8137        line: 3
8138        column: 7
8139
8140  testAstLocationData '''
8141    <div>{### here ###}</div>
8142  ''',
8143    type: 'JSXElement'
8144    children: [
8145      expression:
8146        start: 6
8147        end: 18
8148        range: [6, 18]
8149        loc:
8150          start:
8151            line: 1
8152            column: 6
8153          end:
8154            line: 1
8155            column: 18
8156      start: 5
8157      end: 19
8158      range: [5, 19]
8159      loc:
8160        start:
8161          line: 1
8162          column: 5
8163        end:
8164          line: 1
8165          column: 19
8166    ]
8167    start: 0
8168    end: 25
8169    range: [0, 25]
8170    loc:
8171      start:
8172        line: 1
8173        column: 0
8174      end:
8175        line: 1
8176        column: 25
8177
8178  testAstLocationData '<div:a b:c />',
8179    type: 'JSXElement'
8180    openingElement:
8181      name:
8182        namespace:
8183          start: 1
8184          end: 4
8185          range: [1, 4]
8186          loc:
8187            start:
8188              line: 1
8189              column: 1
8190            end:
8191              line: 1
8192              column: 4
8193        name:
8194          start: 5
8195          end: 6
8196          range: [5, 6]
8197          loc:
8198            start:
8199              line: 1
8200              column: 5
8201            end:
8202              line: 1
8203              column: 6
8204        start: 1
8205        end: 6
8206        range: [1, 6]
8207        loc:
8208          start:
8209            line: 1
8210            column: 1
8211          end:
8212            line: 1
8213            column: 6
8214      attributes: [
8215        name:
8216          namespace:
8217            start: 7
8218            end: 8
8219            range: [7, 8]
8220            loc:
8221              start:
8222                line: 1
8223                column: 7
8224              end:
8225                line: 1
8226                column: 8
8227          name:
8228            start: 9
8229            end: 10
8230            range: [9, 10]
8231            loc:
8232              start:
8233                line: 1
8234                column: 9
8235              end:
8236                line: 1
8237                column: 10
8238          start: 7
8239          end: 10
8240          range: [7, 10]
8241          loc:
8242            start:
8243              line: 1
8244              column: 7
8245            end:
8246              line: 1
8247              column: 10
8248        start: 7
8249        end: 10
8250        range: [7, 10]
8251        loc:
8252          start:
8253            line: 1
8254            column: 7
8255          end:
8256            line: 1
8257            column: 10
8258      ]
8259      start: 0
8260      end: 13
8261      range: [0, 13]
8262      loc:
8263        start:
8264          line: 1
8265          column: 0
8266        end:
8267          line: 1
8268          column: 13
8269    start: 0
8270    end: 13
8271    range: [0, 13]
8272    loc:
8273      start:
8274        line: 1
8275        column: 0
8276      end:
8277        line: 1
8278        column: 13
8279
8280  testAstLocationData '''
8281    <div:a>
8282      {b}
8283    </div:a>
8284  ''',
8285    type: 'JSXElement'
8286    openingElement:
8287      name:
8288        namespace:
8289          start: 1
8290          end: 4
8291          range: [1, 4]
8292          loc:
8293            start:
8294              line: 1
8295              column: 1
8296            end:
8297              line: 1
8298              column: 4
8299        name:
8300          start: 5
8301          end: 6
8302          range: [5, 6]
8303          loc:
8304            start:
8305              line: 1
8306              column: 5
8307            end:
8308              line: 1
8309              column: 6
8310        start: 1
8311        end: 6
8312        range: [1, 6]
8313        loc:
8314          start:
8315            line: 1
8316            column: 1
8317          end:
8318            line: 1
8319            column: 6
8320      start: 0
8321      end: 7
8322      range: [0, 7]
8323      loc:
8324        start:
8325          line: 1
8326          column: 0
8327        end:
8328          line: 1
8329          column: 7
8330    closingElement:
8331      name:
8332        namespace:
8333          start: 16
8334          end: 19
8335          range: [16, 19]
8336          loc:
8337            start:
8338              line: 3
8339              column: 2
8340            end:
8341              line: 3
8342              column: 5
8343        name:
8344          start: 20
8345          end: 21
8346          range: [20, 21]
8347          loc:
8348            start:
8349              line: 3
8350              column: 6
8351            end:
8352              line: 3
8353              column: 7
8354        start: 16
8355        end: 21
8356        range: [16, 21]
8357        loc:
8358          start:
8359            line: 3
8360            column: 2
8361          end:
8362            line: 3
8363            column: 7
8364      start: 14
8365      end: 22
8366      range: [14, 22]
8367      loc:
8368        start:
8369          line: 3
8370          column: 0
8371        end:
8372          line: 3
8373          column: 8
8374    start: 0
8375    end: 22
8376    range: [0, 22]
8377    loc:
8378      start:
8379        line: 1
8380        column: 0
8381      end:
8382        line: 3
8383        column: 8
8384
8385  testAstLocationData '''
8386    <div.a>
8387      {b}
8388    </div.a>
8389  ''',
8390    type: 'JSXElement'
8391    openingElement:
8392      name:
8393        object:
8394          start: 1
8395          end: 4
8396          range: [1, 4]
8397          loc:
8398            start:
8399              line: 1
8400              column: 1
8401            end:
8402              line: 1
8403              column: 4
8404        property:
8405          start: 5
8406          end: 6
8407          range: [5, 6]
8408          loc:
8409            start:
8410              line: 1
8411              column: 5
8412            end:
8413              line: 1
8414              column: 6
8415        start: 1
8416        end: 6
8417        range: [1, 6]
8418        loc:
8419          start:
8420            line: 1
8421            column: 1
8422          end:
8423            line: 1
8424            column: 6
8425      start: 0
8426      end: 7
8427      range: [0, 7]
8428      loc:
8429        start:
8430          line: 1
8431          column: 0
8432        end:
8433          line: 1
8434          column: 7
8435    closingElement:
8436      name:
8437        object:
8438          start: 16
8439          end: 19
8440          range: [16, 19]
8441          loc:
8442            start:
8443              line: 3
8444              column: 2
8445            end:
8446              line: 3
8447              column: 5
8448        property:
8449          start: 20
8450          end: 21
8451          range: [20, 21]
8452          loc:
8453            start:
8454              line: 3
8455              column: 6
8456            end:
8457              line: 3
8458              column: 7
8459        start: 16
8460        end: 21
8461        range: [16, 21]
8462        loc:
8463          start:
8464            line: 3
8465            column: 2
8466          end:
8467            line: 3
8468            column: 7
8469      start: 14
8470      end: 22
8471      range: [14, 22]
8472      loc:
8473        start:
8474          line: 3
8475          column: 0
8476        end:
8477          line: 3
8478          column: 8
8479    start: 0
8480    end: 22
8481    range: [0, 22]
8482    loc:
8483      start:
8484        line: 1
8485        column: 0
8486      end:
8487        line: 3
8488        column: 8
8489
8490test "AST as expected for Try node", ->
8491  testAstLocationData 'try cappuccino',
8492    type: 'TryStatement'
8493    block:
8494      type: 'BlockStatement'
8495      body: [
8496        expression:
8497          start: 4
8498          end: 14
8499          range: [4, 14]
8500          loc:
8501            start:
8502              line: 1
8503              column: 4
8504            end:
8505              line: 1
8506              column: 14
8507        start: 4
8508        end: 14
8509        range: [4, 14]
8510        loc:
8511          start:
8512            line: 1
8513            column: 4
8514          end:
8515            line: 1
8516            column: 14
8517      ]
8518      start: 3
8519      end: 14
8520      range: [3, 14]
8521      loc:
8522        start:
8523          line: 1
8524          column: 3
8525        end:
8526          line: 1
8527          column: 14
8528    start: 0
8529    end: 14
8530    range: [0, 14]
8531    loc:
8532      start:
8533        line: 1
8534        column: 0
8535      end:
8536        line: 1
8537        column: 14
8538
8539  testAstLocationData '''
8540    try
8541      x = 1
8542      y()
8543    catch e
8544      d()
8545    finally
8546      f + g
8547  ''',
8548    type: 'TryStatement'
8549    block:
8550      type: 'BlockStatement'
8551      body: [
8552        expression:
8553          start: 6
8554          end: 11
8555          range: [6, 11]
8556          loc:
8557            start:
8558              line: 2
8559              column: 2
8560            end:
8561              line: 2
8562              column: 7
8563        start: 6
8564        end: 11
8565        range: [6, 11]
8566        loc:
8567          start:
8568            line: 2
8569            column: 2
8570          end:
8571            line: 2
8572            column: 7
8573      ,
8574        expression:
8575          start: 14
8576          end: 17
8577          range: [14, 17]
8578          loc:
8579            start:
8580              line: 3
8581              column: 2
8582            end:
8583              line: 3
8584              column: 5
8585        start: 14
8586        end: 17
8587        range: [14, 17]
8588        loc:
8589          start:
8590            line: 3
8591            column: 2
8592          end:
8593            line: 3
8594            column: 5
8595      ]
8596      start: 4
8597      end: 17
8598      range: [4, 17]
8599      loc:
8600        start:
8601          line: 2
8602          column: 0
8603        end:
8604          line: 3
8605          column: 5
8606    handler:
8607      param:
8608        start: 24
8609        end: 25
8610        range: [24, 25]
8611        loc:
8612          start:
8613            line: 4
8614            column: 6
8615          end:
8616            line: 4
8617            column: 7
8618      body:
8619        body: [
8620          start: 28
8621          end: 31
8622          range: [28, 31]
8623          loc:
8624            start:
8625              line: 5
8626              column: 2
8627            end:
8628              line: 5
8629              column: 5
8630        ]
8631        start: 26
8632        end: 31
8633        range: [26, 31]
8634        loc:
8635          start:
8636            line: 5
8637            column: 0
8638          end:
8639            line: 5
8640            column: 5
8641      start: 18
8642      end: 31
8643      range: [18, 31]
8644      loc:
8645        start:
8646          line: 4
8647          column: 0
8648        end:
8649          line: 5
8650          column: 5
8651    finalizer:
8652      body: [
8653        expression:
8654          start: 42
8655          end: 47
8656          range: [42, 47]
8657          loc:
8658            start:
8659              line: 7
8660              column: 2
8661            end:
8662              line: 7
8663              column: 7
8664        start: 42
8665        end: 47
8666        range: [42, 47]
8667        loc:
8668          start:
8669            line: 7
8670            column: 2
8671          end:
8672            line: 7
8673            column: 7
8674      ]
8675      start: 32
8676      end: 47
8677      range: [32, 47]
8678      loc:
8679        start:
8680          line: 6
8681          column: 0
8682        end:
8683          line: 7
8684          column: 7
8685    start: 0
8686    end: 47
8687    range: [0, 47]
8688    loc:
8689      start:
8690        line: 1
8691        column: 0
8692      end:
8693        line: 7
8694        column: 7
8695
8696  testAstLocationData '''
8697    try
8698    catch {e}
8699      f
8700  ''',
8701    type: 'TryStatement'
8702    handler:
8703      param:
8704        start: 10
8705        end: 13
8706        range: [10, 13]
8707        loc:
8708          start:
8709            line: 2
8710            column: 6
8711          end:
8712            line: 2
8713            column: 9
8714      body:
8715        start: 14
8716        end: 17
8717        range: [14, 17]
8718        loc:
8719          start:
8720            line: 3
8721            column: 0
8722          end:
8723            line: 3
8724            column: 3
8725      start: 4
8726      end: 17
8727      range: [4, 17]
8728      loc:
8729        start:
8730          line: 2
8731          column: 0
8732        end:
8733          line: 3
8734          column: 3
8735
8736test "AST location data as expected for Root node", ->
8737  testAstRootLocationData '1\n2',
8738    type: 'File'
8739    program:
8740      start: 0
8741      end: 3
8742      range: [0, 3]
8743      loc:
8744        start:
8745          line: 1
8746          column: 0
8747        end:
8748          line: 2
8749          column: 1
8750    start: 0
8751    end: 3
8752    range: [0, 3]
8753    loc:
8754      start:
8755        line: 1
8756        column: 0
8757      end:
8758        line: 2
8759        column: 1
8760
8761  testAstRootLocationData 'a = 1\nb',
8762    type: 'File'
8763    program:
8764      start: 0
8765      end: 7
8766      range: [0, 7]
8767      loc:
8768        start:
8769          line: 1
8770          column: 0
8771        end:
8772          line: 2
8773          column: 1
8774    start: 0
8775    end: 7
8776    range: [0, 7]
8777    loc:
8778      start:
8779        line: 1
8780        column: 0
8781      end:
8782        line: 2
8783        column: 1
8784
8785  testAstRootLocationData 'a = 1\nb\n\n',
8786    type: 'File'
8787    program:
8788      start: 0
8789      end: 9
8790      range: [0, 9]
8791      loc:
8792        start:
8793          line: 1
8794          column: 0
8795        end:
8796          line: 4
8797          column: 0
8798    start: 0
8799    end: 9
8800    range: [0, 9]
8801    loc:
8802      start:
8803        line: 1
8804        column: 0
8805      end:
8806        line: 4
8807        column: 0
8808
8809  testAstRootLocationData 'a = 1\n\n# Comment',
8810    type: 'File'
8811    program:
8812      start: 0
8813      end: 16
8814      range: [0, 16]
8815      loc:
8816        start:
8817          line: 1
8818 
8818         column: 0
8819        end:
8820          line: 3
8821          column: 9
8822    start: 0
8823    end: 16
8824    range: [0, 16]
8825    loc:
8826      start:
8827        line: 1
8828        column: 0
8829      end:
8830        line: 3
8831        column: 9
8832
8833  testAstRootLocationData 'a = 1\n\n# Comment\n',
8834    type: 'File'
8835    program:
8836      start: 0
8837      end: 17
8838      range: [0, 17]
8839      loc:
8840        start:
8841          line: 1
8842          column: 0
8843        end:
8844          line: 4
8845          column: 0
8846    start: 0
8847    end: 17
8848    range: [0, 17]
8849    loc:
8850      start:
8851        line: 1
8852        column: 0
8853      end:
8854        line: 4
8855        column: 0
8856
8857  testAstRootLocationData '''
8858    # comment
8859    "use strict"
8860  ''',
8861    type: 'File'
8862    program:
8863      start: 0
8864      end: 22
8865      range: [0, 22]
8866      loc:
8867        start:
8868          line: 1
8869          column: 0
8870        end:
8871          line: 2
8872          column: 12
8873    start: 0
8874    end: 22
8875    range: [0, 22]
8876    loc:
8877      start:
8878        line: 1
8879        column: 0
8880      end:
8881        line: 2
8882        column: 12
8883
8884  testAstRootLocationData ' \n',
8885    type: 'File'
8886    program:
8887      start: 0
8888      end: 2
8889      range: [0, 2]
8890      loc:
8891        start:
8892          line: 1
8893          column: 0
8894        end:
8895          line: 2
8896          column: 0
8897    start: 0
8898    end: 2
8899    range: [0, 2]
8900    loc:
8901      start:
8902        line: 1
8903        column: 0
8904      end:
8905        line: 2
8906        column: 0
8907
8908  testAstRootLocationData '\n',
8909    type: 'File'
8910    program:
8911      start: 0
8912      end: 1
8913      range: [0, 1]
8914      loc:
8915        start:
8916          line: 1
8917          column: 0
8918        end:
8919          line: 2
8920          column: 0
8921    start: 0
8922    end: 1
8923    range: [0, 1]
8924    loc:
8925      start:
8926        line: 1
8927        column: 0
8928      end:
8929        line: 2
8930        column: 0
8931
8932  testAstRootLocationData '',
8933    type: 'File'
8934    program:
8935      start: 0
8936      end: 0
8937      range: [0, 0]
8938      loc:
8939        start:
8940          line: 1
8941          column: 0
8942        end:
8943          line: 1
8944          column: 0
8945    start: 0
8946    end: 0
8947    range: [0, 0]
8948    loc:
8949      start:
8950        line: 1
8951        column: 0
8952      end:
8953        line: 1
8954        column: 0
8955
8956  testAstRootLocationData ' ',
8957    type: 'File'
8958    program:
8959      start: 0
8960      end: 1
8961      range: [0, 1]
8962      loc:
8963        start:
8964          line: 1
8965          column: 0
8966        end:
8967          line: 1
8968          column: 1
8969    start: 0
8970    end: 1
8971    range: [0, 1]
8972    loc:
8973      start:
8974        line: 1
8975        column: 0
8976      end:
8977        line: 1
8978        column: 1
8979
8980test "AST location data as expected for Switch node", ->
8981  testAstLocationData '''
8982    switch x
8983      when a then a
8984      when b, c then c
8985      else 42
8986  ''',
8987    type: 'SwitchStatement'
8988    discriminant:
8989      start: 7
8990      end: 8
8991      range: [7, 8]
8992      loc:
8993        start:
8994          line: 1
8995          column: 7
8996        end:
8997          line: 1
8998          column: 8
8999    cases: [
9000      test:
9001        start: 16
9002        end: 17
9003        range: [16, 17]
9004        loc:
9005          start:
9006            line: 2
9007            column: 7
9008          end:
9009            line: 2
9010            column: 8
9011      consequent: [
9012        expression:
9013          start: 23
9014          end: 24
9015          range: [23, 24]
9016          loc:
9017            start:
9018              line: 2
9019              column: 14
9020            end:
9021              line: 2
9022              column: 15
9023        start: 23
9024        end: 24
9025        range: [23, 24]
9026        loc:
9027          start:
9028            line: 2
9029            column: 14
9030          end:
9031            line: 2
9032            column: 15
9033      ]
9034      start: 11
9035      end: 24
9036      range: [11, 24]
9037      loc:
9038        start:
9039          line: 2
9040          column: 2
9041        end:
9042          line: 2
9043          column: 15
9044    ,
9045      test:
9046        start: 32
9047        end: 33
9048        range: [32, 33]
9049        loc:
9050          start:
9051            line: 3
9052            column: 7
9053          end:
9054            line: 3
9055            column: 8
9056      start: 27
9057      end: 33
9058      range: [27, 33]
9059      loc:
9060        start:
9061          line: 3
9062          column: 2
9063        end:
9064          line: 3
9065          column: 8
9066    ,
9067      test:
9068        start: 35
9069        end: 36
9070        range: [35, 36]
9071        loc:
9072          start:
9073            line: 3
9074            column: 10
9075          end:
9076            line: 3
9077            column: 11
9078      consequent: [
9079        expression:
9080          start: 42
9081          end: 43
9082          range: [42, 43]
9083          loc:
9084            start:
9085              line: 3
9086              column: 17
9087            end:
9088              line: 3
9089              column: 18
9090        start: 42
9091        end: 43
9092        range: [42, 43]
9093        loc:
9094          start:
9095            line: 3
9096            column: 17
9097          end:
9098            line: 3
9099            column: 18
9100      ]
9101      start: 35
9102      end: 43
9103      range: [35, 43]
9104      loc:
9105        start:
9106          line: 3
9107          column: 10
9108        end:
9109          line: 3
9110          column: 18
9111    ,
9112      consequent: [
9113        expression:
9114          start: 51
9115          end: 53
9116          range: [51, 53]
9117          loc:
9118            start:
9119              line: 4
9120              column: 7
9121            end:
9122              line: 4
9123              column: 9
9124        start: 51
9125        end: 53
9126        range: [51, 53]
9127        loc:
9128          start:
9129            line: 4
9130            column: 7
9131          end:
9132            line: 4
9133            column: 9
9134      ]
9135      start: 46
9136      end: 53
9137      range: [46, 53]
9138      loc:
9139        start:
9140          line: 4
9141          column: 2
9142        end:
9143          line: 4
9144          column: 9
9145    ,
9146    ]
9147    start: 0
9148    end: 53
9149    range: [0, 53]
9150    loc:
9151      start:
9152        line: 1
9153        column: 0
9154      end:
9155        line: 4
9156        column: 9
9157
9158  testAstLocationData '''
9159    switch
9160      when some(condition)
9161        doSomething()
9162        andThenSomethingElse
9163  ''',
9164    type: 'SwitchStatement'
9165    cases: [
9166      test:
9167        start: 14
9168        end: 29
9169        range: [14, 29]
9170        loc:
9171          start:
9172            line: 2
9173            column: 7
9174          end:
9175            line: 2
9176            column: 22
9177      consequent: [
9178        expression:
9179          start: 34
9180          end: 47
9181          range: [34, 47]
9182          loc:
9183            start:
9184              line: 3
9185              column: 4
9186            end:
9187              line: 3
9188              column: 17
9189        start: 34
9190        end: 47
9191        range: [34, 47]
9192        loc:
9193          start:
9194            line: 3
9195            column: 4
9196          end:
9197            line: 3
9198            column: 17
9199      ,
9200        expression:
9201          start: 52
9202          end: 72
9203          range: [52, 72]
9204          loc:
9205            start:
9206              line: 4
9207              column: 4
9208            end:
9209              line: 4
9210              column: 24
9211      ]
9212    ]
9213test "AST location data as expected for Code node", ->
9214  testAstLocationData '''
9215    (a) ->
9216      b
9217      c()
9218  ''',
9219    type: 'FunctionExpression'
9220    params: [
9221      start: 1
9222      end: 2
9223      range: [1, 2]
9224      loc:
9225        start:
9226          line: 1
9227          column: 1
9228        end:
9229          line: 1
9230          column: 2
9231    ]
9232    body:
9233      body: [
9234        start: 9
9235        end: 10
9236        range: [9, 10]
9237        loc:
9238          start:
9239            line: 2
9240            column: 2
9241          end:
9242            line: 2
9243            column: 3
9244      ,
9245        start: 13
9246        end: 16
9247        range: [13, 16]
9248        loc:
9249          start:
9250            line: 3
9251            column: 2
9252          end:
9253            line: 3
9254            column: 5
9255      ]
9256      start: 7
9257      end: 16
9258      range: [7, 16]
9259      loc:
9260        start:
9261          line: 2
9262          column: 0
9263        end:
9264          line: 3
9265          column: 5
9266
9267  testAstLocationData '''
9268    -> a
9269  ''',
9270    type: 'FunctionExpression'
9271    body:
9272      start: 2
9273      end: 4
9274      range: [2, 4]
9275      loc:
9276        start:
9277          line: 1
9278          column: 2
9279        end:
9280          line: 1
9281          column: 4
9282    start: 0
9283    end: 4
9284    range: [0, 4]
9285    loc:
9286      start:
9287        line: 1
9288        column: 0
9289      end:
9290        line: 1
9291        column: 4
9292
9293  testAstLocationData '''
9294    (
9295      a,
9296      [
9297        b
9298        c
9299      ]
9300    ) ->
9301      d
9302  ''',
9303    type: 'FunctionExpression'
9304    params: [
9305      start: 4
9306      end: 5
9307      range: [4, 5]
9308      loc:
9309        start:
9310          line: 2
9311          column: 2
9312        end:
9313          line: 2
9314          column: 3
9315    ,
9316      elements: [
9317        start: 15
9318        end: 16
9319        range: [15, 16]
9320        loc:
9321          start:
9322            line: 4
9323            column: 4
9324          end:
9325            line: 4
9326            column: 5
9327      ,
9328        start: 21
9329        end: 22
9330        range: [21, 22]
9331        loc:
9332          start:
9333            line: 5
9334            column: 4
9335          end:
9336            line: 5
9337            column: 5
9338      ]
9339      start: 9
9340      end: 26
9341      range: [9, 26]
9342      loc:
9343        start:
9344          line: 3
9345          column: 2
9346        end:
9347          line: 6
9348          column: 3
9349    ]
9350    start: 0
9351    end: 35
9352    range: [0, 35]
9353    loc:
9354      start:
9355        line: 1
9356        column: 0
9357      end:
9358        line: 8
9359        column: 3
9360
9361  testAstLocationData '''
9362    ->
9363  ''',
9364    type: 'FunctionExpression'
9365    body:
9366      start: 2
9367      end: 2
9368      range: [2, 2]
9369      loc:
9370        start:
9371          line: 1
9372          column: 2
9373        end:
9374          line: 1
9375          column: 2
9376    start: 0
9377    end: 2
9378    range: [0, 2]
9379    loc:
9380      start:
9381        line: 1
9382        column: 0
9383      end:
9384        line: 1
9385        column: 2
9386
9387  testAstLocationData '''
9388    (a...) ->
9389  ''',
9390    type: 'FunctionExpression'
9391    params: [
9392      argument:
9393        start: 1
9394        end: 2
9395        range: [1, 2]
9396        loc:
9397          start:
9398            line: 1
9399            column: 1
9400          end:
9401            line: 1
9402            column: 2
9403      start: 1
9404      end: 5
9405      range: [1, 5]
9406      loc:
9407        start:
9408          line: 1
9409          column: 1
9410        end:
9411          line: 1
9412          column: 5
9413    ]
9414    start: 0
9415    end: 9
9416    range: [0, 9]
9417    loc:
9418      start:
9419        line: 1
9420        column: 0
9421      end:
9422        line: 1
9423        column: 9
9424
9425  testAstLocationData '''
9426    (...a) ->
9427  ''',
9428    type: 'FunctionExpression'
9429    params: [
9430      argument:
9431        start: 4
9432        end: 5
9433        range: [4, 5]
9434        loc:
9435          start:
9436            line: 1
9437            column: 4
9438          end:
9439            line: 1
9440            column: 5
9441      start: 1
9442      end: 5
9443      range: [1, 5]
9444      loc:
9445        start:
9446          line: 1
9447          column: 1
9448        end:
9449          line: 1
9450          column: 5
9451    ]
9452    start: 0
9453    end: 9
9454    range: [0, 9]
9455    loc:
9456      start:
9457        line: 1
9458        column: 0
9459      end:
9460        line: 1
9461        column: 9
9462
9463test "AST location data as expected for Return node", ->
9464  testAstLocationData 'return no',
9465    type: 'ReturnStatement'
9466    argument:
9467      start: 7
9468      end: 9
9469      range: [7, 9]
9470      loc:
9471        start:
9472          line: 1
9473          column: 7
9474        end:
9475          line: 1
9476          column: 9
9477    start: 0
9478    end: 9
9479    range: [0, 9]
9480    loc:
9481      start:
9482        line: 1
9483        column: 0
9484      end:
9485        line: 1
9486        column: 9
9487
9488  testAstLocationData '''
9489    (a, b) ->
9490      return a + b
9491  ''',
9492    type: 'FunctionExpression'
9493    body:
9494      body: [
9495        argument:
9496          start: 19
9497          end: 24
9498          range: [19, 24]
9499          loc:
9500            start:
9501              line: 2
9502              column: 9
9503            end:
9504              line: 2
9505              column: 14
9506        start: 12
9507        end: 24
9508        range: [12, 24]
9509        loc:
9510          start:
9511            line: 2
9512            column: 2
9513          end:
9514            line: 2
9515            column: 14
9516      ]
9517      start: 10
9518      end: 24
9519      range: [10, 24]
9520      loc:
9521        start:
9522          line: 2
9523          column: 0
9524        end:
9525          line: 2
9526          column: 14
9527    start: 0
9528    end: 24
9529    range: [0, 24]
9530    loc:
9531      start:
9532        line: 1
9533        column: 0
9534      end:
9535        line: 2
9536        column: 14
9537
9538  testAstLocationData '-> return',
9539    type: 'FunctionExpression'
9540    body:
9541      body: [
9542        start: 3
9543        end: 9
9544        range: [3, 9]
9545        loc:
9546          start:
9547            line: 1
9548            column: 3
9549          end:
9550            line: 1
9551            column: 9
9552      ]
9553      start: 2
9554      end: 9
9555      range: [2, 9]
9556      loc:
9557        start:
9558          line: 1
9559          column: 2
9560        end:
9561          line: 1
9562          column: 9
9563    start: 0
9564    end: 9
9565    range: [0, 9]
9566    loc:
9567      start:
9568        line: 1
9569        column: 0
9570      end:
9571        line: 1
9572        column: 9
9573
9574test "AST as expected for YieldReturn node", ->
9575  testAstLocationData '-> yield return 1',
9576    type: 'FunctionExpression'
9577    body:
9578      body: [
9579        expression:
9580          argument:
9581            argument:
9582              start: 16
9583              end: 17
9584              range: [16, 17]
9585              loc:
9586                start:
9587                  line: 1
9588                  column: 16
9589                end:
9590                  line: 1
9591                  column: 17
9592            start: 9
9593            end: 17
9594            range: [9, 17]
9595            loc:
9596              start:
9597                line: 1
9598                column: 9
9599              end:
9600                line: 1
9601                column: 17
9602          start: 3
9603          end: 17
9604          range: [3, 17]
9605          loc:
9606            start:
9607              line: 1
9608              column: 3
9609            end:
9610              line: 1
9611              column: 17
9612        start: 3
9613        end: 17
9614        range: [3, 17]
9615        loc:
9616          start:
9617            line: 1
9618            column: 3
9619          end:
9620            line: 1
9621            column: 17
9622      ]
9623      start: 2
9624      end: 17
9625      range: [2, 17]
9626      loc:
9627        start:
9628          line: 1
9629          column: 2
9630        end:
9631          line: 1
9632          column: 17
9633    start: 0
9634    end: 17
9635    range: [0, 17]
9636    loc:
9637      start:
9638        line: 1
9639        column: 0
9640      end:
9641        line: 1
9642        column: 17
9643
9644  testAstLocationData '-> yield return',
9645    type: 'FunctionExpression'
9646    body:
9647      body: [
9648        expression:
9649          argument:
9650            start: 9
9651            end: 15
9652            range: [9, 15]
9653            loc:
9654              start:
9655                line: 1
9656                column: 9
9657              end:
9658                line: 1
9659                column: 15
9660          start: 3
9661          end: 15
9662          range: [3, 15]
9663          loc:
9664            start:
9665              line: 1
9666              column: 3
9667            end:
9668              line: 1
9669              column: 15
9670        start: 3
9671        end: 15
9672        range: [3, 15]
9673        loc:
9674          start:
9675            line: 1
9676            column: 3
9677          end:
9678            line: 1
9679            column: 15
9680      ]
9681      start: 2
9682      end: 15
9683      range: [2, 15]
9684      loc:
9685        start:
9686          line: 1
9687          column: 2
9688        end:
9689          line: 1
9690          column: 15
9691    start: 0
9692    end: 15
9693    range: [0, 15]
9694    loc:
9695      start:
9696        line: 1
9697        column: 0
9698      end:
9699        line: 1
9700        column: 15
9701
9702test "AST as expected for AwaitReturn node", ->
9703  testAstLocationData '-> await return 1',
9704    type: 'FunctionExpression'
9705    body:
9706      body: [
9707        expression:
9708          argument:
9709            argument:
9710              start: 16
9711              end: 17
9712              range: [16, 17]
9713              loc:
9714                start:
9715                  line: 1
9716                  column: 16
9717                end:
9718                  line: 1
9719                  column: 17
9720            start: 9
9721            end: 17
9722            range: [9, 17]
9723            loc:
9724              start:
9725                line: 1
9726                column: 9
9727              end:
9728                line: 1
9729                column: 17
9730          start: 3
9731          end: 17
9732          range: [3, 17]
9733          loc:
9734            start:
9735              line: 1
9736              column: 3
9737            end:
9738              line: 1
9739              column: 17
9740        start: 3
9741        end: 17
9742        range: [3, 17]
9743        loc:
9744          start:
9745            line: 1
9746            column: 3
9747          end:
9748            line: 1
9749            column: 17
9750      ]
9751      start: 2
9752      end: 17
9753      range: [2, 17]
9754      loc:
9755        start:
9756          line: 1
9757          column: 2
9758        end:
9759          line: 1
9760          column: 17
9761    start: 0
9762    end: 17
9763    range: [0, 17]
9764    loc:
9765      start:
9766        line: 1
9767        column: 0
9768      end:
9769        line: 1
9770        colu
9770mn: 17
9771
9772  testAstLocationData '-> await return',
9773    type: 'FunctionExpression'
9774    body:
9775      body: [
9776        expression:
9777          argument:
9778            start: 9
9779            end: 15
9780            range: [9, 15]
9781            loc:
9782              start:
9783                line: 1
9784                column: 9
9785              end:
9786                line: 1
9787                column: 15
9788          start: 3
9789          end: 15
9790          range: [3, 15]
9791          loc:
9792            start:
9793              line: 1
9794              column: 3
9795            end:
9796              line: 1
9797              column: 15
9798        start: 3
9799        end: 15
9800        range: [3, 15]
9801        loc:
9802          start:
9803            line: 1
9804            column: 3
9805          end:
9806            line: 1
9807            column: 15
9808      ]
9809      start: 2
9810      end: 15
9811      range: [2, 15]
9812      loc:
9813        start:
9814          line: 1
9815          column: 2
9816        end:
9817          line: 1
9818          column: 15
9819    start: 0
9820    end: 15
9821    range: [0, 15]
9822    loc:
9823      start:
9824        line: 1
9825        column: 0
9826      end:
9827        line: 1
9828        column: 15
9829
9830test "AST as expected for If node", ->
9831  testAstLocationData 'if maybe then yes',
9832    type: 'IfStatement'
9833    test:
9834      start: 3
9835      end: 8
9836      range: [3, 8]
9837      loc:
9838        start:
9839          line: 1
9840          column: 3
9841        end:
9842          line: 1
9843          column: 8
9844    consequent:
9845      body: [
9846        expression:
9847          start: 14
9848          end: 17
9849          range: [14, 17]
9850          loc:
9851            start:
9852              line: 1
9853              column: 14
9854            end:
9855              line: 1
9856              column: 17
9857        start: 14
9858        end: 17
9859        range: [14, 17]
9860        loc:
9861          start:
9862            line: 1
9863            column: 14
9864          end:
9865            line: 1
9866            column: 17
9867      ]
9868      start: 9
9869      end: 17
9870      range: [9, 17]
9871      loc:
9872        start:
9873          line: 1
9874          column: 9
9875        end:
9876          line: 1
9877          column: 17
9878    start: 0
9879    end: 17
9880    range: [0, 17]
9881    loc:
9882      start:
9883        line: 1
9884        column: 0
9885      end:
9886        line: 1
9887        column: 17
9888
9889  testAstLocationData 'yes if maybe',
9890    type: 'IfStatement'
9891    test:
9892      start: 7
9893      end: 12
9894      range: [7, 12]
9895      loc:
9896        start:
9897          line: 1
9898          column: 7
9899        end:
9900          line: 1
9901          column: 12
9902    consequent:
9903      body: [
9904        expression:
9905          start: 0
9906          end: 3
9907          range: [0, 3]
9908          loc:
9909            start:
9910              line: 1
9911              column: 0
9912            end:
9913              line: 1
9914              column: 3
9915        start: 0
9916        end: 3
9917        range: [0, 3]
9918        loc:
9919          start:
9920            line: 1
9921            column: 0
9922          end:
9923            line: 1
9924            column: 3
9925      ]
9926      start: 0
9927      end: 3
9928      range: [0, 3]
9929      loc:
9930        start:
9931          line: 1
9932          column: 0
9933        end:
9934          line: 1
9935          column: 3
9936    start: 0
9937    end: 12
9938    range: [0, 12]
9939    loc:
9940      start:
9941        line: 1
9942        column: 0
9943      end:
9944        line: 1
9945        column: 12
9946
9947  testAstLocationData 'unless x then x else if y then y else z',
9948    type: 'IfStatement'
9949    test:
9950      start: 7
9951      end: 8
9952      range: [7, 8]
9953      loc:
9954        start:
9955          line: 1
9956          column: 7
9957        end:
9958          line: 1
9959          column: 8
9960    consequent:
9961      body: [
9962        expression:
9963          start: 14
9964          end: 15
9965          range: [14, 15]
9966          loc:
9967            start:
9968              line: 1
9969              column: 14
9970            end:
9971              line: 1
9972              column: 15
9973        start: 14
9974        end: 15
9975        range: [14, 15]
9976        loc:
9977          start:
9978            line: 1
9979            column: 14
9980          end:
9981            line: 1
9982            column: 15
9983      ]
9984      start: 9
9985      end: 15
9986      range: [9, 15]
9987      loc:
9988        start:
9989          line: 1
9990          column: 9
9991        end:
9992          line: 1
9993          column: 15
9994    alternate:
9995      test:
9996        start: 24
9997        end: 25
9998        range: [24, 25]
9999        loc:
10000          start:
10001            line: 1
10002            column: 24
10003          end:
10004            line: 1
10005            column: 25
10006      consequent:
10007        body: [
10008          expression:
10009            start: 31
10010            end: 32
10011            range: [31, 32]
10012            loc:
10013              start:
10014                line: 1
10015                column: 31
10016              end:
10017                line: 1
10018                column: 32
10019          start: 31
10020          end: 32
10021          range: [31, 32]
10022          loc:
10023            start:
10024              line: 1
10025              column: 31
10026            end:
10027              line: 1
10028              column: 32
10029        ]
10030        start: 26
10031        end: 32
10032        range: [26, 32]
10033        loc:
10034          start:
10035            line: 1
10036            column: 26
10037          end:
10038            line: 1
10039            column: 32
10040      alternate:
10041        body: [
10042          expression:
10043            start: 38
10044            end: 39
10045            range: [38, 39]
10046            loc:
10047              start:
10048                line: 1
10049                column: 38
10050              end:
10051                line: 1
10052                column: 39
10053          start: 38
10054          end: 39
10055          range: [38, 39]
10056          loc:
10057            start:
10058              line: 1
10059              column: 38
10060            end:
10061              line: 1
10062              column: 39
10063        ]
10064        start: 37
10065        end: 39
10066        range: [37, 39]
10067        loc:
10068          start:
10069            line: 1
10070            column: 37
10071          end:
10072            line: 1
10073            column: 39
10074      start: 21
10075      end: 39
10076      range: [21, 39]
10077      loc:
10078        start:
10079          line: 1
10080          column: 21
10081        end:
10082          line: 1
10083          column: 39
10084    start: 0
10085    end: 39
10086    range: [0, 39]
10087    loc:
10088      start:
10089        line: 1
10090        column: 0
10091      end:
10092        line: 1
10093        column: 39
10094
10095  testAstLocationData '''
10096    if a
10097      b
10098    else
10099      if c
10100        d
10101  ''',
10102    type: 'IfStatement'
10103    test:
10104      start: 3
10105      end: 4
10106      range: [3, 4]
10107      loc:
10108        start:
10109          line: 1
10110          column: 3
10111        end:
10112          line: 1
10113          column: 4
10114    consequent:
10115      body: [
10116        expression:
10117          start: 7
10118          end: 8
10119          range: [7, 8]
10120          loc:
10121            start:
10122              line: 2
10123              column: 2
10124            end:
10125              line: 2
10126              column: 3
10127        start: 7
10128        end: 8
10129        range: [7, 8]
10130        loc:
10131          start:
10132            line: 2
10133            column: 2
10134          end:
10135            line: 2
10136            column: 3
10137      ]
10138      start: 5
10139      end: 8
10140      range: [5, 8]
10141      loc:
10142        start:
10143          line: 2
10144          column: 0
10145        end:
10146          line: 2
10147          column: 3
10148    alternate:
10149      body: [
10150        test:
10151          start: 19
10152          end: 20
10153          range: [19, 20]
10154          loc:
10155            start:
10156              line: 4
10157              column: 5
10158            end:
10159              line: 4
10160              column: 6
10161        consequent:
10162          body: [
10163            expression:
10164              start: 25
10165              end: 26
10166              range: [25, 26]
10167              loc:
10168                start:
10169                  line: 5
10170                  column: 4
10171                end:
10172                  line: 5
10173                  column: 5
10174            start: 25
10175            end: 26
10176            range: [25, 26]
10177            loc:
10178              start:
10179                line: 5
10180                column: 4
10181              end:
10182                line: 5
10183                column: 5
10184          ]
10185          start: 21
10186          end: 26
10187          range: [21, 26]
10188          loc:
10189            start:
10190              line: 5
10191              column: 0
10192            end:
10193              line: 5
10194              column: 5
10195        start: 16
10196        end: 26
10197        range: [16, 26]
10198        loc:
10199          start:
10200            line: 4
10201            column: 2
10202          end:
10203            line: 5
10204            column: 5
10205      ]
10206      start: 14
10207      end: 26
10208      range: [14, 26]
10209      loc:
10210        start:
10211          line: 4
10212          column: 0
10213        end:
10214          line: 5
10215          column: 5
10216    start: 0
10217    end: 26
10218    range: [0, 26]
10219    loc:
10220      start:
10221        line: 1
10222        column: 0
10223      end:
10224        line: 5
10225        column: 5
10226
10227  testAstLocationData '''
10228    a =
10229      if b then c else if d then e
10230  ''',
10231    type: 'AssignmentExpression'
10232    right:
10233      test:
10234        start: 9
10235        end: 10
10236        range: [9, 10]
10237        loc:
10238          start:
10239            line: 2
10240            column: 5
10241          end:
10242            line: 2
10243            column: 6
10244      consequent:
10245        start: 16
10246        end: 17
10247        range: [16, 17]
10248        loc:
10249          start:
10250            line: 2
10251            column: 12
10252          end:
10253            line: 2
10254            column: 13
10255      alternate:
10256        test:
10257          start: 26
10258          end: 27
10259          range: [26, 27]
10260          loc:
10261            start:
10262              line: 2
10263              column: 22
10264            end:
10265              line: 2
10266              column: 23
10267        consequent:
10268          start: 33
10269          end: 34
10270          range: [33, 34]
10271          loc:
10272            start:
10273              line: 2
10274              column: 29
10275            end:
10276              line: 2
10277              column: 30
10278        start: 23
10279        end: 34
10280        range: [23, 34]
10281        loc:
10282          start:
10283            line: 2
10284            column: 19
10285          end:
10286            line: 2
10287            column: 30
10288      start: 6
10289      end: 34
10290      range: [6, 34]
10291      loc:
10292        start:
10293          line: 2
10294          column: 2
10295        end:
10296          line: 2
10297          column: 30
10298    start: 0
10299    end: 34
10300    range: [0, 34]
10301    loc:
10302      start:
10303        line: 1
10304        column: 0
10305      end:
10306        line: 2
10307        column: 30
10308
10309  testAstLocationData '''
10310    f(
10311      if b
10312        c
10313        d
10314    )
10315  ''',
10316    type: 'CallExpression'
10317    arguments: [
10318      test:
10319        start: 8
10320        end: 9
10321        range: [8, 9]
10322        loc:
10323          start:
10324            line: 2
10325            column: 5
10326          end:
10327            line: 2
10328            column: 6
10329      consequent:
10330        body: [
10331          expression:
10332            start: 14
10333            end: 15
10334            range: [14, 15]
10335            loc:
10336              start:
10337                line: 3
10338                column: 4
10339              end:
10340                line: 3
10341                column: 5
10342          start: 14
10343          end: 15
10344          range: [14, 15]
10345          loc:
10346            start:
10347              line: 3
10348              column: 4
10349            end:
10350              line: 3
10351              column: 5
10352        ,
10353          expression:
10354            start: 20
10355            end: 21
10356            range: [20, 21]
10357            loc:
10358              start:
10359                line: 4
10360                column: 4
10361              end:
10362                line: 4
10363                column: 5
10364          start: 20
10365          end: 21
10366          range: [20, 21]
10367          loc:
10368            start:
10369              line: 4
10370              column: 4
10371            end:
10372              line: 4
10373              column: 5
10374        ]
10375        start: 10
10376        end: 21
10377        range: [10, 21]
10378        loc:
10379          start:
10380            line: 3
10381            column: 0
10382          end:
10383            line: 4
10384            column: 5
10385    ]
10386    start: 0
10387    end: 23
10388    range: [0, 23]
10389    loc:
10390      start:
10391        line: 1
10392        column: 0
10393      end:
10394        line: 5
10395        column: 1
10396
10397test "AST as expected for While node", ->
10398  testAstLocationData 'loop 1',
10399    type: 'WhileStatement'
10400    test:
10401      start: 0
10402      end: 4
10403      range: [0, 4]
10404      loc:
10405        start:
10406          line: 1
10407          column: 0
10408        end:
10409          line: 1
10410          column: 4
10411    body:
10412      body: [
10413        expression:
10414          start: 5
10415          end: 6
10416          range: [5, 6]
10417          loc:
10418            start:
10419              line: 1
10420              column: 5
10421            end:
10422              line: 1
10423              column: 6
10424        start: 5
10425        end: 6
10426        range: [5, 6]
10427        loc:
10428          start:
10429            line: 1
10430            column: 5
10431          end:
10432            line: 1
10433            column: 6
10434      ]
10435      start: 5
10436      end: 6
10437      range: [5, 6]
10438      loc:
10439        start:
10440          line: 1
10441          column: 5
10442        end:
10443          line: 1
10444          column: 6
10445    start: 0
10446    end: 6
10447    range: [0, 6]
10448    loc:
10449      start:
10450        line: 1
10451        column: 0
10452      end:
10453        line: 1
10454        column: 6
10455
10456  testAstLocationData 'while 1 < 2 then',
10457    type: 'WhileStatement'
10458    test:
10459      start: 6
10460      end: 11
10461      range: [6, 11]
10462      loc:
10463        start:
10464          line: 1
10465          column: 6
10466        end:
10467          line: 1
10468          column: 11
10469    body:
10470      start: 12
10471      end: 16
10472      range: [12, 16]
10473      loc:
10474        start:
10475          line: 1
10476          column: 12
10477        end:
10478          line: 1
10479          column: 16
10480    start: 0
10481    end: 16
10482    range: [0, 16]
10483    loc:
10484      start:
10485        line: 1
10486        column: 0
10487      end:
10488        line: 1
10489        column: 16
10490
10491  testAstLocationData 'while 1 < 2 then fn()',
10492    type: 'WhileStatement'
10493    test:
10494      start: 6
10495      end: 11
10496      range: [6, 11]
10497      loc:
10498        start:
10499          line: 1
10500          column: 6
10501        end:
10502          line: 1
10503          column: 11
10504    body:
10505      body: [
10506        expression:
10507          start: 17
10508          end: 21
10509          range: [17, 21]
10510          loc:
10511            start:
10512              line: 1
10513              column: 17
10514            end:
10515              line: 1
10516              column: 21
10517        start: 17
10518        end: 21
10519        range: [17, 21]
10520        loc:
10521          start:
10522            line: 1
10523            column: 17
10524          end:
10525            line: 1
10526            column: 21
10527      ]
10528      start: 12
10529      end: 21
10530      range: [12, 21]
10531      loc:
10532        start:
10533          line: 1
10534          column: 12
10535        end:
10536          line: 1
10537          column: 21
10538    start: 0
10539    end: 21
10540    range: [0, 21]
10541    loc:
10542      start:
10543        line: 1
10544        column: 0
10545      end:
10546        line: 1
10547        column: 21
10548
10549
10550  testAstLocationData '''
10551    x() until y
10552  ''',
10553    type: 'WhileStatement'
10554    test:
10555      start: 10
10556      end: 11
10557      range: [10, 11]
10558      loc:
10559        start:
10560          line: 1
10561          column: 10
10562        end:
10563          line: 1
10564          column: 11
10565    body:
10566      body: [
10567        expression:
10568          start: 0
10569          end: 3
10570          range: [0, 3]
10571          loc:
10572            start:
10573              line: 1
10574              column: 0
10575            end:
10576              line: 1
10577              column: 3
10578        start: 0
10579        end: 3
10580        range: [0, 3]
10581        loc:
10582          start:
10583            line: 1
10584            column: 0
10585          end:
10586            line: 1
10587            column: 3
10588      ]
10589      start: 0
10590      end: 3
10591      range: [0, 3]
10592      loc:
10593        start:
10594          line: 1
10595          column: 0
10596        end:
10597          line: 1
10598          column: 3
10599    start: 0
10600    end: 11
10601    range: [0, 11]
10602    loc:
10603      start:
10604        line: 1
10605        column: 0
10606      end:
10607        line: 1
10608        column: 11
10609
10610  testAstLocationData '''
10611    until x when y
10612      z++
10613  ''',
10614    type: 'WhileStatement'
10615    test:
10616      start: 6
10617      end: 7
10618      range: [6, 7]
10619      loc:
10620        start:
10621          line: 1
10622          column: 6
10623        end:
10624          line: 1
10625          column: 7
10626    body:
10627      body: [
10628        expression:
10629          start: 17
10630          end: 20
10631          range: [17, 20]
10632          loc:
10633            start:
10634              line: 2
10635              column: 2
10636            end:
10637              line: 2
10638              column: 5
10639        start: 17
10640        end: 20
10641        range: [17, 20]
10642        loc:
10643          start:
10644            line: 2
10645            column: 2
10646          end:
10647            line: 2
10648            column: 5
10649      ]
10650      start: 15
10651      end: 20
10652      range: [15, 20]
10653      loc:
10654        start:
10655          line: 2
10656          column: 0
10657        end:
10658          line: 2
10659          column: 5
10660    guard:
10661      start: 13
10662      end: 14
10663      range: [13, 14]
10664      loc:
10665        start:
10666          line: 1
10667          column: 13
10668        end:
10669          line: 1
10670          column: 14
10671    start: 0
10672    end: 20
10673    range: [0, 20]
10674    loc:
10675      start:
10676        line: 1
10677        column: 0
10678      end:
10679        line: 2
10680        column: 5
10681
10682  testAstLocationData '''
10683    x while y when z
10684  ''',
10685    type: 'WhileStatement'
10686    test:
10687      start: 8
10688      end: 9
10689      range: [8, 
106899]
10690      loc:
10691        start:
10692          line: 1
10693          column: 8
10694        end:
10695          line: 1
10696          column: 9
10697    body:
10698      body: [
10699        expression:
10700          start: 0
10701          end: 1
10702          range: [0, 1]
10703          loc:
10704            start:
10705              line: 1
10706              column: 0
10707            end:
10708              line: 1
10709              column: 1
10710        start: 0
10711        end: 1
10712        range: [0, 1]
10713        loc:
10714          start:
10715            line: 1
10716            column: 0
10717          end:
10718            line: 1
10719            column: 1
10720      ]
10721      start: 0
10722      end: 1
10723      range: [0, 1]
10724      loc:
10725        start:
10726          line: 1
10727          column: 0
10728        end:
10729          line: 1
10730          column: 1
10731    guard:
10732      start: 15
10733      end: 16
10734      range: [15, 16]
10735      loc:
10736        start:
10737          line: 1
10738          column: 15
10739        end:
10740          line: 1
10741          column: 16
10742    start: 0
10743    end: 16
10744    range: [0, 16]
10745    loc:
10746      start:
10747        line: 1
10748        column: 0
10749      end:
10750        line: 1
10751        column: 16
10752
10753  testAstLocationData '''
10754    loop
10755      a()
10756      b++
10757  ''',
10758    type: 'WhileStatement'
10759    test:
10760      start: 0
10761      end: 4
10762      range: [0, 4]
10763      loc:
10764        start:
10765          line: 1
10766          column: 0
10767        end:
10768          line: 1
10769          column: 4
10770    body:
10771      body: [
10772        expression:
10773          start: 7
10774          end: 10
10775          range: [7, 10]
10776          loc:
10777            start:
10778              line: 2
10779              column: 2
10780            end:
10781              line: 2
10782              column: 5
10783        start: 7
10784        end: 10
10785        range: [7, 10]
10786        loc:
10787          start:
10788            line: 2
10789            column: 2
10790          end:
10791            line: 2
10792            column: 5
10793      ,
10794        expression:
10795          start: 13
10796          end: 16
10797          range: [13, 16]
10798          loc:
10799            start:
10800              line: 3
10801              column: 2
10802            end:
10803              line: 3
10804              column: 5
10805        start: 13
10806        end: 16
10807        range: [13, 16]
10808        loc:
10809          start:
10810            line: 3
10811            column: 2
10812          end:
10813            line: 3
10814            column: 5
10815      ]
10816      start: 5
10817      end: 16
10818      range: [5, 16]
10819      loc:
10820        start:
10821          line: 2
10822          column: 0
10823        end:
10824          line: 3
10825          column: 5
10826    start: 0
10827    end: 16
10828    range: [0, 16]
10829    loc:
10830      start:
10831        line: 1
10832        column: 0
10833      end:
10834        line: 3
10835        column: 5
10836
10837test "AST location data as expected for `new.target` MetaProperty node", ->
10838  testAstLocationData '''
10839    -> new.target
10840  ''',
10841    type: 'FunctionExpression'
10842    body:
10843      body: [
10844        expression:
10845          meta:
10846            start: 3
10847            end: 6
10848            range: [3, 6]
10849            loc:
10850              start:
10851                line: 1
10852                column: 3
10853              end:
10854                line: 1
10855                column: 6
10856          property:
10857            start: 7
10858            end: 13
10859            range: [7, 13]
10860            loc:
10861              start:
10862                line: 1
10863                column: 7
10864              end:
10865                line: 1
10866                column: 13
10867          start: 3
10868          end: 13
10869          range: [3, 13]
10870          loc:
10871            start:
10872              line: 1
10873              column: 3
10874            end:
10875              line: 1
10876              column: 13
10877      ]
10878    start: 0
10879    end: 13
10880    range: [0, 13]
10881    loc:
10882      start:
10883        line: 1
10884        column: 0
10885      end:
10886        line: 1
10887        column: 13
10888
10889test "AST location data as expected for `import.meta` MetaProperty node", ->
10890  testAstLocationData '''
10891    import.meta
10892  ''',
10893    type: 'MetaProperty'
10894    meta:
10895      start: 0
10896      end: 6
10897      range: [0, 6]
10898      loc:
10899        start:
10900          line: 1
10901          column: 0
10902        end:
10903          line: 1
10904          column: 6
10905    property:
10906      start: 7
10907      end: 11
10908      range: [7, 11]
10909      loc:
10910        start:
10911          line: 1
10912          column: 7
10913        end:
10914          line: 1
10915          column: 11
10916    start: 0
10917    end: 11
10918    range: [0, 11]
10919    loc:
10920      start:
10921        line: 1
10922        column: 0
10923      end:
10924        line: 1
10925        column: 11
10926
10927test "AST location data as expected for For node", ->
10928  testAstLocationData 'for x, i in arr when x? then return',
10929    type: 'For'
10930    name:
10931      start: 4
10932      end: 5
10933      range: [4, 5]
10934      loc:
10935        start:
10936          line: 1
10937          column: 4
10938        end:
10939          line: 1
10940          column: 5
10941    index:
10942      start: 7
10943      end: 8
10944      range: [7, 8]
10945      loc:
10946        start:
10947          line: 1
10948          column: 7
10949        end:
10950          line: 1
10951          column: 8
10952    guard:
10953      start: 21
10954      end: 23
10955      range: [21, 23]
10956      loc:
10957        start:
10958          line: 1
10959          column: 21
10960        end:
10961          line: 1
10962          column: 23
10963    source:
10964      start: 12
10965      end: 15
10966      range: [12, 15]
10967      loc:
10968        start:
10969          line: 1
10970          column: 12
10971        end:
10972          line: 1
10973          column: 15
10974    body:
10975      body: [
10976        start: 29
10977        end: 35
10978        range: [29, 35]
10979        loc:
10980          start:
10981            line: 1
10982            column: 29
10983          end:
10984            line: 1
10985            column: 35
10986      ]
10987      start: 24
10988      end: 35
10989      range: [24, 35]
10990      loc:
10991        start:
10992          line: 1
10993          column: 24
10994        end:
10995          line: 1
10996          column: 35
10997    start: 0
10998    end: 35
10999    range: [0, 35]
11000    loc:
11001      start:
11002        line: 1
11003        column: 0
11004      end:
11005        line: 1
11006        column: 35
11007
11008  testAstLocationData 'a = (x for x in y)',
11009    type: 'AssignmentExpression'
11010    right:
11011      name:
11012        start: 11
11013        end: 12
11014        range: [11, 12]
11015        loc:
11016          start:
11017            line: 1
11018            column: 11
11019          end:
11020            line: 1
11021            column: 12
11022      body:
11023        start: 5
11024        end: 6
11025        range: [5, 6]
11026        loc:
11027          start:
11028            line: 1
11029            column: 5
11030          end:
11031            line: 1
11032            column: 6
11033      source:
11034        start: 16
11035        end: 17
11036        range: [16, 17]
11037        loc:
11038          start:
11039            line: 1
11040            column: 16
11041          end:
11042            line: 1
11043            column: 17
11044      start: 5
11045      end: 17
11046      range: [5, 17]
11047      loc:
11048        start:
11049          line: 1
11050          column: 5
11051        end:
11052          line: 1
11053          column: 17
11054    start: 0
11055    end: 18
11056    range: [0, 18]
11057    loc:
11058      start:
11059        line: 1
11060        column: 0
11061      end:
11062        line: 1
11063        column: 18
11064
11065  testAstLocationData 'x for [0...1]',
11066    type: 'For'
11067    body:
11068      start: 0
11069      end: 1
11070      range: [0, 1]
11071      loc:
11072        start:
11073          line: 1
11074          column: 0
11075        end:
11076          line: 1
11077          column: 1
11078    source:
11079      start: 6
11080      end: 13
11081      range: [6, 13]
11082      loc:
11083        start:
11084          line: 1
11085          column: 6
11086        end:
11087          line: 1
11088          column: 13
11089    start: 0
11090    end: 13
11091    range: [0, 13]
11092    loc:
11093      start:
11094        line: 1
11095        column: 0
11096      end:
11097        line: 1
11098        column: 13
11099
11100  testAstLocationData '''
11101    for own x, y of z
11102      c()
11103      d
11104  ''',
11105    type: 'For'
11106    name:
11107      start: 11
11108      end: 12
11109      range: [11, 12]
11110      loc:
11111        start:
11112          line: 1
11113          column: 11
11114        end:
11115          line: 1
11116          column: 12
11117    index:
11118      start: 8
11119      end: 9
11120      range: [8, 9]
11121      loc:
11122        start:
11123          line: 1
11124          column: 8
11125        end:
11126          line: 1
11127          column: 9
11128    body:
11129      body: [
11130        start: 20
11131        end: 23
11132        range: [20, 23]
11133        loc:
11134          start:
11135            line: 2
11136            column: 2
11137          end:
11138            line: 2
11139            column: 5
11140      ,
11141        start: 26
11142        end: 27
11143        range: [26, 27]
11144        loc:
11145          start:
11146            line: 3
11147            column: 2
11148          end:
11149            line: 3
11150            column: 3
11151      ]
11152      start: 18
11153      end: 27
11154      range: [18, 27]
11155      loc:
11156        start:
11157          line: 2
11158          column: 0
11159        end:
11160          line: 3
11161          column: 3
11162    source:
11163      start: 16
11164      end: 17
11165      range: [16, 17]
11166      loc:
11167        start:
11168          line: 1
11169          column: 16
11170        end:
11171          line: 1
11172          column: 17
11173    start: 0
11174    end: 27
11175    range: [0, 27]
11176    loc:
11177      start:
11178        line: 1
11179        column: 0
11180      end:
11181        line: 3
11182        column: 3
11183
11184  testAstLocationData '''
11185    ->
11186      for await x from y
11187        z
11188  ''',
11189    type: 'FunctionExpression'
11190    body:
11191      body: [
11192        name:
11193          start: 15
11194          end: 16
11195          range: [15, 16]
11196          loc:
11197            start:
11198              line: 2
11199              column: 12
11200            end:
11201              line: 2
11202              column: 13
11203        body:
11204          body: [
11205            start: 28
11206            end: 29
11207            range: [28, 29]
11208            loc:
11209              start:
11210                line: 3
11211                column: 4
11212              end:
11213                line: 3
11214                column: 5
11215          ]
11216          start: 24
11217          end: 29
11218          range: [24, 29]
11219          loc:
11220            start:
11221              line: 3
11222              column: 0
11223            end:
11224              line: 3
11225              column: 5
11226        source:
11227          start: 22
11228          end: 23
11229          range: [22, 23]
11230          loc:
11231            start:
11232              line: 2
11233              column: 19
11234            end:
11235              line: 2
11236              column: 20
11237        start: 5
11238        end: 29
11239        range: [5, 29]
11240        loc:
11241          start:
11242            line: 2
11243            column: 2
11244          end:
11245            line: 3
11246            column: 5
11247      ]
11248      start: 3
11249      end: 29
11250      range: [3, 29]
11251      loc:
11252        start:
11253          line: 2
11254          column: 0
11255        end:
11256          line: 3
11257          column: 5
11258    start: 0
11259    end: 29
11260    range: [0, 29]
11261    loc:
11262      start:
11263        line: 1
11264        column: 0
11265      end:
11266        line: 3
11267        column: 5
11268
11269  testAstLocationData '''
11270    for {x} in y
11271      z
11272  ''',
11273    type: 'For'
11274    name:
11275      properties: [
11276        start: 5
11277        end: 6
11278        range: [5, 6]
11279        loc:
11280          start:
11281            line: 1
11282            column: 5
11283          end:
11284            line: 1
11285            column: 6
11286      ]
11287      start: 4
11288      end: 7
11289      range: [4, 7]
11290      loc:
11291        start:
11292          line: 1
11293          column: 4
11294        end:
11295          line: 1
11296          column: 7
11297    body:
11298      body: [
11299        start: 15
11300        end: 16
11301        range: [15, 16]
11302        loc:
11303          start:
11304            line: 2
11305            column: 2
11306          end:
11307            line: 2
11308            column: 3
11309      ]
11310      start: 13
11311      end: 16
11312      range: [13, 16]
11313      loc:
11314        start:
11315          line: 2
11316          column: 0
11317        end:
11318          line: 2
11319          column: 3
11320    source:
11321      start: 11
11322      end: 12
11323      range: [11, 12]
11324      loc:
11325        start:
11326          line: 1
11327          column: 11
11328        end:
11329          line: 1
11330          column: 12
11331    start: 0
11332    end: 16
11333    range: [0, 16]
11334    loc:
11335      start:
11336        line: 1
11337        column: 0
11338      end:
11339        line: 2
11340        column: 3
11341
11342test "AST location data as expected for StringWithInterpolations node", ->
11343  testAstLocationData '"a#{b}c"',
11344    type: 'TemplateLiteral'
11345    expressions: [
11346      start: 4
11347      end: 5
11348      range: [4, 5]
11349      loc:
11350        start:
11351          line: 1
11352          column: 4
11353        end:
11354          line: 1
11355          column: 5
11356    ]
11357    quasis: [
11358      start: 1
11359      end: 2
11360      range: [1, 2]
11361      loc:
11362        start:
11363          line: 1
11364          column: 1
11365        end:
11366          line: 1
11367          column: 2
11368    ,
11369      start: 6
11370      end: 7
11371      range: [6, 7]
11372      loc:
11373        start:
11374          line: 1
11375          column: 6
11376        end:
11377          line: 1
11378          column: 7
11379    ]
11380    start: 0
11381    end: 8
11382    range: [0, 8]
11383    loc:
11384      start:
11385        line: 1
11386        column: 0
11387      end:
11388        line: 1
11389        column: 8
11390
11391  testAstLocationData '"""a#{b}c"""',
11392    type: 'TemplateLiteral'
11393    expressions: [
11394      start: 6
11395      end: 7
11396      range: [6, 7]
11397      loc:
11398        start:
11399          line: 1
11400          column: 6
11401        end:
11402          line: 1
11403          column: 7
11404    ]
11405    quasis: [
11406      start: 3
11407      end: 4
11408      range: [3, 4]
11409      loc:
11410        start:
11411          line: 1
11412          column: 3
11413        end:
11414          line: 1
11415          column: 4
11416    ,
11417      start: 8
11418      end: 9
11419      range: [8, 9]
11420      loc:
11421        start:
11422          line: 1
11423          column: 8
11424        end:
11425          line: 1
11426          column: 9
11427    ]
11428    start: 0
11429    end: 12
11430    range: [0, 12]
11431    loc:
11432      start:
11433        line: 1
11434        column: 0
11435      end:
11436        line: 1
11437        column: 12
11438
11439  testAstLocationData '"#{b}"',
11440    type: 'TemplateLiteral'
11441    expressions: [
11442      start: 3
11443      end: 4
11444      range: [3, 4]
11445      loc:
11446        start:
11447          line: 1
11448          column: 3
11449        end:
11450          line: 1
11451          column: 4
11452    ]
11453    quasis: [
11454      start: 1
11455      end: 1
11456      range: [1, 1]
11457      loc:
11458        start:
11459          line: 1
11460          column: 1
11461        end:
11462          line: 1
11463          column: 1
11464    ,
11465      start: 5
11466      end: 5
11467      range: [5, 5]
11468      loc:
11469        start:
11470          line: 1
11471          column: 5
11472        end:
11473          line: 1
11474          column: 5
11475    ]
11476    start: 0
11477    end: 6
11478    range: [0, 6]
11479    loc:
11480      start:
11481        line: 1
11482        column: 0
11483      end:
11484        line: 1
11485        column: 6
11486
11487  testAstLocationData '''
11488    " a
11489      #{b}
11490      c
11491    "
11492  ''',
11493    type: 'TemplateLiteral'
11494    expressions: [
11495      start: 8
11496      end: 9
11497      range: [8, 9]
11498      loc:
11499        start:
11500          line: 2
11501          column: 4
11502        end:
11503          line: 2
11504          column: 5
11505    ]
11506    quasis: [
11507      start: 1
11508      end: 6
11509      range: [1, 6]
11510      loc:
11511        start:
11512          line: 1
11513          column: 1
11514        end:
11515          line: 2
11516          column: 2
11517    ,
11518      start: 10
11519      end: 15
11520      range: [10, 15]
11521      loc:
11522        start:
11523          line: 2
11524          column: 6
11525        end:
11526          line: 4
11527          column: 0
11528    ]
11529    start: 0
11530    end: 16
11531    range: [0, 16]
11532    loc:
11533      start:
11534        line: 1
11535        column: 0
11536      end:
11537        line: 4
11538        column: 1
11539
11540  testAstLocationData '''
11541    """
11542      a
11543        b#{
11544        c
11545      }d
11546    """
11547  ''',
11548    type: 'TemplateLiteral'
11549    expressions: [
11550      start: 20
11551      end: 21
11552      range: [20, 21]
11553      loc:
11554        start:
11555          line: 4
11556          column: 4
11557        end:
11558          line: 4
11559          column: 5
11560    ]
11561    quasis: [
11562      start: 3
11563      end: 13
11564      range: [3, 13]
11565      loc:
11566        start:
11567          line: 1
11568          column: 3
11569        end:
11570          line: 3
11571          column: 5
11572    ,
11573      start: 25
11574      end: 27
11575      range: [25, 27]
11576      loc:
11577        start:
11578          line: 5
11579          column: 3
11580        end:
11581          line: 6
11582          column: 0
11583    ]
11584    start: 0
11585    end: 30
11586    range: [0, 30]
11587    loc:
11588      start:
11589        line: 1
11590        column: 0
11591      end:
11592        line: 6
11593        column: 3
11594
11595  # empty interpolation
11596  testAstLocationData '"#{}"',
11597    type: 'TemplateLiteral'
11598    expressions: [
11599      start: 3
11600      end: 3
11601      range: [3, 3]
11602      loc:
11603        start:
11604          line: 1
11605          column: 3
11606        end:
11607          line: 1
11608          column: 3
11609    ]
11610    quasis: [
11611      start: 1
11612      end: 1
11613      range: [1, 1]
11614      loc:
11615        start:
11616          line: 1
11617          column: 1
11618        end:
11619          line: 1
11620          column: 1
11621    ,
11622      start: 4
11623      end: 4
11624      range: [4, 4]
11625      loc:
11626        start:
11627          line: 1
11628          column: 4
11629        end:
11630          line: 1
11631          column: 4
11632    ]
11633    start: 0
11634    end: 5
11635    range: [0, 5]
11636    loc:
11637      start:
11638        line: 1
11639        column: 0
11640      end:
11641        line: 1
11642        column: 5
11643
11644  testAstLocationData '''
11645    "#{
11646      # comment
11647     }"
11648    ''',
11649    type: 'TemplateLiteral'
11650    expressions: [
11651      start: 3
11652      end: 17
11653      range: [3, 17]
11654      loc:
11655        start:
11656          line: 1
11657          column: 3
11658        end:
11659          line: 3
11660          column: 1
11661    ]
11662    quasis: [
11663      start: 1
11664      end: 1
11665      range: [1, 1]
11666      loc:
11667        start:
11668          line: 1
11669          column: 1
11670        end:
11671          line: 1
11672          column: 1
11673    ,
11674      start: 18
11675      end: 18
11676      range: 
11676[18, 18]
11677      loc:
11678        start:
11679          line: 3
11680          column: 2
11681        end:
11682          line: 3
11683          column: 2
11684    ]
11685    start: 0
11686    end: 19
11687    range: [0, 19]
11688    loc:
11689      start:
11690        line: 1
11691        column: 0
11692      end:
11693        line: 3
11694        column: 3
11695
11696  testAstLocationData '"#{ ### here ### }"',
11697    type: 'TemplateLiteral'
11698    expressions: [
11699      start: 3
11700      end: 17
11701      range: [3, 17]
11702      loc:
11703        start:
11704          line: 1
11705          column: 3
11706        end:
11707          line: 1
11708          column: 17
11709    ]
11710    quasis: [
11711      start: 1
11712      end: 1
11713      range: [1, 1]
11714      loc:
11715        start:
11716          line: 1
11717          column: 1
11718        end:
11719          line: 1
11720          column: 1
11721    ,
11722      start: 18
11723      end: 18
11724      range: [18, 18]
11725      loc:
11726        start:
11727          line: 1
11728          column: 18
11729        end:
11730          line: 1
11731          column: 18
11732    ]
11733    start: 0
11734    end: 19
11735    range: [0, 19]
11736    loc:
11737      start:
11738        line: 1
11739        column: 0
11740      end:
11741        line: 1
11742        column: 19
11743
11744test "AST location data as expected for dynamic import", ->
11745  testAstLocationData '''
11746    import('a')
11747  ''',
11748    type: 'CallExpression'
11749    callee:
11750      start: 0
11751      end: 6
11752      range: [0, 6]
11753      loc:
11754        start:
11755          line: 1
11756          column: 0
11757        end:
11758          line: 1
11759          column: 6
11760    arguments: [
11761      start: 7
11762      end: 10
11763      range: [7, 10]
11764      loc:
11765        start:
11766          line: 1
11767          column: 7
11768        end:
11769          line: 1
11770          column: 10
11771    ]
11772    start: 0
11773    end: 11
11774    range: [0, 11]
11775    loc:
11776      start:
11777        line: 1
11778        column: 0
11779      end:
11780        line: 1
11781        column: 11
11782
11783test "AST location data as expected for RegexWithInterpolations node", ->
11784  testAstLocationData '///^#{flavor}script$///',
11785    type: 'InterpolatedRegExpLiteral'
11786    interpolatedPattern:
11787      expressions: [
11788        start: 6
11789        end: 12
11790        range: [6, 12]
11791        loc:
11792          start:
11793            line: 1
11794            column: 6
11795          end:
11796            line: 1
11797            column: 12
11798      ]
11799      quasis: [
11800        start: 3
11801        end: 4
11802        range: [3, 4]
11803        loc:
11804          start:
11805            line: 1
11806            column: 3
11807          end:
11808            line: 1
11809            column: 4
11810      ,
11811        start: 13
11812        end: 20
11813        range: [13, 20]
11814        loc:
11815          start:
11816            line: 1
11817            column: 13
11818          end:
11819            line: 1
11820            column: 20
11821      ]
11822      start: 0
11823      end: 23
11824      range: [0, 23]
11825      loc:
11826        start:
11827          line: 1
11828          column: 0
11829        end:
11830          line: 1
11831          column: 23
11832    start: 0
11833    end: 23
11834    range: [0, 23]
11835    loc:
11836      start:
11837        line: 1
11838        column: 0
11839      end:
11840        line: 1
11841        column: 23
11842
11843  testAstLocationData '''
11844    ///
11845      a
11846      #{b}///ig
11847  ''',
11848    type: 'InterpolatedRegExpLiteral'
11849    interpolatedPattern:
11850      expressions: [
11851        start: 12
11852        end: 13
11853        range: [12, 13]
11854        loc:
11855          start:
11856            line: 3
11857            column: 4
11858          end:
11859            line: 3
11860            column: 5
11861      ]
11862      quasis: [
11863        start: 3
11864        end: 10
11865        range: [3, 10]
11866        loc:
11867          start:
11868            line: 1
11869            column: 3
11870          end:
11871            line: 3
11872            column: 2
11873      ,
11874        start: 14
11875        end: 14
11876        range: [14, 14]
11877        loc:
11878          start:
11879            line: 3
11880            column: 6
11881          end:
11882            line: 3
11883            column: 6
11884      ]
11885      start: 0
11886      end: 17
11887      range: [0, 17]
11888      loc:
11889        start:
11890          line: 1
11891          column: 0
11892        end:
11893          line: 3
11894          column: 9
11895    start: 0
11896    end: 19
11897    range: [0, 19]
11898    loc:
11899      start:
11900        line: 1
11901        column: 0
11902      end:
11903        line: 3
11904        column: 11
11905
11906  testAstLocationData '''
11907    ///
11908      a # first
11909      #{b} ### second ###
11910    ///ig
11911  ''',
11912    type: 'InterpolatedRegExpLiteral'
11913    comments: [
11914      start: 8
11915      end: 15
11916      range: [8, 15]
11917      loc:
11918        start:
11919          line: 2
11920          column: 4
11921        end:
11922          line: 2
11923          column: 11
11924    ,
11925      start: 23
11926      end: 37
11927      range: [23, 37]
11928      loc:
11929        start:
11930          line: 3
11931          column: 7
11932        end:
11933          line: 3
11934          column: 21
11935    ]
11936
11937test "AST location data as expected for RegexLiteral node", ->
11938  testAstLocationData '/a/ig',
11939    type: 'RegExpLiteral'
11940    start: 0
11941    end: 5
11942    range: [0, 5]
11943    loc:
11944      start:
11945        line: 1
11946        column: 0
11947      end:
11948        line: 1
11949        column: 5
11950
11951  testAstLocationData '''
11952    ///
11953      a
11954    ///i
11955  ''',
11956    type: 'RegExpLiteral'
11957    start: 0
11958    end: 12
11959    range: [0, 12]
11960    loc:
11961      start:
11962        line: 1
11963        column: 0
11964      end:
11965        line: 3
11966        column: 4
11967
11968  testAstLocationData '/a\\w\\u1111\\u{11111}/',
11969    type: 'RegExpLiteral'
11970    start: 0
11971    end: 20
11972    range: [0, 20]
11973    loc:
11974      start:
11975        line: 1
11976        column: 0
11977      end:
11978        line: 1
11979        column: 20
11980
11981  testAstLocationData '''
11982    ///
11983      a
11984      \\w\\u1111\\u{11111}
11985    ///
11986  ''',
11987    type: 'RegExpLiteral'
11988    start: 0
11989    end: 31
11990    range: [0, 31]
11991    loc:
11992      start:
11993        line: 1
11994        column: 0
11995      end:
11996        line: 4
11997        column: 3
11998
11999  testAstLocationData '''
12000    ///
12001      /
12002      (.+)
12003      /
12004    ///
12005  ''',
12006    type: 'RegExpLiteral'
12007    start: 0
12008    end: 22
12009    range: [0, 22]
12010    loc:
12011      start:
12012        line: 1
12013        column: 0
12014      end:
12015        line: 5
12016        column: 3
12017
12018  testAstLocationData '''
12019    ///
12020      a # first
12021      b ### second ###
12022    ///
12023  ''',
12024    type: 'RegExpLiteral'
12025    comments: [
12026      start: 8
12027      end: 15
12028      range: [8, 15]
12029      loc:
12030        start:
12031          line: 2
12032          column: 4
12033        end:
12034          line: 2
12035          column: 11
12036    ,
12037      start: 20
12038      end: 34
12039      range: [20, 34]
12040      loc:
12041        start:
12042          line: 3
12043          column: 4
12044        end:
12045          line: 3
12046          column: 18
12047    ]
12048    start: 0
12049    end: 38
12050    range: [0, 38]
12051    loc:
12052      start:
12053        line: 1
12054        column: 0
12055      end:
12056        line: 4
12057        column: 3
12058
12059test "AST location data as expected for TaggedTemplateCall node", ->
12060  testAstLocationData 'func"tagged"',
12061    type: 'TaggedTemplateExpression'
12062    tag:
12063      start: 0
12064      end: 4
12065      range: [0, 4]
12066      loc:
12067        start:
12068          line: 1
12069          column: 0
12070        end:
12071          line: 1
12072          column: 4
12073    quasi:
12074      quasis: [
12075        start: 5
12076        end: 11
12077        range: [5, 11]
12078        loc:
12079          start:
12080            line: 1
12081            column: 5
12082          end:
12083            line: 1
12084            column: 11
12085      ]
12086      start: 4
12087      end: 12
12088      range: [4, 12]
12089      loc:
12090        start:
12091          line: 1
12092          column: 4
12093        end:
12094          line: 1
12095          column: 12
12096    start: 0
12097    end: 12
12098    range: [0, 12]
12099    loc:
12100      start:
12101        line: 1
12102        column: 0
12103      end:
12104        line: 1
12105        column: 12
12106
12107  testAstLocationData 'a"b#{c}"',
12108    type: 'TaggedTemplateExpression'
12109    tag:
12110      start: 0
12111      end: 1
12112      range: [0, 1]
12113      loc:
12114        start:
12115          line: 1
12116          column: 0
12117        end:
12118          line: 1
12119          column: 1
12120    quasi:
12121      expressions: [
12122        start: 5
12123        end: 6
12124        range: [5, 6]
12125        loc:
12126          start:
12127            line: 1
12128            column: 5
12129          end:
12130            line: 1
12131            column: 6
12132      ]
12133      quasis: [
12134        start: 2
12135        end: 3
12136        range: [2, 3]
12137        loc:
12138          start:
12139            line: 1
12140            column: 2
12141          end:
12142            line: 1
12143            column: 3
12144      ,
12145        start: 7
12146        end: 7
12147        range: [7, 7]
12148        loc:
12149          start:
12150            line: 1
12151            column: 7
12152          end:
12153            line: 1
12154            column: 7
12155      ]
12156      start: 1
12157      end: 8
12158      range: [1, 8]
12159      loc:
12160        start:
12161          line: 1
12162          column: 1
12163        end:
12164          line: 1
12165          column: 8
12166    start: 0
12167    end: 8
12168    range: [0, 8]
12169    loc:
12170      start:
12171        line: 1
12172        column: 0
12173      end:
12174        line: 1
12175        column: 8
12176
12177  testAstLocationData '''
12178    a"""
12179      b#{c}
12180    """
12181  ''',
12182    type: 'TaggedTemplateExpression'
12183    tag:
12184      start: 0
12185      end: 1
12186      range: [0, 1]
12187      loc:
12188        start:
12189          line: 1
12190          column: 0
12191        end:
12192          line: 1
12193          column: 1
12194    quasi:
12195      expressions: [
12196        start: 10
12197        end: 11
12198        range: [10, 11]
12199        loc:
12200          start:
12201            line: 2
12202            column: 5
12203          end:
12204            line: 2
12205            column: 6
12206      ]
12207      quasis: [
12208        start: 4
12209        end: 8
12210        range: [4, 8]
12211        loc:
12212          start:
12213            line: 1
12214            column: 4
12215          end:
12216            line: 2
12217            column: 3
12218      ,
12219        start: 12
12220        end: 13
12221        range: [12, 13]
12222        loc:
12223          start:
12224            line: 2
12225            column: 7
12226          end:
12227            line: 3
12228            column: 0
12229      ]
12230      start: 1
12231      end: 16
12232      range: [1, 16]
12233      loc:
12234        start:
12235          line: 1
12236          column: 1
12237        end:
12238          line: 3
12239          column: 3
12240    start: 0
12241    end: 16
12242    range: [0, 16]
12243    loc:
12244      start:
12245        line: 1
12246        column: 0
12247      end:
12248        line: 3
12249        column: 3
12250
12251  testAstLocationData """
12252    a'''
12253      b
12254    '''
12255  """,
12256    type: 'TaggedTemplateExpression'
12257    tag:
12258      start: 0
12259      end: 1
12260      range: [0, 1]
12261      loc:
12262        start:
12263          line: 1
12264          column: 0
12265        end:
12266          line: 1
12267          column: 1
12268    quasi:
12269      quasis: [
12270        start: 4
12271        end: 9
12272        range: [4, 9]
12273        loc:
12274          start:
12275            line: 1
12276            column: 4
12277          end:
12278            line: 3
12279            column: 0
12280      ]
12281      start: 1
12282      end: 12
12283      range: [1, 12]
12284      loc:
12285        start:
12286          line: 1
12287          column: 1
12288        end:
12289          line: 3
12290          column: 3
12291    start: 0
12292    end: 12
12293    range: [0, 12]
12294    loc:
12295      start:
12296        line: 1
12297        column: 0
12298      end:
12299        line: 3
12300        column: 3
12301
12302test "AST location data as expected for Class node", ->
12303  testAstLocationData 'class Klass',
12304    type: 'ClassDeclaration'
12305    id:
12306      start: 6
12307      end: 11
12308      range: [6, 11]
12309      loc:
12310        start:
12311          line: 1
12312          column: 6
12313        end:
12314          line: 1
12315          column: 11
12316    body:
12317      start: 11
12318      end: 11
12319      range: [11, 11]
12320      loc:
12321        start:
12322          line: 1
12323          column: 11
12324        end:
12325          line: 1
12326          column: 11
12327    start: 0
12328    end: 11
12329    range: [0, 11]
12330    loc:
12331      start:
12332        line: 1
12333        column: 0
12334      end:
12335        line: 1
12336        column: 11
12337
12338  testAstLocationData 'class child extends parent',
12339    type: 'ClassDeclaration'
12340    id:
12341      start: 6
12342      end: 11
12343      range: [6, 11]
12344      loc:
12345        start:
12346          line: 1
12347          column: 6
12348        end:
12349          line: 1
12350          column: 11
12351    superClass:
12352      start: 20
12353      end: 26
12354      range: [20, 26]
12355      loc:
12356        start:
12357          line: 1
12358          column: 20
12359        end:
12360          line: 1
12361          column: 26
12362    body:
12363      start: 26
12364      end: 26
12365      range: [26, 26]
12366      loc:
12367        start:
12368          line: 1
12369          column: 26
12370        end:
12371          line: 1
12372          column: 26
12373    start: 0
12374    end: 26
12375    range: [0, 26]
12376    loc:
12377      start:
12378        line: 1
12379        column: 0
12380      end:
12381        line: 1
12382        column: 26
12383
12384  testAstLocationData 'class Klass then constructor: ->',
12385    type: 'ClassDeclaration'
12386    id:
12387      start: 6
12388      end: 11
12389      range: [6, 11]
12390      loc:
12391        start:
12392          line: 1
12393          column: 6
12394        end:
12395          line: 1
12396          column: 11
12397    body:
12398      body: [
12399        key:
12400          start: 17
12401          end: 28
12402          range: [17, 28]
12403          loc:
12404            start:
12405              line: 1
12406              column: 17
12407            end:
12408              line: 1
12409              column: 28
12410        start: 17
12411        end: 32
12412        range: [17, 32]
12413        loc:
12414          start:
12415            line: 1
12416            column: 17
12417          end:
12418            line: 1
12419            column: 32
12420      ]
12421      start: 12
12422      end: 32
12423      range: [12, 32]
12424      loc:
12425        start:
12426          line: 1
12427          column: 12
12428        end:
12429          line: 1
12430          column: 32
12431    start: 0
12432    end: 32
12433    range: [0, 32]
12434    loc:
12435      start:
12436        line: 1
12437        column: 0
12438      end:
12439        line: 1
12440        column: 32
12441
12442  testAstLocationData '''
12443    a = class A
12444      b: ->
12445        c
12446  ''',
12447    type: 'AssignmentExpression'
12448    right:
12449      id:
12450        start: 10
12451        end: 11
12452        range: [10, 11]
12453        loc:
12454          start:
12455            line: 1
12456            column: 10
12457          end:
12458            line: 1
12459            column: 11
12460      body:
12461        body: [
12462          key:
12463            start: 14
12464            end: 15
12465            range: [14, 15]
12466            loc:
12467              start:
12468                line: 2
12469                column: 2
12470              end:
12471                line: 2
12472                column: 3
12473          body:
12474            body: [
12475              start: 24
12476              end: 25
12477              range: [24, 25]
12478              loc:
12479                start:
12480                  line: 3
12481                  column: 4
12482                end:
12483                  line: 3
12484                  column: 5
12485            ]
12486            start: 20
12487            end: 25
12488            range: [20, 25]
12489            loc:
12490              start:
12491                line: 3
12492                column: 0
12493              end:
12494                line: 3
12495                column: 5
12496          start: 14
12497          end: 25
12498          range: [14, 25]
12499          loc:
12500            start:
12501              line: 2
12502              column: 2
12503            end:
12504              line: 3
12505              column: 5
12506        ]
12507        start: 12
12508        end: 25
12509        range: [12, 25]
12510        loc:
12511          start:
12512            line: 2
12513            column: 0
12514          end:
12515            line: 3
12516            column: 5
12517      start: 4
12518      end: 25
12519      range: [4, 25]
12520      loc:
12521        start:
12522          line: 1
12523          column: 4
12524        end:
12525          line: 3
12526          column: 5
12527    start: 0
12528    end: 25
12529    range: [0, 25]
12530    loc:
12531      start:
12532        line: 1
12533        column: 0
12534      end:
12535        line: 3
12536        column: 5
12537
12538  testAstLocationData '''
12539    class A
12540      @b: ->
12541      @c = ->
12542      @d: 1
12543      @e = 2
12544      A.f = 3
12545      A.g = ->
12546      this.h = ->
12547      this.i = 4
12548  ''',
12549    type: 'ClassDeclaration'
12550    id:
12551      start: 6
12552      end: 7
12553      range: [6, 7]
12554      loc:
12555        start:
12556          line: 1
12557          column: 6
12558        end:
12559          line: 1
12560          column: 7
12561    body:
12562      body: [
12563        key:
12564          start: 11
12565          end: 12
12566          range: [11, 12]
12567          loc:
12568            start:
12569              line: 2
12570              column: 3
12571            end:
12572              line: 2
12573              column: 4
12574        staticClassName:
12575          start: 10
12576          end: 11
12577          range: [10, 11]
12578          loc:
12579            start:
12580              line: 2
12581              column: 2
12582            end:
12583              line: 2
12584              column: 3
12585        start: 10
12586        end: 16
12587        range: [10, 16]
12588        loc:
12589          start:
12590            line: 2
12591            column: 2
12592          end:
12593            line: 2
12594            column: 8
12595      ,
12596        key:
12597          start: 20
12598          end: 21
12599          range: [20, 21]
12600          loc:
12601            start:
12602              line: 3
12603              column: 3
12604            end:
12605              line: 3
12606              column: 4
12607        staticClassName:
12608          start: 19
12609          end: 20
12610          range: [19, 20]
12611          loc:
12612            start:
12613              line: 3
12614              column: 2
12615            end:
12616              line: 3
12617              column: 3
12618        start: 19
12619        end: 26
12620        range: [19, 26]
12621        loc:
12622          start:
12623            line: 3
12624            column: 2
12625          end:
12626            line: 3
12627            column: 9
12628      ,
12629        key:
12630          start: 30
12631          end: 31
12632          range: [30, 31]
12633          loc:
12634            start:
12635              line: 4
12636              column: 3
12637            end:
12638              line: 4
12639              column: 4
12640        staticClassN
12640ame:
12641          start: 29
12642          end: 30
12643          range: [29, 30]
12644          loc:
12645            start:
12646              line: 4
12647              column: 2
12648            end:
12649              line: 4
12650              column: 3
12651        value:
12652          start: 33
12653          end: 34
12654          range: [33, 34]
12655          loc:
12656            start:
12657              line: 4
12658              column: 6
12659            end:
12660              line: 4
12661              column: 7
12662        start: 29
12663        end: 34
12664        range: [29, 34]
12665        loc:
12666          start:
12667            line: 4
12668            column: 2
12669          end:
12670            line: 4
12671            column: 7
12672      ,
12673        key:
12674          start: 38
12675          end: 39
12676          range: [38, 39]
12677          loc:
12678            start:
12679              line: 5
12680              column: 3
12681            end:
12682              line: 5
12683              column: 4
12684        staticClassName:
12685          start: 37
12686          end: 38
12687          range: [37, 38]
12688          loc:
12689            start:
12690              line: 5
12691              column: 2
12692            end:
12693              line: 5
12694              column: 3
12695        value:
12696          start: 42
12697          end: 43
12698          range: [42, 43]
12699          loc:
12700            start:
12701              line: 5
12702              column: 7
12703            end:
12704              line: 5
12705              column: 8
12706        start: 37
12707        end: 43
12708        range: [37, 43]
12709        loc:
12710          start:
12711            line: 5
12712            column: 2
12713          end:
12714            line: 5
12715            column: 8
12716      ,
12717        key:
12718          start: 48
12719          end: 49
12720          range: [48, 49]
12721          loc:
12722            start:
12723              line: 6
12724              column: 4
12725            end:
12726              line: 6
12727              column: 5
12728        staticClassName:
12729          start: 46
12730          end: 47
12731          range: [46, 47]
12732          loc:
12733            start:
12734              line: 6
12735              column: 2
12736            end:
12737              line: 6
12738              column: 3
12739        value:
12740          start: 52
12741          end: 53
12742          range: [52, 53]
12743          loc:
12744            start:
12745              line: 6
12746              column: 8
12747            end:
12748              line: 6
12749              column: 9
12750        start: 46
12751        end: 53
12752        range: [46, 53]
12753        loc:
12754          start:
12755            line: 6
12756            column: 2
12757          end:
12758            line: 6
12759            column: 9
12760      ,
12761        key:
12762          start: 58
12763          end: 59
12764          range: [58, 59]
12765          loc:
12766            start:
12767              line: 7
12768              column: 4
12769            end:
12770              line: 7
12771              column: 5
12772        staticClassName:
12773          start: 56
12774          end: 57
12775          range: [56, 57]
12776          loc:
12777            start:
12778              line: 7
12779              column: 2
12780            end:
12781              line: 7
12782              column: 3
12783        start: 56
12784        end: 64
12785        range: [56, 64]
12786        loc:
12787          start:
12788            line: 7
12789            column: 2
12790          end:
12791            line: 7
12792            column: 10
12793      ,
12794        key:
12795          start: 72
12796          end: 73
12797          range: [72, 73]
12798          loc:
12799            start:
12800              line: 8
12801              column: 7
12802            end:
12803              line: 8
12804              column: 8
12805        staticClassName:
12806          start: 67
12807          end: 71
12808          range: [67, 71]
12809          loc:
12810            start:
12811              line: 8
12812              column: 2
12813            end:
12814              line: 8
12815              column: 6
12816        start: 67
12817        end: 78
12818        range: [67, 78]
12819        loc:
12820          start:
12821            line: 8
12822            column: 2
12823          end:
12824            line: 8
12825            column: 13
12826      ,
12827        key:
12828          start: 86
12829          end: 87
12830          range: [86, 87]
12831          loc:
12832            start:
12833              line: 9
12834              column: 7
12835            end:
12836              line: 9
12837              column: 8
12838        staticClassName:
12839          start: 81
12840          end: 85
12841          range: [81, 85]
12842          loc:
12843            start:
12844              line: 9
12845              column: 2
12846            end:
12847              line: 9
12848              column: 6
12849        value:
12850          start: 90
12851          end: 91
12852          range: [90, 91]
12853          loc:
12854            start:
12855              line: 9
12856              column: 11
12857            end:
12858              line: 9
12859              column: 12
12860        start: 81
12861        end: 91
12862        range: [81, 91]
12863        loc:
12864          start:
12865            line: 9
12866            column: 2
12867          end:
12868            line: 9
12869            column: 12
12870      ]
12871      start: 8
12872      end: 91
12873      range: [8, 91]
12874      loc:
12875        start:
12876          line: 2
12877          column: 0
12878        end:
12879          line: 9
12880          column: 12
12881    start: 0
12882    end: 91
12883    range: [0, 91]
12884    loc:
12885      start:
12886        line: 1
12887        column: 0
12888      end:
12889        line: 9
12890        column: 12
12891
12892  testAstLocationData '''
12893    class A
12894      b: 1
12895      [c]: 2
12896  ''',
12897    type: 'ClassDeclaration'
12898    body:
12899      body: [
12900        key:
12901          start: 10
12902          end: 11
12903          range: [10, 11]
12904          loc:
12905            start:
12906              line: 2
12907              column: 2
12908            end:
12909              line: 2
12910              column: 3
12911        value:
12912          start: 13
12913          end: 14
12914          range: [13, 14]
12915          loc:
12916            start:
12917              line: 2
12918              column: 5
12919            end:
12920              line: 2
12921              column: 6
12922        start: 10
12923        end: 14
12924        range: [10, 14]
12925        loc:
12926          start:
12927            line: 2
12928            column: 2
12929          end:
12930            line: 2
12931            column: 6
12932      ,
12933        key:
12934          start: 18
12935          end: 19
12936          range: [18, 19]
12937          loc:
12938            start:
12939              line: 3
12940              column: 3
12941            end:
12942              line: 3
12943              column: 4
12944        value:
12945          start: 22
12946          end: 23
12947          range: [22, 23]
12948          loc:
12949            start:
12950              line: 3
12951              column: 7
12952            end:
12953              line: 3
12954              column: 8
12955        start: 17
12956        end: 23
12957        range: [17, 23]
12958        loc:
12959          start:
12960            line: 3
12961            column: 2
12962          end:
12963            line: 3
12964            column: 8
12965      ]
12966      start: 8
12967      end: 23
12968      range: [8, 23]
12969      loc:
12970        start:
12971          line: 2
12972          column: 0
12973        end:
12974          line: 3
12975          column: 8
12976    start: 0
12977    end: 23
12978    range: [0, 23]
12979    loc:
12980      start:
12981        line: 1
12982        column: 0
12983      end:
12984        line: 3
12985        column: 8
12986
12987  testAstLocationData '''
12988    class A
12989      @[b]: 1
12990      @[c]: ->
12991  ''',
12992    type: 'ClassDeclaration'
12993    body:
12994      body: [
12995        key:
12996          start: 12
12997          end: 13
12998          range: [12, 13]
12999          loc:
13000            start:
13001              line: 2
13002              column: 4
13003            end:
13004              line: 2
13005              column: 5
13006        staticClassName:
13007          start: 10
13008          end: 11
13009          range: [10, 11]
13010          loc:
13011            start:
13012              line: 2
13013              column: 2
13014            end:
13015              line: 2
13016              column: 3
13017        value:
13018          start: 16
13019          end: 17
13020          range: [16, 17]
13021          loc:
13022            start:
13023              line: 2
13024              column: 8
13025            end:
13026              line: 2
13027              column: 9
13028        start: 10
13029        end: 17
13030        range: [10, 17]
13031        loc:
13032          start:
13033            line: 2
13034            column: 2
13035          end:
13036            line: 2
13037            column: 9
13038      ,
13039        key:
13040          start: 22
13041          end: 23
13042          range: [22, 23]
13043          loc:
13044            start:
13045              line: 3
13046              column: 4
13047            end:
13048              line: 3
13049              column: 5
13050        staticClassName:
13051          start: 20
13052          end: 21
13053          range: [20, 21]
13054          loc:
13055            start:
13056              line: 3
13057              column: 2
13058            end:
13059              line: 3
13060              column: 3
13061        start: 20
13062        end: 28
13063        range: [20, 28]
13064        loc:
13065          start:
13066            line: 3
13067            column: 2
13068          end:
13069            line: 3
13070            column: 10
13071      ]
13072      start: 8
13073      end: 28
13074      range: [8, 28]
13075      loc:
13076        start:
13077          line: 2
13078          column: 0
13079        end:
13080          line: 3
13081          column: 10
13082    start: 0
13083    end: 28
13084    range: [0, 28]
13085    loc:
13086      start:
13087        line: 1
13088        column: 0
13089      end:
13090        line: 3
13091        column: 10
13092
13093  testAstLocationData '''
13094    class A
13095      b = 1
13096  ''',
13097    type: 'ClassDeclaration'
13098    body:
13099      body: [
13100        expression:
13101          left:
13102            start: 10
13103            end: 11
13104            range: [10, 11]
13105            loc:
13106              start:
13107                line: 2
13108                column: 2
13109              end:
13110                line: 2
13111                column: 3
13112          right:
13113            start: 14
13114            end: 15
13115            range: [14, 15]
13116            loc:
13117              start:
13118                line: 2
13119                column: 6
13120              end:
13121                line: 2
13122                column: 7
13123          start: 10
13124          end: 15
13125          range: [10, 15]
13126          loc:
13127            start:
13128              line: 2
13129              column: 2
13130            end:
13131              line: 2
13132              column: 7
13133        start: 10
13134        end: 15
13135        range: [10, 15]
13136        loc:
13137          start:
13138            line: 2
13139            column: 2
13140          end:
13141            line: 2
13142            column: 7
13143      ]
13144      start: 8
13145      end: 15
13146      range: [8, 15]
13147      loc:
13148        start:
13149          line: 2
13150          column: 0
13151        end:
13152          line: 2
13153          column: 7
13154    start: 0
13155    end: 15
13156    range: [0, 15]
13157    loc:
13158      start:
13159        line: 1
13160        column: 0
13161      end:
13162        line: 2
13163        column: 7
13164
13165test "AST location data as expected for directives", ->
13166  testAstRootLocationData '''
13167    'directive 1'
13168    'use strict'
13169    f()
13170  ''',
13171    type: 'File'
13172    program:
13173      body: [
13174        start: 27
13175        end: 30
13176        range: [27, 30]
13177        loc:
13178          start:
13179            line: 3
13180            column: 0
13181          end:
13182            line: 3
13183            column: 3
13184      ]
13185      directives: [
13186        start: 0
13187        end: 13
13188        range: [0, 13]
13189        loc:
13190          start:
13191            line: 1
13192            column: 0
13193          end:
13194            line: 1
13195            column: 13
13196      ,
13197        start: 14
13198        end: 26
13199        range: [14, 26]
13200        loc:
13201          start:
13202            line: 2
13203            column: 0
13204          end:
13205            line: 2
13206            column: 12
13207      ]
13208      start: 0
13209      end: 30
13210      range: [0, 30]
13211      loc:
13212        start:
13213          line: 1
13214          column: 0
13215        end:
13216          line: 3
13217          column: 3
13218    start: 0
13219    end: 30
13220    range: [0, 30]
13221    loc:
13222      start:
13223        line: 1
13224        column: 0
13225      end:
13226        line: 3
13227        column: 3
13228
13229  testAstRootLocationData '''
13230    'use strict'
13231  ''',
13232    type: 'File'
13233    program:
13234      directives: [
13235        start: 0
13236        end: 12
13237        range: [0, 12]
13238        loc:
13239          start:
13240            line: 1
13241            column: 0
13242          end:
13243            line: 1
13244            column: 12
13245      ]
13246      start: 0
13247      end: 12
13248      range: [0, 12]
13249      loc:
13250        start:
13251          line: 1
13252          column: 0
13253        end:
13254          line: 1
13255          column: 12
13256    start: 0
13257    end: 12
13258    range: [0, 12]
13259    loc:
13260      start:
13261        line: 1
13262        column: 0
13263      end:
13264        line: 1
13265        column: 12
13266
13267  testAstLocationData '''
13268    ->
13269      'use strict'
13270      f()
13271      'not a directive'
13272      g
13273  ''',
13274    type: 'FunctionExpression'
13275    body:
13276      directives: [
13277        value:
13278          start: 5
13279          end: 17
13280          range: [5, 17]
13281          loc:
13282            start:
13283              line: 2
13284              column: 2
13285            end:
13286              line: 2
13287              column: 14
13288        start: 5
13289        end: 17
13290        range: [5, 17]
13291        loc:
13292          start:
13293            line: 2
13294            column: 2
13295          end:
13296            line: 2
13297            column: 14
13298      ]
13299      start: 3
13300      end: 47
13301      range: [3, 47]
13302      loc:
13303        start:
13304          line: 2
13305          column: 0
13306        end:
13307          line: 5
13308          column: 3
13309    start: 0
13310    end: 47
13311    range: [0, 47]
13312    loc:
13313      start:
13314        line: 1
13315        column: 0
13316      end:
13317        line: 5
13318        column: 3
13319
13320  testAstLocationData '''
13321    class A
13322      'classes can have directives too'
13323      a: ->
13324  ''',
13325    type: 'ClassDeclaration'
13326    body:
13327      directives: [
13328        start: 10
13329        end: 43
13330        range: [10, 43]
13331        loc:
13332          start:
13333            line: 2
13334            column: 2
13335          end:
13336            line: 2
13337            column: 35
13338      ]
13339      start: 8
13340      end: 51
13341      range: [8, 51]
13342      loc:
13343        start:
13344          line: 2
13345          column: 0
13346        end:
13347          line: 3
13348          column: 7
13349    start: 0
13350    end: 51
13351    range: [0, 51]
13352    loc:
13353      start:
13354        line: 1
13355        column: 0
13356      end:
13357        line: 3
13358        column: 7
13359
13360test "AST location data as expected for PassthroughLiteral node", ->
13361  testAstLocationData "`abc`",
13362    type: 'PassthroughLiteral'
13363    start: 0
13364    end: 5
13365    range: [0, 5]
13366    loc:
13367      start:
13368        line: 1
13369        column: 0
13370      end:
13371        line: 1
13372        column: 5
13373
13374  code = '\nconst CONSTANT = "unreassignable!"\n'
13375  testAstLocationData """
13376    ```
13377      abc
13378    ```
13379  """,
13380    type: 'PassthroughLiteral'
13381    start: 0
13382    end: 13
13383    range: [0, 13]
13384    loc:
13385      start:
13386        line: 1
13387        column: 0
13388      end:
13389        line: 3
13390        column: 3
13391
13392  testAstLocationData "``",
13393    type: 'PassthroughLiteral'
13394    start: 0
13395    end: 2
13396    range: [0, 2]
13397    loc:
13398      start:
13399        line: 1
13400        column: 0
13401      end:
13402        line: 1
13403        column: 2
13404
13405test "AST location data as expected for comments", ->
13406  testAstCommentsLocationData '''
13407    a # simple line comment
13408  ''', [
13409    start: 2
13410    end: 23
13411    range: [2, 23]
13412    loc:
13413      start:
13414        line: 1
13415        column: 2
13416      end:
13417        line: 1
13418        column: 23
13419  ]
13420
13421  testAstCommentsLocationData '''
13422    a ### simple here comment ###
13423  ''', [
13424    start: 2
13425    end: 29
13426    range: [2, 29]
13427    loc:
13428      start:
13429        line: 1
13430        column: 2
13431      end:
13432        line: 1
13433        column: 29
13434  ]
13435
13436  testAstCommentsLocationData '''
13437    # just a line comment
13438  ''', [
13439    start: 0
13440    end: 21
13441    range: [0, 21]
13442    loc:
13443      start:
13444        line: 1
13445        column: 0
13446      end:
13447        line: 1
13448        column: 21
13449  ]
13450
13451  testAstCommentsLocationData '''
13452    ### just a here comment ###
13453  ''', [
13454    start: 0
13455    end: 27
13456    range: [0, 27]
13457    loc:
13458      start:
13459        line: 1
13460        column: 0
13461      end:
13462        line: 1
13463        column: 27
13464  ]
13465
13466  testAstCommentsLocationData '''
13467    "#{
13468      # empty interpolation line comment
13469     }"
13470  ''', [
13471    start: 6
13472    end: 40
13473    range: [6, 40]
13474    loc:
13475      start:
13476        line: 2
13477        column: 2
13478      end:
13479        line: 2
13480        column: 36
13481  ]
13482
13483  testAstCommentsLocationData '''
13484    "#{
13485      ### empty interpolation block comment ###
13486     }"
13487  ''', [
13488    start: 6
13489    end: 47
13490    range: [6, 47]
13491    loc:
13492      start:
13493        line: 2
13494        column: 2
13495      end:
13496        line: 2
13497        column: 43
13498  ]
13499
13500  testAstCommentsLocationData '''
13501    # multiple line comments
13502    # on consecutive lines
13503  ''', [
13504    start: 0
13505    end: 24
13506    range: [0, 24]
13507    loc:
13508      start:
13509        line: 1
13510        column: 0
13511      end:
13512        line: 1
13513        column: 24
13514  ,
13515    start: 25
13516    end: 47
13517    range: [25, 47]
13518    loc:
13519      start:
13520        line: 2
13521        column: 0
13522      end:
13523        line: 2
13524        column: 22
13525  ]
13526
13527  testAstCommentsLocationData '''
13528    # multiple line comments
13529
13530    # with blank line
13531  ''', [
13532    start: 0
13533    end: 24
13534    range: [0, 24]
13535    loc:
13536      start:
13537        line: 1
13538        column: 0
13539      end:
13540        line: 1
13541        column: 24
13542  ,
13543    start: 26
13544    end: 43
13545    range: [26, 43]
13546    loc:
13547      start:
13548        line: 3
13549        column: 0
13550      end:
13551        line: 3
13552        column: 17
13553  ]
13554
13555  testAstCommentsLocationData '''
13556    #no whitespace line comment
13557  ''', [
13558    start: 0
13559    end: 27
13560    range: [0, 27]
13561    loc:
13562      start:
13563        line: 1
13564        column: 0
13565      end:
13566        line: 1
13567        column: 27
13568  ]
13569
13570  testAstCommentsLocationData '''
13571 
13571   ###no whitespace here comment###
13572  ''', [
13573    start: 0
13574    end: 32
13575    range: [0, 32]
13576    loc:
13577      start:
13578        line: 1
13579        column: 0
13580      end:
13581        line: 1
13582        column: 32
13583  ]
13584
13585  testAstCommentsLocationData '''
13586    ###
13587    # multiline
13588    # here comment
13589    ###
13590  ''', [
13591    start: 0
13592    end: 34
13593    range: [0, 34]
13594    loc:
13595      start:
13596        line: 1
13597        column: 0
13598      end:
13599        line: 4
13600        column: 3
13601  ]
13602
13603  testAstCommentsLocationData '''
13604    if b
13605      ###
13606      # multiline
13607      # indented here comment
13608      ###
13609      c
13610  ''', [
13611    start: 7
13612    end: 56
13613    range: [7, 56]
13614    loc:
13615      start:
13616        line: 2
13617        column: 2
13618      end:
13619        line: 5
13620        column: 5
13621  ]
13622
13623test "AST location data as expected for chained comparisons", ->
13624  testAstLocationData '''
13625    a >= b < c
13626  ''',
13627    type: 'ChainedComparison'
13628    operands: [
13629      start: 0
13630      end: 1
13631      range: [0, 1]
13632      loc:
13633        start:
13634          line: 1
13635          column: 0
13636        end:
13637          line: 1
13638          column: 1
13639    ,
13640      start: 5
13641      end: 6
13642      range: [5, 6]
13643      loc:
13644        start:
13645          line: 1
13646          column: 5
13647        end:
13648          line: 1
13649          column: 6
13650    ,
13651      start: 9
13652      end: 10
13653      range: [9, 10]
13654      loc:
13655        start:
13656          line: 1
13657          column: 9
13658        end:
13659          line: 1
13660          column: 10
13661    ]
13662    start: 0
13663    end: 10
13664    range: [0, 10]
13665    loc:
13666      start:
13667        line: 1
13668        column: 0
13669      end:
13670        line: 1
13671        column: 10
13672
13673test "AST location data as expected for Sequence", ->
13674  testAstLocationData '''
13675    (a; b)
13676  ''',
13677    type: 'SequenceExpression'
13678    expressions: [
13679      start: 1
13680      end: 2
13681      range: [1, 2]
13682      loc:
13683        start:
13684          line: 1
13685          column: 1
13686        end:
13687          line: 1
13688          column: 2
13689    ,
13690      start: 4
13691      end: 5
13692      range: [4, 5]
13693      loc:
13694        start:
13695          line: 1
13696          column: 4
13697        end:
13698          line: 1
13699          column: 5
13700    ]
13701    start: 1
13702    end: 5
13703    range: [1, 5]
13704    loc:
13705      start:
13706        line: 1
13707        column: 1
13708      end:
13709        line: 1
13710        column: 5
13711
13712  testAstLocationData '''
13713    (a; b)""
13714  ''',
13715    type: 'TaggedTemplateExpression'
13716    tag:
13717      expressions: [
13718        start: 1
13719        end: 2
13720        range: [1, 2]
13721        loc:
13722          start:
13723            line: 1
13724            column: 1
13725          end:
13726            line: 1
13727            column: 2
13728      ,
13729        start: 4
13730        end: 5
13731        range: [4, 5]
13732        loc:
13733          start:
13734            line: 1
13735            column: 4
13736          end:
13737            line: 1
13738            column: 5
13739      ]
13740      start: 1
13741      end: 5
13742      range: [1, 5]
13743      loc:
13744        start:
13745          line: 1
13746          column: 1
13747        end:
13748          line: 1
13749          column: 5
13750    start: 0
13751    end: 8
13752    range: [0, 8]
13753    loc:
13754      start:
13755        line: 1
13756        column: 0
13757      end:
13758        line: 1
13759        column: 8
13760
13761test "AST location data as expected for blocks with comments", ->
13762  # trailing indented comment
13763  testAstLocationData '''
13764    ->
13765      a
13766      # b
13767  ''',
13768    type: 'FunctionExpression'
13769    body:
13770      start: 3
13771      end: 12
13772      range: [3, 12]
13773      loc:
13774        start:
13775          line: 2
13776          column: 0
13777        end:
13778          line: 3
13779          column: 5
13780    start: 0
13781    end: 12
13782    range: [0, 12]
13783    loc:
13784      start:
13785        line: 1
13786        column: 0
13787      end:
13788        line: 3
13789        column: 5
13790
13791  testAstLocationData '''
13792    if a
13793      b
13794      ### c ###
13795  ''',
13796    type: 'IfStatement'
13797    consequent:
13798      start: 5
13799      end: 20
13800      range: [5, 20]
13801      loc:
13802        start:
13803          line: 2
13804          column: 0
13805        end:
13806          line: 3
13807          column: 11
13808    start: 0
13809    end: 20
13810    range: [0, 20]
13811    loc:
13812      start:
13813        line: 1
13814        column: 0
13815      end:
13816        line: 3
13817        column: 11
13818
13819  # trailing non-indented comment
13820  testAstLocationData '''
13821    ->
13822      a
13823    # b
13824  ''',
13825    type: 'FunctionExpression'
13826    body:
13827      start: 3
13828      end: 6
13829      range: [3, 6]
13830      loc:
13831        start:
13832          line: 2
13833          column: 0
13834        end:
13835          line: 2
13836          column: 3
13837    start: 0
13838    end: 6
13839    range: [0, 6]
13840    loc:
13841      start:
13842        line: 1
13843        column: 0
13844      end:
13845        line: 2
13846        column: 3
13847
13848  testAstLocationData '''
13849    if a
13850      b
13851    ### c ###
13852  ''',
13853    type: 'IfStatement'
13854    consequent:
13855      start: 5
13856      end: 8
13857      range: [5, 8]
13858      loc:
13859        start:
13860          line: 2
13861          column: 0
13862        end:
13863          line: 2
13864          column: 3
13865    start: 0
13866    end: 8
13867    range: [0, 8]
13868    loc:
13869      start:
13870        line: 1
13871        column: 0
13872      end:
13873        line: 2
13874        column: 3
13875
13876  # multiple trailing indented comments
13877  testAstLocationData '''
13878    class A
13879      a: ->
13880      # b
13881      #comment
13882  ''',
13883    type: 'ClassDeclaration'
13884    body:
13885      start: 8
13886      end: 32
13887      range: [8, 32]
13888      loc:
13889        start:
13890          line: 2
13891          column: 0
13892        end:
13893          line: 4
13894          column: 10
13895    start: 0
13896    end: 32
13897    range: [0, 32]
13898    loc:
13899      start:
13900        line: 1
13901        column: 0
13902      end:
13903        line: 4
13904        column: 10
13905
13906  testAstLocationData '''
13907    a = ->
13908      c
13909      # b
13910      ### comment ###
13911  ''',
13912    type: 'AssignmentExpression'
13913    right:
13914      start: 4
13915      end: 34
13916      range: [4, 34]
13917      loc:
13918        start:
13919          line: 1
13920          column: 4
13921        end:
13922          line: 4
13923          column: 17
13924    start: 0
13925    end: 34
13926    range: [0, 34]
13927    loc:
13928      start:
13929        line: 1
13930        column: 0
13931      end:
13932        line: 4
13933        column: 17
13934
13935  # multiple trailing comments, some indented
13936  testAstLocationData '''
13937    class A
13938      a: ->
13939      # b
13940    #comment
13941  ''',
13942    type: 'ClassDeclaration'
13943    body:
13944      start: 8
13945      end: 21
13946      range: [8, 21]
13947      loc:
13948        start:
13949          line: 2
13950          column: 0
13951        end:
13952          line: 3
13953          column: 5
13954    start: 0
13955    end: 21
13956    range: [0, 21]
13957    loc:
13958      start:
13959        line: 1
13960        column: 0
13961      end:
13962        line: 3
13963        column: 5
13964
13965  # leading indented comment
13966  testAstLocationData '''
13967    ->
13968      # a
13969      b
13970  ''',
13971    type: 'FunctionExpression'
13972    body:
13973      start: 3
13974      end: 12
13975      range: [3, 12]
13976      loc:
13977        start:
13978          line: 2
13979          column: 0
13980        end:
13981          line: 3
13982          column: 3
13983    start: 0
13984    end: 12
13985    range: [0, 12]
13986    loc:
13987      start:
13988        line: 1
13989        column: 0
13990      end:
13991        line: 3
13992        column: 3
13993
13994  testAstLocationData '''
13995    if a
13996      ### b ###
13997      c
13998  ''',
13999    type: 'IfStatement'
14000    consequent:
14001      start: 5
14002      end: 20
14003      range: [5, 20]
14004      loc:
14005        start:
14006          line: 2
14007          column: 0
14008        end:
14009          line: 3
14010          column: 3
14011    start: 0
14012    end: 20
14013    range: [0, 20]
14014    loc:
14015      start:
14016        line: 1
14017        column: 0
14018      end:
14019        line: 3
14020        column: 3
14021
14022  # multiple leading indented comments
14023  testAstLocationData '''
14024    ->
14025      # a
14026      # b
14027      c
14028  ''',
14029    type: 'FunctionExpression'
14030    body:
14031      start: 3
14032      end: 18
14033      range: [3, 18]
14034      loc:
14035        start:
14036          line: 2
14037          column: 0
14038        end:
14039          line: 4
14040          column: 3
14041    start: 0
14042    end: 18
14043    range: [0, 18]
14044    loc:
14045      start:
14046        line: 1
14047        column: 0
14048      end:
14049        line: 4
14050        column: 3
14051
14052  testAstLocationData '''
14053    if a
14054      ### b ###
14055      # c
14056      d
14057  ''',
14058    type: 'IfStatement'
14059    consequent:
14060      start: 5
14061      end: 26
14062      range: [5, 26]
14063      loc:
14064        start:
14065          line: 2
14066          column: 0
14067        end:
14068          line: 4
14069          column: 3
14070    start: 0
14071    end: 26
14072    range: [0, 26]
14073    loc:
14074      start:
14075        line: 1
14076        column: 0
14077      end:
14078        line: 4
14079        column: 3
14080
14081  # just a comment
14082  testAstLocationData '''
14083    ->
14084      # a
14085  ''',
14086    type: 'FunctionExpression'
14087    body:
14088      start: 3
14089      end: 8
14090      range: [3, 8]
14091      loc:
14092        start:
14093          line: 2
14094          column: 0
14095        end:
14096          line: 2
14097          column: 5
14098    start: 0
14099    end: 8
14100    range: [0, 8]
14101    loc:
14102      start:
14103        line: 1
14104        column: 0
14105      end:
14106        line: 2
14107        column: 5
14108
14109  testAstLocationData '''
14110    if a
14111      ### b ###
14112    else
14113      c
14114  ''',
14115    type: 'IfStatement'
14116    consequent:
14117      start: 5
14118      end: 16
14119      range: [5, 16]
14120      loc:
14121        start:
14122          line: 2
14123          column: 0
14124        end:
14125          line: 2
14126          column: 11
14127    start: 0
14128    end: 25
14129    range: [0, 25]
14130    loc:
14131      start:
14132        line: 1
14133        column: 0
14134      end:
14135        line: 4
14136        column: 3
14137
14138  # just a non-indented comment
14139  testAstLocationData '''
14140    ->
14141    # a
14142  ''',
14143    type: 'FunctionExpression'
14144    body:
14145      start: 2
14146      end: 2
14147      range: [2, 2]
14148      loc:
14149        start:
14150          line: 1
14151          column: 2
14152        end:
14153          line: 1
14154          column: 2
14155    start: 0
14156    end: 2
14157    range: [0, 2]
14158    loc:
14159      start:
14160        line: 1
14161        column: 0
14162      end:
14163        line: 1
14164        column: 2
14165
14166  # nested dedented comment
14167  testAstLocationData '''
14168    switch a
14169      when b
14170        c
14171      # d
14172  ''',
14173    type: 'SwitchStatement'
14174    cases: [
14175      start: 11
14176      end: 23
14177      range: [11, 23]
14178      loc:
14179        start:
14180          line: 2
14181          column: 2
14182        end:
14183          line: 3
14184          column: 5
14185    ]
14186    start: 0
14187    end: 29
14188    range: [0, 29]
14189    loc:
14190      start:
14191        line: 1
14192        column: 0
14193      end:
14194        line: 4
14195        column: 5
14196
14197  # trailing implicit call in condition followed by indented comment
14198  testAstLocationData '''
14199    if a b
14200      # c
14201      d
14202  ''',
14203    type: 'IfStatement'
14204    test:
14205      start: 3
14206      end: 6
14207      range: [3, 6]
14208      loc:
14209        start:
14210          line: 1
14211          column: 3
14212        end:
14213          line: 1
14214          column: 6
14215    consequent:
14216      start: 7
14217      end: 16
14218      range: [7, 16]
14219      loc:
14220        start:
14221          line: 2
14222          column: 0
14223        end:
14224          line: 3
14225          column: 3
14226    start: 0
14227    end: 16
14228    range: [0, 16]
14229    loc:
14230      start:
14231        line: 1
14232        column: 0
14233      end:
14234        line: 3
14235        column: 3
14236
14237test "AST location data as expected for heregex comments", ->
14238  code = '''
14239    ///
14240      a # b
14241    ///
14242  '''
14243
14244  testAstLocationData code,
14245    type: 'RegExpLiteral'
14246    start: 0
14247    end: 15
14248    range: [0, 15]
14249    loc:
14250      start:
14251        line: 1
14252        column: 0
14253      end:
14254        line: 3
14255        column: 3
14256
14257  eq getAstRoot(code).comments.length, 0
14258
14259test "AST location data as expected with carriage returns", ->
14260  code = '''
14261    a =\r
14262    "#{\r
14263      b\r
14264    }"
14265  '''
14266
14267  testAstLocationData code,
14268    type: 'AssignmentExpression'
14269    right:
14270      expressions: [
14271        start: 12
14272        end: 13
14273        range: [12, 13]
14274        loc:
14275          start:
14276            line: 3
14277            column: 2
14278          end:
14279            line: 3
14280            column: 3
14281      ]
14282      quasis: [
14283        start: 6
14284        end: 6
14285        range: [6, 6]
14286        loc:
14287          start:
14288            line: 2
14289            column: 1
14290          end:
14291            line: 2
14292            column: 1
14293      ,
14294        start: 16
14295        end: 16
14296        range: [16, 16]
14297        loc:
14298          start:
14299            line: 4
14300            column: 1
14301          end:
14302            line: 4
14303            column: 1
14304      ]
14305      start: 5
14306      end: 17
14307      range: [5, 17]
14308      loc:
14309        start:
14310          line: 2
14311          column: 0
14312        end:
14313          line: 4
14314          column: 2
14315    start: 0
14316    end: 17
14317    range: [0, 17]
14318    loc:
14319      start:
14320        line: 1
14321        column: 0
14322      end:
14323        line: 4
14324        column: 2
14325
14326</script>
vendor: 1 bytes, line 14326
14326
14327<script type="text/x-coffeescript" class="test" id="argument_parsing">
14328return unless require?
14329{buildCSOptionParser} = require '../lib/coffeescript/command'
14330
14331optionParser = buildCSOptionParser()
14332
14333sameOptions = (opts1, opts2, msg) ->
14334  ownKeys = Object.keys(opts1).sort()
14335  otherKeys = Object.keys(opts2).sort()
14336  arrayEq ownKeys, otherKeys, msg
14337  for k in ownKeys
14338    arrayEq opts1[k], opts2[k], msg
14339  yes
14340
14341test "combined options are not split after initial file name", ->
14342  argv = ['some-file.coffee', '-bc']
14343  parsed = optionParser.parse argv
14344  expected = arguments: ['some-file.coffee', '-bc']
14345  sameOptions parsed, expected
14346
14347  argv = ['some-file.litcoffee', '-bc']
14348  parsed = optionParser.parse argv
14349  expected = arguments: ['some-file.litcoffee', '-bc']
14350  sameOptions parsed, expected
14351
14352  argv = ['-c', 'some-file.coffee', '-bc']
14353  parsed = optionParser.parse argv
14354  expected =
14355    compile: yes
14356    arguments: ['some-file.coffee', '-bc']
14357  sameOptions parsed, expected
14358
14359  argv = ['-bc', 'some-file.coffee', '-bc']
14360  parsed = optionParser.parse argv
14361  expected =
14362    bare: yes
14363    compile: yes
14364    arguments: ['some-file.coffee', '-bc']
14365  sameOptions parsed, expected
14366
14367test "combined options are not split after a '--', which is discarded", ->
14368  argv = ['--', '-bc']
14369  parsed = optionParser.parse argv
14370  expected =
14371    doubleDashed: yes
14372    arguments: ['-bc']
14373  sameOptions parsed, expected
14374
14375  argv = ['-bc', '--', '-bc']
14376  parsed = optionParser.parse argv
14377  expected =
14378    bare: yes
14379    compile: yes
14380    doubleDashed: yes
14381    arguments: ['-bc']
14382  sameOptions parsed, expected
14383
14384test "options are not split after any '--'", ->
14385  argv = ['--', '--', '-bc']
14386  parsed = optionParser.parse argv
14387  expected =
14388    doubleDashed: yes
14389    arguments: ['--', '-bc']
14390  sameOptions parsed, expected
14391
14392  argv = ['--', 'some-file.coffee', '--', 'arg']
14393  parsed = optionParser.parse argv
14394  expected =
14395    doubleDashed: yes
14396    arguments: ['some-file.coffee', '--', 'arg']
14397  sameOptions parsed, expected
14398
14399  argv = ['--', 'arg', 'some-file.coffee', '--', '-bc']
14400  parsed = optionParser.parse argv
14401  expected =
14402    doubleDashed: yes
14403    arguments: ['arg', 'some-file.coffee', '--', '-bc']
14404  sameOptions parsed, expected
14405
14406test "any non-option argument stops argument parsing", ->
14407  argv = ['arg', '-bc']
14408  parsed = optionParser.parse argv
14409  expected = arguments: ['arg', '-bc']
14410  sameOptions parsed, expected
14411
14412test "later '--' are not removed", ->
14413  argv = ['some-file.coffee', '--', '-bc']
14414  parsed = optionParser.parse argv
14415  expected = arguments: ['some-file.coffee', '--', '-bc']
14416  sameOptions parsed, expected
14417
14418test "throw on invalid options", ->
14419  argv = ['-k']
14420  throws -> optionParser.parse argv
14421
14422  argv = ['-ck']
14423  throws (-> optionParser.parse argv), /multi-flag/
14424
14425  argv = ['-kc']
14426  throws (-> optionParser.parse argv), /multi-flag/
14427
14428  argv = ['-oc']
14429  throws (-> optionParser.parse argv), /needs an argument/
14430
14431  argv = ['-o']
14432  throws (-> optionParser.parse argv), /value required/
14433
14434  argv = ['-co']
14435  throws (-> optionParser.parse argv), /value required/
14436
14437  # Check if all flags in a multi-flag are recognized before checking if flags
14438  # before the last need arguments.
14439  argv = ['-ok']
14440  throws (-> optionParser.parse argv), /unrecognized option/
14441
14442test "has expected help text", ->
14443  ok optionParser.help() is '''
14444
14445Usage: coffee [options] path/to/script.coffee [args]
14446
14447If called without options, `coffee` will run your script.
14448
14449      --ast          generate an abstract syntax tree of nodes
14450  -b, --bare         compile without a top-level function wrapper
14451  -c, --compile      compile to JavaScript and save as .js files
14452  -e, --eval         pass a string from the command line as input
14453  -h, --help         display this help message
14454  -i, --interactive  run an interactive CoffeeScript REPL
14455  -j, --join         concatenate the source CoffeeScript before compiling
14456  -l, --literate     treat stdio as literate style coffeescript
14457  -m, --map          generate source map and save as .js.map files
14458  -M, --inline-map   generate source map and include it directly in output
14459  -n, --nodes        print out the parse tree that the parser produces
14460      --nodejs       pass options directly to the "node" binary
14461      --no-header    suppress the "Generated by" header
14462  -o, --output       set the output path or path/filename for compiled JavaScript
14463  -p, --print        print out the compiled JavaScript
14464  -r, --require      require the given module before eval or REPL
14465  -s, --stdio        listen for and compile scripts over stdio
14466  -t, --transpile    pipe generated JavaScript through Babel
14467      --tokens       print out the tokens that the lexer/rewriter produce
14468  -v, --version      display the version number
14469  -w, --watch        watch scripts for changes and rerun commands
14470
14471  '''
14472
14473</script>
vendor: 1 bytes, line 14473
14473
14474<script type="text/x-coffeescript" class="test" id="arrays">
14475# Array Literals
14476# --------------
14477
14478# * Array Literals
14479# * Splats in Array Literals
14480
14481# TODO: add indexing and method invocation tests: [1][0] is 1, [].toString()
14482
14483test "trailing commas", ->
14484  trailingComma = [1, 2, 3,]
14485  ok (trailingComma[0] is 1) and (trailingComma[2] is 3) and (trailingComma.length is 3)
14486
14487  trailingComma = [
14488    1, 2, 3,
14489    4, 5, 6
14490    7, 8, 9,
14491  ]
14492  (sum = (sum or 0) + n) for n in trailingComma
14493
14494  a = [((x) -> x), ((x) -> x * x)]
14495  ok a.length is 2
14496
14497test "incorrect indentation without commas", ->
14498  result = [['a']
14499   {b: 'c'}]
14500  ok result[0][0] is 'a'
14501  ok result[1]['b'] is 'c'
14502
14503# Elisions
14504test "array elisions", ->
14505  eq [,1].length, 2
14506  eq [,,1,2,,].length, 5
14507  arr = [1,,2]
14508  eq arr.length, 3
14509  eq arr[1], undefined
14510  eq [,,].length, 2
14511
14512test "array elisions indentation and commas", ->
14513  arr1 = [
14514    , 1, 2, , , 3,
14515    4, 5, 6
14516    , , 8, 9,
14517  ]
14518  eq arr1.length, 12
14519  eq arr1[5], 3
14520  eq arr1[9], undefined
14521  arr2 = [, , 1,
14522    2, , 3,
14523    , 4, 5
14524    6
14525    , , ,
14526  ]
14527  eq arr2.length, 12
14528  eq arr2[8], 5
14529  eq arr2[1], undefined
14530
14531test "array elisions destructuring", ->
14532  arr = [1,2,3,4,5,6,7,8,9]
14533  [,a] = arr
14534  [,,,b] = arr
14535  arrayEq [a,b], [2,4]
14536  [,a,,b,,c,,,d] = arr
14537  arrayEq [a,b,c,d], [2,4,6,9]
14538  [
14539    ,e,
14540    ,f,
14541    ,g,
14542    ,,h] = arr
14543  arrayEq [e,f,g,h], [2,4,6,9]
14544
14545test "array elisions destructuring with splats and expansions", ->
14546  arr = [1,2,3,4,5,6,7,8,9]
14547  [,a,,,b...] = arr
14548  arrayEq [a,b], [2,[5,6,7,8,9]]
14549  [,c,...,,d,,e] = arr
14550  arrayEq [c,d,e], [2,7,9]
14551  [...,f,,,g,,,] = arr
14552  arrayEq [f,g], [4,7]
14553
14554test "array elisions as function parameters", ->
14555  arr = [1,2,3,4,5,6,7,8,9]
14556  foo = ([,a]) -> a
14557  a = foo arr
14558  eq a, 2
14559  foo = ([,,,a]) -> a
14560  a = foo arr
14561  eq a, 4
14562  foo = ([,a,,b,,c,,,d]) -> [a,b,c,d]
14563  [a,b,c,d] = foo arr
14564  arrayEq [a,b,c,d], [2,4,6,9]
14565
14566test "array elisions nested destructuring", ->
14567  arr = [
14568    1,
14569    [2,3, [4,5,6, [7,8,9] ] ]
14570  ]
14571  [,a] = arr
14572  arrayEq a[2][3], [7,8,9]
14573  [,[,,[,b,,[,,c]]]] = arr
14574  eq b, 5
14575  eq c, 9
14576  aobj = [
14577    {},
14578    {x: 2},
14579    {},
14580    [
14581      {},
14582      {},
14583      {z:1, w:[1,2,4], p:3, q:4}
14584      {},
14585      {}
14586    ]
14587  ]
14588  [,d,,[,,{w}]] = aobj
14589  deepEqual d, {x:2}
14590  arrayEq w, [1,2,4]
14591
14592test "#5112: array elisions not detected inside strings", ->
14593  arr = [
14594    str: ", #{3}"
14595  ]
14596  eq arr[0].str, ', 3'
14597
14598# Splats in Array Literals
14599
14600test "array splat expansions with assignments", ->
14601  nums = [1, 2, 3]
14602  list = [a = 0, nums..., b = 4]
14603  eq 0, a
14604  eq 4, b
14605  arrayEq [0,1,2,3,4], list
14606
14607
14608test "mixed shorthand objects in array lists", ->
14609  arr = [
14610    a:1
14611    'b'
14612    c:1
14613  ]
14614  ok arr.length is 3
14615  ok arr[2].c is 1
14616
14617  arr = [b: 1, a: 2, 100]
14618  eq arr[1], 100
14619
14620  arr = [a:0, b:1, (1 + 1)]
14621  eq arr[1], 2
14622
14623  arr = [a:1, 'a', b:1, 'b']
14624  eq arr.length, 4
14625  eq arr[2].b, 1
14626  eq arr[3], 'b'
14627
14628test "array splats with nested arrays", ->
14629  nonce = {}
14630  a = [nonce]
14631  list = [1, 2, a...]
14632  eq list[0], 1
14633  eq list[2], nonce
14634
14635  a = [[nonce]]
14636  list = [1, 2, a...]
14637  arrayEq list, [1, 2, [nonce]]
14638
14639test "#4260: splat after existential operator soak", ->
14640  a = {b: [3]}
14641  foo = (a) -> [a]
14642  arrayEq [a?.b...], [3]
14643  arrayEq [c?.b ? []...], []
14644  arrayEq [...a?.b], [3]
14645  arrayEq [...c?.b ? []], []
14646  arrayEq foo(a?.b...), [3]
14647  arrayEq foo(...a?.b), [3]
14648  arrayEq foo(c?.b ? []...), [undefined]
14649  arrayEq foo(...c?.b ? []), [undefined]
14650  e = yes
14651  f = null
14652  arrayEq [(a if e)?.b...], [3]
14653  arrayEq [(a if f)?.b ? []...], []
14654  arrayEq [...(a if e)?.b], [3]
14655  arrayEq [...(a if f)?.b ? []], []
14656  arrayEq foo((a if e)?.b...), [3]
14657  arrayEq foo(...(a if e)?.b), [3]
14658  arrayEq foo((a if f)?.b ? []...), [undefined]
14659  arrayEq foo(...(a if f)?.b ? []), [undefined]
14660
14661  # Should not trigger implicit call, e.g. rest ... => rest(...)
14662  arrayEq [... a?.b], [3]
14663  arrayEq [... c?.b ? []], []
14664  arrayEq [a?.b ...], [3]
14665  arrayEq [(a if e)?.b ...], [3]
14666  arrayEq foo(a?.b ...), [3]
14667  arrayEq foo(... a?.b), [3]
14668
14669test "#1349: trailing if after splat", ->
14670  a = [3]
14671  b = yes
14672  c = null
14673  foo = (a) -> [a]
14674  arrayEq [a if b...], [3]
14675  arrayEq [(a if c) ? []...], []
14676  arrayEq [...a if b], [3]
14677  arrayEq [...(a if c) ? []], []
14678  arrayEq foo((a if b)...), [3]
14679  arrayEq foo(...(a if b)), [3]
14680  arrayEq foo((a if c) ? []...), [undefined]
14681  arrayEq foo(...(a if c) ? []), [undefined]
14682
14683  # Should not trigger implicit call, e.g. rest ... => rest(...)
14684  arrayEq [... a if b], [3]
14685  arrayEq [a if b ...], [3]
14686
14687test "#1274: `[] = a()` compiles to `false` instead of `a()`", ->
14688  a = false
14689  fn = -> a = true
14690  [] = fn()
14691  ok a
14692
14693test "#3194: string interpolation in array", ->
14694  arr = [ "a"
14695          key: 'value'
14696        ]
14697  eq 2, arr.length
14698  eq 'a', arr[0]
14699  eq 'value', arr[1].key
14700
14701  b = 'b'
14702  arr = [ "a#{b}"
14703          key: 'value'
14704        ]
14705  eq 2, arr.length
14706  eq 'ab', arr[0]
14707  eq 'value', arr[1].key
14708
14709test "regex interpolation in array", ->
14710  arr = [ /a/
14711          key: 'value'
14712        ]
14713  eq 2, arr.length
14714  eq 'a', arr[0].source
14715  eq 'value', arr[1].key
14716
14717  b = 'b'
14718  arr = [ ///a#{b}///
14719          key: 'value'
14720        ]
14721  eq 2, arr.length
14722  eq 'ab', arr[0].source
14723  eq 'value', arr[1].key
14724
14725test "splat extraction from generators", ->
14726  gen = ->
14727    yield 1
14728    yield 2
14729    yield 3
14730  arrayEq [ gen()... ], [ 1, 2, 3 ]
14731
14732test "for-from loops over Array", ->
14733  array1 = [50, 30, 70, 20]
14734  array2 = []
14735  for x from array1
14736    array2.push(x)
14737  arrayEq array1, array2
14738
14739  array1 = [[20, 30], [40, 50]]
14740  array2 = []
14741  for [a, b] from array1
14742    array2.push(b)
14743    array2.push(a)
14744  arrayEq array2, [30, 20, 50, 40]
14745
14746  array1 = [{a: 10, b: 20, c: 30}, {a: 40, b: 50, c: 60}]
14747  array2 = []
14748  for {a: a, b, c: d} from array1
14749    array2.push([a, b, d])
14750  arrayEq array2, [[10, 20, 30], [40, 50, 60]]
14751
14752  array1 = [[10, 20, 30, 40, 50]]
14753  for [a, b..., c] from array1
14754    eq 10, a
14755    arrayEq [20, 30, 40], b
14756    eq 50, c
14757
14758test "for-from comprehensions over Array", ->
14759  array1 = (x + 10 for x from [10, 20, 30])
14760  ok array1.join(' ') is '20 30 40'
14761
14762  array2 = (x for x from [30, 41, 57] when x %% 3 is 0)
14763  ok array2.join(' ') is '30 57'
14764
14765  array1 = (b + 5 for [a, b] from [[20, 30], [40, 50]])
14766  ok array1.join(' ') is '35 55'
14767
14768  array2 = (a + b for [a, b] from [[10, 20], [30, 40], [50, 60]] when a + b >= 70)
14769  ok array2.join(' ') is '70 110'
14770
14771test "#5201: simple indented elisions", ->
14772  arr1 = [
14773    ,
14774    1,
14775    2,
14776    ,
14777    ,
14778    3,
14779    4,
14780    5,
14781    6
14782    ,
14783    ,
14784    8,
14785    9,
14786  ]
14787  eq arr1.length, 12
14788  eq arr1[5], 3
14789  eq arr1[9], undefined
14790
14791  arr2 = [
14792    ,
14793    ,
14794    1,
14795    2,
14796    ,
14797    3,
14798    ,
14799    4,
14800    5
14801    6
14802    ,
14803    ,
14804    ,
14805  ]
14806  eq arr2.length, 12
14807  eq arr2[8], 5
14808  eq arr2[1], undefined
14809
14810  arr3 = [
14811    ,
14812    ,
14813    ,
14814  ]
14815  eq arr3.length, 3
14816
14817  arr4 = [, , ,]
14818  eq arr4.length, 3
14819
14820</script>
vendor: 1 bytes, line 14820
14820
14821<script type="text/x-coffeescript" class="test" id="assignment">
14822# Assignment
14823# ----------
14824
14825# * Assignment
14826# * Compound Assignment
14827# * Destructuring Assignment
14828# * Context Property (@) Assignment
14829# * Existential Assignment (?=)
14830# * Assignment to variables similar to generated variables
14831
14832test "context property assignment (using @)", ->
14833  nonce = {}
14834  addMethod = ->
14835    @method = -> nonce
14836    this
14837  eq nonce, addMethod.call({}).method()
14838
14839test "unassignable values", ->
14840  nonce = {}
14841  for nonref in ['', '""', '0', 'f()'].concat CoffeeScript.RESERVED
14842    eq nonce, (try CoffeeScript.compile "#{nonref} = v" catch e then nonce)
14843
14844# Compound Assignment
14845
14846test "boolean operators", ->
14847  nonce = {}
14848
14849  a  = 0
14850  a or= nonce
14851  eq nonce, a
14852
14853  b  = 1
14854  b or= nonce
14855  eq 1, b
14856
14857  c = 0
14858  c and= nonce
14859  eq 0, c
14860
14861  d = 1
14862  d and= nonce
14863  eq nonce, d
14864
14865  # ensure that RHS is treated as a group
14866  e = f = false
14867  e and= f or true
14868  eq false, e
14869
14870test "compound assignment as a sub expression", ->
14871  [a, b, c] = [1, 2, 3]
14872  eq 6, (a + b += c)
14873  eq 1, a
14874  eq 5, b
14875  eq 3, c
14876
14877# *note: this test could still use refactoring*
14878test "compound assignment should be careful about caching variables", ->
14879  count = 0
14880  list = []
14881
14882  list[++count] or= 1
14883  eq 1, list[1]
14884  eq 1, count
14885
14886  list[++count] ?= 2
14887  eq 2, list[2]
14888  eq 2, count
14889
14890  list[count++] and= 6
14891  eq 6, list[2]
14892  eq 3, count
14893
14894  base = ->
14895    ++count
14896    base
14897
14898  base().four or= 4
14899  eq 4, base.four
14900  eq 4, count
14901
14902  base().five ?= 5
14903  eq 5, base.five
14904  eq 5, count
14905
14906  eq 5, base().five ?= 6
14907  eq 6, count
14908
14909test "compound assignment with implicit objects", ->
14910  obj = undefined
14911  obj ?=
14912    one: 1
14913
14914  eq 1, obj.one
14915
14916  obj and=
14917    two: 2
14918
14919  eq undefined, obj.one
14920  eq         2, obj.two
14921
14922test "compound assignment (math operators)", ->
14923  num = 10
14924  num -= 5
14925  eq 5, num
14926
14927  num *= 10
14928  eq 50, num
14929
14930  num /= 10
14931  eq 5, num
14932
14933  num %= 3
14934  eq 2, num
14935
14936test "more compound assignment", ->
14937  a = {}
14938  val = undefined
14939  val ||= a
14940  val ||= true
14941  eq a, val
14942
14943  b = {}
14944  val &&= true
14945  eq val, true
14946  val &&= b
14947  eq b, val
14948
14949  c = {}
14950  val = null
14951  val ?= c
14952  val ?= true
14953  eq c, val
14954
14955test "#1192: assignment starting with object literals", ->
14956  doesNotThrow (-> CoffeeScript.run "{}.p = 0")
14957  doesNotThrow (-> CoffeeScript.run "{}.p++")
14958  doesNotThrow (-> CoffeeScript.run "{}[0] = 1")
14959  doesNotThrow (-> CoffeeScript.run """{a: 1, 'b', "#{1}": 2}.p = 0""")
14960  doesNotThrow (-> CoffeeScript.run "{a:{0:{}}
14960}.a[0] = 0")
14961
14962
14963# Destructuring Assignment
14964
14965test "empty destructuring assignment", ->
14966  {} = {}
14967  [] = []
14968
14969test "chained destructuring assignments", ->
14970  [a] = {0: b} = {'0': c} = [nonce={}]
14971  eq nonce, a
14972  eq nonce, b
14973  eq nonce, c
14974
14975test "variable swapping to verify caching of RHS values when appropriate", ->
14976  a = nonceA = {}
14977  b = nonceB = {}
14978  c = nonceC = {}
14979  [a, b, c] = [b, c, a]
14980  eq nonceB, a
14981  eq nonceC, b
14982  eq nonceA, c
14983  [a, b, c] = [b, c, a]
14984  eq nonceC, a
14985  eq nonceA, b
14986  eq nonceB, c
14987  fn = ->
14988    [a, b, c] = [b, c, a]
14989  arrayEq [nonceA,nonceB,nonceC], fn()
14990  eq nonceA, a
14991  eq nonceB, b
14992  eq nonceC, c
14993
14994test "#713: destructuring assignment should return right-hand-side value", ->
14995  nonces = [nonceA={},nonceB={}]
14996  eq nonces, [a, b] = [c, d] = nonces
14997  eq nonceA, a
14998  eq nonceA, c
14999  eq nonceB, b
15000  eq nonceB, d
15001
15002test "#4787 destructuring of objects within arrays", ->
15003  arr = [1, {a:1, b:2}]
15004  [...,{a, b}] = arr
15005  eq a, 1
15006  eq b, arr[1].b
15007  deepEqual {a, b}, arr[1]
15008
15009test "destructuring assignment with splats", ->
15010  a = {}; b = {}; c = {}; d = {}; e = {}
15011  [x,y...,z] = [a,b,c,d,e]
15012  eq a, x
15013  arrayEq [b,c,d], y
15014  eq e, z
15015
15016  # Should not trigger implicit call, e.g. rest ... => rest(...)
15017  [x,y ...,z] = [a,b,c,d,e]
15018  eq a, x
15019  arrayEq [b,c,d], y
15020  eq e, z
15021
15022test "deep destructuring assignment with splats", ->
15023  a={}; b={}; c={}; d={}; e={}; f={}; g={}; h={}; i={}
15024  [u, [v, w..., x], y..., z] = [a, [b, c, d, e], f, g, h, i]
15025  eq a, u
15026  eq b, v
15027  arrayEq [c,d], w
15028  eq e, x
15029  arrayEq [f,g,h], y
15030  eq i, z
15031
15032test "destructuring assignment with objects", ->
15033  a={}; b={}; c={}
15034  obj = {a,b,c}
15035  {a:x, b:y, c:z} = obj
15036  eq a, x
15037  eq b, y
15038  eq c, z
15039
15040test "deep destructuring assignment with objects", ->
15041  a={}; b={}; c={}; d={}
15042  obj = {
15043    a
15044    b: {
15045      'c': {
15046        d: [
15047          b
15048          {e: c, f: d}
15049        ]
15050      }
15051    }
15052  }
15053  {a: w, 'b': {c: d: [x, {'f': z, e: y}]}} = obj
15054  eq a, w
15055  eq b, x
15056  eq c, y
15057  eq d, z
15058
15059test "destructuring assignment with objects and splats", ->
15060  a={}; b={}; c={}; d={}
15061  obj = a: b: [a, b, c, d]
15062  {a: b: [y, z...]} = obj
15063  eq a, y
15064  arrayEq [b,c,d], z
15065
15066  # Should not trigger implicit call, e.g. rest ... => rest(...)
15067  {a: b: [y, z ...]} = obj
15068  eq a, y
15069  arrayEq [b,c,d], z
15070
15071test "destructuring assignment against an expression", ->
15072  a={}; b={}
15073  [y, z] = if true then [a, b] else [b, a]
15074  eq a, y
15075  eq b, z
15076
15077test "bracket insertion when necessary", ->
15078  [a] = [0] ? [1]
15079  eq a, 0
15080
15081# for implicit destructuring assignment in comprehensions, see the comprehension tests
15082
15083test "destructuring assignment with context (@) properties", ->
15084  a={}; b={}; c={}; d={}; e={}
15085  obj =
15086    fn: () ->
15087      local = [a, {b, c}, d, e]
15088      [@a, {b: @b, c: @c}, @d, @e] = local
15089  eq undefined, obj[key] for key in ['a','b','c','d','e']
15090  obj.fn()
15091  eq a, obj.a
15092  eq b, obj.b
15093  eq c, obj.c
15094  eq d, obj.d
15095  eq e, obj.e
15096
15097test "#1024: destructure empty assignments to produce javascript-like results", ->
15098  eq 2 * [] = 3 + 5, 16
15099
15100test "#1005: invalid identifiers allowed on LHS of destructuring assignment", ->
15101  disallowed = ['eval', 'arguments'].concat CoffeeScript.RESERVED
15102  throwsCompileError "[#{disallowed.join ', '}] = x", null, null, 'all disallowed'
15103  throwsCompileError "[#{disallowed.join '..., '}...] = x", null, null, 'all disallowed as splats'
15104  t = tSplat = null
15105  for v in disallowed when v isnt 'class' # `class` by itself is an expression
15106    throwsCompileError t, null, null, t = "[#{v}] = x"
15107    throwsCompileError tSplat, null, null, tSplat = "[#{v}...] = x"
15108  for v in disallowed
15109    doesNotThrowCompileError "[a.#{v}] = x"
15110    doesNotThrowCompileError "[a.#{v}...] = x"
15111    doesNotThrowCompileError "[@#{v}] = x"
15112    doesNotThrowCompileError "[@#{v}...] = x"
15113
15114test "#2055: destructuring assignment with `new`", ->
15115  {length} = new Array
15116  eq 0, length
15117
15118test "#156: destructuring with expansion", ->
15119  array = [1..5]
15120  [first, ..., last] = array
15121  eq 1, first
15122  eq 5, last
15123  [..., lastButOne, last] = array
15124  eq 4, lastButOne
15125  eq 5, last
15126  [first, second, ..., last] = array
15127  eq 2, second
15128  [..., last] = 'strings as well -> x'
15129  eq 'x', last
15130  throwsCompileError "[1, ..., 3]",        null, null, "prohibit expansion outside of assignment"
15131  throwsCompileError "[..., a, b...] = c", null, null, "prohibit expansion and a splat"
15132  throwsCompileError "[...] = c",          null, null, "prohibit lone expansion"
15133
15134test "destructuring with dynamic keys", ->
15135  {"#{'a'}": a, """#{'b'}""": b, c} = {a: 1, b: 2, c: 3}
15136  eq 1, a
15137  eq 2, b
15138  eq 3, c
15139  throwsCompileError '{"#{a}"} = b'
15140
15141test "simple array destructuring defaults", ->
15142  [a = 1] = []
15143  eq 1, a
15144  [a = 2] = [undefined]
15145  eq 2, a
15146  [a = 3] = [null]
15147  eq null, a # Breaking change in CS2: per ES2015, default values are applied for `undefined` but not for `null`.
15148  [a = 4] = [0]
15149  eq 0, a
15150  arr = [a = 5]
15151  eq 5, a
15152  arrayEq [5], arr
15153
15154test "simple object destructuring defaults", ->
15155  {b = 1} = {}
15156  eq b, 1
15157  {b = 2} = {b: undefined}
15158  eq b, 2
15159  {b = 3} = {b: null}
15160  eq b, null # Breaking change in CS2: per ES2015, default values are applied for `undefined` but not for `null`.
15161  {b = 4} = {b: 0}
15162  eq b, 0
15163
15164  {b: c = 1} = {}
15165  eq c, 1
15166  {b: c = 2} = {b: undefined}
15167  eq c, 2
15168  {b: c = 3} = {b: null}
15169  eq c, null # Breaking change in CS2: per ES2015, default values are applied for `undefined` but not for `null`.
15170  {b: c = 4} = {b: 0}
15171  eq c, 0
15172
15173test "multiple array destructuring defaults", ->
15174  [a = 1, b = 2, c] = [undefined, 12, 13]
15175  eq a, 1
15176  eq b, 12
15177  eq c, 13
15178  [a, b = 2, c = 3] = [undefined, 12, 13]
15179  eq a, undefined
15180  eq b, 12
15181  eq c, 13
15182  [a = 1, b, c = 3] = [11, 12]
15183  eq a, 11
15184  eq b, 12
15185  eq c, 3
15186
15187test "multiple object destructuring defaults", ->
15188  {a = 1, b: bb = 2, 'c': c = 3, "#{0}": d = 4} = {"#{'b'}": 12}
15189  eq a, 1
15190  eq bb, 12
15191  eq c, 3
15192  eq d, 4
15193
15194test "array destructuring defaults with splats", ->
15195  [..., a = 9] = []
15196  eq a, 9
15197  [..., b = 9] = [19]
15198  eq b, 19
15199
15200test "deep destructuring assignment with defaults", ->
15201  [a, [{b = 1, c = 3}] = [c: 2]] = [0]
15202  eq a, 0
15203  eq b, 1
15204  eq c, 2
15205
15206test "destructuring assignment with context (@) properties and defaults", ->
15207  a={}; b={}; c={}; d={}; e={}
15208  obj =
15209    fn: () ->
15210      local = [a, {b, c: undefined}, d]
15211      [@a, {b: @b = b, @c = c}, @d, @e = e] = local
15212  eq undefined, obj[key] for key in ['a','b','c','d','e']
15213  obj.fn()
15214  eq a, obj.a
15215  eq b, obj.b
15216  eq c, obj.c
15217  eq d, obj.d
15218  eq e, obj.e
15219
15220test "destructuring assignment with defaults single evaluation", ->
15221  callCount = 0
15222  fn = -> callCount++
15223  [a = fn()] = []
15224  eq 0, a
15225  eq 1, callCount
15226  [a = fn()] = [10]
15227  eq 10, a
15228  eq 1, callCount
15229  {a = fn(), b: c = fn()} = {a: 20, b: undefined}
15230  eq 20, a
15231  eq c, 1
15232  eq callCount, 2
15233
15234
15235# Existential Assignment
15236
15237test "existential assignment", ->
15238  nonce = {}
15239  a = false
15240  a ?= nonce
15241  eq false, a
15242  b = undefined
15243  b ?= nonce
15244  eq nonce, b
15245  c = null
15246  c ?= nonce
15247  eq nonce, c
15248
15249test "#1627: prohibit conditional assignment of undefined variables", ->
15250  throwsCompileError "x ?= 10",        null, null, "prohibit (x ?= 10)"
15251  throwsCompileError "x ||= 10",       null, null, "prohibit (x ||= 10)"
15252  throwsCompileError "x or= 10",       null, null, "prohibit (x or= 10)"
15253  throwsCompileError "do -> x ?= 10",  null, null, "prohibit (do -> x ?= 10)"
15254  throwsCompileError "do -> x ||= 10", null, null, "prohibit (do -> x ||= 10)"
15255  throwsCompileError "do -> x or= 10", null, null, "prohibit (do -> x or= 10)"
15256  doesNotThrowCompileError "x = null; x ?= 10",        null, "allow (x = null; x ?= 10)"
15257  doesNotThrowCompileError "x = null; x ||= 10",       null, "allow (x = null; x ||= 10)"
15258  doesNotThrowCompileError "x = null; x or= 10",       null, "allow (x = null; x or= 10)"
15259  doesNotThrowCompileError "x = null; do -> x ?= 10",  null, "allow (x = null; do -> x ?= 10)"
15260  doesNotThrowCompileError "x = null; do -> x ||= 10", null, "allow (x = null; do -> x ||= 10)"
15261  doesNotThrowCompileError "x = null; do -> x or= 10", null, "allow (x = null; do -> x or= 10)"
15262
15263  throwsCompileError "-> -> -> x ?= 10", null, null, "prohibit (-> -> -> x ?= 10)"
15264  doesNotThrowCompileError "x = null; -> -> -> x ?= 10", null, "allow (x = null; -> -> -> x ?= 10)"
15265
15266test "more existential assignment", ->
15267  global.temp ?= 0
15268  eq global.temp, 0
15269  global.temp or= 100
15270  eq global.temp, 100
15271  delete global.temp
15272
15273test "#1348, #1216: existential assignment compilation", ->
15274  nonce = {}
15275  a = nonce
15276  b = (a ?= 0)
15277  eq nonce, b
15278  #the first ?= compiles into a statement; the second ?= compiles to a ternary expression
15279  eq a ?= b ?= 1, nonce
15280
15281  if a then a ?= 2 else a = 3
15282  eq a, nonce
15283
15284test "#1591, #1101: splatted expressions in destructuring assignment must be assignable", ->
15285  nonce = {}
15286  for nonref in ['', '""', '0', 'f()', '(->)'].concat CoffeeScript.RESERVED
15287    eq nonce, (try CoffeeScript.compile "[#{nonref}...] = v" catch e then nonce)
15288
15289test "#1643: splatted accesses in destructuring assignments should not be declared as variables", ->
15290  nonce = {}
15291  accesses = ['o.a', 'o["a"]', '(o.a)', '(o.a).a', '@o.a', 'C::a', 'f().a', 'o?.a', 'o?.a.b', 'f?().a']
15292  for access in accesses
15293    for i,j in [1,2,3] #position can matter
15294      code =
15295        """
15296        nonce = {}; nonce2 = {}; nonce3 = {};
15297        @o = o = new (class C then a:{}); f = -> o
15298        [#{new Array(i).join('x,')}#{access}...] = [#{new Array(i).join('0,')}nonce, nonce2, nonce3]
15299        unless #{access}[0] is nonce and #{access}[1] is nonce2 and #{access}[2] is nonce3 then throw new Error('[...]')
15300        """
15301      eq nonce, unless (try CoffeeScript.run code, bare: true catch e then true) then nonce
15302  # subpatterns like `[[a]...]` and `[{a}...]`
15303  subpatterns = ['[sub, sub2, sub3]', '{0: sub, 1: sub2, 2: sub3}']
15304  for subpattern in subpatterns
15305    for i,j in [1,2,3]
15306      code =
15307        """
15308        nonce = {}; nonce2 = {}; nonce3 = {};
15309        [#{new Array(i).join('x,')}#{subpattern}...] = [#{new Array(i).join('0,')}nonce, nonce2, nonce3]
15310        unless sub is nonce and sub2 is nonce2 and sub3 is nonce3 then throw new Error('[sub...]')
15311        """
15312      eq nonce, unless (try CoffeeScript.run code, bare: true catch e then true) then nonce
15313
15314test "#1838: Regression with variable assignment", ->
15315  name =
15316  'dave'
15317
15318  eq name, 'dave'
15319
15320test '#2211: splats in destructured parameters', ->
15321  doesNotThrowCompileError '([a...]) ->'
15322  doesNotThrowCompileError '([a...],b) ->'
15323  doesNotThrowCompileError '([a...],[b...]) ->'
15324  throwsCompileError '([a...,[a...]]) ->'
15325  doesNotThrowCompileError '([a...,[b...]]) ->'
15326
15327test '#2213: invocations within destructured parameters', ->
15328  throwsCompileError '([a()])->'
15329  throwsCompileError '([a:b()])->'
15330  throwsCompileError '([a:b.c()])->'
15331  throwsCompileError '({a()})->'
15332  throwsCompileError '({a:b()})->'
15333  throwsCompileError '({a:b.c()})->'
15334
15335test '#2532: compound assignment with terminator', ->
15336  doesNotThrowCompileError """
15337  a = "hello"
15338  a +=
15339  "
15340  world
15341  !
15342  "
15343  """
15344
15345test "#2613: parens on LHS of destructuring", ->
15346  a = {}
15347  [(a).b] = [1, 2, 3]
15348  eq a.b, 1
15349
15350test "#2181: conditional assignment as a subexpression", ->
15351  a = false
15352  false && a or= true
15353  eq false, a
15354  eq false, not a or= true
15355
15356test "#1500: Assignment to variables similar to generated variables", ->
15357  len = 0
15358  x = ((results = null; n) for n in [1, 2, 3])
15359  arrayEq [1, 2, 3], x
15360  eq 0, len
15361
15362  for x in [1, 2, 3]
15363    f = ->
15364      i = 0
15365    f()
15366    eq 'undefined', typeof i
15367
15368  ref = 2
15369  x = ref * 2 ? 1
15370  eq x, 4
15371  eq 'undefined', typeof ref1
15372
15373  x = {}
15374  base = -> x
15375  name = -1
15376  base()[-name] ?= 2
15377  eq x[1], 2
15378  eq base(), x
15379  eq name, -1
15380
15381  f = (@a, a) -> [@a, a]
15382  arrayEq [1, 2], f.call scope = {}, 1, 2
15383  eq 1, scope.a
15384
15385  try throw 'foo'
15386  catch error
15387    eq error, 'foo'
15388
15389  eq error, 'foo'
15390
15391  doesNotThrowCompileError '(@slice...) ->'
15392
15393test "Assignment to variables similar to helper functions", ->
15394  f = (slice...) -> slice
15395  arrayEq [1, 2, 3], f 1, 2, 3
15396  eq 'undefined', typeof slice1
15397
15398  class A
15399  class B extends A
15400    extend = 3
15401    hasProp = 4
15402    value: 5
15403    method: (bind, bind1) => [bind, bind1, extend, hasProp, @value]
15404  {method} = new B
15405  arrayEq [1, 2, 3, 4, 5], method 1, 2
15406
15407  modulo = -1 %% 3
15408  eq 2, modulo
15409
15410  indexOf = [1, 2, 3]
15411  ok 2 in indexOf
15412
15413test "#4566: destructuring with nested default values", ->
15414  {a: {b = 1}} = a: {}
15415  eq 1, b
15416
15417  {c: {d} = {}} = c: d: 3
15418  eq 3, d
15419
15420  {e: {f = 5} = {}} = {}
15421  eq 5, f
15422
15423test "#4878: Compile error when using destructuring with a splat or expansion in an array", ->
15424  arr = ['a', 'b', 'c', 'd']
15425
15426  f1 = (list) ->
15427    [first, ..., last] = list
15428
15429  f2 = (list) ->
15430    [first..., last] = list
15431
15432  f3 = (list) ->
15433    ([first, ...] = list); first
15434
15435  f4 = (list) ->
15436    ([first, rest...] = list); rest
15437
15438  arrayEq f1(arr), arr
15439  arrayEq f2(arr), arr
15440  arrayEq f3(arr), 'a'
15441  arrayEq f4(arr), ['b', 'c', 'd']
15442
15443  foo = (list) ->
15444    ret =
15445      if list?.length > 0
15446        [first, ..., last] = list
15447        [first, last]
15448      else
15449        []
15450
15451  arrayEq foo(arr), ['a', 'd']
15452
15453  bar = (list) ->
15454    ret =
15455      if list?.length > 0
15456        [first, rest...] = list
15457        [first, rest]
15458      else
15459        []
15460
15461  arrayEq bar(arr), ['a', ['b', 'c', 'd']]
15462
15463test "destructuring assignment with an empty array in object", ->
15464  obj =
15465    a1: [1, 2]
15466    b1: 3
15467
15468  {a1:[], b1} = obj
15469  eq 'undefined', typeof a1
15470  eq b1, 3
15471
15472  obj =
15473    a2:
15474      b2: [1, 2]
15475    c2: 3
15476
15477  {a2: {b2:[]}, c2} = obj
15478  eq 'undefined', typeof b2
15479  eq c2, 3
15480
15481test "#5004: array destructuring with accessors", ->
15482  obj =
15483    arr: ['a', 'b', 'c', 'd']
15484    list: {}
15485    f1: ->
15486      [@first, @rest...] = @arr
15487    f2: ->
15488      [@second, @third..., @last] = @rest
15489    f3: ->
15490      [@list.a, @list.middle..., @list.d] = @arr
15491
15492  obj.f1()
15493  eq obj.first, 'a'
15494  arrayEq obj.rest, ['b', 'c', 'd']
15495
15496  obj.f2()
15497  eq obj.second, 'b'
15498  arrayEq obj.third, ['c']
15499  eq obj.last, 'd'
15500
15501  obj.f3()
15502  eq obj.list.a, 'a'
15503  arrayEq obj.list.middle, ['b', 'c']
15504  eq obj.list.d, 'd'
15505
15506  [obj.list.middle..., d] = obj.arr
15507  eq d, 'd'
15508  arrayEq obj.list.middle, ['a', 'b', 'c']
15509
15510test "#4884: destructured object splat", ->
15511  [{length}...] = [1, 2, 3]
15512  eq length, 3
15513  [{length: len}...] = [1, 2, 3]
15514  eq len, 3
15515  [{length}..., three] = [1, 2, 3]
15516  eq length, 2
15517  eq three, 3
15518  [{length: len}..., three] = [1, 2, 3]
15519  eq len, 2
15520  eq three, 3
15521  x = [{length}..., three] = [1, 2, 3]
15522  eq length, 2
15523  eq three, 3
15524  eq x[2], 3
15525  x = [{length: len}..., three] = [1, 2, 3]
15526  eq len, 2
15527  eq three, 3
15528  eq x[2], 3
15529
15530test "#4884: destructured array splat", ->
15531  [[one, two, three]...] = [1, 2, 3]
15532  eq one, 1
15533  eq two, 2
15534  eq three, 3
15535  [[one, two]..., three] = [1, 2, 3]
15536  eq one, 1
15537  eq two, 2
15538  eq three, 3
15539  x = [[one, two]..., three] = [1, 2, 3]
15540  eq one, 1
15541  eq two, 2
15542  eq three, 3
15543  eq x[2], 3
15544
15545</script>
vendor: 1 bytes, line 15545
15545
15546<script type="text/x-coffeescript" class="test" id="async">
15547# Functions that contain the `await` keyword will compile into async functions,
15548# supported by Node 7.6+, Chrome 55+, Firefox 52+, Safari 10.1+ and Edge.
15549# But runtimes that don’t support the `await` keyword will throw an error just
15550# from parsing this file, even without executing it, even if we put
15551# `return unless try new Function 'async () => {}'` at the top of this file.
15552# Therefore we need to prevent runtimes which will choke on such code from
15553# parsing it, which is handled in `Cakefile`.
15554
15555
15556# This is always fulfilled.
15557winning = (val) -> Promise.resolve val
15558
15559# This is always rejected.
15560failing = (val) -> Promise.reject new Error val
15561
15562
15563test "async as argument", ->
15564  ok ->
15565    await winning()
15566
15567test "explicit async", ->
15568  a = do ->
15569    await return 5
15570  eq a.constructor, Promise
15571  a.then (val) ->
15572    eq val, 5
15573
15574test "implicit async", ->
15575  a = do ->
15576    x = await winning(5)
15577    y = await winning(4)
15578    z = await winning(3)
15579    [x, y, z]
15580
15581  eq a.constructor, Promise
15582
15583test "async return value (implicit)", ->
15584  out = null
15585  a = ->
15586    x = await winning(5)
15587    y = await winning(4)
15588    z = await winning(3)
15589    [x, y, z]
15590
15591  b = do ->
15592    out = await a()
15593
15594  b.then ->
15595    arrayEq out, [5, 4, 3]
15596
15597test "async return value (explicit)", ->
15598  out = null
15599  a = ->
15600    await return [5, 2, 3]
15601
15602  b = do ->
15603    out = await a()
15604
15605  b.then ->
15606    arrayEq out, [5, 2, 3]
15607
15608
15609test "async parameters", ->
15610  [out1, out2] = [null, null]
15611  a = (a, [b, c])->
15612    arr = [a]
15613    arr.push b
15614    arr.push c
15615    await return arr
15616
15617  b = (a, b, c = 5)->
15618    arr = [a]
15619    arr.push b
15620    arr.push c
15621    await return arr
15622
15623  c = do ->
15624    out1 = await a(5, [4, 3])
15625    out2 = await b(4, 4)
15626
15627  c.then ->
15628    arrayEq out1, [5, 4, 3]
15629    arrayEq out2, [4, 4, 5]
15630
15631test "async `this` scoping", ->
15632  bnd = null
15633  ubnd = null
15634  nst = null
15635  obj =
15636    bound: ->
15637      return do =>
15638        await return this
15639    unbound: ->
15640      return do ->
15641        await return this
15642    nested: ->
15643      return do =>
15644        await do =>
15645          await do =>
15646            await return this
15647
15648  promise = do ->
15649    bnd = await obj.bound()
15650    ubnd = await obj.unbound()
15651    nst = await obj.nested()
15652
15653  promise.then ->
15654    eq bnd, obj
15655    ok ubnd isnt obj
15656    eq nst, obj
15657
15658test "await precedence", ->
15659  out = null
15660
15661  fn = (win, fail) ->
15662    win(3)
15663
15664  promise = do ->
15665    # assert precedence between unary (new) and power (**) operators
15666    out = 1 + await new Promise(fn) ** 2
15667
15668  promise.then ->
15669    eq out, 10
15670
15671test "`await` inside IIFEs", ->
15672  [x, y, z] = new Array(3)
15673
15674  a = do ->
15675    x = switch (4)  # switch 4
15676      when 2
15677        await winning(1)
15678      when 4
15679        await winning(5)
15680      when 7
15681        await winning(2)
15682
15683    y = try
15684      text = "this should be caught"
15685      throw new Error(text)
15686      await winning(1)
15687    catch e
15688      await winning(4)
15689
15690    z = for i in [0..5]
15691      a = i * i
15692      await winning(a)
15693
15694  a.then ->
15695    eq x, 5
15696    eq y, 4
15697
15698    arrayEq z, [0, 1, 4, 9, 16, 25]
15699
15700test "error handling", ->
15701  res = null
15702  val = 0
15703  a = ->
15704    try
15705      await failing("fail")
15706    catch e
15707      val = 7  # to assure the catch block runs
15708      return e
15709
15710  b = do ->
15711    res = await a()
15712
15713  b.then ->
15714    eq val, 7
15715
15716    ok res.message?
15717    eq res.message, "fail"
15718
15719test "await expression evaluates to argument if not A+", ->
15720  eq(await 4, 4)
15721
15722
15723test "implicit call with `await`", ->
15724  addOne = (arg) -> arg + 1
15725
15726  a = addOne await 3
15727  eq a, 4
15728
15729test "async methods in classes", ->
15730  class Base
15731    @static: ->
15732      await 1
15733    method: ->
15734      await 2
15735
15736  eq await Base.static(), 1
15737  eq await new Base().method(), 2
15738
15739  class Child extends Base
15740    @static: -> super()
15741    method: -> super()
15742
15743  eq await Child.static(), 1
15744  eq await new Child().method(), 2
15745
15746test "#3199: await multiline implicit object", ->
15747  do ->
15748    y =
15749      if no then await
15750        type: 'a'
15751        msg: 'b'
15752    eq undefined, y
15753
15754test "top-level await", ->
15755  eqJS 'await null', 'await null;'
15756
15757test "top-level wrapper has correct async attribute", ->
15758  starts = (code, prefix) ->
15759    compiled = CoffeeScript.compile code
15760    unless compiled.startsWith prefix
15761      fail """Expected generated JavaScript to start with:
15762        #{reset}#{prefix}#{red}
15763        but instead it was:
15764        #{reset}#{compiled}#{red}"""
15765  starts 'await null', '(async function'
15766  starts 'do -> await null', '(function'
15767
15768</script>
vendor: 1 bytes, line 15768
15768
15769<script type="text/x-coffeescript" class="test" id="async_iterators">
15770# This is always fulfilled.
15771winLater = (val, ms) ->
15772  new Promise (resolve) -> setTimeout (-> resolve val), ms
15773
15774# This is always rejected.
15775failLater = (val, ms) ->
15776  new Promise (resolve, reject) -> setTimeout (-> reject new Error val), ms
15777
15778createAsyncIterable = (syncIterable) ->
15779  for elem in syncIterable
15780    yield await winLater elem, 50
15781
15782test "async iteration", ->
15783  foo = (x for await x from createAsyncIterable [1,2,3])
15784  arrayEq foo, [1, 2, 3]
15785
15786test "async generator functions", ->
15787  foo = (val) ->
15788    yield await winLater val + 1, 50
15789
15790  bar = (val) ->
15791    yield await failLater val - 1, 50
15792
15793  a = await foo(41).next()
15794  eq a.value, 42
15795
15796  try
15797    b = do -> await bar(41).next()
15798    b.catch (err) ->
15799      eq "40", err.message
15800  catch err
15801    ok no
15802
15803</script>
vendor: 1 bytes, line 15803
15803
15804<script type="text/x-coffeescript" class="test" id="booleans">
15805# Boolean Literals
15806# ----------------
15807
15808# TODO: add method invocation tests: true.toString() is "true"
15809
15810test "#764 Booleans should be indexable", ->
15811  toString = Boolean::toString
15812
15813  eq toString, true['toString']
15814  eq toString, false['toString']
15815  eq toString, yes['toString']
15816  eq toString, no['toString']
15817  eq toString, on['toString']
15818  eq toString, off['toString']
15819
15820  eq toString, true.toString
15821  eq toString, false.toString
15822  eq toString, yes.toString
15823  eq toString, no.toString
15824  eq toString, on.toString
15825  eq toString, off.toString
15826
15827</script>
vendor: 1 bytes, line 15827
15827
15828<script type="text/x-coffeescript" class="test" id="classes">
15829# Classes
15830# -------
15831
15832# * Class Definition
15833# * Class Instantiation
15834# * Inheritance and Super
15835# * ES2015+ Class Interoperability
15836
15837test "classes with a four-level inheritance chain", ->
15838
15839  class Base
15840    func: (string) ->
15841      "zero/#{string}"
15842
15843    @static: (string) ->
15844      "static/#{string}"
15845
15846  class FirstChild extends Base
15847    func: (string) ->
15848      super('one/') + string
15849
15850  SecondChild = class extends FirstChild
15851    func: (string) ->
15852      super('two/') + string
15853
15854  thirdCtor = ->
15855    @array = [1, 2, 3]
15856
15857  class ThirdChild extends SecondChild
15858    constructor: ->
15859      super()
15860      thirdCtor.call this
15861
15862    # Gratuitous comment for testing.
15863    func: (string) ->
15864      super('three/') + string
15865
15866  result = (new ThirdChild).func 'four'
15867
15868  ok result is 'zero/one/two/three/four'
15869  ok Base.static('word') is 'static/word'
15870
15871  ok (new ThirdChild).array.join(' ') is '1 2 3'
15872
15873
15874test "constructors with inheritance and super", ->
15875
15876  identity = (f) -> f
15877
15878  class TopClass
15879    constructor: (arg) ->
15880      @prop = 'top-' + arg
15881
15882  class SuperClass extends TopClass
15883    constructor: (arg) ->
15884      identity super 'super-' + arg
15885
15886  class SubClass extends SuperClass
15887    constructor: ->
15888      identity super 'sub'
15889
15890  ok (new SubClass).prop is 'top-super-sub'
15891
15892
15893test "'super' with accessors", ->
15894  class Base
15895    m: -> 4
15896    n: -> 5
15897    o: -> 6
15898
15899  name = 'o'
15900  class A extends Base
15901    m: -> super()
15902    n: -> super.n()
15903    "#{name}": -> super()
15904    p: -> super[name]()
15905
15906  a = new A
15907  eq 4, a.m()
15908  eq 5, a.n()
15909  eq 6, a.o()
15910  eq 6, a.p()
15911
15912
15913test "soaked 'super' invocation", ->
15914  class Base
15915    method: -> 2
15916
15917  class A extends Base
15918    method: -> super?()
15919    noMethod: -> super?()
15920
15921  a = new A
15922  eq 2, a.method()
15923  eq undefined, a.noMethod()
15924
15925  name = 'noMethod'
15926  class B extends Base
15927    "#{'method'}": -> super?()
15928    "#{'noMethod'}": -> super?() ? super['method']()
15929
15930  b = new B
15931  eq 2, b.method()
15932  eq 2, b.noMethod()
15933
15934test "'@' referring to the current instance, and not being coerced into a call", ->
15935
15936  class ClassName
15937    amI: ->
15938      @ instanceof ClassName
15939
15940  obj = new ClassName
15941  ok obj.amI()
15942
15943
15944test "super() calls in constructors of classes that are defined as object properties", ->
15945
15946  class Hive
15947    constructor: (name) -> @name = name
15948
15949  class Hive.Bee extends Hive
15950    constructor: (name) -> super name
15951
15952  maya = new Hive.Bee 'Maya'
15953  ok maya.name is 'Maya'
15954
15955
15956test "classes with JS-keyword properties", ->
15957
15958  class Class
15959    class: 'class'
15960    name: -> @class
15961
15962  instance = new Class
15963  ok instance.class is 'class'
15964  ok instance.name() is 'class'
15965
15966
15967test "Classes with methods that are pre-bound to the instance, or statically, to the class", ->
15968
15969  class Dog
15970    constructor: (name) ->
15971      @name = name
15972
15973    bark: =>
15974      "#{@name} woofs!"
15975
15976    @static = =>
15977      new this('Dog')
15978
15979  spark = new Dog('Spark')
15980  fido  = new Dog('Fido')
15981  fido.bark = spark.bark
15982
15983  ok fido.bark() is 'Spark woofs!'
15984
15985  obj = func: Dog.static
15986
15987  ok obj.func().name is 'Dog'
15988
15989
15990test "a bound function in a bound function", ->
15991
15992  class Mini
15993    num: 10
15994    generate: =>
15995      for i in [1..3]
15996        =>
15997          @num
15998
15999  m = new Mini
16000  eq (func() for func in m.generate()).join(' '), '10 10 10'
16001
16002
16003test "contructor called with varargs", ->
16004
16005  class Connection
16006    constructor: (one, two, three) ->
16007      [@one, @two, @three] = [one, two, three]
16008
16009    out: ->
16010      "#{@one}-#{@two}-#{@three}"
16011
16012  list = [3, 2, 1]
16013  conn = new Connection list...
16014  ok conn instanceof Connection
16015  ok conn.out() is '3-2-1'
16016
16017
16018test "calling super and passing along all arguments", ->
16019
16020  class Parent
16021    method: (args...) -> @args = args
16022
16023  class Child extends Parent
16024    method: -> super arguments...
16025
16026  c = new Child
16027  c.method 1, 2, 3, 4
16028  ok c.args.join(' ') is '1 2 3 4'
16029
16030
16031test "classes wrapped in decorators", ->
16032
16033  func = (klass) ->
16034    klass::prop = 'value'
16035    klass
16036
16037  func class Test
16038    prop2: 'value2'
16039
16040  ok (new Test).prop  is 'value'
16041  ok (new Test).prop2 is 'value2'
16042
16043
16044test "anonymous classes", ->
16045
16046  obj =
16047    klass: class
16048      method: -> 'value'
16049
16050  instance = new obj.klass
16051  ok instance.method() is 'value'
16052
16053
16054test "Implicit objects as static properties", ->
16055
16056  class Static
16057    @static =
16058      one: 1
16059      two: 2
16060
16061  ok Static.static.one is 1
16062  ok Static.static.two is 2
16063
16064
16065test "nothing classes", ->
16066
16067  c = class
16068  ok c instanceof Function
16069
16070
16071test "classes with static-level implicit objects", ->
16072
16073  class A
16074    @static = one: 1
16075    two: 2
16076
16077  class B
16078    @static = one: 1,
16079    two: 2
16080
16081  eq A.static.one, 1
16082  eq A.static.two, undefined
16083  eq (new A).two, 2
16084
16085  eq B.static.one, 1
16086  eq B.static.two, 2
16087  eq (new B).two, undefined
16088
16089
16090test "classes with value'd constructors", ->
16091
16092  counter = 0
16093  classMaker = ->
16094    inner = ++counter
16095    ->
16096      @value = inner
16097      @
16098
16099  class One
16100    constructor: classMaker()
16101
16102  class Two
16103    constructor: classMaker()
16104
16105  eq (new One).value, 1
16106  eq (new Two).value, 2
16107  eq (new One).value, 1
16108  eq (new Two).value, 2
16109
16110
16111test "executable class bodies", ->
16112
16113  class A
16114    if true
16115      b: 'b'
16116    else
16117      c: 'c'
16118
16119  a = new A
16120
16121  eq a.b, 'b'
16122  eq a.c, undefined
16123
16124
16125test "#2502: parenthesizing inner object values", ->
16126
16127  class A
16128    category:  (type: 'string')
16129    sections:  (type: 'number', default: 0)
16130
16131  eq (new A).category.type, 'string'
16132
16133  eq (new A).sections.default, 0
16134
16135
16136test "conditional prototype property assignment", ->
16137  debug = false
16138
16139  class Person
16140    if debug
16141      age: -> 10
16142    else
16143      age: -> 20
16144
16145  eq (new Person).age(), 20
16146
16147
16148test "mild metaprogramming", ->
16149
16150  class Base
16151    @attr: (name) ->
16152      @::[name] = (val) ->
16153        if arguments.length > 0
16154          @["_#{name}"] = val
16155        else
16156          @["_#{name}"]
16157
16158  class Robot extends Base
16159    @attr 'power'
16160    @attr 'speed'
16161
16162  robby = new Robot
16163
16164  ok robby.power() is undefined
16165
16166  robby.power 11
16167  robby.speed Infinity
16168
16169  eq robby.power(), 11
16170  eq robby.speed(), Infinity
16171
16172
16173test "namespaced classes do not reserve their function name in outside scope", ->
16174
16175  one = {}
16176  two = {}
16177
16178  class one.Klass
16179    @label = "one"
16180
16181  class two.Klass
16182    @label = "two"
16183
16184  eq typeof Klass, 'undefined'
16185  eq one.Klass.label, 'one'
16186  eq two.Klass.label, 'two'
16187
16188
16189test "nested classes", ->
16190
16191  class Outer
16192    constructor: ->
16193      @label = 'outer'
16194
16195    class @Inner
16196      constructor: ->
16197        @label = 'inner'
16198
16199  eq (new Outer).label, 'outer'
16200  eq (new Outer.Inner).label, 'inner'
16201
16202
16203test "variables in constructor bodies are correctly scoped", ->
16204
16205  class A
16206    x = 1
16207    constructor: ->
16208      x = 10
16209      y = 20
16210    y = 2
16211    captured: ->
16212      {x, y}
16213
16214  a = new A
16215  eq a.captured().x, 10
16216  eq a.captured().y, 2
16217
16218
16219test "Issue #924: Static methods in nested classes", ->
16220
16221  class A
16222    @B: class
16223      @c = -> 5
16224
16225  eq A.B.c(), 5
16226
16227
16228test "`class extends this`", ->
16229
16230  class A
16231    func: -> 'A'
16232
16233  B = null
16234  makeClass = ->
16235    B = class extends this
16236      func: -> super() + ' B'
16237
16238  makeClass.call A
16239
16240  eq (new B()).func(), 'A B'
16241
16242
16243test "ensure that constructors invoked with splats return a new object", ->
16244
16245  args = [1, 2, 3]
16246  Type = (@args) ->
16247  type = new Type args
16248
16249  ok type and type instanceof Type
16250  ok type.args and type.args instanceof Array
16251  ok v is args[i] for v, i in type.args
16252
16253  Type1 = (@a, @b, @c) ->
16254  type1 = new Type1 args...
16255
16256  ok type1 instanceof   Type1
16257  eq type1.constructor, Type1
16258  ok type1.a is args[0] and type1.b is args[1] and type1.c is args[2]
16259
16260  # Ensure that constructors invoked with splats cache the function.
16261  called = 0
16262  get = -> if called++ then false else class Type
16263  new (get()) args...
16264
16265test "`new` shouldn't add extra parens", ->
16266
16267  ok new Date().constructor is Date
16268
16269
16270test "`new` works against bare function", ->
16271
16272  eq Date, new ->
16273    Date
16274
16275test "`new` works against statement", ->
16276
16277  class A
16278  (new try A) instanceof A
16279
16280test "#1182: a subclass should be able to set its constructor to an external function", ->
16281  ctor = ->
16282    @val = 1
16283    return
16284  class A
16285  class B extends A
16286    constructor: ctor
16287  eq (new B).val, 1
16288
16289test "#1182: external constructors continued", ->
16290  ctor = ->
16291  class A
16292  class B extends A
16293    method: ->
16294    constructor: ctor
16295  ok B::method
16296
16297test "#1313: misplaced __extends", ->
16298  nonce = {}
16299  class A
16300  class B extends A
16301    prop: nonce
16302    constructor: -> super()
16303  eq nonce, B::prop
16304
16305test "#1182: execution order needs to be considered as well", ->
16306  counter = 0
16307  makeFn = (n) -> eq n, ++counter; ->
16308  class B extends (makeFn 1)
16309    @B: makeFn 2
16310    constructor: makeFn 3
16311
16312test "#1182: external constructors with bound functions", ->
16313  fn = ->
16314    {one: 1}
16315    this
16316  class B
16317  class A
16318    constructor: fn
16319    method: => this instanceof A
16320  ok (new A).method.call(new B)
16321
16322test "#1372: bound class methods with reserved names", ->
16323  class C
16324    delete: =>
16325  ok C::delete
16326
16327test "#1380: `super` with reserved names", ->
16328  class C
16329    do: -> super()
16330  ok C::do
16331
16332  class B
16333    0: -> super()
16334  ok B::[0]
16335
16336test "#1464: bound class methods should keep context", ->
16337  nonce  = {}
16338  nonce2 = {}
16339  class C
16340    constructor: (@id) ->
16341    @boundStaticColon: => new this(nonce)
16342    @boundStaticEqual= => new this(nonce2)
16343  eq nonce,  C.boundStaticColon().id
16344  eq nonce2, C.boundStaticEqual().id
16345
16346test "#1009: classes with reserved words as determined names", -> (->
16347  eq 'function', typeof (class @for)
16348  ok not /\beval\b/.test (class @eval).toString()
16349  ok not /\barguments\b/.test (class @arguments).toString()
16350).call {}
16351
16352test "#1482: classes can extend expressions", ->
16353  id = (x) -> x
16354  nonce = {}
16355  class A then nonce: nonce
16356  class B extends id A
16357  eq nonce, (new B).nonce
16358
16359test "#1598: super works for static methods too", ->
16360
16361  class Parent
16362    method: ->
16363      'NO'
16364    @method: ->
16365      'yes'
16366
16367  class Child extends Parent
16368    @method: ->
16369      'pass? ' + super()
16370
16371  eq Child.method(), 'pass? yes'
16372
16373test "#1842: Regression with bound functions within bound class methods", ->
16374
16375  class Store
16376    @bound: =>
16377      do =>
16378        eq this, Store
16379
16380  Store.bound()
16381
16382  # And a fancier case:
16383
16384  class Store
16385
16386    eq this, Store
16387
16388    @bound: =>
16389      do =>
16390        eq this, Store
16391
16392    @unbound: ->
16393      eq this, Store
16394
16395    instance: =>
16396      ok this instanceof Store
16397
16398  Store.bound()
16399  Store.unbound()
16400  (new Store).instance()
16401
16402test "#1876: Class @A extends A", ->
16403  class A
16404  class @A extends A
16405
16406  ok (new @A) instanceof A
16407
16408test "#1813: Passing class definitions as expressions", ->
16409  ident = (x) -> x
16410
16411  result = ident class A then x = 1
16412
16413  eq result, A
16414
16415  result = ident class B extends A
16416    x = 1
16417
16418  eq result, B
16419
16420test "#1966: external constructors should produce their return value", ->
16421  ctor = -> {}
16422  class A then constructor: ctor
16423  ok (new A) not instanceof A
16424
16425test "#1980: regression with an inherited class with static function members", ->
16426
16427  class A
16428
16429  class B extends A
16430    @static: => 'value'
16431
16432  eq B.static(), 'value'
16433
16434test "#1534: class then 'use strict'", ->
16435  # [14.1 Directive Prologues and the Use Strict Directive](http://es5.github.com/#x14.1)
16436  nonce = {}
16437  error = 'do -> ok this'
16438  strictTest = "do ->'use strict';#{error}"
16439  return unless (try CoffeeScript.run strictTest, bare: yes catch e then nonce) is nonce
16440
16441  throws -> CoffeeScript.run "class then 'use strict';#{error}", bare: yes
16442  doesNotThrow -> CoffeeScript.run "class then #{error}", bare: yes
16443  doesNotThrow -> CoffeeScript.run "class then #{error};'use strict'", bare: yes
16444
16445  # comments are ignored in the Directive Prologue
16446  comments = ["""
16447  class
16448    ### comment ###
16449    'use strict'
16450    #{error}""",
16451  """
16452  class
16453    ### comment 1 ###
16454    ### comment 2 ###
16455    'use strict'
16456    #{error}""",
16457  """
16458  class
16459    ### comment 1 ###
16460    ### comment 2 ###
16461    'use strict'
16462    #{error}
16463    ### comment 3 ###"""
16464  ]
16465  throws (-> CoffeeScript.run comment, bare: yes) for comment in comments
16466
16467  # [ES5 §14.1](http://es5.github.com/#x14.1) allows for other directives
16468  directives = ["""
16469  class
16470    'directive 1'
16471    'use strict'
16472    #{error}""",
16473  """
16474  class
16475    'use strict'
16476    'directive 2'
16477    #{error}""",
16478  """
16479  class
16480    ### comment 1 ###
16481    'directive 1'
16482    'use strict'
16483    #{error}""",
16484  """
16485  class
16486    ### comment 1 ###
16487    'directive 1'
16488    ### comment 2 ###
16489    'use strict'
16490    #{error}"""
16491  ]
16492  throws (-> CoffeeScript.run directive, bare: yes) for directive in directives
16493
16494test "#2052: classes should work in strict mode", ->
16495  try
16496    do ->
16497      'use strict'
16498      class A
16499  catch e
16500    ok no
16501
16502test "directives in class with extends ", ->
16503  strictTest = """
16504    class extends Object
16505      ### comment ###
16506      'use strict'
16507      do -> eq this, undefined
16508  """
16509  CoffeeScript.run strictTest, bare: yes
16510
16511test "#2630: class bodies can't reference arguments", ->
16512  throwsCompileError 'class Test then arguments'
16513
16514  # #4320: Don't be too eager when checking, though.
16515  class Test
16516    arguments: 5
16517  eq 5, Test::arguments
16518
16519test "#2319: fn class n extends o.p [INDENT] x = 123", ->
16520  first = ->
16521
16522  base = onebase: ->
16523
16524  first class OneKeeper extends base.onebase
16525    one = 1
16526    one: -> one
16527
16528  eq new OneKeeper().one(), 1
16529
16530
16531test "#2599: other typed constructors should be inherited", ->
16532  class Base
16533    constructor: -> return {}
16534
16535  class Derived extends Base
16536
16537  ok (new Derived) not instanceof Derived
16538  ok (new Derived) not instanceof Base
16539  ok (new Base) not instanceof Base
16540
16541test "extending native objects works with and without defining a constructor", ->
16542  class MyArray extends Array
16543    method: -> 'yes!'
16544
16545  myArray = new MyArray
16546  ok myArray instanceof MyArray
16547  ok 'yes!', myArray.method()
16548
16549  class OverrideArray extends Array
16550    constructor: -> super()
16551    method: -> 'yes!'
16552
16553  overrideArray = new OverrideArray
16554  ok overrideArray instanceof OverrideArray
16555  eq 'yes!', overrideArray.method()
16556
16557
16558test "#2782: non-alphanumeric-named bound functions", ->
16559  class A
16560    'b:c': =>
16561      'd'
16562
16563  eq (new A)['b:c'](), 'd'
16564
16565
16566test "#2781: overriding bound functions", ->
16567  class A
16568    a: ->
16569        @b()
16570    b: =>
16571        1
16572
16573  class B extends A
16574    b: =>
16575        2
16576
16577  b = (new A).b
16578  eq b(), 1
16579
16580  b = (new B).b
16581  eq b(), 2
16582
16583
16584test "#2791: bound function with destructured argument", ->
16585  class Foo
16586    method: ({a}) => 'Bar'
16587
16588  eq (new Foo).method({a: 'Bar'}), 'Bar'
16589
16590
16591test "#2796: ditto, ditto, ditto", ->
16592  answer = null
16593
16594  outsideMethod = (func) ->
16595    func.call message: 'wrong!'
16596
16597  class Base
16598    constructor: ->
16599      @message = 'right!'
16600      outsideMethod @echo
16601
16602    echo: =>
16603      answer = @message
16604
16605  new Base
16606  eq answer, 'right!'
16607
16608test "#3063: Class bodies cannot contain pure statements", ->
16609  throwsCompileError """
16610    class extends S
16611      return if S.f
16612      @f: => this
16613  """
16614
16615test "#2949: super in static method with reserved name", ->
16616  class Foo
16617    @static: -> 'baz'
16618
16619  class Bar extends Foo
16620    @static: -> super()
16621
16622  eq Bar.static(), 'baz'
16623
16624test "#3232: super in static methods (not object-assigned)", ->
16625  class Foo
16626    @baz = -> true
16627    @qux = -> true
16628
16629  class Bar extends Foo
16630    @baz = -> super()
16631    Bar.qux = -> super()
16632
16633  ok Bar.baz()
16634  ok Bar.qux()
16635
16636test "#1392 calling `super` in methods defined on namespaced classes", ->
16637  class Base
16638    m: -> 5
16639    n: -> 4
16640  namespace =
16641    A: ->
16642    B: ->
16643  class namespace.A extends Base
16644    m: -> super()
16645
16646  eq 5, (new namespace.A).m()
16647  namespace.B::m = namespace.A::m
16648  namespace.A::m = null
16649  eq 5, (new namespace.B).m()
16650
16651  class C
16652    @a: class extends Base
16653      m: -> super()
16654  eq 5, (new C.a).m()
16655
16656
16657test "#4436 immediately instantiated named class", ->
16658  ok new class Foo
16659
16660
16661test "dynamic method names", ->
16662  class A
16663    "#{name = 'm'}": -> 1
16664  eq 1, new A().m()
16665
16666  class B extends A
16667    "#{name = 'm'}": -> super()
16668  eq 1, new B().m()
16669
16670  getName = -> 'm'
16671  class C
16672    "#{name = getName()}": -> 1
16673  eq 1, new C().m()
16674
16675
16676test "dynamic method names and super", ->
16677  class Base
16678    @m: -> 6
16679    m: -> 5
16680    m2: -> 4.5
16681    n: -> 4
16682
16683  name = -> count++; 'n'
16684  count = 0
16685
16686  m = 'm'
16687  class A extends Base
16688    "#{m}": -> super()
16689    "#{name()}": -> super()
16690
16691  m = 'n'
16692  eq 5, (new A).m()
16693
16694  eq 4, (new A).n()
16695  eq 1, count
16696
16697  m = 'm'
16698  m2 = 'm2'
16699  count = 0
16700  class B extends Base
16701    @[name()] = -> super()
16702    "#{m}": -> super()
16703    "#{m2}": -> super()
16704  b = new B
16705  m = m2 = 'n'
16706  eq 6, B.m()
16707  eq 5, b.m()
16708  eq 4.5, b.m2()
16709  eq 1, count
16710
16711  class C extends B
16712    m: -> super()
16713  eq 5, (new C).m()
16714
16715# ES2015+ class interoperability
16716# Based on https://github.com/balupton/es6-javascript-class-interop
16717# Helper functions to generate true ES classes to extend:
16718getBasicClass = ->
16719  ```
16720  class BasicClass {
16721    constructor (greeting) {
16722      this.greeting = greeting || 'hi'
16723    }
16724  }
16725  ```
16726  BasicClass
16727
16728getExtendedClass = (BaseClass) ->
16729  ```
16730  class ExtendedClass extends BaseClass {
16731    constructor (greeting, name) {
16732      super(greeting || 'hello')
16733      this.name = name
16734    }
16735  }
16736  ```
16737  ExtendedClass
16738
16739test "can instantiate a basic ES class", ->
16740  BasicClass = getBasicClass()
16741  i = new BasicClass 'howdy!'
16742  eq i.greeting, 'howdy!'
16743
16744test "can instantiate an extended ES class", ->
16745  BasicClass = getBasicClass()
16746  ExtendedClass = getExtendedClass BasicClass
16747  i = new ExtendedClass 'yo', 'buddy'
16748  eq i.greeting, 'yo'
16749  eq i.name, 'buddy'
16750
16751test "can extend a basic ES class", ->
16752  BasicClass = getBasicClass()
16753  class ExtendedClass extends BasicClass
16754    constructor: (@name) ->
16755      super()
16756  i = new ExtendedClass 'dude'
16757  eq i.name, 'dude'
16758
16759test "can extend an extended ES class", ->
16760  BasicClass = getBasicClass()
16761  ExtendedClass = getExtendedClass BasicClass
16762
16763  class ExtendedExtendedClass extends ExtendedClass
16764    constructor: (@value) ->
16765      super()
16766    getDoubledValue: ->
16767      @value * 2
16768
16769  i = new ExtendedExtendedClass 7
16770  eq i.getDoubledValue(), 14
16771
16772test "CoffeeScript class can be extended in ES", ->
16773  class CoffeeClass
16774    constructor: (@favoriteDrink = 'latte', @size = 'grande') ->
16775    getDrinkOrder: ->
16776      "#{@size} #{@favoriteDrink}"
16777
16778  ```
16779  class ECMAScriptClass extends CoffeeClass {
16780    constructor (favoriteDrink) {
16781      super(favoriteDrink);
16782      this.favoriteDrink = this.favoriteDrink + ' with a dash of semicolons';
16783    }
16784  }
16785  ```
16786
16787  e = new ECMAScriptClass 'coffee'
16788  eq e.getDrinkOrder(), 'grande coffee with a dash of semicolons'
16789
16790test "extended CoffeeScript class can be extended in ES", ->
16791  class CoffeeClass
16792    constructor: (@favoriteDrink = 'latte') ->
16793
16794  class CoffeeClassWithDrinkOrder extends CoffeeClass
16795    constructor: (@favoriteDrink, @size = 'grande') ->
16796      super()
16797    getDrinkOrder: ->
16798      "#{@size} #{@favoriteDrink}"
16799
16800  ```
16801  class ECMAScriptClass extends CoffeeClassWithDrinkOrder {
16802    constructor (favoriteDrink) {
16803      super(favoriteDrink);
16804      this.favoriteDrink = this.favoriteDrink + ' with a dash of semicolons';
16805    }
16806  }
16807  ```
16808
16809  e = new ECMAScriptClass 'coffee'
16810  eq e.getDrinkOrder(), 'grande coffee with a dash of semicolons'
16811
16812test "`this` access after `super` in extended classes", ->
16813  class Base
16814
16815  class Test extends Base
16816    constructor: (param, @param) ->
16817      eq param, nonce
16818
16819      result = { super: super(), @param, @method }
16820      eq result.super, this
16821      eq result.param, @param
16822      eq result.method, @method
16823      ok result.method isnt Test::method
16824
16825    method: =>
16826
16827  nonce = {}
16828  new Test nonce, {}
16829
16830test "`@`-params and bound methods with multiple `super` paths (blocks)", ->
16831  nonce = {}
16832
16833  class Base
16834    constructor: (@name) ->
16835
16836  class Test extends Base
16837    constructor: (param, @param) ->
16838      if param
16839        super 'param'
16840        eq @name, 'param'
16841      else
16842        super 'not param'
16843        eq @name, 'not param'
16844      eq @param, nonce
16845      ok @method isnt Test::method
16846    method: =>
16847  new Test true, nonce
16848  new Test false, nonce
16849
16850
16851test "`@`-params and bound methods with multiple `super` paths (expressions)", ->
16852  nonce = {}
16853
16854  class Base
16855    constructor: (@name) ->
16856
16857  class Test extends Base
16858    constructor: (param, @param) ->
16859      # Contrived example: force each path into an expression with inline assertions
16860      if param
16861        result = (
16862          eq (super 'param'), @;
16863          eq @name, 'param';
16864          eq @param, nonce;
16865          ok @method isnt Test::method
16866        )
16867      else
16868        result = (
16869          eq (super 'not param'), @;
16870          eq @name, 'not param';
16871          eq @param, nonce;
16872          ok @method isnt Test::method
16873        )
16874    method: =>
16875  new Test true, nonce
16876  new Test false, nonce
16877
16878test "constructor super in arrow functions", ->
16879  class Test extends (class)
16880    constructor: (@param) ->
16881      do => super()
16882      eq @param, nonce
16883
16884  new Test nonce = {}
16885
16886# TODO Some of these tests use CoffeeScript.compile and CoffeeScript.run when they could use
16887# regular test mechanics.
16888# TODO Some of these tests might be better placed in `test/error_messages.coffee`.
16889# TODO Some of these tests are duplicates.
16890
16891# Ensure that we always throw if we experience more than one super()
16892# call in a constructor.  This ends up being a runtime error.
16893# Should be caught at compile time.
16894test "multiple super calls", ->
16895  throwsA = """
16896  class A
16897    constructor: (@drink) ->
16898    make: -> "Making a #{@drink}"
16899
16900  class MultiSuper extends A
16901    constructor: (drink) ->
16902      super(drink)
16903      super(drink)
16904      @newDrink = drink
16905  new MultiSuper('Late').make()
16906  """
16907  throws -> CoffeeScript.run throwsA, bare: yes
16908
16909# Basic test to ensure we can pass @params in a constuctor and
16910# inheritance works correctly
16911test "@ params", ->
16912  class A
16913    constructor: (@drink, @shots, @flavor) ->
16914    make: -> "Making a #{@flavor} #{@drink} with #{@shots} shot(s)"
16915
16916  a = new A('Machiato', 2, 'chocolate')
16917  eq a.make(),  "Making a chocolate Machiato with 2 shot(s)"
16918
16919  class B extends A
16920  b = new B('Machiato', 2, 'chocolate')
16921  eq b.make(),  "Making a chocolate Machiato with 2 shot(s)"
16922
16923# Ensure we can accept @params with default parameters in a constructor
16924test "@ params with defaults in a constructor", ->
16925  class A
16926    # Multiple @ params with defaults
16927    constructor: (@drink = 'Americano', @shots = '1', @flavor = 'caramel') ->
16928    make: -> "Making a #{@flavor} #{@drink} with #{@shots} shot(s)"
16929
16930  a = new A()
16931  eq a.make(),  "Making a caramel Americano with 1 shot(s)"
16932
16933# Ensure we can handle default constructors with class params
16934test "@ params with class params", ->
16935  class Beverage
16936    drink: 'Americano'
16937    shots: '1'
16938    flavor: 'caramel'
16939
16940  class A
16941    # Class creation as a default param with `this`
16942    constructor: (@drink = new Beverage()) ->
16943  a = new A()
16944  eq a.drink.drink, 'Americano'
16945
16946  beverage = new Beverage
16947  class B
16948    # class costruction with a default external param
16949    constructor: (@drink = beverage) ->
16950
16951  b = new B()
16952  eq b.drink.drink, 'Americano'
16953
16954  class C
16955    # Default constructor with anonymous empty class
16956    constructor: (@meta = class) ->
16957  c = new C()
16958  ok c.meta instanceof Function
16959
16960test "@ params without super, including errors", ->
16961  classA = """
16962  class A
16963    constructor: (@drink) ->
16964    make: -> "Making a #{@drink}"
16965  a = new A('Machiato')
16966  """
16967
16968  throwsB = """
16969  class B extends A
16970    #implied super
16971    constructor: (@drink) ->
16972  b = new B('Machiato')
16973  """
16974  throwsCompileError classA + throwsB, bare: yes
16975
16976test "@ params super race condition", ->
16977  classA = """
16978  class A
16979    constructor: (@drink) ->
16980    make: -> "Making a #{@drink}"
16981  """
16982
16983  throwsB = """
16984  class B extends A
16985    constructor: (@params) ->
16986
16987  b = new B('Machiato')
16988  """
16989  throwsCompileError classA + throwsB, bare: yes
16990
16991  # Race condition with @ and super
16992  throwsC = """
16993  class C extends A
16994    constructor: (@params) ->
16995      super(@params)
16996
16997  c = new C('Machiato')
16998  """
16999  throwsCompileError classA + throwsC, bare: yes
17000
17001
17002test "@ with super call", ->
17003  class D
17004    make: -> "Making a #{@drink}"
17005
17006  class E extends D
17007    constructor: (@drink) ->
17008      super()
17009
17010  e = new E('Machiato')
17011  eq e.make(),  "Making a Machiato"
17012
17013test "@ with splats and super call", ->
17014  class A
17015    make: -> "Making a #{@drink}"
17016
17017  class B extends A
17018    constructor: (@drink...) ->
17019      super()
17020
17021  B = new B('Machiato')
17022  eq B.make(),  "Making a Machiato"
17023
17024
17025test "super and external constructors", ->
17026  # external constructor with @ param is allowed
17027  ctorA = (@drink) ->
17028  class A
17029    constructor: ctorA
17030    make: -> "Making a #{@drink}"
17031  a = new A('Machiato')
17032  eq a.make(),  "Making a Machiato"
17033
17034  # External constructor with super
17035  throwsC = """
17036  class B
17037    constructor: (@drink) ->
17038    make: -> "Making a #{@drink}"
17039
17040  ctorC = (drink) ->
17041    super(drink)
17042
17043  class C extends B
17044    constructor: ctorC
17045  c = new C('Machiato')
17046  """
17047  throwsCompileError throwsC, bare: yes
17048
17049
17050test "bound functions without super", ->
17051  # Bound function with @
17052  # Throw on compile, since bound
17053  # constructors are illegal
17054  throwsA = """
17055  class A
17056    constructor: (drink) =>
17057      @drink = drink
17058
17059  """
17060  throwsCompileError throwsA, bare: yes
17061
17062test "super in a bound function in a constructor", ->
17063  throwsB = """
17064  class A
17065  class B extends A
17066    constructor: do => super
17067  """
17068  throwsCompileError throwsB, bare: yes
17069
17070test "super in a bound function", ->
17071  class A
17072    constructor: (@drink) ->
17073    make: -> "Making a #{@drink}"
17074
17075  class B extends A
17076    make: (@flavor) =>
17077      super() + " with #{@flavor}"
17078
17079  b = new B('Machiato')
17080  eq b.make('vanilla'),  "Making a Machiato with vanilla"
17081
17082  # super in a bound function in a bound function
17083  class C extends A
17084    make: (@flavor) =>
17085      func = () =>
17086        super() + " with #{@flavor}"
17087      func()
17088
17089  c = new C('Machiato')
17090  eq c.make('vanilla'), "Making a Machiato with vanilla"
17091
17092  # bound function in a constructor
17093  class D extends A
17094    constructor: (drink) ->
17095      super(drink)
17096      x = =>
17097        eq @drink,  "Machiato"
17098      x()
17099  d = new D('Machiato')
17100  eq d.make(),  "Making a Machiato"
17101
17102# duplicate
17103test "super in a try/catch", ->
17104  classA = """
17105  class A
17106    constructor: (param) ->
17107      throw "" unless param
17108  """
17109
17110  throwsB = """
17111  class B extends A
17112      constructor: ->
17113        try
17114          super()
17115  """
17116
17117  throwsC = """
17118  ctor = ->
17119    try
17120      super()
17121
17122  class C extends A
17123      constructor: ctor
17124  """
17125  throws -> CoffeeScript.run classA + throwsB, bare: yes
17126  throws -> CoffeeScript.run classA + throwsC, bare: yes
17127
17128test "mixed ES6 and CS6 classes with a four-level inheritance chain", ->
17129  # Extended test
17130  # ES2015+ class interoperability
17131
17132  ```
17133  class Base {
17134    constructor (greeting) {
17135      this.greeting = greeting || 'hi';
17136    }
17137    func (string) {
17138      return 'zero/' + string;
17139    }
17140    static  staticFunc (string) {
17141      return 'static/' + string;
17142    }
17143  }
17144  ```
17145
17146  class FirstChild extends Base
17147    func: (string) ->
17148      super('one/') + string
17149
17150
17151  ```
17152  class SecondChild extends FirstChild {
17153    func (string) {
17154      return super.func('two/' + string);
17155    }
17156  }
17157  ```
17158
17159  thirdCtor = ->
17160    @array = [1, 2, 3]
17161
17162  class ThirdChild extends SecondChild
17163    constructor: ->
17164      super()
17165      thirdCtor.call this
17166    func: (string) ->
17167      super('three/') + string
17168
17169  result = (new ThirdChild).func 'four'
17170  ok result is 'zero/one/two/three/four'
17171  ok Base.staticFunc('word') is 'static/word'
17172
17173# exercise extends in a nested class
17174test "nested classes with super", ->
17175  class Outer
17176    constructor: ->
17177      @label = 'outer'
17178
17179    class @Inner
17180      constructor: ->
17181        @label = 'inner'
17182
17183    class @ExtendedInner extends @Inner
17184      constructor: ->
17185        tmp = super()
17186        @label = tmp.label + ' extended'
17187
17188    @extender: () =>
17189      class ExtendedSelf extends @
17190        constructor: ->
17191          tmp = super()
17192          @label = tmp.label + ' from this'
17193      new ExtendedSelf
17194
17195  eq (new Outer).label, 'outer'
17196  eq (new Outer.Inner).label, 'inner'
17197  eq (new Outer.ExtendedInner).label, 'inner extended'
17198  eq (Outer.extender()).label, 'outer from this'
17199
17200test "Static methods generate 'static' keywords", ->
17201  compile = """
17202  class CheckStatic
17203    constructor: (@drink) ->
17204    @className: -> 'CheckStatic'
17205
17206  c = new CheckStatic('Machiato')
17207  """
17208  result = CoffeeScript.compile compile, bare: yes
17209  ok result.match(' static ')
17210
17211test "Static methods in nested classes", ->
17212  class Outer
17213    @name: -> 'Outer'
17214
17215    class @Inner
17216      @name: -> 'Inner'
17217
17218  eq Outer.name(), 'Outer'
17219  eq Outer.Inner.name(), 'Inner'
17220
17221
17222test "mixed constructors with inheritance and ES6 super", ->
17223  identity = (f) -> f
17224
17225  class TopClass
17226    constructor: (arg) ->
17227      @prop = 'top-' + arg
17228
17229  ```
17230  class SuperClass extends TopClass {
17231    constructor (arg) {
17232      identity(super('super-' + arg));
17233    }
17234  }
17235  ```
17236  class SubClass extends SuperClass
17237    constructor: ->
17238      identity super 'sub'
17239
17240  ok (new SubClass).prop is 'top-super-sub'
17241
17242test "ES6 static class methods can be overriden", ->
17243  class A
17244    @name: -> 'A'
17245
17246  class B extends A
17247    @name: -> 'B'
17248
17249  eq A.name(), 'A'
17250  eq B.name(), 'B'
17251
17252# If creating static by direct assignment rather than ES6 static keyword
17253test "ES6 Static methods should set `this` to undefined // ES6 ", ->
17254  class A
17255    @test: ->
17256      eq this, undefined
17257
17258# Ensure that our object prototypes work with ES6
17259test "ES6 prototypes can be overriden", ->
17260  class A
17261    className: 'classA'
17262
17263  ```
17264  class B {
17265    test () {return "B";};
17266  }
17267  ```
17268  b = new B
17269  a = new A
17270  eq a.className, 'classA'
17271  eq b.test(), 'B'
17272  Object.setPrototypeOf(b, a)
17273  eq b.className, 'classA'
17274  # This shouldn't throw,
17275  # as we only change inheritance not object construction
17276  # This may be an issue with ES, rather than CS construction?
17277  #eq b.test(), 'B'
17278
17279  class D extends B
17280  B::test = () -> 'D'
17281  eq (new D).test(), 'D'
17282
17283# TODO: implement this error check
17284# test "ES6 conformance to extending non-classes", ->
17285#   A = (@title) ->
17286#     'Title: ' + @
17287
17288#   class B extends A
17289#   b = new B('caffeinated')
17290#   eq b.title, 'caffeinated'
17291
17292#   # Check inheritance chain
17293#   A::getTitle = () -> @title
17294#   eq b.getTitle(), 'caffeinated'
17295
17296#   throwsC = """
17297#   C = {title: 'invalid'}
17298#   class D extends {}
17299#   """
17300#   # This should catch on compile and message should be "class can only extend classes and functions."
17301#   throws -> CoffeeScript.run throwsC, bare: yes
17302
17303# TODO: Evaluate future compliance with "strict mode";
17304# test "Class function environment should be in `strict mode`, ie as if 'use strict' was in use", ->
17305#   class A
17306#     # this might be a meaningless test, since these are likely to be runtime errors and different
17307#     # for every browser.  Thoughts?
17308#     constructor: () ->
17309#       # Ivalid: prop reassignment
17310#       @state = {prop: [1], prop: {a: 'a'}}
17311#       # eval reassignment
17312#       @badEval = eval;
17313
17314#   # Should throw, but doesn't
17315#   a = new A
17316
17317test "only one method named constructor allowed", ->
17318  throwsA = """
17319  class A
17320    constructor: (@first) ->
17321    constructor: (@last) ->
17322  """
17323  throwsCompileError throwsA, bare: yes
17324
17325test "If the constructor of a child class does not call super,it should return an object.", ->
17326  nonce = {}
17327
17328  class A
17329  class B extends A
17330    constructor: ->
17331      return nonce
17332
17333  eq nonce, new B
17334
17335
17336test "super can only exist in extended classes", ->
17337  throwsA = """
17338  class A
17339    constructor: (@name) ->
17340      super()
17341  """
17342  throwsCompileError throwsA, bare: yes
17343
17344# --- CS1 classes compatability breaks ---
17345test "CS6 Class extends a CS1 compiled class", ->
17346  ```
17347  // Generated by CoffeeScript 1.11.1
17348  var BaseCS1, ExtendedCS1,
17349    extend = 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; },
17350    hasProp = {}.hasOwnProperty;
17351
17352  BaseCS1 = (function() {
17353    function BaseCS1(drink) {
17354      this.drink = drink;
17355    }
17356
17357    BaseCS1.prototype.make = function() {
17358      return "making a " + this.drink;
17359    };
17360
17361    BaseCS1.className = function() {
17362      return 'BaseCS1';
17363    };
17364
17365    return BaseCS1;
17366
17367  })();
17368
17369  ExtendedCS1 = (function(superClass) {
17370    extend(ExtendedCS1, superClass);
17371
17372    function ExtendedCS1(flavor) {
17373      this.flavor = flavor;
17374      ExtendedCS1.__super__.constructor.call(this, 'cafe ole');
17375    }
17376
17377    ExtendedCS1.prototype.make = function() {
17378      return "making a " + this.drink + " with " + this.flavor;
17379    };
17380
17381    ExtendedCS1.className = function() {
17382      return 'ExtendedCS1';
17383    };
17384
17385    return ExtendedCS1;
17386
17387  })(BaseCS1);
17388
17389  ```
17390  class B extends BaseCS1
17391  eq B.className(), 'BaseCS1'
17392  b = new B('machiato')
17393  eq b.make(), "making a machiato"
17394
17395
17396test "CS6 Class extends an extended CS1 compiled class", ->
17397  ```
17398  // Generated by CoffeeScript 1.11.1
17399  var BaseCS1, ExtendedCS1,
17400    extend = 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; },
17401    hasProp = {}.hasOwnProperty;
17402
17403  BaseCS1 = (function() {
17404    function BaseCS1(drink) {
17405      this.drink = drink;
17406    }
17407
17408    BaseCS1.prototype.make = function() {
17409      return "making a " + this.drink;
17410    };
17411
17412    BaseCS1.className = function() {
17413      return 'BaseCS1';
17414    };
17415
17416    return BaseCS1;
17417
17418  })();
17419
17420  ExtendedCS1 = (function(superClass) {
17421    extend(ExtendedCS1, superClass);
17422
17423    function ExtendedCS1(flavor) {
17424      this.flavor = flavor;
17425      ExtendedCS1.__super__.constructor.call(this, 'cafe ole');
17426    }
17427
17428    ExtendedCS1.prototype.make = function() {
17429      return "making a " + this.drink + " with " + this.flavor;
17430    };
17431
17432    ExtendedCS1.className = function() {
17433      return 'ExtendedCS1';
17434    };
17435
17436    return ExtendedCS1;
17437
17438  })(BaseCS1);
17439
17440  ```
17441  class B extends ExtendedCS1
17442  eq B.className(), 'ExtendedCS1'
17443  b = new B('vanilla')
17444  eq b.make(), "making a cafe ole with vanilla"
17445
17446test "CS6 Class extends a CS1 compiled class with super()", ->
17447  ```
17448  // Generated by CoffeeScript 1.11.1
17449  var BaseCS1, ExtendedCS1,
17450    extend = 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; },
17451    hasProp = {}.hasOwnProperty;
17452
17453  BaseCS1 = (function() {
17454    function BaseCS1(drink) {
17455      this.drink = drink;
17456    }
17457
17458    BaseCS1.prototype.make = function() {
17459      return "making a " + this.drink;
17460    };
17461
17462    BaseCS1.className = function() {
17463      return 'BaseCS1';
17464    };
17465
17466    return BaseCS1;
17467
17468  })();
17469
17470  ExtendedCS1 = (function(superClass) {
17471    extend(ExtendedCS1, superClass);
17472
17473    function ExtendedCS1(flavor) {
17474      this.flavor = flavor;
17475      ExtendedCS1.__super__.constructor.call(this, 'cafe ole');
17476    }
17477
17478    ExtendedCS1.prototype.make = function() {
17479      return "making a " + this.drink + " with " + this.flavor;
17480    };
17481
17482    ExtendedCS1.className = function() {
17483      return 'ExtendedCS1';
17484    };
17485
17486    return ExtendedCS1;
17487
17488  })(BaseCS1);
17489
17490  ```
17491  class B extends ExtendedCS1
17492    constructor: (@shots) ->
17493      super('caramel')
17494    make: () ->
17495      super() + " and #{@shots} shots of espresso"
17496
17497  eq B.className(), 'ExtendedCS1'
17498  b = new B('three')
17499  eq b.make(), "making a cafe ole with caramel and three shots of espresso"
17500
17501test 'Bound method called normally before binding is ok', ->
17502  class Base
17503    constructor: ->
17504      @setProp()
17505      eq @derivedBound(), 3
17506
17507  class Derived extends Base
17508    setProp: ->
17509      @prop = 3
17510
17511    derivedBound: =>
17512      @prop
17513
17514  d = new Derived
17515
17516test 'Bound method called as callback after super() is ok', ->
17517  class Base
17518
17519  class Derived extends Base
17520    constructor: (@prop = 3) ->
17521      super()
17522      f = @derivedBound
17523      eq f(), 3
17524
17525    derivedBound: =>
17526      @prop
17527
17528  d = new Derived
17529  {derivedBound} = d
17530  eq derivedBound(), 3
17531
17532test 'Bound method of base class called as callback is ok', ->
17533  class Base
17534    constructor: (@prop = 3) ->
17535      f = @baseBound
17536      eq f(), 3
17537
17538    baseBound: =>
17539      @prop
17540
17541  b = new Base
17542  {baseBound} = b
17543  eq baseBound(), 3
17544
17545test 'Bound method of prop-named class called as callback is ok', ->
17546  Hive = {}
17547  class Hive.Bee
17548    constructor: (@prop = 3) ->
17549      f = @baseBound
17550      eq f(), 3
17551
17552    baseBound: =>
17553      @prop
17554
17555  b = new Hive.Bee
17556  {baseBound} = b
17557  eq baseBound(), 3
17558
17559test 'Bound method of class with expression base class called as callback is ok', ->
17560  calledB = no
17561  B = ->
17562    throw new Error if calledB
17563    calledB = yes
17564    class
17565  class A extends B()
17566    constructor: (@prop = 3) ->
17567      super()
17568      f = @derivedBound
17569      eq f(), 3
17570
17571    derivedBound: =>
17572      @prop
17573
17574  b = new A
17575  {derivedBound} = b
17576  eq derivedBound(), 3
17577
17578test 'Bound method of class with expression class name called as callback is ok', ->
17579  calledF = no
17580  obj = {}
17581  B = class
17582  f = ->
17583    throw new Error if calledF
17584    calledF = yes
17585    obj
17586  class f().A extends B
17587    constructor: (@prop = 3) ->
17588      super()
17589      g = @derivedBound
17590      eq g(), 3
17591
17592    derivedBound: =>
17593      @prop
17594
17595  a = new obj.A
17596  {derivedBound} = a
17597  eq derivedBound(), 3
17598
17599test 'Bound method of anonymous child class called as callback is ok', ->
17600  f = ->
17601    B = class
17602    class extends B
17603      constructor: (@prop = 3) ->
17604        super()
17605        g = @derivedBound
17606        eq g(), 3
17607
17608      derivedBound: =>
17609        @prop
17610
17611  a = new (f())
17612  {derivedBound} = a
17613  eq derivedBound(), 3
17614
17615test 'Bound method of immediately instantiated class with expression base class called as callback is ok', ->
17616  calledF = no
17617  obj = {}
17618  B = class
17619  f = ->
17620    throw new Error if calledF
17621    calledF = yes
17622    obj
17623  a = new class f().A extends B
17624    constructor: (@prop = 3) ->
17625      super()
17626      g = @derivedBound
17627      eq g(), 3
17628
17629    derivedBound: =>
17630      @prop
17631
17632  {derivedBound} = a
17633  eq derivedBound(), 3
17634
17635test "#4591: super.x.y, super['x'].y", ->
17636  class A
17637    x:
17638      y: 1
17639      z: -> 2
17640
17641  class B extends A
17642    constructor: ->
17643      super()
17644
17645      @w = super.x.y
17646      @v = super['x'].y
17647      @u = super.x['y']
17648      @t = super.x.z()
17649      @s = super['x'].z()
17650      @r = super.x['z']()
17651
17652  b = new B
17653  eq 1, b.w
17654  eq 1, b.v
17655  eq 1, b.u
17656  eq 2, b.t
17657  eq 2, b.s
17658  eq 2, b.r
17659
17660test "#4464: backticked expressions in class body", ->
17661  class A
17662    `get x() { return 42; }`
17663
17664  class B
17665    `get x() { return 42; }`
17666    constructor: ->
17667      @y = 84
17668
17669  a = new A
17670  eq 42, a.x
17671  b = new B
17672  eq 42, b.x
17673  eq 84, b.y
17674
17675test "#4724: backticked expression in a class body with hoisted member", ->
17676  class A
17677    `get x() { return 42; }`
17678    hoisted: 84
17679
17680  a = new A
17681  eq 42, a.x
17682  eq 84, a.hoisted
17683
17684test "#4822: nested anonymous classes use non-conflicting variable names", ->
17685  Class = class
17686    @a: class
17687      @b: 1
17688
17689  eq Class.a.b, 1
17690
17691test "#4827: executable class body wrappers have correct context", ->
17692  test = ->
17693    class @A
17694    class @B extends @A
17695      @property = 1
17696
17697  o = {}
17698  test.call o
17699  ok typeof o.A is typeof o.B is 'function'
17700
17701test "#4868: Incorrect ‘Can’t call super with @params’ error", ->
17702  class A
17703    constructor: (@func = ->) ->
17704      @x = 1
17705      @func()
17706
17707  class B extends A
17708    constructor: ->
17709      super -> @x = 2
17710
17711  a = new A
17712  b = new B
17713  eq 1, a.x
17714  eq 2, b.x
17715
17716  class C
17717    constructor: (@c = class) -> @c
17718
17719  class D extends C
17720    constructor: ->
17721      super class then constructor: (@a) -> @a = 3
17722
17723  d = new (new D).c
17724  eq 3, d.a
17725
17726test "#4609: Support new.target", ->
17727  class A
17728    constructor: ->
17729      @calledAs = new.target.name
17730
17731  class B extends A
17732
17733  b = new B
17734  eq b.calledAs, 'B'
17735
17736  newTarget = null
17737  Foo = ->
17738    newTarget = !!new.target
17739
17740  Foo()
17741  eq newTarget, no
17742
17743  newTarget = null
17744
17745  new Foo()
17746  eq newTarget, yes
17747
17748test "#5323: new.target can be the argument of a function", ->
17749  fn = (arg) -> arg
17750  fn new.target
17751
17752test "#5085: Bug: @ reference to class not maintained in do block", ->
17753  thisFoo = 'initial foo'
17754  thisBar = 'initial bar'
17755  fn = (o) -> o.bar()
17756
17757  class A
17758    @foo = 'foo assigned in class'
17759    do => thisFoo = @foo
17760    fn bar: => thisBar = @foo
17761
17762  eq thisFoo, 'foo assigned in class'
17763  eq thisBar, 'foo assigned in class'
17764
17765test "#5204: Computed class property", ->
17766  foo = 'bar'
17767  class A
17768    [foo]: 'baz'
17769  a = new A()
17770  eq a.bar, 'baz'
17771  eq A::bar, 'baz'
17772
17773test "#5204: Static computed class property", ->
17774  foo = 'bar'
17775  qux = 'quux'
17776  class A
17777    @[foo]: 'baz'
17778    @[qux]: -> 3
17779  eq A.bar, 'baz'
17780  eq A.quux(), 3
17781
17782</script>
vendor: 1 bytes, line 17782
17782
17783<script type="text/x-coffeescript" class="test" id="cluster">
17784# Cluster Module
17785# ---------
17786
17787return if testingBrowser?
17788
17789cluster = require 'cluster'
17790
17791if cluster.isMaster
17792  test "#2737 - cluster module can spawn workers from a coffeescript process", ->
17793    cluster.once 'exit', (worker, code) ->
17794      eq code, 0
17795
17796    cluster.fork()
17797else
17798  process.exit 0
17799
17800</script>
vendor: 1 bytes, line 17800
17800
17801<script type="text/x-coffeescript" class="test" id="comments">
17802# Comments
17803# --------
17804
17805# * Single-Line Comments
17806# * Block Comments
17807
17808# Note: awkward spacing seen in some tests is likely intentional.
17809
17810test "comments in objects", ->
17811  obj1 = {
17812  # comment
17813    # comment
17814      # comment
17815    one: 1
17816  # comment
17817    two: 2
17818      # comment
17819  }
17820
17821  ok Object::hasOwnProperty.call(obj1,'one')
17822  eq obj1.one, 1
17823  ok Object::hasOwnProperty.call(obj1,'two')
17824  eq obj1.two, 2
17825
17826test "comments in YAML-style objects", ->
17827  obj2 =
17828  # comment
17829    # comment
17830      # comment
17831    three: 3
17832  # comment
17833    four: 4
17834      # comment
17835
17836  ok Object::hasOwnProperty.call(obj2,'three')
17837  eq obj2.three, 3
17838  ok Object::hasOwnProperty.call(obj2,'four')
17839  eq obj2.four, 4
17840
17841test "comments following operators that continue lines", ->
17842  sum =
17843    1 +
17844    1 + # comment
17845    1
17846  eq 3, sum
17847
17848test "comments in functions", ->
17849  fn = ->
17850  # comment
17851    false
17852    false   # comment
17853    false
17854    # comment
17855
17856  # comment before return
17857    true
17858
17859  ok fn()
17860
17861  fn2 = -> #comment
17862    fn()
17863    # comment after return
17864
17865  ok fn2()
17866
17867test "trailing comment before an outdent", ->
17868  nonce = {}
17869  fn3 = ->
17870    if true
17871      undefined # comment
17872    nonce
17873
17874  eq nonce, fn3()
17875
17876test "comments in a switch", ->
17877  nonce = {}
17878  result = switch nonce #comment
17879    # comment
17880    when false then undefined
17881    # comment
17882    when null #comment
17883      undefined
17884    else nonce # comment
17885
17886  eq nonce, result
17887
17888test "comment with conditional statements", ->
17889  nonce = {}
17890  result = if false # comment
17891    undefined
17892  #comment
17893  else # comment
17894    nonce
17895    # comment
17896  eq nonce, result
17897
17898test "spaced comments with conditional statements", ->
17899  nonce = {}
17900  result = if false
17901    undefined
17902
17903  # comment
17904  else if false
17905    undefined
17906
17907  # comment
17908  else
17909    nonce
17910
17911  eq nonce, result
17912
17913
17914# Block Comments
17915
17916###
17917  This is a here-comment.
17918  Kind of like a heredoc.
17919###
17920
17921test "block comments in objects", ->
17922  a = {}
17923  b = {}
17924  obj = {
17925    a: a
17926    ###
17927    block comment in object
17928    ###
17929    b: b
17930  }
17931
17932  eq a, obj.a
17933  eq b, obj.b
17934
17935test "block comments in YAML-style", ->
17936  a = {}
17937  b = {}
17938  obj =
17939    a: a
17940    ###
17941    block comment in YAML-style
17942    ###
17943    b: b
17944
17945  eq a, obj.a
17946  eq b, obj.b
17947
17948
17949test "block comments in functions", ->
17950  nonce = {}
17951
17952  fn1 = ->
17953    true
17954    ###
17955    false
17956    ###
17957
17958  ok fn1()
17959
17960  fn2 = ->
17961    ###
17962    block comment in function 1
17963    ###
17964    nonce
17965
17966  eq nonce, fn2()
17967
17968  fn3 = ->
17969    nonce
17970  ###
17971  block comment in function 2
17972  ###
17973
17974  eq nonce, fn3()
17975
17976  fn4 = ->
17977    one = ->
17978      ###
17979        block comment in function 3
17980      ###
17981      two = ->
17982        three = ->
17983          nonce
17984
17985  eq nonce, fn4()()()()
17986
17987test "block comments inside class bodies", ->
17988  class A
17989    a: ->
17990
17991    ###
17992    Comment in class body 1
17993    ###
17994    b: ->
17995
17996  ok A.prototype.b instanceof Function
17997
17998  class B
17999    ###
18000    Comment in class body 2
18001    ###
18002    a: ->
18003    b: ->
18004
18005  ok B.prototype.a instanceof Function
18006
18007test "#2037: herecomments shouldn't imply line terminators", ->
18008  do (-> ### ###yes; fail)
18009
18010test "#2916: block comment before implicit call with implicit object", ->
18011  fn = (obj) -> ok obj.a
18012  ### ###
18013  fn
18014    a: yes
18015
18016test "#3132: Format single-line block comment nicely", ->
18017  eqJS """
18018  ### Single-line block comment without additional space here => ###""",
18019  """
18020  /* Single-line block comment without additional space here => */
18021  """
18022
18023test "#3132: Format multiline block comment nicely", ->
18024  eqJS """
18025  ###
18026  # Multiline
18027  # block
18028  # comment
18029  ###""",
18030  """
18031  /*
18032   * Multiline
18033   * block
18034   * comment
18035   */
18036  """
18037
18038test "#3132: Format simple block comment nicely", ->
18039  eqJS """
18040  ###
18041  No
18042  Preceding hash
18043  ###""",
18044  """
18045  /*
18046  No
18047  Preceding hash
18048  */
18049  """
18050
18051
18052test "#3132: Format indented block-comment nicely", ->
18053  eqJS """
18054  fn = ->
18055    ###
18056    # Indented
18057    Multiline
18058    ###
18059    1""",
18060  """
18061  var fn;
18062
18063  fn = function() {
18064    /*
18065     * Indented
18066    Multiline
18067     */
18068    return 1;
18069  };
18070  """
18071
18072# Although adequately working, block comment-placement is not yet perfect.
18073# (Considering a case where multiple variables have been declared …)
18074test "#3132: Format jsdoc-style block-comment nicely", ->
18075  eqJS """
18076  ###*
18077  # Multiline for jsdoc-"@doctags"
18078  #
18079  # @type {Function}
18080  ###
18081  fn = () -> 1
18082  """,
18083  """
18084  /**
18085   * Multiline for jsdoc-"@doctags"
18086   *
18087   * @type {Function}
18088   */
18089  var fn;
18090
18091  fn = function() {
18092    return 1;
18093  };"""
18094
18095# Although adequately working, block comment-placement is not yet perfect.
18096# (Considering a case where multiple variables have been declared …)
18097test "#3132: Format hand-made (raw) jsdoc-style block-comment nicely", ->
18098  eqJS """
18099  ###*
18100   * Multiline for jsdoc-"@doctags"
18101   *
18102   * @type {Function}
18103  ###
18104  fn = () -> 1
18105  """,
18106  """
18107  /**
18108   * Multiline for jsdoc-"@doctags"
18109   *
18110   * @type {Function}
18111   */
18112  var fn;
18113
18114  fn = function() {
18115    return 1;
18116  };"""
18117
18118# Although adequately working, block comment-placement is not yet perfect.
18119# (Considering a case where multiple variables have been declared …)
18120test "#3132: Place block-comments nicely", ->
18121  eqJS """
18122  ###*
18123  # A dummy class definition
18124  #
18125  # @class
18126  ###
18127  class DummyClass
18128
18129    ###*
18130    # @constructor
18131    ###
18132    constructor: ->
18133
18134    ###*
18135    # Singleton reference
18136    #
18137    # @type {DummyClass}
18138    ###
18139    @instance = new DummyClass()
18140
18141  """,
18142  """
18143  /**
18144   * A dummy class definition
18145   *
18146   * @class
18147   */
18148  var DummyClass;
18149
18150  DummyClass = (function() {
18151    class DummyClass {
18152      /**
18153       * @constructor
18154       */
18155      constructor() {}
18156
18157    };
18158
18159    /**
18160     * Singleton reference
18161     *
18162     * @type {DummyClass}
18163     */
18164    DummyClass.instance = new DummyClass();
18165
18166    return DummyClass;
18167
18168  }).call(this);"""
18169
18170test "#3638: Demand a whitespace after # symbol", ->
18171  eqJS """
18172  ###
18173  #No
18174  #whitespace
18175  ###""",
18176  """
18177  /*
18178  #No
18179  #whitespace
18180   */"""
18181
18182
18183test "#3761: Multiline comment at end of an object", ->
18184  anObject =
18185    x: 3
18186    ###
18187    #Comment
18188    ###
18189
18190  ok anObject.x is 3
18191
18192test "#4375: UTF-8 characters in comments", ->
18193  # 智に働けば角が立つ、情に掉させば流される。
18194  ok yes
18195
18196test "#4290: Block comments in array literals", ->
18197  arr = [
18198    ###  ###
18199    3
18200    ###
18201      What is the meaning of life, the universe, and everything?
18202    ###
18203    42
18204  ]
18205  arrayEq arr, [3, 42]
18206
18207test "Block comments in array literals are properly indented 1", ->
18208  eqJS '''
18209  arr = [
18210    ### ! ###
18211    3
18212    42
18213  ]''', '''
18214  var arr;
18215
18216  arr = [/* ! */ 3, 42];'''
18217
18218test "Block comments in array literals are properly indented 2", ->
18219  eqJS '''
18220  arr = [
18221    ###  ###
18222    3
18223    ###
18224      What is the meaning of life, the universe, and everything?
18225    ###
18226    42
18227  ]''', '''
18228  var arr;
18229
18230  arr = [
18231    /*  */
18232    3,
18233    /*
18234      What is the meaning of life, the universe, and everything?
18235    */
18236    42
18237  ];'''
18238
18239test "Block comments in array literals are properly indented 3", ->
18240  eqJS '''
18241  arr = [
18242    ###
18243      How many stooges are there?
18244    ###
18245    3
18246    ### Who’s on first? ###
18247    'Who'
18248  ]''', '''
18249  var arr;
18250
18251  arr = [
18252    /*
18253      How many stooges are there?
18254    */
18255    3,
18256    /* Who’s on first? */
18257    'Who'
18258  ];'''
18259
18260test "Block comments in array literals are properly indented 4", ->
18261  eqJS '''
18262  if yes
18263    arr = [
18264      1
18265      ###
18266        How many stooges are there?
18267      ###
18268      3
18269      ### Who’s on first? ###
18270      'Who'
18271    ]''', '''
18272  var arr;
18273
18274  if (true) {
18275    arr = [
18276      1,
18277      /*
18278        How many stooges are there?
18279      */
18280      3,
18281      /* Who’s on first? */
18282      'Who'
18283    ];
18284  }'''
18285
18286test "Line comments in array literals are properly indented 1", ->
18287  eqJS '''
18288  arr = [
18289    # How many stooges are there?
18290    3
18291    # Who’s on first?
18292    'Who'
18293  ]''', '''
18294  var arr;
18295
18296  arr = [
18297    // How many stooges are there?
18298    3,
18299    // Who’s on first?
18300    'Who'
18301  ];'''
18302
18303test "Line comments in array literals are properly indented 2", ->
18304  eqJS '''
18305  arr = [
18306    # How many stooges are there?
18307    3
18308    # Who’s on first?
18309    'Who'
18310    # Who?
18311    {
18312      firstBase: 'Who'
18313      secondBase: 'What'
18314      leftField: 'Why'
18315    }
18316  ]''', '''
18317  var arr;
18318
18319  arr = [
18320    // How many stooges are there?
18321    3,
18322    // Who’s on first?
18323    'Who',
18324    {
18325      // Who?
18326      firstBase: 'Who',
18327      secondBase: 'What',
18328      leftField: 'Why'
18329    }
18330  ];'''
18331
18332test "Block comments trailing their attached token are properly indented", ->
18333  eqJS '''
18334  if indented
18335    if indentedAgain
18336      a
18337      ###
18338        Multiline
18339        comment
18340      ###
18341    a
18342  ''', '''
18343  if (indented) {
18344    if (indentedAgain) {
18345      a;
18346    }
18347    /*
18348      Multiline
18349      comment
18350    */
18351    a;
18352  }
18353  '''
18354
18355test "Comments in proper order 1", ->
18356  eqJS '''
18357  # 1
18358  ### 2 ###
18359  # 3
18360  ''', '''
18361  // 1
18362  /* 2 */
18363  // 3
18364  '''
18365
18366test "Comments in proper order 2", ->
18367  eqJS '''
18368  if indented
18369    # 1
18370    ### 2 ###
18371    # 3
18372    a
18373  ''', '''
18374  if (indented) {
18375    // 1
18376    /* 2 */
18377    // 3
18378    a;
18379  }
18380  '''
18381
18382test "Line comment above interpolated string", ->
18383  eqJS '''
18384  if indented
18385    # comment
18386    "#{1}"
18387  ''', '''
18388  if (indented) {
18389    // comment
18390    `${1}`;
18391  }'''
18392
18393test "Line comment above interpolated string object key", ->
18394  eqJS '''
18395  {
18396    # comment
18397    "#{1}": 2
18398  }
18399  ''', '''
18400  ({
18401    // comment
18402    [`${1}`]: 2
18403  });'''
18404
18405test "Line comments in classes are properly indented", ->
18406  eqJS '''
18407  class A extends B
18408    # This is a fine class.
18409    # I could tell you all about it, but what else do you need to know?
18410    constructor: ->
18411      # Something before `super`
18412      super()
18413
18414    # This next method is a doozy!
18415    # A doozy, I tell ya!
18416    method: ->
18417      # Whoa.
18418      # Can you believe it?
18419      no
18420
18421    ### Look out, incoming! ###
18422    anotherMethod: ->
18423      ### Ha! ###
18424      off
18425  ''', '''
18426  var A;
18427
18428  A = class A extends B {
18429    // This is a fine class.
18430    // I could tell you all about it, but what else do you need to know?
18431    constructor() {
18432      // Something before `super`
18433      super();
18434    }
18435
18436    // This next method is a doozy!
18437    // A doozy, I tell ya!
18438    method() {
18439      // Whoa.
18440      // Can you believe it?
18441      return false;
18442    }
18443
18444    /* Look out, incoming! */
18445    anotherMethod() {
18446      /* Ha! */
18447      return false;
18448    }
18449
18450  };'''
18451
18452test "Line comments are properly indented", ->
18453  eqJS '''
18454  # Unindented comment
18455  if yes
18456    # Comment indented one tab
18457    1
18458    if yes
18459      # Comment indented two tabs
18460      2
18461    else
18462      # Another comment indented two tabs
18463      # Yet another comment indented two tabs
18464      3
18465  else
18466    # Another comment indented one tab
18467    # Yet another comment indented one tab
18468    4
18469
18470  # Another unindented comment''', '''
18471  // Unindented comment
18472  if (true) {
18473    // Comment indented one tab
18474    1;
18475    if (true) {
18476      // Comment indented two tabs
18477      2;
18478    } else {
18479      // Another comment indented two tabs
18480      // Yet another comment indented two tabs
18481      3;
18482    }
18483  } else {
18484    // Another comment indented one tab
18485    // Yet another comment indented one tab
18486    4;
18487  }
18488
18489  // Another unindented comment'''
18490
18491test "Line comments that trail code, followed by line comments that start a new line", ->
18492  eqJS '''
18493  a = ->
18494    b 1 # Trailing comment
18495
18496  # Comment that starts a new line
18497  2
18498  ''', '''
18499  var a;
18500
18501  a = function() {
18502    return b(1); // Trailing comment
18503  };
18504
18505
18506  // Comment that starts a new line
18507  2;
18508  '''
18509
18510test "Empty lines between comments are preserved", ->
18511  eqJS '''
18512  if indented
18513    # 1
18514
18515    # 2
18516    3
18517  ''', '''
18518  if (indented) {
18519    // 1
18520
18521    // 2
18522    3;
18523  }'''
18524
18525test "Block comment in an interpolated string", ->
18526  eqJS '"a#{### Comment ###}b"', '`a${/* Comment */""}b`;'
18527  eqJS '"a#{### 1 ###}b#{### 2 ###}c"', '`a${/* 1 */""}b${/* 2 */""}c`;'
18528
18529test "#4629: Block comment in JSX interpolation", ->
18530  eqJS '<div>{### Comment ###}</div>', '<div>{/* Comment */}</div>;'
18531  eqJS '''
18532  <div>
18533  {###
18534    Multiline
18535    Comment
18536  ###}
18537  </div>''', '''
18538  <div>
18539  {/*
18540    Multiline
18541    Comment
18542  */}
18543  </div>;'''
18544
18545test "Line comment in an interpolated string", ->
18546  eqJS '''
18547  "a#{# Comment
18548  1}b"
18549  ''', '''
18550  `a${// Comment
18551  1}b`;'''
18552
18553test "Line comments before `throw`", ->
18554  eqJS '''
18555  if indented
18556    1/0
18557    # Uh-oh!
18558    # You really shouldn’t have done that.
18559    throw DivideByZeroError()
18560  ''', '''
18561  if (indented) {
18562    1 / 0;
18563    // Uh-oh!
18564    // You really shouldn’t have done that.
18565    throw DivideByZeroError();
18566  }'''
18567
18568test "Comments before if this exists", ->
18569  js = CoffeeScript.compile '''
18570  1
18571  # Comment
18572  if @huh?
18573    2
18574  '''
18575  ok js.includes '// Comment'
18576
18577test "Comment before unary (`not`)", ->
18578  js = CoffeeScript.compile '''
18579  1
18580  # Comment
18581  if not doubleNegative
18582    dontDoIt()
18583  '''
18584  ok js.includes '// Comment'
18585
18586test "Comments before postfix", ->
18587  js = CoffeeScript.compile '''
18588  # 1
18589  2
18590
18591  # 3
18592  return unless window?
18593
18594  ### 4 ###
18595  return if global?
18596  '''
18597  ok js.includes '// 3'
18598  ok js.includes '/* 4 */'
18599
18600test "Comments before assignment if", ->
18601  js = CoffeeScript.compile '''
18602  1
18603  # Line comment
18604  a = if b
18605    3
18606  else
18607    4
18608
18609  ### Block comment ###
18610  c = if d
18611    5
18612  '''
18613  ok js.includes '// Line comment'
18614  ok js.includes '/* Block comment */'
18615
18616test "Comments before for loop", ->
18617  js = CoffeeScript.compile '''
18618  1
18619  # Comment
18620  for drop in ocean
18621    drink drop
18622  '''
18623  ok js.includes '// Comment'
18624
18625test "Comments after for loop", ->
18626  js = CoffeeScript.compile '''
18627  for drop in ocean # Comment after source variable
18628    drink drop
18629  for i in [1, 2] # Comment after array literal element
18630    count i
18631  for key, val of {a: 1} # Comment after object literal
18632    turn key
18633  '''
18634  ok js.includes '// Comment after source variable'
18635  ok js.includes '// Comment after array literal element'
18636  ok js.includes '// Comment after object literal'
18637
18638test "Comments before soak", ->
18639  js = CoffeeScript.compile '''
18640  # 1
18641  2
18642
18643  # 3
18644  return unless window?.location?.hash
18645
18646  ### 4 ###
18647  return if process?.env?.ENV
18648  '''
18649  ok js.includes '// 3'
18650  ok js.includes '/* 4 */'
18651
18652test "Comments before splice", ->
18653  js = CoffeeScript.compile '''
18654  1
18655  # Comment
18656  a[1..2] = [1, 2, 3]
18657  '''
18658  ok js.includes '// Comment'
18659
18660test "Comments before object destructuring", ->
18661  js = CoffeeScript.compile '''
18662  1
18663  # Comment before splat token
18664  { x... } = { a: 1, b: 2 }
18665
18666  # Comment before destructured token
18667  { x, y, z... } = { x: 1, y: 2, a: 3, b: 4 }
18668  '''
18669  ok js.includes 'Comment before splat token'
18670  ok js.includes 'Comment before destructured token'
18671
18672test "Comment before splat function parameter", ->
18673  js = CoffeeScript.compile '''
18674  1
18675  # Comment
18676  (blah..., yadda) ->
18677  '''
18678  ok js.includes 'Comment'
18679
18680test "Comments before static method", ->
18681  eqJS '''
18682  class Child extends Base
18683    # Static method:
18684    @method = ->
18685  ''', '''
18686  var Child;
18687
18688  Child = class Child extends Base {
18689    // Static method:
18690    static method() {}
18691
18692  };'''
18693
18694test "Comment before method that calls `super()`", ->
18695  eqJS '''
18696  class Dismissed
18697    # Before a method calling `super`
18698    method: ->
18699      super()
18700  ''', '''
18701  var Dismissed;
18702
18703  Dismissed = class Dismissed {
18704    // Before a method calling `super`
18705    method() {
18706      return super.method();
18707    }
18708
18709  };
18710  '''
18711
18712test "Comment in interpolated regex", ->
18713  js = CoffeeScript.compile '''
18714  1
18715  ///
18716    #{1}
18717    # Comment
18718  ///
18719  '''
18720  ok js.includes 'Comment'
18721
18722test "Line comment after line continuation", ->
18723  eqJS '''
18724  1 + \\ # comment
18725    2
18726  ''', '''
18727  1 + 2; // comment
18728  '''
18729
18730test "Comments appear above scope `var` declarations", ->
18731  eqJS '''
18732  # @flow
18733
18734  fn = (str) -> str
18735  ''', '''
18736  // @flow
18737  var fn;
18738
18739  fn = function(str) {
18740    return str;
18741  };'''
18742
18743test "Block comments can appear with function arguments", ->
18744  eqJS '''
18745  fn = (str ###: string ###, num ###: number ###) -> str + num
18746  ''', '''
18747  var fn;
18748
18749  fn = function(str/*: string */, num/*: number */) {
18750    return str + num;
18751  };'''
18752
18753test "Block comments can appear between function parameters and function opening brace", ->
18754  eqJS '''
18755  fn = (str ###: string ###, num ###: number ###) ###: string ### ->
18756    str + num
18757  ''', '''
18758  var fn;
18759
18760  fn = function(str/*: string */, num/*: number */)/*: string */ {
18761    return str + num;
18762  };'''
18763
18764test "Flow comment-based syntax support", ->
18765  eqJS '''
18766  # @flow
18767
18768  fn = (str ###: string ###, num ###: number ###) ###: string ### ->
18769    str + num
18770  ''', '''
18771  // @flow
18772  var fn;
18773
18774  fn = function(str/*: string */, num/*: number */)/*: string */ {
18775    return str + num;
18776  };'''
18777
18778test "#4706: Flow comments around function parameters", ->
18779  eqJS '''
18780  identity = ###::<T>### (value ###: T ###) ###: T ### ->
18781    value
18782  ''', '''
18783  var identity;
18784
18785  identity = function/*::<T>*/(value/*: T */)/*: T */ {
18786    return value;
18787  };'''
18788
18789test "#4706: Flow comments around function parameters", ->
18790  eqJS '''
18791  copy = arr.map(###:: <T> ###(item ###: T ###) ###: T ### => item)
18792  ''', '''
18793  var copy;
18794
18795  copy = arr.map(/*:: <T> */(item/*: T */)/*: T */ => {
18796    return item;
18797  });'''
18798
18799test "#4706: Flow comments after class name", ->
18800  eqJS '''
18801  class Container ###::<T> ###
18802    method: ###::<U> ### () -> true
18803  ''', '''
18804  var Container;
18805
18806  Container = class Container/*::<T> */ {
18807    method/*::<U> */() {
18808      return true;
18809    }
18810
18811  };'''
18812
18813test "#4706: Identifiers with comments wrapped in parentheses remain wrapped", ->
18814  eqJS '(arr ###: Array<number> ###)', '(arr/*: Array<number> */);'
18815  eqJS 'other = (arr ###: any ###)', '''
18816  var other;
18817
18818  other = (arr/*: any */);'''
18819
18820test "#4706: Flow comments before class methods", ->
18821  eqJS '''
18822  class Container
18823    ###::
18824    method: (number) => string;
18825    method: (string) => number;
18826    ###
18827    method: -> true
18828  ''', '''
18829  var Container;
18830
18831  Container = class Container {
18832    /*::
18833    method: (number) => string;
18834    method: (string) => number;
18835    */
18836    method() {
18837      return true;
18838    }
18839
18840  };'''
18841
18842test "#4706: Flow comments for class method params", ->
18843  eqJS '''
18844  class Container
18845    method: (param ###: string ###) -> true
18846  ''', '''
18847  var Container;
18848
18849  Container = class Container {
18850    method(param/*: string */) {
18851      return true;
18852    }
18853
18854  };'''
18855
18856test "#4706: Flow comments for class method returns", ->
18857  eqJS '''
18858  class Container
18859    method: () ###: string ### -> true
18860  ''', '''
18861  var Container;
18862
18863  Container = class Container {
18864    method()/*: string */ {
18865      return true;
18866    }
18867
18868  };'''
18869
18870test "#4706: Flow comments for function spread", ->
18871  eqJS '''
18872  method = (...rest ###: Array<string> ###) =>
18873  ''', '''
18874  var method;
18875
18876  method = (...rest/*: Array<string> */) => {};'''
18877
18878test "#4747: Flow comments for local variable declaration", ->
18879  eqJS 'a ###: number ### = 1', '''
18880  var a/*: number */;
18881
18882  a = 1;
18883  '''
18884
18885test "#4747: Flow comments for local variable declarations", ->
18886  eqJS '''
18887  a ###: number ### = 1
18888  b ###: string ### = 'c'
18889  ''', '''
18890  var a/*: number */, b/*: string */;
18891
18892  a = 1;
18893
18894  b = 'c';
18895  '''
18896
18897test "#4747: Flow comments for local variable declarations with reassignment", ->
18898  eqJS '''
18899  a ###: number ### = 1
18900  b ###: string ### = 'c'
18901  a ### some other comment ### = 2
18902  ''', '''
18903  var a/*: number */, b/*: string */;
18904
18905  a = 1;
18906
18907  b = 'c';
18908
18909  a/* some other comment */ = 2;
18910  '''
18911
18912test "#4756: Comment before ? operation", ->
18913  eqJS '''
18914  do ->
18915    ### Comment ###
18916    @foo ? 42
18917  ''', '''
18918  (function() {
18919    var ref;
18920    /* Comment */
18921    return (ref = this.foo) != null ? ref : 42;
18922  })();
18923  '''
18924
18925test "#5241: Comment after :", ->
18926  eqJS '''
18927  return
18928    a: # Comment
18929      b: 1
18930  ''', '''
18931  return {
18932    a: { // Comment
18933      b: 1
18934    }
18935  };
18936  '''
18937
18938</script>
vendor: 1 bytes, line 18938
18938
18939<script type="text/x-coffeescript" class="test" id="compilation">
18940# Compilation
18941# -----------
18942
18943# Helper to pipe the CoffeeScript compiler’s output through a transpiler.
18944transpile = (method, code, options = {}) ->
18945  # `method` should be 'compile' or 'eval' or 'run'
18946  options.bare = yes
18947  options.transpile =
18948    # Target Internet Explorer 6, which supports no ES2015+ features.
18949    presets: [['@babel/env', {targets: browsers: ['ie 6']}]]
18950  CoffeeScript[method] code, options
18951
18952
18953test "ensure that carriage returns don't break compilation on Windows", ->
18954  doesNotThrowCompileError 'one\r\ntwo', bare: on
18955
18956test "#3089 - don't mutate passed in options to compile", ->
18957  opts = {}
18958  CoffeeScript.compile '1 + 1', opts
18959  ok !opts.scope
18960
18961test "--bare", ->
18962  eq -1, CoffeeScript.compile('x = y', bare: on).indexOf 'function'
18963  ok 'passed' is CoffeeScript.eval '"passed"', bare: on, filename: 'test'
18964
18965test "header (#1778)", ->
18966  header = "// Generated by CoffeeScript #{CoffeeScript.VERSION}\n"
18967  eq 0, CoffeeScript.compile('x = y', header: on).indexOf header
18968
18969test "header is disabled by default", ->
18970  header = "// Generated by CoffeeScript #{CoffeeScript.VERSION}\n"
18971  eq -1, CoffeeScript.compile('x = y').indexOf header
18972
18973test "multiple generated references", ->
18974  a = {b: []}
18975  a.b[true] = -> this == a.b
18976  c = 0
18977  d = []
18978  ok a.b[0<++c<2] d...
18979
18980test "splat on a line by itself is invalid", ->
18981  throwsCompileError "x 'a'\n...\n"
18982
18983test "Issue 750", ->
18984
18985  throwsCompileError 'f(->'
18986
18987  throwsCompileError 'a = (break)'
18988
18989  throwsCompileError 'a = (return 5 for item in list)'
18990
18991  throwsCompileError 'a = (return 5 while condition)'
18992
18993  throwsCompileError 'a = for x in y\n  return 5'
18994
18995test "Issue #986: Unicode identifiers", ->
18996  λ = 5
18997  eq λ, 5
18998
18999test "#2516: Unicode spaces should not be part of identifiers", ->
19000  a = (x) -> x * 2
19001  b = 3
19002  eq 6, a b # U+00A0 NO-BREAK SPACE
19003  eq 6, a b # U+1680 OGHAM SPACE MARK
19004  eq 6, a b # U+2000 EN QUAD
19005  eq 6, a b # U+2001 EM QUAD
19006  eq 6, a b # U+2002 EN SPACE
19007  eq 6, a b # U+2003 EM SPACE
19008  eq 6, a b # U+2004 THREE-PER-EM SPACE
19009  eq 6, a b # U+2005 FOUR-PER-EM SPACE
19010  eq 6, a b # U+2006 SIX-PER-EM SPACE
19011  eq 6, a b # U+2007 FIGURE SPACE
19012  eq 6, a b # U+2008 PUNCTUATION SPACE
19013  eq 6, a b # U+2009 THIN SPACE
19014  eq 6, a b # U+200A HAIR SPACE
19015  eq 6, a b # U+202F NARROW NO-BREAK SPACE
19016  eq 6, a b # U+205F MEDIUM MATHEMATICAL SPACE
19017  eq 6, a b # U+3000 IDEOGRAPHIC SPACE
19018
19019  # #3560: Non-breaking space (U+00A0) (before `'c'`)
19020  eq 5, {c: 5}[ 'c' ]
19021
19022  # A line where every space in non-breaking
19023  eq 1 + 1, 2  
19024
19025test "don't accidentally stringify keywords", ->
19026  ok (-> this == 'this')() is false
19027
19028test "#1026: no if/else/else allowed", ->
19029  throwsCompileError '''
19030    if a
19031      b
19032    else
19033      c
19034    else
19035      d
19036  '''
19037
19038test "#1050: no closing asterisk comments from within block comments", ->
19039  throwsCompileError "### */ ###"
19040
19041test "#1273: escaping quotes at the end of heredocs", ->
19042  throwsCompileError '"""\\"""' # """\"""
19043  throwsCompileError '"""\\\\\\"""' # """\\\"""
19044
19045test "#1106: __proto__ compilation", ->
19046  object = eq
19047  @["__proto__"] = true
19048  ok __proto__
19049
19050test "reference named hasOwnProperty", ->
19051  CoffeeScript.compile 'hasOwnProperty = 0; a = 1'
19052
19053test "#1055: invalid keys in real (but not work-product) objects", ->
19054  throwsCompileError "@key: value"
19055
19056test "#1066: interpolated strings are not implicit functions", ->
19057  throwsCompileError '"int#{er}polated" arg'
19058
19059test "#2846: while with empty body", ->
19060  CoffeeScript.compile 'while 1 then', {sourceMap: true}
19061
19062test "#2944: implicit call with a regex argument", ->
19063  CoffeeScript.compile 'o[key] /regex/'
19064
19065test "#3001: `own` shouldn't be allowed in a `for`-`in` loop", ->
19066  throwsCompileError "a for own b in c"
19067
19068test "#2994: single-line `if` requires `then`", ->
19069  throwsCompileError "if b else x"
19070
19071test "transpile option, for Node API CoffeeScript.compile", ->
19072  return if global.testingBrowser
19073  ok transpile('compile', "import fs from 'fs'").includes 'require'
19074
19075test "transpile option, for Node API CoffeeScript.eval", ->
19076  return if global.testingBrowser
19077  ok transpile 'eval', "import path from 'path'; path.sep in ['/', '\\\\']"
19078
19079test "transpile option, for Node API CoffeeScript.run", ->
19080  return if global.testingBrowser
19081  doesNotThrow -> transpile 'run', "import fs from 'fs'"
19082
19083test "transpile option has merged source maps", ->
19084  return if global.testingBrowser
19085  untranspiledOutput = CoffeeScript.compile "import path from 'path'\nconsole.log path.sep", sourceMap: yes
19086  transpiledOutput   = transpile 'compile', "import path from 'path'\nconsole.log path.sep", sourceMap: yes
19087  untranspiledOutput.v3SourceMap = JSON.parse untranspiledOutput.v3SourceMap
19088  transpiledOutput.v3SourceMap   = JSON.parse transpiledOutput.v3SourceMap
19089  ok untranspiledOutput.v3SourceMap.mappings isnt transpiledOutput.v3SourceMap.mappings
19090  # Babel adds `'use strict';` to the top of files with the modules transform.
19091  eq transpiledOutput.js.indexOf('use strict'), 1
19092  # The `'use strict';` followed by two newlines results in the first two lines
19093  # of the source map mappings being two blank/skipped lines.
19094  eq transpiledOutput.v3SourceMap.mappings.indexOf(';;'), 0
19095  # The number of lines in the transpiled code should match the number of lines
19096  # in the source map.
19097  eq transpiledOutput.js.split('\n').length, transpiledOutput.v3SourceMap.mappings.split(';').length
19098
19099test "using transpile from the Node API requires an object", ->
19100  try
19101    CoffeeScript.compile '', transpile: yes
19102  catch exception
19103    eq exception.message, 'The transpile option must be given an object with options to pass to Babel'
19104
19105test "transpile option applies to imported .coffee files", ->
19106  return if global.testingBrowser
19107  doesNotThrow -> transpile 'run', "import { getSep } from './test/importing/transpile_import'\ngetSep()"
19108
19109test "#3306: trailing comma in a function call in the last line", ->
19110  eqJS '''
19111  foo bar,
19112  ''', '''
19113  foo(bar);
19114  '''
19115
19116</script>
vendor: 1 bytes, line 19116
19116
19117<script type="text/x-coffeescript" class="test" id="comprehensions">
19118# Comprehensions
19119# --------------
19120
19121# * Array Comprehensions
19122# * Range Comprehensions
19123# * Object Comprehensions
19124# * Implicit Destructuring Assignment
19125# * Comprehensions with Nonstandard Step
19126
19127# TODO: refactor comprehension tests
19128
19129test "Basic array comprehensions.", ->
19130
19131  nums    = (n * n for n in [1, 2, 3] when n & 1)
19132  results = (n * 2 for n in nums)
19133
19134  ok results.join(',') is '2,18'
19135
19136
19137test "Basic object comprehensions.", ->
19138
19139  obj   = {one: 1, two: 2, three: 3}
19140  names = (prop + '!' for prop of obj)
19141  odds  = (prop + '!' for prop, value of obj when value & 1)
19142
19143  ok names.join(' ') is "one! two! three!"
19144  ok odds.join(' ')  is "one! three!"
19145
19146
19147test "Basic range comprehensions.", ->
19148
19149  nums = (i * 3 for i in [1..3])
19150
19151  negs = (x for x in [-20..-5*2])
19152  negs = negs[0..2]
19153
19154  result = nums.concat(negs).join(', ')
19155
19156  ok result is '3, 6, 9, -20, -19, -18'
19157
19158
19159test "With range comprehensions, you can loop in steps.", ->
19160
19161  results = (x for x in [0...15] by 5)
19162  ok results.join(' ') is '0 5 10'
19163
19164  results = (x for x in [0..100] by 10)
19165  ok results.join(' ') is '0 10 20 30 40 50 60 70 80 90 100'
19166
19167
19168test "And can loop downwards, with a negative step.", ->
19169
19170  results = (x for x in [5..1])
19171
19172  ok results.join(' ') is '5 4 3 2 1'
19173  ok results.join(' ') is [(10-5)..(-2+3)].join(' ')
19174
19175  results = (x for x in [10..1])
19176  ok results.join(' ') is [10..1].join(' ')
19177
19178  results = (x for x in [10...0] by -2)
19179  ok results.join(' ') is [10, 8, 6, 4, 2].join(' ')
19180
19181
19182test "Range comprehension gymnastics.", ->
19183
19184  eq "#{i for i in [5..1]}", '5,4,3,2,1'
19185  eq "#{i for i in [5..-5] by -5}", '5,0,-5'
19186
19187  a = 6
19188  b = 0
19189  c = -2
19190
19191  eq "#{i for i in [a..b]}", '6,5,4,3,2,1,0'
19192  eq "#{i for i in [a..b] by c}", '6,4,2,0'
19193
19194
19195test "Multiline array comprehension with filter.", ->
19196
19197  evens = for num in [1, 2, 3, 4, 5, 6] when not (num & 1)
19198             num *= -1
19199             num -= 2
19200             num * -1
19201  eq evens + '', '4,6,8'
19202
19203
19204  test "The in operator still works, standalone.", ->
19205
19206    ok 2 of evens
19207
19208
19209test "all isn't reserved.", ->
19210
19211  all = 1
19212
19213
19214test "Ensure that the closure wrapper preserves local variables.", ->
19215
19216  obj = {}
19217
19218  for method in ['one', 'two', 'three'] then do (method) ->
19219    obj[method] = ->
19220      "I'm " + method
19221
19222  ok obj.one()   is "I'm one"
19223  ok obj.two()   is "I'm two"
19224  ok obj.three() is "I'm three"
19225
19226
19227test "Index values at the end of a loop.", ->
19228
19229  i = 0
19230  for i in [1..3]
19231    -> 'func'
19232    break if false
19233  ok i is 4
19234
19235
19236test "Ensure that local variables are closed over for range comprehensions.", ->
19237
19238  funcs = for i in [1..3]
19239    do (i) ->
19240      -> -i
19241
19242  eq (func() for func in funcs).join(' '), '-1 -2 -3'
19243  ok i is 4
19244
19245
19246test "Even when referenced in the filter.", ->
19247
19248  list = ['one', 'two', 'three']
19249
19250  methods = for num, i in list when num isnt 'two' and i isnt 1
19251    do (num, i) ->
19252      -> num + ' ' + i
19253
19254  ok methods.length is 2
19255  ok methods[0]() is 'one 0'
19256  ok methods[1]() is 'three 2'
19257
19258
19259test "Even a convoluted one.", ->
19260
19261  funcs = []
19262
19263  for i in [1..3]
19264    do (i) ->
19265      x = i * 2
19266      ((z)->
19267        funcs.push -> z + ' ' + i
19268      )(x)
19269
19270  ok (func() for func in funcs).join(', ') is '2 1, 4 2, 6 3'
19271
19272  funcs = []
19273
19274  results = for i in [1..3]
19275    do (i) ->
19276      z = (x * 3 for x in [1..i])
19277      ((a, b, c) -> [a, b, c].join(' ')).apply this, z
19278
19279  ok results.join(', ') is '3  , 3 6 , 3 6 9'
19280
19281
19282test "Naked ranges are expanded into arrays.", ->
19283
19284  array = [0..10]
19285  ok(num % 2 is 0 for num in array by 2)
19286
19287
19288test "Nested shared scopes.", ->
19289
19290  foo = ->
19291    for i in [0..7]
19292      do (i) ->
19293        for j in [0..7]
19294          do (j) ->
19295            -> i + j
19296
19297  eq foo()[3][4](), 7
19298
19299
19300test "Scoped loop pattern matching.", ->
19301
19302  a = [[0], [1]]
19303  funcs = []
19304
19305  for [v] in a
19306    do (v) ->
19307      funcs.push -> v
19308
19309  eq funcs[0](), 0
19310  eq funcs[1](), 1
19311
19312
19313test "Nested comprehensions.", ->
19314
19315  multiLiner =
19316    for x in [3..5]
19317      for y in [3..5]
19318        [x, y]
19319
19320  singleLiner =
19321    (([x, y] for y in [3..5]) for x in [3..5])
19322
19323  ok multiLiner.length is singleLiner.length
19324  ok 5 is multiLiner[2][2][1]
19325  ok 5 is singleLiner[2][2][1]
19326
19327
19328test "Comprehensions within parentheses.", ->
19329
19330  result = null
19331  store = (obj) -> result = obj
19332  store (x * 2 for x in [3, 2, 1])
19333
19334  ok result.join(' ') is '6 4 2'
19335
19336
19337test "Closure-wrapped comprehensions that refer to the 'arguments' object.", ->
19338
19339  expr = ->
19340    result = (item * item for item in arguments)
19341
19342  ok expr(2, 4, 8).join(' ') is '4 16 64'
19343
19344
19345test "Fast object comprehensions over all properties, including prototypal ones.", ->
19346
19347  class Cat
19348    constructor: -> @name = 'Whiskers'
19349    breed: 'tabby'
19350    hair:  'cream'
19351
19352  whiskers = new Cat
19353  own = (value for own key, value of whiskers)
19354  all = (value for key, value of whiskers)
19355
19356  ok own.join(' ') is 'Whiskers'
19357  ok all.sort().join(' ') is 'Whiskers cream tabby'
19358
19359
19360test "Optimized range comprehensions.", ->
19361
19362  exxes = ('x' for [0...10])
19363  ok exxes.join(' ') is 'x x x x x x x x x x'
19364
19365
19366test "#3671: Allow step in optimized range comprehensions.", ->
19367
19368  exxes = ('x' for [0...10] by 2)
19369  eq exxes.join(' ') , 'x x x x x'
19370
19371
19372test "#3671: Disallow guard in optimized range comprehensions.", ->
19373
19374  throwsCompileError "exxes = ('x' for [0...10] when a)"
19375
19376
19377test "Loop variables should be able to reference outer variables", ->
19378  outer = 1
19379  do ->
19380    null for outer in [1, 2, 3]
19381  eq outer, 3
19382
19383
19384test "Lenient on pure statements not trying to reach out of the closure", ->
19385
19386  val = for i in [1]
19387    for j in [] then break
19388    i
19389  ok val[0] is i
19390
19391
19392test "Comprehensions only wrap their last line in a closure, allowing other lines
19393  to have pure expressions in them.", ->
19394
19395  func = -> for i in [1]
19396    break if i is 2
19397    j for j in [1]
19398
19399  ok func()[0][0] is 1
19400
19401  i = 6
19402  odds = while i--
19403    continue unless i & 1
19404    i
19405
19406  ok odds.join(', ') is '5, 3, 1'
19407
19408
19409test "Issue #897: Ensure that plucked function variables aren't leaked.", ->
19410
19411  facets = {}
19412  list = ['one', 'two']
19413
19414  (->
19415    for entity in list
19416      facets[entity] = -> entity
19417  )()
19418
19419  eq typeof entity, 'undefined'
19420  eq facets['two'](), 'two'
19421
19422
19423test "Issue #905. Soaks as the for loop subject.", ->
19424
19425  a = {b: {c: [1, 2, 3]}}
19426  for d in a.b?.c
19427    e = d
19428
19429  eq e, 3
19430
19431
19432test "Issue #948. Capturing loop variables.", ->
19433
19434  funcs = []
19435  list  = ->
19436    [1, 2, 3]
19437
19438  for y in list()
19439    do (y) ->
19440      z = y
19441      funcs.push -> "y is #{y} and z is #{z}"
19442
19443  eq funcs[1](), "y is 2 and z is 2"
19444
19445
19446test "Cancel the comprehension if there's a jump inside the loop.", ->
19447
19448  result = try
19449    for i in [0...10]
19450      continue if i < 5
19451    i
19452
19453  eq result, 10
19454
19455
19456test "Comprehensions over break.", ->
19457
19458  arrayEq (break for [1..10]), []
19459
19460
19461test "Comprehensions over continue.", ->
19462
19463  arrayEq (continue for [1..10]), []
19464
19465
19466test "Comprehensions over function literals.", ->
19467
19468  a = 0
19469  for f in [-> a = 1]
19470    do (f) ->
19471      do f
19472
19473  eq a, 1
19474
19475
19476test "Comprehensions that mention arguments.", ->
19477
19478  list = [arguments: 10]
19479  args = for f in list
19480    do (f) ->
19481      f.arguments
19482  eq args[0], 10
19483
19484
19485test "expression conversion under explicit returns", ->
19486  nonce = {}
19487  fn = ->
19488    return (nonce for x in [1,2,3])
19489  arrayEq [nonce,nonce,nonce], fn()
19490  fn = ->
19491    return [nonce for x in [1,2,3]][0]
19492  arrayEq [nonce,nonce,nonce], fn()
19493  fn = ->
19494    return [(nonce for x in [1..3])][0]
19495  arrayEq [nonce,nonce,nonce], fn()
19496
19497
19498test "implicit destructuring assignment in object of objects", ->
19499  a={}; b={}; c={}
19500  obj = {
19501    a: { d: a },
19502    b: { d: b }
19503    c: { d: c }
19504  }
19505  result = ([y,z] for y, { d: z } of obj)
19506  arrayEq [['a',a],['b',b],['c',c]], result
19507
19508
19509test "implicit destructuring assignment in array of objects", ->
19510  a={}; b={}; c={}; d={}; e={}; f={}
19511  arr = [
19512    { a: a, b: { c: b } },
19513    { a: c, b: { c: d } },
19514    { a: e, b: { c: f } }
19515  ]
19516  result = ([y,z] for { a: y, b: { c: z } } in arr)
19517  arrayEq [[a,b],[c,d],[e,f]], result
19518
19519
19520test "implicit destructuring assignment in array of arrays", ->
19521  a={}; b={}; c={}; d={}; e={}; f={}
19522  arr = [[a, [b]], [c, [d]], [e, [f]]]
19523  result = ([y,z] for [y, [z]] in arr)
19524  arrayEq [[a,b],[c,d],[e,f]], result
19525
19526test "issue #1124: don't assign a variable in two scopes", ->
19527  lista = [1, 2, 3, 4, 5]
19528  listb = (_i + 1 for _i in lista)
19529  arrayEq [2, 3, 4, 5, 6], listb
19530
19531test "#1326: `by` value is uncached", ->
19532  a = [0,1,2]
19533  fi = gi = hi = 0
19534  f = -> ++fi
19535  g = -> ++gi
19536  h = -> ++hi
19537
19538  forCompile = []
19539  rangeCompileSimple = []
19540
19541  #exercises For.compile
19542  for v, i in a by f()
19543    forCompile.push i
19544
19545  #exercises Range.compileSimple
19546  rangeCompileSimple = (i for i in [0..2] by g())
19547
19548  arrayEq a, forCompile
19549  arrayEq a, rangeCompileSimple
19550  #exercises Range.compile
19551  eq "#{i for i in [0..2] by h()}", '0,1,2'
19552
19553test "#1669: break/continue should skip the result only for that branch", ->
19554  ns = for n in [0..99]
19555    if n > 9
19556      break
19557    else if n & 1
19558      continue
19559    else
19560      n
19561  eq "#{ns}", '0,2,4,6,8'
19562
19563  # `else undefined` is implied.
19564  ns = for n in [1..9]
19565    if n % 2
19566      continue unless n % 5
19567      n
19568  eq "#{ns}", "1,,3,,,7,,9"
19569
19570  # Ditto.
19571  ns = for n in [1..9]
19572    switch
19573      when n % 2
19574        continue unless n % 5
19575        n
19576  eq "#{ns}", "1,,3,,,7,,9"
19577
19578test "#1850: inner `for` should not be expression-ized if `return`ing", ->
19579  eq '3,4,5', do ->
19580    for a in [1..9] then \
19581    for b in [1..9]
19582      c = Math.sqrt a*a + b*b
19583      return String [a, b, c] unless c % 1
19584
19585test "#1910: loop index should be mutable within a loop iteration and immutable between loop iterations", ->
19586  n = 1
19587  iterations = 0
19588  arr = [0..n]
19589  for v, k in arr
19590    ++iterations
19591    v = k = 5
19592    eq 5, k
19593  eq 2, k
19594  eq 2, iterations
19595
19596  iterations = 0
19597  for v in [0..n]
19598    ++iterations
19599  eq 2, k
19600  eq 2, iterations
19601
19602  arr = ([v, v + 1] for v in [0..5])
19603  iterations = 0
19604  for [v0, v1], k in arr when v0
19605    k += 3
19606    ++iterations
19607  eq 6, k
19608  eq 5, iterations
19609
19610test "#2007: Return object literal from comprehension", ->
19611  y = for x in [1, 2]
19612    foo: "foo" + x
19613  eq 2, y.length
19614  eq "foo1", y[0].foo
19615  eq "foo2", y[1].foo
19616
19617  x = 2
19618  y = while x
19619    x: --x
19620  eq 2, y.length
19621  eq 1, y[0].x
19622  eq 0, y[1].x
19623
19624test "#2274: Allow @values as loop variables", ->
19625  obj = {
19626    item: null
19627    method: ->
19628      for @item in [1, 2, 3]
19629        null
19630  }
19631  eq obj.item, null
19632  obj.method()
19633  eq obj.item, 3
19634
19635test "#4411: Allow @values as loop indices", ->
19636  obj =
19637    index: null
19638    get: -> @index
19639    method: ->
19640      @get() for _, @index in [1, 2, 3]
19641  eq obj.index, null
19642  arrayEq obj.method(), [0, 1, 2]
19643  eq obj.index, 3
19644
19645test "#2525, #1187, #1208, #1758, looping over an array forwards", ->
19646  list = [0, 1, 2, 3, 4]
19647
19648  ident = (x) -> x
19649
19650  arrayEq (i for i in list), list
19651
19652  arrayEq (index for i, index in list), list
19653
19654  arrayEq (i for i in list by 1), list
19655
19656  arrayEq (i for i in list by ident 1), list
19657
19658  arrayEq (i for i in list by ident(1) * 2), [0, 2, 4]
19659
19660  arrayEq (index for i, index in list by ident(1) * 2), [0, 2, 4]
19661
19662test "#2525, #1187, #1208, #1758, looping over an array backwards", ->
19663  list = [0, 1, 2, 3, 4]
19664  backwards = [4, 3, 2, 1, 0]
19665
19666  ident = (x) -> x
19667
19668  arrayEq (i for i in list by -1), backwards
19669
19670  arrayEq (index for i, index in list by -1), backwards
19671
19672  arrayEq (i for i in list by ident -1), backwards
19673
19674  arrayEq (i for i in list by ident(-1) * 2), [4, 2, 0]
19675
19676  arrayEq (index for i, index in list by ident(-1) * 2), [4, 2, 0]
19677
19678test "splats in destructuring in comprehensions", ->
19679  list = [[0, 1, 2], [2, 3, 4], [4, 5, 6]]
19680  arrayEq (seq for [rep, seq...] in list), [[1, 2], [3, 4], [5, 6]]
19681
19682test "#156: expansion in destructuring in comprehensions", ->
19683  list = [[0, 1, 2], [2, 3, 4], [4, 5, 6]]
19684  arrayEq (last for [..., last] in list), [2, 4, 6]
19685
19686test "#3778: Consistently always cache for loop range boundaries and steps, even
19687      if they are simple identifiers", ->
19688  a = 1; arrayEq [1, 2, 3], (for n in [1, 2, 3] by  a then a = 4; n)
19689  a = 1; arrayEq [1, 2, 3], (for n in [1, 2, 3] by +a then a = 4; n)
19690  a = 1; arrayEq [1, 2, 3], (for n in [a..3]          then a = 4; n)
19691  a = 1; arrayEq [1, 2, 3], (for n in [+a..3]         then a = 4; n)
19692  a = 3; arrayEq [1, 2, 3], (for n in [1..a]          then a = 4; n)
19693  a = 3; arrayEq [1, 2, 3], (for n in [1..+a]         then a = 4; n)
19694  a = 1; arrayEq [1, 2, 3], (for n in [1..3] by  a    then a = 4; n)
19695  a = 1; arrayEq [1, 2, 3], (for n in [1..3] by +a    then a = 4; n)
19696
19697test "for pattern variables can linebreak/indent", ->
19698  listOfObjects = [a: 1]
19699  sum = 0
19700  for {
19701    a
19702    somethingElse
19703    anotherProperty
19704  } in listOfObjects
19705    sum += a
19706  eq a, 1
19707
19708  sum = 0
19709  sum += a for {
19710    a,
19711    somethingElse,
19712    anotherProperty,
19713  } in listOfObjects
19714  eq a, 1
19715
19716  listOfArrays = [[2]]
19717  sum = 0
19718  for [
19719    a
19720    nonexistentElement
19721    anotherNonexistentElement
19722  ] in listOfArrays
19723    sum += a
19724  eq a, 2
19725
19726  sum = 0
19727  sum += a for [
19728    a,
19729    nonexistentElement,
19730    anotherNonexistentElement
19731  ] in listOfArrays
19732  eq a, 2
19733
19734test "#5309: comprehension as postfix condition", ->
19735  doesNotThrowCompileError """
19736    throw new Error "DOOM was called with a null element" unless elm? for elm in elms
19737  """
19738
19739test "#5410: for from loops shouldn't make excess refs", ->
19740  js = CoffeeScript.compile """
19741    for x from fn()
19742      alert x
19743  """
19744
19745  ok !js.match /ref/
19746
19747</script>
vendor: 1 bytes, line 19747
19747
19748<script type="text/x-coffeescript" class="test" id="control_flow">
19749# Control Flow
19750# ------------
19751
19752# * Conditionals
19753# * Loops
19754#   * For
19755#   * While
19756#   * Until
19757#   * Loop
19758# * Switch
19759# * Throw
19760
19761# TODO: make sure postfix forms and expression coercion are properly tested
19762
19763# shared identity function
19764id = (_) -> if arguments.length is 1 then _ else Array::slice.call(arguments)
19765
19766# Conditionals
19767
19768test "basic conditionals", ->
19769  if false
19770    ok false
19771  else if false
19772    ok false
19773  else
19774    ok true
19775
19776  if true
19777    ok true
19778  else if true
19779    ok false
19780  else
19781    ok true
19782
19783  unless true
19784    ok false
19785  else unless true
19786    ok false
19787  else
19788    ok true
19789
19790  unless false
19791    ok true
19792  else unless false
19793    ok false
19794  else
19795    ok true
19796
19797test "single-line conditional", ->
19798  if false then ok false else ok true
19799  unless false then ok true else ok false
19800
19801test "nested conditionals", ->
19802  nonce = {}
19803  eq nonce, (if true
19804    unless false
19805      if false then false else
19806        if true
19807          nonce)
19808
19809test "nested single-line conditionals", ->
19810  nonce = {}
19811
19812  a = if false then undefined else b = if 0 then undefined else nonce
19813  eq nonce, a
19814  eq nonce, b
19815
19816  c = if false then undefined else (if 0 then undefined else nonce)
19817  eq nonce, c
19818
19819  d = if true then id(if false then undefined else nonce)
19820  eq nonce, d
19821
19822test "empty conditional bodies", ->
19823  eq undefined, (if false
19824  else if false
19825  else)
19826
19827test "conditional bodies containing only comments", ->
19828  eq undefined, (if true
19829    ###
19830    block comment
19831    ###
19832  else
19833    # comment
19834  )
19835
19836  eq undefined, (if false
19837    # comment
19838  else if true
19839    ###
19840    block comment
19841    ###
19842  else)
19843
19844test "return value of if-else is from the proper body", ->
19845  nonce = {}
19846  eq nonce, if false then undefined else nonce
19847
19848test "return value of unless-else is from the proper body", ->
19849  nonce = {}
19850  eq nonce, unless true then undefined else nonce
19851
19852test "assign inside the condition of a conditional statement", ->
19853  nonce = {}
19854  if a = nonce then 1
19855  eq nonce, a
19856  1 if b = nonce
19857  eq nonce, b
19858
19859
19860# Interactions With Functions
19861
19862test "single-line function definition with single-line conditional", ->
19863  fn = -> if 1 < 0.5 then 1 else -1
19864  ok fn() is -1
19865
19866test "function resturns conditional value with no `else`", ->
19867  fn = ->
19868    return if false then true
19869  eq undefined, fn()
19870
19871test "function returns a conditional value", ->
19872  a = {}
19873  fnA = ->
19874    return if false then undefined else a
19875  eq a, fnA()
19876
19877  b = {}
19878  fnB = ->
19879    return unless false then b else undefined
19880  eq b, fnB()
19881
19882test "passing a conditional value to a function", ->
19883  nonce = {}
19884  eq nonce, id if false then undefined else nonce
19885
19886test "unmatched `then` should catch implicit calls", ->
19887  a = 0
19888  trueFn = -> true
19889  if trueFn undefined then a++
19890  eq 1, a
19891
19892
19893# if-to-ternary
19894
19895test "if-to-ternary with instanceof requires parentheses", ->
19896  nonce = {}
19897  eq nonce, (if {} instanceof Object
19898    nonce
19899  else
19900    undefined)
19901
19902test "if-to-ternary as part of a larger operation requires parentheses", ->
19903  ok 2, 1 + if false then 0 else 1
19904
19905
19906# Odd Formatting
19907
19908test "if-else indented within an assignment", ->
19909  nonce = {}
19910  result =
19911    if false
19912      undefined
19913    else
19914      nonce
19915  eq nonce, result
19916
19917test "suppressed indentation via assignment", ->
19918  nonce = {}
19919  result =
19920    if      false then undefined
19921    else if no    then undefined
19922    else if 0     then undefined
19923    else if 1 < 0 then undefined
19924    else               id(
19925         if false then undefined
19926         else          nonce
19927    )
19928  eq nonce, result
19929
19930test "tight formatting with leading `then`", ->
19931  nonce = {}
19932  eq nonce,
19933  if true
19934  then nonce
19935  else undefined
19936
19937test "#738: inline function defintion", ->
19938  nonce = {}
19939  fn = if true then -> nonce
19940  eq nonce, fn()
19941
19942test "#748: trailing reserved identifiers", ->
19943  nonce = {}
19944  obj = delete: true
19945  result = if obj.delete
19946    nonce
19947  eq nonce, result
19948
19949test 'if-else within an assignment, condition parenthesized', ->
19950  result = if (1 is 1) then 'correct'
19951  eq result, 'correct'
19952
19953  result = if ('whatever' ? no) then 'correct'
19954  eq result, 'correct'
19955
19956  f = -> 'wrong'
19957  result = if (f?()) then 'correct' else 'wrong'
19958  eq result, 'correct'
19959
19960# Postfix
19961
19962test "#3056: multiple postfix conditionals", ->
19963  temp = 'initial'
19964  temp = 'ignored' unless true if false
19965  eq temp, 'initial'
19966
19967# Loops
19968
19969test "basic `while` loops", ->
19970
19971  i = 5
19972  list = while i -= 1
19973    i * 2
19974  ok list.join(' ') is "8 6 4 2"
19975
19976  i = 5
19977  list = (i * 3 while i -= 1)
19978  ok list.join(' ') is "12 9 6 3"
19979
19980  i = 5
19981  func   = (num) -> i -= num
19982  assert = -> ok i < 5 > 0
19983  results = while func 1
19984    assert()
19985    i
19986  ok results.join(' ') is '4 3 2 1'
19987
19988  i = 10
19989  results = while i -= 1 when i % 2 is 0
19990    i * 2
19991  ok results.join(' ') is '16 12 8 4'
19992
19993
19994test "Issue 759: `if` within `while` condition", ->
19995
19996  2 while if 1 then 0
19997
19998
19999test "assignment inside the condition of a `while` loop", ->
20000
20001  nonce = {}
20002  count = 1
20003  a = nonce while count--
20004  eq nonce, a
20005  count = 1
20006  while count--
20007    b = nonce
20008  eq nonce, b
20009
20010
20011test "While over break.", ->
20012
20013  i = 0
20014  result = while i < 10
20015    i++
20016    break
20017  arrayEq result, []
20018
20019
20020test "While over continue.", ->
20021
20022  i = 0
20023  result = while i < 10
20024    i++
20025    continue
20026  arrayEq result, []
20027
20028
20029test "Basic `until`", ->
20030
20031  value = false
20032  i = 0
20033  results = until value
20034    value = true if i is 5
20035    i++
20036  ok i is 6
20037
20038
20039test "Basic `loop`", ->
20040
20041  i = 5
20042  list = []
20043  loop
20044    i -= 1
20045    break if i is 0
20046    list.push i * 2
20047  ok list.join(' ') is '8 6 4 2'
20048
20049
20050test "break at the top level", ->
20051  for i in [1,2,3]
20052    result = i
20053    if i == 2
20054      break
20055  eq 2, result
20056
20057test "break *not* at the top level", ->
20058  someFunc = ->
20059    i = 0
20060    while ++i < 3
20061      result = i
20062      break if i > 1
20063    result
20064  eq 2, someFunc()
20065
20066# Switch
20067
20068test "basic `switch`", ->
20069
20070  num = 10
20071  result = switch num
20072    when 5 then false
20073    when 'a'
20074      true
20075      true
20076      false
20077    when 10 then true
20078
20079
20080    # Mid-switch comment with whitespace
20081    # and multi line
20082    when 11 then false
20083    else false
20084
20085  ok result
20086
20087
20088  func = (num) ->
20089    switch num
20090      when 2, 4, 6
20091        true
20092      when 1, 3, 5
20093        false
20094
20095  ok func(2)
20096  ok func(6)
20097  ok !func(3)
20098  eq func(8), undefined
20099
20100
20101test "Ensure that trailing switch elses don't get rewritten.", ->
20102
20103  result = false
20104  switch "word"
20105    when "one thing"
20106      doSomething()
20107    else
20108      result = true unless false
20109
20110  ok result
20111
20112  result = false
20113  switch "word"
20114    when "one thing"
20115      doSomething()
20116    when "other thing"
20117      doSomething()
20118    else
20119      result = true unless false
20120
20121  ok result
20122
20123
20124test "Should be able to handle switches sans-condition.", ->
20125
20126  result = switch
20127    when null                     then 0
20128    when !1                       then 1
20129    when '' not of {''}           then 2
20130    when [] not instanceof Array  then 3
20131    when true is false            then 4
20132    when 'x' < 'y' > 'z'          then 5
20133    when 'a' in ['b', 'c']        then 6
20134    when 'd' in (['e', 'f'])      then 7
20135    else ok
20136
20137  eq result, ok
20138
20139
20140test "Should be able to use `@properties` within the switch clause.", ->
20141
20142  obj = {
20143    num: 101
20144    func: ->
20145      switch @num
20146        when 101 then '101!'
20147        else 'other'
20148  }
20149
20150  ok obj.func() is '101!'
20151
20152
20153test "Should be able to use `@properties` within the switch cases.", ->
20154
20155  obj = {
20156    num: 101
20157    func: (yesOrNo) ->
20158      result = switch yesOrNo
20159        when yes then @num
20160        else 'other'
20161      result
20162  }
20163
20164  ok obj.func(yes) is 101
20165
20166
20167test "Switch with break as the return value of a loop.", ->
20168
20169  i = 10
20170  results = while i > 0
20171    i--
20172    switch i % 2
20173      when 1 then i
20174      when 0 then break
20175
20176  eq results.join(', '), '9, 7, 5, 3, 1'
20177
20178
20179test "Issue #997. Switch doesn't fallthrough.", ->
20180
20181  val = 1
20182  switch true
20183    when true
20184      if false
20185        return 5
20186    else
20187      val = 2
20188
20189  eq val, 1
20190
20191# Throw
20192
20193test "Throw should be usable as an expression.", ->
20194  try
20195    false or throw 'up'
20196    throw new Error 'failed'
20197  catch e
20198    ok e is 'up'
20199
20200
20201test "#2555, strange function if bodies", ->
20202  success = -> ok true
20203  failure = -> ok false
20204
20205  success() if do ->
20206    yes
20207
20208  failure() if try
20209    false
20210
20211test "#1057: `catch` or `finally` in single-line functions", ->
20212  ok do -> try throw 'up' catch then yes
20213  ok do -> try yes finally 'nothing'
20214
20215test "#2367: super in for-loop", ->
20216  class Foo
20217    sum: 0
20218    add: (val) -> @sum += val
20219
20220  class Bar extends Foo
20221    add: (vals...) ->
20222      super val for val in vals
20223      @sum
20224
20225  eq 10, (new Bar).add 2, 3, 5
20226
20227test "#4267: lots of for-loops in the same scope", ->
20228  # This used to include the invalid JavaScript `var do = 0`.
20229  code = """
20230    do ->
20231      #{Array(200).join('for [0..0] then\n  ')}
20232      true
20233  """
20234  ok CoffeeScript.eval(code)
20235
20236# Test for issue #2342: Lexer: Inline `else` binds to wrong `if`/`switch`
20237test "#2343: if / then / if / then / else", ->
20238  a = b = yes
20239  c = e = g = no
20240  d = 1
20241  f = 2
20242  h = 3
20243  i = 4
20244
20245  s = ->
20246    if a
20247      if b
20248        if c
20249          d
20250        else
20251          if e
20252            f
20253          else
20254            if g
20255              h
20256            else
20257              i
20258
20259  t = ->
20260    if a then if b
20261      if c then d
20262      else if e
20263        f
20264      else if g
20265        h
20266      else
20267        i
20268
20269  u = ->
20270    if a then if b
20271      if c then d else if e
20272        f
20273      else if g
20274        h
20275      else i
20276
20277  v = ->
20278    if a then if b
20279      if c then d else if e then f
20280      else if g then h
20281      else i
20282
20283  w = ->
20284    if a then if b
20285      if c then d
20286      else if e
20287          f
20288        else
20289          if g then h
20290          else i
20291
20292  x = -> if a then if b then if c then d else if e then f else if g then h else i
20293
20294  y = -> if a then if b then (if c then d else (if e then f else (if g then h else i)))
20295
20296  eq 4, s()
20297  eq 4, t()
20298  eq 4, u()
20299  eq 4, v()
20300  eq 4, w()
20301  eq 4, x()
20302  eq 4, y()
20303
20304  c = yes
20305  eq 1, s()
20306  eq 1, t()
20307  eq 1, u()
20308  eq 1, v()
20309  eq 1, w()
20310  eq 1, x()
20311  eq 1, y()
20312
20313  b = no
20314  eq undefined, s()
20315  eq undefined, t()
20316  eq undefined, u()
20317  eq undefined, v()
20318  eq undefined, w()
20319  eq undefined, x()
20320  eq undefined, y()
20321
20322test "#2343: if / then / if / then / else / else", ->
20323  a = b = yes
20324  c = e = g = no
20325  d = 1
20326  f = 2
20327  h = 3
20328  i = 4
20329  j = 5
20330  k = 6
20331
20332  s = ->
20333    if a
20334      if b
20335        if c
20336          d
20337        else
20338          e
20339          if e
20340            f
20341          else
20342            if g
20343              h
20344            else
20345              i
20346      else
20347        j
20348    else
20349      k
20350
20351  t = ->
20352    if a
20353      if b
20354        if c then d
20355        else if e
20356          f
20357        else if g
20358          h
20359        else
20360          i
20361      else
20362        j
20363    else
20364      k
20365
20366  u = ->
20367    if a
20368      if b
20369        if c then d else if e
20370          f
20371        else if g
20372          h
20373        else i
20374      else j
20375    else k
20376
20377  v = ->
20378    if a
20379      if b
20380        if c then d else if e then f
20381        else if g then h
20382        else i
20383      else j else k
20384
20385  w = ->
20386    if a then if b
20387        if c then d
20388        else if e
20389            f
20390          else
20391            if g then h
20392            else i
20393    else j else k
20394
20395  x = -> if a then if b then if c then d else if e then f else if g then h else i else j else k
20396
20397  y = -> if a then (if b then (if c then d else (if e then f else (if g then h else i))) else j) else k
20398
20399  eq 4, s()
20400  eq 4, t()
20401  eq 4, u()
20402  eq 4, v()
20403  eq 4, w()
20404  eq 4, x()
20405  eq 4, y()
20406
20407  c = yes
20408  eq 1, s()
20409  eq 1, t()
20410  eq 1, u()
20411  eq 1, v()
20412  eq 1, w()
20413  eq 1, x()
20414  eq 1, y()
20415
20416  b = no
20417  eq 5, s()
20418  eq 5, t()
20419  eq 5, u()
20420  eq 5, v()
20421  eq 5, w()
20422  eq 5, x()
20423  eq 5, y()
20424
20425  a = no
20426  eq 6, s()
20427  eq 6, t()
20428  eq 6, u()
20429  eq 6, v()
20430  eq 6, w()
20431  eq 6, x()
20432  eq 6, y()
20433
20434
20435test "#2343: switch / when / then / if / then / else", ->
20436  a = b = yes
20437  c = e = g = no
20438  d = 1
20439  f = 2
20440  h = 3
20441  i = 4
20442
20443  s = ->
20444    switch
20445      when a
20446        if b
20447          if c
20448            d
20449          else
20450            if e
20451              f
20452            else
20453              if g
20454                h
20455              else
20456                i
20457
20458
20459  t = ->
20460    switch
20461      when a then if b
20462        if c then d
20463        else if e
20464          f
20465        else if g
20466          h
20467        else
20468          i
20469
20470  u = ->
20471    switch
20472      when a then if b then if c then d
20473      else if e then f
20474      else if g then h else i
20475
20476  v = ->
20477    switch
20478      when a then if b then if c then d else if e then f
20479      else if g then h else i
20480
20481  w = ->
20482    switch
20483      when a then if b then if c then d else if e then f
20484      else if g
20485        h
20486      else i
20487
20488  x = ->
20489    switch
20490     when a then if b then if c then d else if e then f else if g then h else i
20491
20492  y = -> switch
20493    when a then if b then (if c then d else (if e then f else (if g then h else i)))
20494
20495  eq 4, s()
20496  eq 4, t()
20497  eq 4, u()
20498  eq 4, v()
20499  eq 4, w()
20500  eq 4, x()
20501  eq 4, y()
20502
20503  c = yes
20504  eq 1, s()
20505  eq 1, t()
20506  eq 1, u()
20507  eq 1, v()
20508  eq 1, w()
20509  eq 1, x()
20510  eq 1, y()
20511
20512  b = no
20513  eq undefined, s()
20514  eq undefined, t()
20515  eq undefined, u()
20516  eq undefined, v()
20517  eq undefined, w()
20518  eq undefined, x()
20519  eq undefined, y()
20520
20521test "#2343: switch / when / then / if / then / else / else", ->
20522  a = b = yes
20523  c = e = g = no
20524  d = 1
20525  f = 2
20526  h = 3
20527  i = 4
20528
20529  s = ->
20530    switch
20531      when a
20532        if b
20533          if c
20534            d
20535          else if e
20536            f
20537          else if g
20538            h
20539          else
20540            i
20541      else
20542        0
20543
20544  t = ->
20545    switch
20546      when a
20547        if b
20548          if c then d
20549          else if e
20550            f
20551          else if g
20552            h
20553          else i
20554      else 0
20555
20556  u = ->
20557    switch
20558      when a
20559        if b then if c
20560            d
20561          else if e
20562            f
20563          else if g
20564            h
20565          else i
20566      else 0
20567
20568  v = ->
20569    switch
20570      when a
20571        if b then if c then d
20572        else if e
20573          f
20574        else if g
20575          h
20576        else i
20577      else 0
20578
20579  w = ->
20580    switch
20581      when a
20582        if b then if c then d
20583        else if e then f
20584        else if g then h
20585        else i
20586      else 0
20587
20588  x = ->
20589    switch
20590     when a
20591       if b then if c then d else if e then f else if g then h else i
20592     else 0
20593
20594  y = -> switch
20595    when a
20596      if b then (if c then d else (if e then f else (if g then h else i)))
20597    else 0
20598
20599  eq 4, s()
20600  eq 4, t()
20601  eq 4, u()
20602  eq 4, v()
20603  eq 4, w()
20604  eq 4, x()
20605  eq 4, y()
20606
20607  c = yes
20608  eq 1, s()
20609  eq 1, t()
20610  eq 1, u()
20611  eq 1, v()
20612  eq 1, w()
20613  eq 1, x()
20614  eq 1, y()
20615
20616  b = no
20617  eq undefined, s()
20618  eq undefined, t()
20619  eq undefined, u()
20620  eq undefined, v()
20621  eq undefined, w()
20622  eq undefined, x()
20623  eq undefined, y()
20624
20625  b = yes
20626  a = no
20627  eq 0, s()
20628  eq 0, t()
20629  eq 0, u()
20630  eq 0, v()
20631  eq 0, w()
20632  eq 0, x()
20633  eq 0, y()
20634
20635test "#2343: switch / when / then / if / then / else / else / else", ->
20636  a = b = yes
20637  c = e = g = no
20638  d = 1
20639  f = 2
20640  h = 3
20641  i = 4
20642  j = 5
20643
20644  s = ->
20645    switch
20646      when a
20647        if b
20648          if c
20649            d
20650          else if e
20651            f
20652          else if g
20653            h
20654          else
20655            i
20656        else
20657          j
20658      else
20659        0
20660
20661  t = ->
20662    switch
20663      when a
20664        if b
20665          if c then d
20666          else if e
20667            f
20668          else if g
20669            h
20670          else i
20671        else
20672          j
20673      else 0
20674
20675  u = ->
20676    switch
20677      when a
20678        if b
20679          if c
20680            d
20681          else if e
20682            f
20683          else if g
20684            h
20685          else i
20686        else j
20687      else 0
20688
20689  v = ->
20690    switch
20691      when a
20692        if b
20693          if c then d
20694          else if e
20695            f
20696          else if g then h
20697          else i
20698        else j
20699      else 0
20700
20701  w = ->
20702    switch
20703      when a
20704        if b
20705          if c then d
20706          else if e then f
20707          else if g then h
20708          else i
20709        else j
20710      else 0
20711
20712  x = ->
20713    switch
20714     when a
20715       if b then if c then d else if e then f else if g then h else i else j
20716     else 0
20717
20718  y = -> switch
20719    when a
20720      if b then (if c then d else (if e then f else (if g then h else i))) else j
20721    else 0
20722
20723  eq 4, s()
20724  eq 4, t()
20725  eq 4, u()
20726  eq 4, v()
20727  eq 4, w()
20728  eq 4, x()
20729  eq 4, y()
20730
20731  c = yes
20732  eq 1, s()
20733  eq 1, t()
20734  eq 1, u()
20735  eq 1, v()
20736  eq 1, w()
20737  eq 1, x()
20738  eq 1, y()
20739
20740  b = no
20741  eq 5, s()
20742  eq 5, t()
20743  eq 5, u()
20744  eq 5, v()
20745  eq 5, w()
20746  eq 5, x()
20747  eq 5, y()
20748
20749  b = yes
20750  a = no
20751  eq 0, s()
20752  eq 0, t()
20753  eq 0, u()
20754  eq 0, v()
20755  eq 0, w()
20756  eq 0, x()
20757  eq 0, y()
20758
20759# Test for issue #3921: Inline function without parentheses used in condition fails to compile
20760test "#3921: `if` & `unless`", ->
20761  a = {}
20762  eq a, if do -> no then undefined else a
20763  a1 = undefined
20764  if do -> yes
20765    a1 = a
20766  eq a, a1
20767
20768  b = {}
20769  eq b, unless do -> no then b else undefined
20770  b1 = undefined
20771  unless do -> no
20772    b1 = b
20773  eq b, b1
20774
20775  c = 0
20776  if (arg = undefined) -> yes then c++
20777  eq 1, c
20778  d = 0
20779  if (arg = undefined) -> yes
20780    d++
20781  eq 1, d
20782
20783  answer = 'correct'
20784  eq answer, if do -> 'wrong' then 'correct' else 'wrong'
20785  eq answer, unless do -> no then 'correct' else 'wrong'
20786  statm1 = undefined
20787  if do -> 'wrong'
20788    statm1 = 'correct'
20789  eq answer, statm1
20790  statm2 = undefined
20791  unless do -> no
20792    statm2 = 'correct'
20793  eq answer, statm2
20794
20795test "#3921: `post if`", ->
20796  a = {}
20797  eq a, a unless do -> no
20798  a1 = a if do -> yes
20799  eq a, a1
20800
20801  c = 0
20802  c++ if (arg = undefined) -> yes
20803  eq 1, c
20804  d = 0
20805  d++ if (arg = undefined) -> yes
20806  eq 1, d
20807
20808  answer = 'correct'
20809  eq answer, 'correct' if do -> 'wrong'
20810  eq answer, 'correct' unless do -> not 'wrong'
20811  statm1 = undefined
20812  statm1 = 'correct' if do -> 'wrong'
20813  eq answer, statm1
20814  statm2 = undefined
20815  statm2 = 'correct' unless do -> not 'wrong'
20816  eq answer, statm2
20817
20818test "Issue 3921: `while` & `until`", ->
20819  i = 5
20820  assert = (a) -> ok 5 > a > 0
20821  result1 = while do (num = 1) -> i -= num
20822    assert i
20823    i
20824  ok result1.join(' ') is '4 3 2 1'
20825
20826  j = 5
20827  result2 = until do (num = 1) -> (j -= num) < 1
20828    assert j
20829    j
20830  ok result2.join(' ') is '4 3 2 1'
20831
20832test "#3921: `switch`", ->
20833  i = 1
20834  a = switch do (m = 2) -> i * m
20835    when 5 then "five"
20836    when 4 then "four"
20837    when 3 then "three"
20838    when 2 then "two"
20839    when 1 then "one"
20840    else "none"
20841  eq "two", a
20842
20843  j = 12
20844  b = switch do (m = 3) -> j / m
20845    when 5 then "five"
20846    when 4 then "four"
20847    when 3 then "three"
20848    when 2 then "two"
20849    when 1 then "one"
20850    else "none"
20851  eq "four", b
20852
20853  k = 20
20854  c = switch do (m = 4) -> k / m
20855    when 5 then "five"
20856    when 4 then "four"
20857    when 3 then "three"
20858    when 2 then "two"
20859    when 1 then "one"
20860    else "none"
20861  eq "five", c
20862
20863# Issue #3909: backslash to break line in `for` loops throw syntax error
20864test "#3909: backslash `for own ... of`", ->
20865
20866  obj = {a: 1, b: 2, c: 3}
20867  arr = ['a', 'b', 'c']
20868
20869  x1 \
20870    = ( key for own key of obj )
20871  arrayEq x1, arr
20872
20873  x2 = \
20874    ( key for own key of obj )
20875  arrayEq x2, arr
20876
20877  x3 = ( \
20878    key for own key of obj )
20879  arrayEq x3, arr
20880
20881  x4 = ( key \
20882    for own key of obj )
20883  arrayEq x4, arr
20884
20885  x5 = ( key for own key of \
20886    obj )
20887  arrayEq x5, arr
20888
20889  x6 = ( key for own key of obj \
20890    )
20891  arrayEq x6, arr
20892
20893  x7 = ( key for \
20894    own key of obj )
20895  arrayEq x7, arr
20896
20897  x8 = ( key for own \
20898    key of obj )
20899  arrayEq x8, arr
20900
20901  x9 = ( key for own key \
20902    of obj )
20903  arrayEq x9, arr
20904
20905
20906test "#3909: backslash `for ... of`", ->
20907  obj = {a: 1, b: 2, c: 3}
20908  arr = ['a', 'b', 'c']
20909
20910  x1 \
20911    = ( key for key of obj )
20912  arrayEq x1, arr
20913
20914  x2 = \
20915    ( key for key of obj )
20916  arrayEq x2, arr
20917
20918  x3 = ( \
20919    key for key of obj )
20920  arrayEq x3, arr
20921
20922  x4 = ( key \
20923    for key of obj )
20924  arrayEq x4, arr
20925
20926  x5 = ( key for key of \
20927    obj )
20928  arrayEq x5, arr
20929
20930  x6 = ( key for key of obj \
20931    )
20932  arrayEq x6, arr
20933
20934  x7 = ( key for \
20935    key of obj )
20936  arrayEq x7, arr
20937
20938  x8 = ( key for key \
20939    of obj )
20940  arrayEq x8, arr
20941
20942
20943test "#3909: backslash `for ... in`", ->
20944  arr = ['a', 'b', 'c']
20945
20946  x1 \
20947    = ( key for key in arr )
20948  arrayEq x1, arr
20949
20950  x2 = \
20951    ( key for key in arr )
20952  arrayEq x2, arr
20953
20954  x3 = ( \
20955    key for key in arr )
20956  arrayEq x3, arr
20957
20958  x4 = ( key \
20959    for key in arr )
20960  arrayEq x4, arr
20961
20962  x5 = ( key for key in \
20963    arr )
20964  arrayEq x5, arr
20965
20966  x6 = ( key for key in arr \
20967    )
20968  arrayEq x6, arr
20969
20970  x7 = ( key for \
20971    key in arr )
20972  arrayEq x7, arr
20973
20974  x8 = ( key for key \
20975    in arr )
20976  arrayEq x8, arr
20977
20978test "#4871: `else if` no longer output together ", ->
20979   eqJS '''
20980   if a then b else if c then d else if e then f else g
20981   ''',
20982   '''
20983   if (a) {
20984     b;
20985   } else if (c) {
20986     d;
20987   } else if (e) {
20988     f;
20989   } else {
20990     g;
20991   }
20992   '''
20993
20994   eqJS '''
20995   if no
20996     1
20997   else if yes
20998     2
20999   ''',
21000   '''
21001   if (false) {
21002     1;
21003   } else if (true) {
21004     2;
21005   }
21006   '''
21007
21008test "#4898: Lexer: backslash line continuation is inconsistent", ->
21009  if ( \
21010      false \
21011      or \
21012      true \
21013    )
21014    a = 42
21015
21016  eq a, 42
21017
21018  if ( \
21019      false \
21020      or \
21021      true \
21022  )
21023    b = 42
21024
21025  eq b, 42
21026
21027  if ( \
21028            false \
21029         or \
21030   true \
21031  )
21032    c = 42
21033
21034  eq c, 42
21035
21036  if \
21037   false \
21038        or \
21039   true
21040    d = 42
21041
21042  eq d, 42
21043
21044  if \
21045              false or \
21046  true
21047    e = 42
21048
21049  eq e, 42
21050
21051  if \
21052       false or \
21053    true \
21054       then \
21055   f = 42 \
21056   else
21057     f = 24
21058
21059  eq f, 42
21060
21061</script>
vendor: 1 bytes, line 21061
21061
21062<script type="text/x-coffeescript" class="test" id="error_messages">
21063# Error Formatting
21064# ----------------
21065
21066# Ensure that errors of different kinds (lexer, parser and compiler) are shown
21067# in a consistent way.
21068
21069errCallback = (expectedErrorFormat) -> (err) ->
21070  err.colorful = no
21071  eq expectedErrorFormat, "#{err}"
21072  yes
21073assertErrorFormatNoAst = (code, expectedErrorFormat) ->
21074  throws (-> CoffeeScript.run code), errCallback(expectedErrorFormat)
21075assertErrorFormat = (code, expectedErrorFormat) ->
21076  assertErrorFormatNoAst code, expectedErrorFormat
21077  throws (-> CoffeeScript.compile code, ast: yes), errCallback(expectedErrorFormat)
21078
21079test "lexer errors formatting", ->
21080  assertErrorFormat '''
21081    normalObject    = {}
21082    insideOutObject = }{
21083  ''',
21084  '''
21085    [stdin]:2:19: error: unmatched }
21086    insideOutObject = }{
21087                      ^
21088  '''
21089
21090test "parser error formatting", ->
21091  assertErrorFormat '''
21092    foo in bar or in baz
21093  ''',
21094  '''
21095    [stdin]:1:15: error: unexpected in
21096    foo in bar or in baz
21097                  ^^
21098  '''
21099
21100test "compiler error formatting", ->
21101  assertErrorFormat '''
21102    evil = (foo, eval, bar) ->
21103  ''',
21104  '''
21105    [stdin]:1:14: error: 'eval' can't be assigned
21106    evil = (foo, eval, bar) ->
21107                 ^^^^
21108  '''
21109
21110if require?
21111  os   = require 'os'
21112  fs   = require 'fs'
21113  path = require 'path'
21114
21115  test "patchStackTrace line patching", ->
21116    err = new Error 'error'
21117    ok err.stack.match /test[\/\\]error_messages\.coffee:\d+:\d+\b/
21118
21119  test "patchStackTrace stack prelude consistent with V8", ->
21120    err = new Error
21121    ok err.stack.match /^Error\n/ # Notice no colon when no message.
21122
21123    err = new Error 'error'
21124    ok err.stack.match /^Error: error\n/
21125
21126  test "#2849: compilation error in a require()d file", ->
21127    # Create a temporary file to require().
21128    tempFile = path.join os.tmpdir(), 'syntax-error.coffee'
21129    ok not fs.existsSync tempFile
21130    fs.writeFileSync tempFile, 'foo in bar or in baz'
21131
21132    try
21133      assertErrorFormatNoAst """
21134        require '#{tempFile.replace /\\/g, '\\\\'}'
21135      """,
21136      """
21137        #{fs.realpathSync tempFile}:1:15: error: unexpected in
21138        foo in bar or in baz
21139                      ^^
21140      """
21141    finally
21142      fs.unlinkSync tempFile
21143
21144  test "#3890: Error.prepareStackTrace doesn't throw an error if a compiled file is deleted", ->
21145    # Adapted from https://github.com/atom/coffee-cash/blob/master/spec/coffee-cash-spec.coffee
21146    filePath = path.join os.tmpdir(), 'PrepareStackTraceTestFile.coffee'
21147    fs.writeFileSync filePath, "module.exports = -> throw new Error('hello world')"
21148    throwsAnError = require filePath
21149    fs.unlinkSync filePath
21150
21151    try
21152      throwsAnError()
21153    catch error
21154
21155    eq error.message, 'hello world'
21156    doesNotThrow(-> error.stack)
21157    notEqual error.stack.toString().indexOf(filePath), -1, "Expected " + filePath + "in stack trace: " + error.stack.toString()
21158
21159  test "#4418: stack traces for compiled files reference the correct line number", ->
21160    # The browser is already compiling other anonymous scripts (the tests)
21161    # which will conflict.
21162    return if global.testingBrowser
21163    filePath = path.join os.tmpdir(), 'StackTraceLineNumberTestFile.coffee'
21164    fileContents = """
21165      testCompiledFileStackTraceLineNumber = ->
21166        # `a` on the next line is undefined and should throw a ReferenceError
21167        console.log a if true
21168
21169      do testCompiledFileStackTraceLineNumber
21170      """
21171    fs.writeFileSync filePath, fileContents
21172
21173    try
21174      require filePath
21175    catch error
21176    fs.unlinkSync filePath
21177
21178    # Make sure the line number reported is line 3 (the original Coffee source)
21179    # and not line 6 (the generated JavaScript).
21180    eq /StackTraceLineNumberTestFile.coffee:(\d)/.exec(error.stack.toString())[1], '3'
21181
21182
21183test "#4418: stack traces for compiled strings reference the correct line number", ->
21184  # The browser is already compiling other anonymous scripts (the tests)
21185  # which will conflict.
21186  return if global.testingBrowser
21187  try
21188    CoffeeScript.run '''
21189      testCompiledStringStackTraceLineNumber = ->
21190        # `a` on the next line is undefined and should throw a ReferenceError
21191        console.log a if true
21192
21193      do testCompiledStringStackTraceLineNumber
21194      '''
21195  catch error
21196
21197  # Make sure the line number reported is line 3 (the original Coffee source)
21198  # and not line 6 (the generated JavaScript).
21199  eq /testCompiledStringStackTraceLineNumber.*:(\d):/.exec(error.stack.toString())[1], '3'
21200
21201
21202test "#4558: compiling a string inside a script doesn’t screw up stack trace line number", ->
21203  # The browser is already compiling other anonymous scripts (the tests)
21204  # which will conflict.
21205  return if global.testingBrowser
21206  try
21207    CoffeeScript.run '''
21208      testCompilingInsideAScriptDoesntScrewUpStackTraceLineNumber = ->
21209        if require?
21210          CoffeeScript = require './lib/coffeescript'
21211          CoffeeScript.compile ''
21212        throw new Error 'Some Error'
21213
21214      do testCompilingInsideAScriptDoesntScrewUpStackTraceLineNumber
21215      '''
21216  catch error
21217
21218  # Make sure the line number reported is line 5 (the original Coffee source)
21219  # and not line 10 (the generated JavaScript).
21220  eq /testCompilingInsideAScriptDoesntScrewUpStackTraceLineNumber.*:(\d):/.exec(error.stack.toString())[1], '5'
21221
21222test "#1096: unexpected generated tokens", ->
21223  # Implicit ends
21224  assertErrorFormat 'a:, b', '''
21225    [stdin]:1:3: error: unexpected ,
21226    a:, b
21227      ^
21228  '''
21229  # Explicit ends
21230  assertErrorFormat '(a:)', '''
21231    [stdin]:1:4: error: unexpected )
21232    (a:)
21233       ^
21234  '''
21235  # Unexpected end of file
21236  assertErrorFormat 'a:', '''
21237    [stdin]:1:3: error: unexpected end of input
21238    a:
21239      ^
21240  '''
21241  assertErrorFormat 'a +', '''
21242    [stdin]:1:4: error: unexpected end of input
21243    a +
21244       ^
21245  '''
21246  # Unexpected key in implicit object (an implicit object itself is _not_
21247  # unexpected here)
21248  assertErrorFormat '''
21249    for i in [1]:
21250      1
21251  ''', '''
21252    [stdin]:2:4: error: unexpected end of input
21253      1
21254       ^
21255  '''
21256  # Unexpected regex
21257  assertErrorFormat '{/a/i: val}', '''
21258    [stdin]:1:2: error: unexpected regex
21259    {/a/i: val}
21260     ^^^^
21261  '''
21262  assertErrorFormat '{///a///i: val}', '''
21263    [stdin]:1:2: error: unexpected regex
21264    {///a///i: val}
21265     ^^^^^^^^
21266  '''
21267  assertErrorFormat '{///#{a}///i: val}', '''
21268    [stdin]:1:2: error: unexpected regex
21269    {///#{a}///i: val}
21270     ^^^^^^^^^^^
21271  '''
21272  # Unexpected string
21273  assertErrorFormat 'import foo from "lib-#{version}"', '''
21274    [stdin]:1:17: error: the name of the module to be imported from must be an uninterpolated string
21275    import foo from "lib-#{version}"
21276                    ^^^^^^^^^^^^^^^^
21277  '''
21278
21279  # Unexpected number
21280  assertErrorFormat '"a"0x00Af2', '''
21281    [stdin]:1:4: error: unexpected number
21282    "a"0x00Af2
21283       ^^^^^^^
21284  '''
21285
21286test "#1316: unexpected end of interpolation", ->
21287  assertErrorFormat '''
21288    "#{+}"
21289  ''', '''
21290    [stdin]:1:5: error: unexpected end of interpolation
21291    "#{+}"
21292        ^
21293  '''
21294  assertErrorFormat '''
21295    "#{++}"
21296  ''', '''
21297    [stdin]:1:6: error: unexpected end of interpolation
21298    "#{++}"
21299         ^
21300  '''
21301  assertErrorFormat '''
21302    "#{-}"
21303  ''', '''
21304    [stdin]:1:5: error: unexpected end of interpolation
21305    "#{-}"
21306        ^
21307  '''
21308  assertErrorFormat '''
21309    "#{--}"
21310  ''', '''
21311    [stdin]:1:6: error: unexpected end of interpolation
21312    "#{--}"
21313         ^
21314  '''
21315  assertErrorFormat '''
21316    "#{~}"
21317  ''', '''
21318    [stdin]:1:5: error: unexpected end of interpolation
21319    "#{~}"
21320        ^
21321  '''
21322  assertErrorFormat '''
21323    "#{!}"
21324  ''', '''
21325    [stdin]:1:5: error: unexpected end of interpolation
21326    "#{!}"
21327        ^
21328  '''
21329  assertErrorFormat '''
21330    "#{not}"
21331  ''', '''
21332    [stdin]:1:7: error: unexpected end of interpolation
21333    "#{not}"
21334          ^
21335  '''
21336  assertErrorFormat '''
21337    "#{5) + (4}_"
21338  ''', '''
21339    [stdin]:1:5: error: unmatched )
21340    "#{5) + (4}_"
21341        ^
21342  '''
21343  # #2918
21344  assertErrorFormat '''
21345    "#{foo.}"
21346  ''', '''
21347    [stdin]:1:8: error: unexpected end of interpolation
21348    "#{foo.}"
21349           ^
21350  '''
21351
21352test "#3325: implicit indentation errors", ->
21353  assertErrorFormat '''
21354    i for i in a then i
21355  ''', '''
21356    [stdin]:1:14: error: unexpected then
21357    i for i in a then i
21358                 ^^^^
21359  '''
21360
21361test "explicit indentation errors", ->
21362  assertErrorFormat '''
21363    a = b
21364      c
21365  ''', '''
21366    [stdin]:2:1: error: unexpected indentation
21367      c
21368    ^^
21369  '''
21370
21371test "unclosed strings", ->
21372  assertErrorFormat '''
21373    '
21374  ''', '''
21375    [stdin]:1:1: error: missing '
21376    '
21377    ^
21378  '''
21379  assertErrorFormat '''
21380    "
21381  ''', '''
21382    [stdin]:1:1: error: missing "
21383    "
21384    ^
21385  '''
21386  assertErrorFormat """
21387    '''
21388  """, """
21389    [stdin]:1:1: error: missing '''
21390    '''
21391    ^^^
21392  """
21393  assertErrorFormat '''
21394    """
21395  ''', '''
21396    [stdin]:1:1: error: missing """
21397    """
21398    ^^^
21399  '''
21400  assertErrorFormat '''
21401    "#{"
21402  ''', '''
21403    [stdin]:1:4: error: missing "
21404    "#{"
21405       ^
21406  '''
21407  assertErrorFormat '''
21408    """#{"
21409  ''', '''
21410    [stdin]:1:6: error: missing "
21411    """#{"
21412         ^
21413  '''
21414  assertErrorFormat '''
21415    "#{"""
21416  ''', '''
21417    [stdin]:1:4: error: missing """
21418    "#{"""
21419       ^^^
21420  '''
21421  assertErrorFormat '''
21422    """#{"""
21423  ''', '''
21424    [stdin]:1:6: error: missing """
21425    """#{"""
21426         ^^^
21427  '''
21428  assertErrorFormat '''
21429    ///#{"""
21430  ''', '''
21431    [stdin]:1:6: error: missing """
21432    ///#{"""
21433         ^^^
21434  '''
21435  assertErrorFormat '''
21436    "a
21437      #{foo """
21438        bar
21439          #{ +'12 }
21440        baz
21441        """} b"
21442  ''', '''
21443    [stdin]:4:11: error: missing '
21444          #{ +'12 }
21445              ^
21446  '''
21447  # https://github.com/jashkenas/coffeescript/issues/3301#issuecomment-31735168
21448  assertErrorFormat '''
21449    # Note the double escaping; this would be `"""a\"""` real code.
21450    """a\\"""
21451  ''', '''
21452    [stdin]:2:1: error: missing """
21453    """a\\"""
21454    ^^^
21455  '''
21456
21457test "unclosed heregexes", ->
21458  assertErrorFormat '''
21459    ///
21460  ''', '''
21461    [stdin]:1:1: error: missing ///
21462    ///
21463    ^^^
21464  '''
21465  # https://github.com/jashkenas/coffeescript/issues/3301#issuecomment-31735168
21466  assertErrorFormat '''
21467    # Note the double escaping; this would be `///a\///` real code.
21468    ///a\\///
21469  ''', '''
21470    [stdin]:2:1: error: missing ///
21471    ///a\\///
21472    ^^^
21473  '''
21474
21475test "unexpected token after string", ->
21476  # Parsing error.
21477  assertErrorFormat '''
21478    'foo'bar
21479  ''', '''
21480    [stdin]:1:6: error: unexpected identifier
21481    'foo'bar
21482         ^^^
21483  '''
21484  assertErrorFormat '''
21485    "foo"bar
21486  ''', '''
21487    [stdin]:1:6: error: unexpected identifier
21488    "foo"bar
21489         ^^^
21490  '''
21491  # Lexing error.
21492  assertErrorFormat '''
21493    'foo'bar'
21494  ''', '''
21495    [stdin]:1:9: error: missing '
21496    'foo'bar'
21497            ^
21498  '''
21499  assertErrorFormat '''
21500    "foo"bar"
21501  ''', '''
21502    [stdin]:1:9: error: missing "
21503    "foo"bar"
21504            ^
21505  '''
21506
21507test "#3348: Location data is wrong in interpolations with leading whitespace", ->
21508  assertErrorFormat '''
21509    "#{ * }"
21510  ''', '''
21511    [stdin]:1:5: error: unexpected *
21512    "#{ * }"
21513        ^
21514  '''
21515
21516test "octal escapes", ->
21517  assertErrorFormat '''
21518    "a\\0\\tb\\\\\\07c"
21519  ''', '''
21520    [stdin]:1:10: error: octal escape sequences are not allowed \\07
21521    "a\\0\\tb\\\\\\07c"
21522      \  \   \ \ ^\^^
21523  '''
21524  assertErrorFormat '''
21525    "a
21526      #{b} \\1"
21527  ''', '''
21528    [stdin]:2:8: error: octal escape sequences are not allowed \\1
21529      #{b} \\1"
21530           ^\^
21531  '''
21532  assertErrorFormat '''
21533    /a\\0\\tb\\\\\\07c/
21534  ''', '''
21535    [stdin]:1:10: error: octal escape sequences are not allowed \\07
21536    /a\\0\\tb\\\\\\07c/
21537      \  \   \ \ ^\^^
21538  '''
21539  assertErrorFormat '''
21540    /a\\1\\tb\\\\\\07c/
21541  ''', '''
21542    [stdin]:1:10: error: octal escape sequences are not allowed \\07
21543    /a\\1\\tb\\\\\\07c/
21544      \  \   \ \ ^\^^
21545  '''
21546  assertErrorFormat '''
21547    ///a
21548      #{b} \\01///
21549  ''', '''
21550    [stdin]:2:8: error: octal escape sequences are not allowed \\01
21551      #{b} \\01///
21552           ^\^^
21553  '''
21554  # per #5211, also treat \0[8-9] as (disallowed) octal escapes
21555  assertErrorFormat '''
21556    "a\\0\\tb\\\\\\09c"
21557  ''', '''
21558    [stdin]:1:10: error: octal escape sequences are not allowed \\09
21559    "a\\0\\tb\\\\\\09c"
21560      \  \   \ \ ^\^^
21561  '''
21562  assertErrorFormat '''
21563    ///a
21564      #{b} \\08///
21565  ''', '''
21566    [stdin]:2:8: error: octal escape sequences are not allowed \\08
21567      #{b} \\08///
21568           ^\^^
21569  '''
21570
21571test "#3795: invalid escapes", ->
21572  assertErrorFormat '''
21573    "a\\0\\tb\\\\\\x7g"
21574  ''', '''
21575    [stdin]:1:10: error: invalid escape sequence \\x7g
21576    "a\\0\\tb\\\\\\x7g"
21577      \  \   \ \ ^\^^^
21578  '''
21579  assertErrorFormat '''
21580    "a
21581      #{b} \\uA02
21582     c"
21583  ''', '''
21584    [stdin]:2:8: error: invalid escape sequence \\uA02
21585      #{b} \\uA02
21586           ^\^^^^
21587  '''
21588  assertErrorFormat '''
21589    /a\\u002space/
21590  ''', '''
21591    [stdin]:1:3: error: invalid escape sequence \\u002s
21592    /a\\u002space/
21593      ^\^^^^^
21594  '''
21595  assertErrorFormat '''
21596    ///a \\u002 0 space///
21597  ''', '''
21598    [stdin]:1:6: error: invalid escape sequence \\u002 \n\
21599    ///a \\u002 0 space///
21600         ^\^^^^^
21601  '''
21602  assertErrorFormat '''
21603    ///a
21604      #{b} \\x0
21605     c///
21606  ''', '''
21607    [stdin]:2:8: error: invalid escape sequence \\x0
21608      #{b} \\x0
21609           ^\^^
21610  '''
21611  assertErrorFormat '''
21612    /ab\\u/
21613  ''', '''
21614    [stdin]:1:4: error: invalid escape sequence \\u
21615    /ab\\u/
21616       ^\^
21617  '''
21618
21619test "illegal herecomment", ->
21620  assertErrorFormat '''
21621    ###
21622      Regex: /a*/g
21623    ###
21624  ''', '''
21625    [stdin]:2:12: error: block comments cannot contain */
21626      Regex: /a*/g
21627               ^^
21628  '''
21629
21630test "#1724: regular expressions beginning with *", ->
21631  assertErrorFormat '''
21632    /* foo/
21633  ''', '''
21634    [stdin]:1:2: error: regular expressions cannot begin with *
21635    /* foo/
21636     ^
21637  '''
21638  assertErrorFormat '''
21639    ///
21640      * foo
21641    ///
21642  ''', '''
21643    [stdin]:2:3: error: regular expressions cannot begin with *
21644      * foo
21645      ^
21646  '''
21647
21648test "invalid regex flags", ->
21649  assertErrorFormat '''
21650    /a/ii
21651  ''', '''
21652    [stdin]:1:4: error: invalid regular expression flags ii
21653    /a/ii
21654       ^^
21655  '''
21656  assertErrorFormat '''
21657    /a/G
21658  ''', '''
21659    [stdin]:1:4: error: invalid regular expression flags G
21660    /a/G
21661       ^
21662  '''
21663  assertErrorFormat '''
21664    /a/gimi
21665  ''', '''
21666    [stdin]:1:4: error: invalid regular expression flags gimi
21667    /a/gimi
21668       ^^^^
21669  '''
21670  assertErrorFormat '''
21671    /a/g_
21672  ''', '''
21673    [stdin]:1:4: error: invalid regular expression flags g_
21674    /a/g_
21675       ^^
21676  '''
21677  assertErrorFormat '''
21678    ///a///ii
21679  ''', '''
21680    [stdin]:1:8: error: invalid regular expression flags ii
21681    ///a///ii
21682           ^^
21683  '''
21684  doesNotThrowCompileError '/a/ymgi'
21685
21686test "missing `)`, `}`, `]`", ->
21687  assertErrorFormat '''
21688    (
21689  ''', '''
21690    [stdin]:1:1: error: missing )
21691    (
21692    ^
21693  '''
21694  assertErrorFormat '''
21695    {
21696  ''', '''
21697    [stdin]:1:1: error: missing }
21698    {
21699    ^
21700  '''
21701  assertErrorFormat '''
21702    [
21703  ''', '''
21704    [stdin]:1:1: error: missing ]
21705    [
21706    ^
21707  '''
21708  assertErrorFormat '''
21709    obj = {a: [1, (2+
21710  ''', '''
21711    [stdin]:1:15: error: missing )
21712    obj = {a: [1, (2+
21713                  ^
21714  '''
21715  assertErrorFormat '''
21716    "#{
21717  ''', '''
21718    [stdin]:1:3: error: missing }
21719    "#{
21720      ^
21721  '''
21722  assertErrorFormat '''
21723    """
21724      foo#{ bar "#{1}"
21725  ''', '''
21726    [stdin]:2:7: error: missing }
21727      foo#{ bar "#{1}"
21728          ^
21729  '''
21730
21731test "unclosed regexes", ->
21732  assertErrorFormat '''
21733    /
21734  ''', '''
21735    [stdin]:1:1: error: missing / (unclosed regex)
21736    /
21737    ^
21738  '''
21739  assertErrorFormat '''
21740    # Note the double escaping; this would be `/a\/` real code.
21741    /a\\/
21742  ''', '''
21743    [stdin]:2:1: error: missing / (unclosed regex)
21744    /a\\/
21745    ^
21746  '''
21747  assertErrorFormat '''
21748    /// ^
21749      a #{""" ""#{if /[/].test "|" then 1 else 0}"" """}
21750    ///
21751  ''', '''
21752    [stdin]:2:18: error: missing / (unclosed regex)
21753      a #{""" ""#{if /[/].test "|" then 1 else 0}"" """}
21754                     ^
21755  '''
21756
21757test "duplicate function arguments", ->
21758  assertErrorFormat '''
21759    (foo, bar, foo) ->
21760  ''', '''
21761    [stdin]:1:12: error: multiple parameters named 'foo'
21762    (foo, bar, foo) ->
21763               ^^^
21764  '''
21765  assertErrorFormat '''
21766    (@foo, bar, @foo) ->
21767  ''', '''
21768    [stdin]:1:13: error: multiple parameters named '@foo'
21769    (@foo, bar, @foo) ->
21770                ^^^^
21771  '''
21772
21773test "reserved words", ->
21774  assertErrorFormat '''
21775    case
21776  ''', '''
21777    [stdin]:1:1: error: reserved word 'case'
21778    case
21779    ^^^^
21780  '''
21781  assertErrorFormat '''
21782    case = 1
21783  ''', '''
21784    [stdin]:1:1: error: reserved word 'case'
21785    case = 1
21786    ^^^^
21787  '''
21788  assertErrorFormat '''
21789    for = 1
21790  ''', '''
21791    [stdin]:1:1: error: keyword 'for' can't be assigned
21792    for = 1
21793    ^^^
21794  '''
21795  assertErrorFormat '''
21796    unless = 1
21797  ''', '''
21798    [stdin]:1:1: error: keyword 'unless' can't be assigned
21799    unless = 1
21800    ^^^^^^
21801  '''
21802  assertErrorFormat '''
21803    for += 1
21804  ''', '''
21805    [stdin]:1:1: error: keyword 'for' can't be assigned
21806    for += 1
21807    ^^^
21808  '''
21809  assertErrorFormat '''
21810    for &&= 1
21811  ''', '''
21812    [stdin]:1:1: error: keyword 'for' can't be assigned
21813    for &&= 1
21814    ^^^
21815  '''
21816  # Make sure token look-behind doesn't go out of range.
21817  assertErrorFormat '''
21818    &&= 1
21819  ''', '''
21820    [stdin]:1:1: error: unexpected &&=
21821    &&= 1
21822    ^^^
21823  '''
21824  # #2306: Show unaliased name in error messages.
21825  assertErrorFormat '''
21826    on = 1
21827  ''', '''
21828    [stdin]:1:1: error: keyword 'on' can't be assigned
21829    on = 1
21830    ^^
21831  '''
21832
21833test "strict mode errors", ->
21834  assertErrorFormat '''
21835    eval = 1
21836  ''', '''
21837    [stdin]:1:1: error: 'eval' can't be assigned
21838    eval = 1
21839    ^^^^
21840  '''
21841  assertErrorFormat '''
21842    class eval
21843  ''', '''
21844    [stdin]:1:7: error: 'eval' can't be assigned
21845    class eval
21846          ^^^^
21847  '''
21848  assertErrorFormat '''
21849    arguments++
21850  ''', '''
21851    [stdin]:1:1: error: 'arguments' can't be assigned
21852    arguments++
21853    ^^^^^^^^^
21854  '''
21855  assertErrorFormat '''
21856    --arguments
21857  ''', '''
21858    [stdin]:1:3: error: 'arguments' can't be assigned
21859    --arguments
21860      ^^^^^^^^^
21861  '''
21862
21863test "invalid numbers", ->
21864  assertErrorFormat '''
21865    0X0
21866  ''', '''
21867    [stdin]:1:2: error: radix prefix in '0X0' must be lowercase
21868    0X0
21869     ^
21870  '''
21871  assertErrorFormat '''
21872    018
21873  ''', '''
21874    [stdin]:1:1: error: decimal literal '018' must not be prefixed with '0'
21875    018
21876    ^^^
21877  '''
21878  assertErrorFormat '''
21879    010
21880  ''', '''
21881    [stdin]:1:1: error: octal literal '010' must be prefixed with '0o'
21882    010
21883    ^^^
21884'''
21885
21886
21887test "unexpected object keys", ->
21888  assertErrorFormat '''
21889    {(a + "b")}
21890  ''', '''
21891    [stdin]:1:11: error: unexpected }
21892    {(a + "b")}
21893              ^
21894  '''
21895  assertErrorFormat '''
21896    {(a + "b"): 1}
21897  ''', '''
21898    [stdin]:1:11: error: unexpected :
21899    {(a + "b"): 1}
21900              ^
21901  '''
21902  assertErrorFormat '''
21903    (a + "b"): 1
21904  ''', '''
21905    [stdin]:1:10: error: unexpected :
21906    (a + "b"): 1
21907             ^
21908  '''
21909
21910test "invalid object keys", ->
21911  assertErrorFormat '''
21912    @a: 1
21913  ''', '''
21914    [stdin]:1:1: error: invalid object key
21915    @a: 1
21916    ^^
21917  '''
21918  assertErrorFormat '''
21919    f
21920      @a: 1
21921  ''', '''
21922    [stdin]:2:3: error: invalid object key
21923      @a: 1
21924      ^^
21925  '''
21926  assertErrorFormat '''
21927    {a=2}
21928  ''', '''
21929    [stdin]:1:3: error: unexpected =
21930    {a=2}
21931      ^
21932  '''
21933  assertErrorFormat '''
21934    @[a]: 1
21935  ''', '''
21936    [stdin]:1:1: error: invalid object key
21937    @[a]: 1
21938    ^^^^
21939  '''
21940
21941test "invalid destructuring default target", ->
21942  assertErrorFormat '''
21943    {'a' = 2} = obj
21944  ''', '''
21945    [stdin]:1:6: error: unexpected =
21946    {'a' = 2} = obj
21947         ^
21948  '''
21949
21950test "#4070: lone expansion", ->
21951  assertErrorFormat '''
21952    [...] = a
21953  ''', '''
21954    [stdin]:1:2: error: Destructuring assignment has no target
21955    [...] = a
21956     ^^^
21957  '''
21958  assertErrorFormat '''
21959    [ ..., ] = a
21960  ''', '''
21961    [stdin]:1:3: error: Destructuring assignment has no target
21962    [ ..., ] = a
21963      ^^^
21964  '''
21965
21966test "#3926: implicit object in parameter list", ->
21967  assertErrorFormat '''
21968    (a: b) ->
21969  ''', '''
21970    [stdin]:1:3: error: unexpected :
21971    (a: b) ->
21972      ^
21973  '''
21974  assertErrorFormat '''
21975    (one, two, {three, four: five}, key: value) ->
21976  ''', '''
21977    [stdin]:1:36: error: unexpected :
21978    (one, two, {three, four: five}, key: value) ->
21979                                       ^
21980  '''
21981
21982test "#4130: unassignable in destructured param", ->
21983  assertErrorFormat '''
21984    fun = ({
21985      @param : null
21986    }) ->
21987      console.log "Oh hello!"
21988  ''', '''
21989    [stdin]:2:12: error: keyword 'null' can't be assigned
21990      @param : null
21991               ^^^^
21992  '''
21993  assertErrorFormat '''
21994    ({a: null}) ->
21995  ''', '''
21996    [stdin]:1:6: error: keyword 'null' can't be assigned
21997    ({a: null}) ->
21998         ^^^^
21999  '''
22000  assertErrorFormat '''
22001    ({a: 1}) ->
22002  ''', '''
22003    [stdin]:1:6: error: '1' can't be assigned
22004    ({a: 1}) ->
22005         ^
22006  '''
22007  assertErrorFormat '''
22008    ({1}) ->
22009  ''', '''
22010    [stdin]:1:3: error: '1' can't be assigned
22011    ({1}) ->
22012      ^
22013  '''
22014  assertErrorFormat '''
22015    ({a: true = 1}) ->
22016  ''', '''
22017    [stdin]:1:6: error: keyword 'true' can't be assigned
22018    ({a: true = 1}) ->
22019         ^^^^
22020  '''
22021
22022test "`yield` outside of a function", ->
22023  assertErrorFormat '''
22024    yield 1
22025  ''', '''
22026    [stdin]:1:1: error: yield can only occur inside functions
22027    yield 1
22028    ^^^^^^^
22029  '''
22030  assertErrorFormat '''
22031    yield return
22032  ''', '''
22033    [stdin]:1:1: error: yield can only occur inside functions
22034    yield return
22035    ^^^^^^^^^^^^
22036  '''
22037
22038test "#4097: `yield return` as an expression", ->
22039  assertErrorFormat '''
22040    -> (yield return)
22041  ''', '''
22042    [stdin]:1:5: error: cannot use a pure statement in an expression
22043    -> (yield return)
22044        ^^^^^^^^^^^^
22045  '''
22046
22047test "#5013: `await return` as an expression", ->
22048  assertErrorFormat '''
22049    -> (await return)
22050  ''', '''
22051    [stdin]:1:5: error: cannot use a pure statement in an expression
22052    -> (await return)
22053        ^^^^^^^^^^^^
22054  '''
22055
22056test "#5013: `return` as an expression", ->
22057  assertErrorFormat '''
22058    -> (return)
22059  ''', '''
22060    [stdin]:1:5: error: cannot use a pure statement in an expression
22061    -> (return)
22062        ^^^^^^
22063  '''
22064
22065test "#5013: `break` as an expression", ->
22066  assertErrorFormat '''
22067    (b = 1; break) for b in a
22068  ''', '''
22069    [stdin]:1:9: error: cannot use a pure statement in an expression
22070    (b = 1; break) for b in a
22071            ^^^^^
22072  '''
22073
22074test "#5013: `continue` as an expression", ->
22075  assertErrorFormat '''
22076    (b = 1; continue) for b in a
22077  ''', '''
22078    [stdin]:1:9: error: cannot use a pure statement in an expression
22079    (b = 1; continue) for b in a
22080            ^^^^^^^^
22081  '''
22082
22083test "`&&=` and `||=` with a space in-between", ->
22084  assertErrorFormat '''
22085    a = 0
22086    a && = 1
22087  ''', '''
22088    [stdin]:2:6: error: unexpected =
22089    a && = 1
22090         ^
22091  '''
22092  assertErrorFormat '''
22093    a = 0
22094    a and = 1
22095  ''', '''
22096    [stdin]:2:7: error: unexpected =
22097    a and = 1
22098          ^
22099  '''
22100  assertErrorFormat '''
22101    a = 0
22102    a || = 1
22103  ''', '''
22104    [stdin]:2:6: error: unexpected =
22105    a || = 1
22106         ^
22107  '''
22108  assertErrorFormat '''
22109    a = 0
22110    a or = 1
22111  ''', '''
22112    [stdin]:2:6: error: unexpected =
22113    a or = 1
22114         ^
22115  '''
22116
22117test "anonymous functions cannot be exported", ->
22118  assertErrorFormat '''
22119    export ->
22120      console.log 'hello, world!'
22121  ''', '''
22122    [stdin]:1:8: error: unexpected ->
22123    export ->
22124           ^^
22125  '''
22126
22127test "anonymous classes cannot be exported", ->
22128  assertErrorFormat '''
22129    export class
22130      constructor: ->
22131        console.log 'hello, world!'
22132  ''', '''
22133    [stdin]:1:8: error: anonymous classes cannot be exported
22134    export class
22135           ^^^^^
22136  '''
22137
22138test "unless enclosed by curly braces, only * can be aliased", ->
22139  assertErrorFormat '''
22140    import foo as bar from 'lib'
22141  ''', '''
22142    [stdin]:1:12: error: unexpected as
22143    import foo as bar from 'lib'
22144               ^^
22145  '''
22146
22147test "unwrapped imports must follow constrained syntax", ->
22148  assertErrorFormat '''
22149    import foo, bar from 'lib'
22150  ''', '''
22151    [stdin]:1:13: error: unexpected identifier
22152    import foo, bar from 'lib'
22153                ^^^
22154  '''
22155  assertErrorFormat '''
22156    import foo, bar, baz from 'lib'
22157  ''', '''
22158    [stdin]:1:13: error: unexpected identifier
22159    import foo, bar, baz from 'lib'
22160                ^^^
22161  '''
22162  assertErrorFormat '''
22163    import foo, bar as baz from 'lib'
22164  ''', '''
22165    [stdin]:1:13: error: unexpected identifier
22166    import foo, bar as baz from 'lib'
22167                ^^^
22168  '''
22169
22170test "cannot export * without a module to export from", ->
22171  assertErrorFormat '''
22172    export *
22173  ''', '''
22174    [stdin]:1:9: error: unexpected end of input
22175    export *
22176            ^
22177  '''
22178
22179test "imports and exports must be top-level", ->
22180  assertErrorFormatNoAst '''
22181    if foo
22182      import { bar } from 'lib'
22183  ''', '''
22184    [stdin]:2:3: error: import statements must be at top-level scope
22185      import { bar } from 'lib'
22186      ^^^^^^^^^^^^^^^^^^^^^^^^^
22187  '''
22188  assertErrorFormatNoAst '''
22189    foo = ->
22190      export { bar }
22191  ''', '''
22192    [stdin]:2:3: error: export statements must be at top-level scope
22193      export { bar }
22194      ^^^^^^^^^^^^^^
22195  '''
22196
22197test "cannot import the same member more than once", ->
22198  assertErrorFormat '''
22199    import { foo, foo } from 'lib'
22200  ''', '''
22201    [stdin]:1:15: error: 'foo' has already been declared
22202    import { foo, foo } from 'lib'
22203                  ^^^
22204  '''
22205  assertErrorFormat '''
22206    import { foo, bar, foo } from 'lib'
22207  ''', '''
22208    [stdin]:1:20: error: 'foo' has already been declared
22209    import { foo, bar, foo } from 'lib'
22210                       ^^^
22211  '''
22212  assertErrorFormat '''
22213    import { foo, bar as foo } from 'lib'
22214  ''', '''
22215    [stdin]:1:15: error: 'foo' has already been declared
22216    import { foo, bar as foo } from 'lib'
22217                  ^^^^^^^^^^
22218  '''
22219  assertErrorFormat '''
22220    import foo, { foo } from 'lib'
22221  ''', '''
22222    [stdin]:1:15: error: 'foo' has already been declared
22223    import foo, { foo } from 'lib'
22224                  ^^^
22225  '''
22226  assertErrorFormat '''
22227    import foo, { bar as foo } from 'lib'
22228  ''', '''
22229    [stdin]:1:15: error: 'foo' has already been declared
22230    import foo, { bar as foo } from 'lib'
22231                  ^^^^^^^^^^
22232  '''
22233  assertErrorFormat '''
22234    import foo from 'libA'
22235    import foo from 'libB'
22236  ''', '''
22237    [stdin]:2:8: error: 'foo' has already been declared
22238    import foo from 'libB'
22239           ^^^
22240  '''
22241  assertErrorFormat '''
22242    import * as foo from 'libA'
22243    import { foo } from 'libB'
22244  ''', '''
22245    [stdin]:2:10: error: 'foo' has already been declared
22246    import { foo } from 'libB'
22247             ^^^
22248  '''
22249
22250test "imported members cannot be reassigned", ->
22251  assertErrorFormat '''
22252    import { foo } from 'lib'
22253    foo = 'bar'
22254  ''', '''
22255    [stdin]:2:1: error: 'foo' is read-only
22256    foo = 'bar'
22257    ^^^
22258  '''
22259  assertErrorFormat '''
22260    import { foo } from 'lib'
22261    export default foo = 'bar'
22262  ''', '''
22263    [stdin]:2:16: error: 'foo' is read-only
22264    export default foo = 'bar'
22265                   ^^^
22266  '''
22267  assertErrorFormat '''
22268    import { foo } from 'lib'
22269    export foo = 'bar'
22270  ''', '''
22271    [stdin]:2:8: error: 'foo' is read-only
22272    export foo = 'bar'
22273           ^^^
22274  '''
22275
22276test "bound functions cannot be generators", ->
22277  assertErrorFormat 'f = => yield this', '''
22278    [stdin]:1:8: error: yield cannot occur inside bound (fat arrow) functions
22279    f = => yield this
22280           ^^^^^^^^^^
22281  '''
22282
22283test "#4790: bound functions cannot be generators, even when we’re creating IIFEs", ->
22284  assertErrorFormat '''
22285  =>
22286    for x in []
22287      for y in []
22288        yield z
22289  ''', '''
22290    [stdin]:4:7: error: yield cannot occur inside bound (fat arrow) functions
22291          yield z
22292          ^^^^^^^
22293  '''
22294
22295test "CoffeeScript keywords cannot be used as unaliased names in import lists", ->
22296  assertErrorFormat """
22297    import { unless, baz as bar } from 'lib'
22298    bar.barMethod()
22299  """, '''
22300    [stdin]:1:10: error: unexpected unless
22301    import { unless, baz as bar } from 'lib'
22302             ^^^^^^
22303  '''
22304
22305test "CoffeeScript keywords cannot be used as local names in import list aliases", ->
22306  assertErrorFormat """
22307    import { bar as unless, baz as bar } from 'lib'
22308    bar.barMethod()
22309  """, '''
22310    [stdin]:1:17: error: unexpected unless
22311    import { bar as unless, baz as bar } from 'lib'
22312                    ^^^^^^
22313  '''
22314
22315test "cannot have `await return` outside a function", ->
22316  assertErrorFormat '''
22317    await return
22318  ''', '''
22319    [stdin]:1:1: error: await can only occur inside functions
22320    await return
22321    ^^^^^^^^^^^^
22322  '''
22323
22324test "indexes are not supported in for-from loops", ->
22325  assertErrorFormat "x for x, i from [1, 2, 3]", '''
22326    [stdin]:1:10: error: cannot use index with for-from
22327    x for x, i from [1, 2, 3]
22328             ^
22329  '''
22330
22331test "own is not supported in for-from loops", ->
22332  assertErrorFormat "x for own x from [1, 2, 3]", '''
22333    [stdin]:1:7: error: cannot use own with for-from
22334    x for own x from [1, 2, 3]
22335          ^^^
22336    '''
22337
22338test "tagged template literals must be called by an identifier", ->
22339  assertErrorFormat "1''", '''
22340    [stdin]:1:1: error: literal is not a function
22341    1''
22342    ^
22343  '''
22344  assertErrorFormat '1""', '''
22345    [stdin]:1:1: error: literal is not a function
22346    1""
22347    ^
22348  '''
22349  assertErrorFormat "1'b'", '''
22350    [stdin]:1:1: error: literal is not a function
22351    1'b'
22352    ^
22353  '''
22354  assertErrorFormat '1"b"', '''
22355    [stdin]:1:1: error: literal is not a function
22356    1"b"
22357    ^
22358  '''
22359  assertErrorFormat "1'''b'''", """
22360    [stdin]:1:1: error: literal is not a function
22361    1'''b'''
22362    ^
22363  """
22364  assertErrorFormat '1"""b"""', '''
22365    [stdin]:1:1: error: literal is not a function
22366    1"""b"""
22367    ^
22368  '''
22369  assertErrorFormat '1"#{b}"', '''
22370    [stdin]:1:1: error: literal is not a function
22371    1"#{b}"
22372    ^
22373  '''
22374  assertErrorFormat '1"""#{b}"""', '''
22375    [stdin]:1:1: error: literal is not a function
22376    1"""#{b}"""
22377    ^
22378  '''
22379
22380test "constructor functions can't be async", ->
22381  assertErrorFormat 'class then constructor: -> await x', '''
22382    [stdin]:1:12: error: Class constructor may not be async
22383    class then constructor: -> await x
22384               ^^^^^^^^^^^
22385  '''
22386
22387test "constructor functions can't be generators", ->
22388  assertErrorFormat 'class then constructor: -> yield', '''
22389    [stdin]:1:12: error: Class constructor may not be a generator
22390    class then constructor: -> yield
22391               ^^^^^^^^^^^
22392  '''
22393
22394test "non-derived constructors can't call super", ->
22395  assertErrorFormat 'class then constructor: -> super()', '''
22396    [stdin]:1:28: error: 'super' is only allowed in derived class constructors
22397    class then constructor: -> super()
22398                               ^^^^^^^
22399  '''
22400
22401test "derived constructors can't reference `this` before calling super", ->
22402  assertErrorFormat 'class extends A then constructor: -> @', '''
22403    [stdin]:1:38: error: Can't reference 'this' before calling super in derived class constructors
22404    class extends A then constructor: -> @
22405                                         ^
22406  '''
22407
22408test "derived constructors can't use @params without calling super", ->
22409  assertErrorFormat 'class extends A then constructor: (@a) ->', '''
22410    [stdin]:1:36: error: Can't use @params in derived class constructors without calling super
22411    class extends A then constructor: (@a) ->
22412                                       ^^
22413  '''
22414
22415test "derived constructors can't call super with @params", ->
22416  assertErrorFormat 'class extends A then constructor: (@a) -> super(@a)', '''
22417    [stdin]:1:49: error: Can't call super with @params in derived class constructors
22418    class extends A then constructor: (@a) -> super(@a)
22419                                                    ^^
22420  '''
22421
22422test "derived constructors can't call super with buried @params", ->
22423  assertErrorFormat 'class extends A then constructor: (@a) -> super((=> @a)())', '''
22424    [stdin]:1:53: error: Can't call super with @params in derived class constructors
22425    class extends A then constructor: (@a) -> super((=> @a)())
22426                                                        ^^
22427  '''
22428
22429test "'super' is not allowed in constructor parameter defaults", ->
22430  assertErrorFormat 'class extends A then constructor: (a = super()) ->', '''
22431    [stdin]:1:40: error: 'super' is not allowed in constructor parameter defaults
22432    class extends A then constructor: (a = super()) ->
22433                                           ^^^^^^^
22434  '''
22435
22436test "can't use pattern matches for loop indices", ->
22437  assertErrorFormat 'a for b, {c} in d', '''
22438    [stdin]:1:10: error: index cannot be a pattern matching expression
22439    a for b, {c} in d
22440             ^^^
22441  '''
22442
22443test "bare 'super' is no longer allowed", ->
22444  # TODO Improve this error message (it should at least be 'unexpected super')
22445  assertErrorFormat 'class extends A then constructor: -> super', '''
22446    [stdin]:1:35: error: unexpected ->
22447    class extends A then constructor: -> super
22448                                      ^^
22449  '''
22450
22451test "soaked 'super' in constructor", ->
22452  assertErrorFormat 'class extends A then constructor: -> super?()', '''
22453    [stdin]:1:38: error: Unsupported reference to 'super'
22454    class extends A then constructor: -> super?()
22455                                         ^^^^^
22456  '''
22457
22458test "new with 'super'", ->
22459  assertErrorFormat 'class extends A then foo: -> new super()', '''
22460    [stdin]:1:34: error: Unsupported reference to 'super'
22461    class extends A then foo: -> new super()
22462                                     ^^^^^
22463  '''
22464
22465test "'super' outside method", ->
22466  assertErrorFormat 'super()', '''
22467    [stdin]:1:1: error: cannot use super outside of an instance method
22468    super()
22469    ^^^^^
22470  '''
22471
22472test "getter keyword in object", ->
22473  assertErrorFormat '''
22474    obj =
22475      get foo: ->
22476  ''', '''
22477    [stdin]:2:3: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22478      get foo: ->
22479      ^^^
22480  '''
22481
22482test "setter keyword in object", ->
22483  assertErrorFormat '''
22484    obj =
22485      set foo: ->
22486  ''', '''
22487    [stdin]:2:3: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22488      set foo: ->
22489      ^^^
22490  '''
22491
22492test "getter keyword in inline implicit object", ->
22493  assertErrorFormat 'obj = get foo: ->', '''
22494    [stdin]:1:7: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22495    obj = get foo: ->
22496          ^^^
22497  '''
22498
22499test "setter keyword in inline implicit object", ->
22500  assertErrorFormat 'obj = set foo: ->', '''
22501    [stdin]:1:7: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22502    obj = set foo: ->
22503          ^^^
22504  '''
22505
22506test "getter keyword in inline explicit object", ->
22507  assertErrorFormat 'obj = {get foo: ->}', '''
22508    [stdin]:1:8: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22509    obj = {get foo: ->}
22510           ^^^
22511  '''
22512
22513test "setter keyword in inline explicit object", ->
22514  assertErrorFormat 'obj = {set foo: ->}', '''
22515    [stdin]:1:8: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22516    obj = {set foo: ->}
22517           ^^^
22518  '''
22519
22520test "getter keyword in function", ->
22521  assertErrorFormat '''
22522    f = ->
22523      get foo: ->
22524  ''', '''
22525    [stdin]:2:3: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22526      get foo: ->
22527      ^^^
22528  '''
22529
22530test "setter keyword in function", ->
22531  assertErrorFormat '''
22532    f = ->
22533      set foo: ->
22534  ''', '''
22535    [stdin]:2:3: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22536      set foo: ->
22537      ^^^
22538  '''
22539
22540test "getter keyword in inline function", ->
22541  assertErrorFormat 'f = -> get foo: ->', '''
22542    [stdin]:1:8: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22543    f = -> get foo: ->
22544           ^^^
22545  '''
22546
22547test "setter keyword in inline function", ->
22548  assertErrorFormat 'f = -> set foo: ->', '''
22549    [stdin]:1:8: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22550    f = -> set foo: ->
22551           ^^^
22552  '''
22553
22554test "getter keyword in class", ->
22555  assertErrorFormat '''
22556    class A
22557      get foo: ->
22558  ''', '''
22559    [stdin]:2:3: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22560      get foo: ->
22561      ^^^
22562  '''
22563
22564test "setter keyword in class", ->
22565  assertErrorFormat '''
22566    class A
22567      set foo: ->
22568  ''', '''
22569    [stdin]:2:3: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22570      set foo: ->
22571      ^^^
22572  '''
22573
22574test "getter keyword in inline class", ->
22575  assertErrorFormat 'class A then get foo: ->', '''
22576      [stdin]:1:14: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22577      class A then get foo: ->
22578                   ^^^
22579  '''
22580
22581test "setter keyword in inline class", ->
22582  assertErrorFormat 'class A then set foo: ->', '''
22583      [stdin]:1:14: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22584      class A then set foo: ->
22585                   ^^^
22586  '''
22587
22588test "getter keyword before static method", ->
22589  assertErrorFormat '''
22590    class A
22591      get @foo = ->
22592  ''', '''
22593    [stdin]:2:3: error: 'get' cannot be used as a keyword, or as a function call without parentheses
22594      get @foo = ->
22595      ^^^
22596  '''
22597
22598test "setter keyword before static method", ->
22599  assertErrorFormat '''
22600    class A
22601      set @foo = ->
22602  ''', '''
22603    [stdin]:2:3: error: 'set' cannot be used as a keyword, or as a function call without parentheses
22604      set @foo = ->
22605      ^^^
22606  '''
22607
22608test "#4248: Unicode code point escapes", ->
22609  assertErrorFormat '''
22610    "a
22611      #{b} \\u{G02}
22612     c"
22613  ''', '''
22614    [stdin]:2:8: error: invalid escape sequence \\u{G02}
22615      #{b} \\u{G02}
22616           ^\^^^^^^
22617  '''
22618  assertErrorFormat '''
22619    /a\\u{}b/
22620  ''', '''
22621    [stdin]:1:3: error: invalid escape sequence \\u{}
22622    /a\\u{}b/
22623      ^\^^^
22624  '''
22625  assertErrorFormat '''
22626    ///a \\u{01abc///
22627  ''', '''
22628    [stdin]:1:6: error: invalid escape sequence \\u{01abc
22629    ///a \\u{01abc///
22630         ^\^^^^^^^
22631  '''
22632
22633  assertErrorFormat '''
22634    /\\u{123} \\u{110000}/
22635  ''', '''
22636    [stdin]:1:10: error: unicode code point escapes greater than \\u{10ffff} are not allowed
22637    /\\u{123} \\u{110000}/
22638      \       ^\^^^^^^^^^
22639  '''
22640
22641  assertErrorFormat '''
22642    ///abc\\\\\\u{123456}///u
22643  ''', '''
22644    [stdin]:1:9: error: unicode code point escapes greater than \\u{10ffff} are not allowed
22645    ///abc\\\\\\u{123456}///u
22646           \ \^\^^^^^^^^^
22647  '''
22648
22649  assertErrorFormat '''
22650    """
22651      \\u{123}
22652      a
22653        \\u{00110000}
22654      #{ 'b' }
22655    """
22656  ''', '''
22657    [stdin]:4:5: error: unicode code point escapes greater than \\u{10ffff} are not allowed
22658        \\u{00110000}
22659        ^\^^^^^^^^^^^
22660  '''
22661
22662  assertErrorFormat '''
22663    '\\u{a}\\u{1111110000}'
22664  ''', '''
22665    [stdin]:1:7: error: unicode code point escapes greater than \\u{10ffff} are not allowed
22666    '\\u{a}\\u{1111110000}'
22667      \    ^\^^^^^^^^^^^^^
22668  '''
22669
22670test "JSX error: non-matching tag names", ->
22671  assertErrorFormat '''
22672    <div><span></div></span>
22673  ''',
22674  '''
22675    [stdin]:1:7: error: expected corresponding JSX closing tag for span
22676    <div><span></div></span>
22677          ^^^^
22678  '''
22679
22680test "JSX error: bare expressions not allowed", ->
22681  assertErrorFormat '''
22682    <div x=3 />
22683  ''',
22684  '''
22685    [stdin]:1:8: error: expected wrapped or quoted JSX attribute
22686    <div x=3 />
22687           ^
22688  '''
22689
22690test "JSX error: unescaped opening tag angle bracket disallowed", ->
22691  assertErrorFormat '''
22692    <Person><<</Person>
22693  ''',
22694  '''
22695    [stdin]:1:9: error: unexpected <<
22696    <Person><<</Person>
22697            ^^
22698  '''
22699
22700test "JSX error: ambiguous tag-like expression", ->
22701  assertErrorFormat '''
22702    x = a <b > c
22703  ''',
22704  '''
22705    [stdin]:1:10: error: missing </
22706    x = a <b > c
22707             ^
22708  '''
22709
22710test 'JSX error: invalid attributes', ->
22711  assertErrorFormat '''
22712    <div a="b" {props} />
22713  ''', '''
22714    [stdin]:1:12: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
22715    <div a="b" {props} />
22716               ^^^^^^^
22717  '''
22718  assertErrorFormat '''
22719    <div a={b} {a:{b}} />
22720  ''', '''
22721    [stdin]:1:12: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
22722    <div a={b} {a:{b}} />
22723               ^^^^^^^
22724  '''
22725  assertErrorFormat '''
22726    <div {"#{a}"} />
22727  ''', '''
22728    [stdin]:1:6: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
22729    <div {"#{a}"} />
22730         ^^^^^^^^
22731  '''
22732  assertErrorFormat '''
22733    <div props... />
22734  ''', '''
22735    [stdin]:1:11: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
22736    <div props... />
22737              ^^^
22738  '''
22739  assertErrorFormat '''
22740    <div {a:"b", props..., c:d()} />
22741  ''', '''
22742    [stdin]:1:6: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
22743    <div {a:"b", props..., c:d()} />
22744         ^^^^^^^^^^^^^^^^^^^^^^^^
22745  '''
22746  assertErrorFormat '''
22747    <div {props..., a, b} />
22748  ''', '''
22749    [stdin]:1:6: error: Unexpected token. Allowed JSX attributes are: id="val", src={source}, {props...} or attribute.
22750    <div {props..., a, b} />
22751         ^^^^^^^^^^^^^^^^
22752  '''
22753
22754test '#5034: JSX error: Adjacent JSX elements must be wrapped in an enclosing tag', ->
22755  assertErrorFormat '''
22756    render = -> (
22757      <Row>a</Row>
22758      <Row>b</Row>
22759    )
22760  ''', '''
22761    [stdin]:3:3: error: Adjacent JSX elements must be wrapped in an enclosing tag
22762      <Row>b</Row>
22763      ^^^^^^^^^^^^
22764  '''
22765  assertErrorFormat '''
22766    render = -> (
22767      a = "foo"
22768      <Row>a</Row>
22769      <Row>b</Row>
22770    )
22771  ''', '''
22772    [stdin]:4:3: error: Adjacent JSX elements must be wrapped in an enclosing tag
22773      <Row>b</Row>
22774      ^^^^^^^^^^^^
22775  '''
22776test 'Bound method called as callback before binding throws runtime error', ->
22777  class Base
22778    constructor: ->
22779      f = @derivedBound
22780      try
22781        f()
22782        ok no
22783      catch e
22784        eq e.message, 'Bound instance method accessed before binding'
22785
22786  class Derived extends Base
22787    derivedBound: =>
22788      ok no
22789  d = new Derived
22790
22791test "#3845/#3446: chain after function glyph (but not inline)", ->
22792  assertErrorFormat '''
22793    a -> .b
22794  ''',
22795  '''
22796    [stdin]:1:6: error: unexpected .
22797    a -> .b
22798         ^
22799  '''
22800
22801test "#3906: error for unusual indentation", ->
22802  assertErrorFormat '''
22803    a
22804      c
22805     .d
22806
22807    e(
22808     f)
22809
22810    g
22811  ''', '''
22812    [stdin]:2:1: error: unexpected indentation
22813      c
22814    ^^
22815  '''
22816
22817test "#4283: error message for implicit call", ->
22818  assertErrorFormat '''
22819    (a, b c) ->
22820  ''', '''
22821    [stdin]:1:5: error: unexpected implicit function call
22822    (a, b c) ->
22823        ^
22824  '''
22825
22826test "#3199: error message for call indented non-object", ->
22827  assertErrorFormat '''
22828    fn = ->
22829    fn
22830      1
22831  ''', '''
22832    [stdin]:3:1: error: unexpected indentation
22833      1
22834    ^^
22835  '''
22836
22837test "#3199: error message for call indented comprehension", ->
22838  assertErrorFormat '''
22839    fn = ->
22840    fn
22841      x for x in [1, 2, 3]
22842  ''', '''
22843    [stdin]:3:1: error: unexpected indentation
22844      x for x in [1, 2, 3]
22845    ^^
22846  '''
22847
22848test "#3199: error message for return indented non-object", ->
22849  assertErrorFormat '''
22850    return
22851      1
22852  ''', '''
22853    [stdin]:2:3: error: unexpected number
22854      1
22855      ^
22856  '''
22857
22858test "#3199: error message for return indented comprehension", ->
22859  assertErrorFormat '''
22860    return
22861      x for x in [1, 2, 3]
22862  ''', '''
22863    [stdin]:2:3: error: unexpected identifier
22864      x for x in [1, 2, 3]
22865      ^
22866  '''
22867
22868test "#3199: error message for throw indented non-object", ->
22869  assertErrorFormat '''
22870    throw
22871      1
22872  ''', '''
22873    [stdin]:2:3: error: unexpected number
22874      1
22875      ^
22876  '''
22877
22878test "#3199: error message for throw indented comprehension", ->
22879  assertErrorFormat '''
22880    throw
22881      x for x in [1, 2, 3]
22882  ''', '''
22883    [stdin]:2:3: error: unexpected identifier
22884      x for x in [1, 2, 3]
22885      ^
22886  '''
22887
22888test "#3199: error message for yield indented non-object", ->
22889  assertErrorFormat '''
22890    ->
22891      yield
22892        1
22893  ''', '''
22894    [stdin]:3:5: error: unexpected number
22895        1
22896        ^
22897  '''
22898
22899test "#3199: error message for yield indented comprehension", ->
22900  assertErrorFormat '''
22901    ->
22902      yield
22903        x for x in [1, 2, 3]
22904  ''', '''
22905    [stdin]:3:5: error: unexpected identifier
22906        x for x in [1, 2, 3]
22907        ^
22908  '''
22909
22910test "#3199: error message for await indented non-object", ->
22911  assertErrorFormat '''
22912    ->
22913      await
22914        1
22915  ''', '''
22916    [stdin]:3:5: error: unexpected number
22917        1
22918        ^
22919  '''
22920
22921test "#3199: error message for await indented comprehension", ->
22922  assertErrorFormat '''
22923    ->
22924      await
22925        x for x in [1, 2, 3]
22926  ''', '''
22927    [stdin]:3:5: error: unexpected identifier
22928        x for x in [1, 2, 3]
22929        ^
22930  '''
22931
22932test "#3098: suppressed newline should be unsuppressed by semicolon", ->
22933  assertErrorFormat '''
22934    a = ; 5
22935  ''', '''
22936    [stdin]:1:5: error: unexpected ;
22937    a = ; 5
22938        ^
22939  '''
22940
22941test "#4811: '///' inside a heregex comment does not close the heregex", ->
22942  assertErrorFormat '''
22943   /// .* # comment ///
22944  ''', '''
22945  [stdin]:1:1: error: missing ///
22946  /// .* # comment ///
22947  ^^^
22948  '''
22949
22950test "#3933: prevent implicit calls when cotrol flow is missing `THEN`", ->
22951  assertErrorFormat '''
22952    for a in b do ->
22953  ''','''
22954    [stdin]:1:12: error: unexpected do
22955    for a in b do ->
22956               ^^
22957  '''
22958
22959  assertErrorFormat '''
22960    for a in b ->
22961  ''','''
22962    [stdin]:1:12: error: unexpected ->
22963    for a in b ->
22964               ^^
22965  '''
22966
22967  assertErrorFormat '''
22968    for a in b do =>
22969  ''','''
22970    [stdin]:1:12: error: unexpected do
22971    for a in b do =>
22972               ^^
22973  '''
22974
22975  assertErrorFormat '''
22976    while a do ->
22977  ''','''
22978    [stdin]:1:9: error: unexpected do
22979    while a do ->
22980            ^^
22981  '''
22982
22983  assertErrorFormat '''
22984    until a do =>
22985  ''','''
22986    [stdin]:1:9: error: unexpected do
22987    until a do =>
22988            ^^
22989  '''
22990
22991  assertErrorFormat '''
22992    switch
22993      when a ->
22994  ''','''
22995    [stdin]:2:10: error: unexpected ->
22996      when a ->
22997             ^^
22998  '''
22999
23000test "`new.target` outside of a function", ->
23001  assertErrorFormat '''
23002    new.target
23003  ''', '''
23004    [stdin]:1:1: error: new.target can only occur inside functions
23005    new.target
23006    ^^^^^^^^^^
23007  '''
23008
23009test "`new.target` is only allowed meta property", ->
23010  assertErrorFormat '''
23011    -> new.something
23012  ''', '''
23013    [stdin]:1:4: error: the only valid meta property for new is new.target
23014    -> new.something
23015       ^^^^^^^^^^^^^
23016  '''
23017
23018test "`import.meta` is only allowed meta property", ->
23019  assertErrorFormat '''
23020    foo = import.something
23021  ''', '''
23022    [stdin]:1:7: error: the only valid meta property for import is import.meta
23023    foo = import.something
23024          ^^^^^^^^^^^^^^^^
23025  '''
23026
23027test "`new.target` cannot be assigned", ->
23028  assertErrorFormat '''
23029    ->
23030      new.target = b
23031  ''', '''
23032    [stdin]:2:14: error: unexpected =
23033      new.target = b
23034                 ^
23035  '''
23036
23037test "#4834: dynamic import accepts either one or two arguments", ->
23038  assertErrorFormat '''
23039    import()
23040  ''', '''
23041    [stdin]:1:1: error: import() accepts either one or two arguments
23042    import()
23043    ^^^^^^^^
23044  '''
23045
23046  assertErrorFormat '''
23047    import('x', {}, 3)
23048  ''', '''
23049    [stdin]:1:1: error: import() accepts either one or two arguments
23050    import('x', {}, 3)
23051    ^^^^^^^^^^^^^^^^^^
23052  '''
23053
23054test "#4834: dynamic import requires explicit call parentheses", ->
23055  assertErrorFormat '''
23056    promise = import 'foo'
23057  ''', '''
23058    [stdin]:1:23: error: unexpected end of input
23059    promise = import 'foo'
23060                          ^
23061  '''
23062
23063</script>
vendor: 1 bytes, line 23063
23063
23064<script type="text/x-coffeescript" class="test" id="eval">
23065if vm = require? 'vm'
23066
23067  test "CoffeeScript.eval runs in the global context by default", ->
23068    global.punctuation = '!'
23069    code = '''
23070    global.fhqwhgads = "global superpower#{global.punctuation}"
23071    '''
23072    result = CoffeeScript.eval code
23073    eq result, 'global superpower!'
23074    eq fhqwhgads, 'global superpower!'
23075
23076  test "CoffeeScript.eval can run in, and modify, a Script context sandbox", ->
23077    createContext = vm.Script.createContext ? vm.createContext
23078    sandbox = createContext()
23079    sandbox.foo = 'bar'
23080    code = '''
23081    global.foo = 'not bar!'
23082    '''
23083    result = CoffeeScript.eval code, {sandbox}
23084    eq result, 'not bar!'
23085    eq sandbox.foo, 'not bar!'
23086
23087  test "CoffeeScript.eval can run in, but cannot modify, an ordinary object sandbox", ->
23088    sandbox = {foo: 'bar'}
23089    code = '''
23090    global.foo = 'not bar!'
23091    '''
23092    result = CoffeeScript.eval code, {sandbox}
23093    eq result, 'not bar!'
23094    eq sandbox.foo, 'bar'
23095
23096</script>
vendor: 1 bytes, line 23096
23096
23097<script type="text/x-coffeescript" class="test" id="exception_handling">
23098# Exception Handling
23099# ------------------
23100
23101# shared nonce
23102nonce = {}
23103
23104
23105# Throw
23106
23107test "basic exception throwing", ->
23108  throws (-> throw 'error'), /^error$/
23109
23110
23111# Empty Try/Catch/Finally
23112
23113test "try can exist alone", ->
23114  try
23115
23116test "try/catch with empty try, empty catch", ->
23117  try
23118    # nothing
23119  catch err
23120    # nothing
23121
23122test "single-line try/catch with empty try, empty catch", ->
23123  try catch err
23124
23125test "try/finally with empty try, empty finally", ->
23126  try
23127    # nothing
23128  finally
23129    # nothing
23130
23131test "single-line try/finally with empty try, empty finally", ->
23132  try finally
23133
23134test "try/catch/finally with empty try, empty catch, empty finally", ->
23135  try
23136  catch err
23137  finally
23138
23139test "single-line try/catch/finally with empty try, empty catch, empty finally", ->
23140  try catch err then finally
23141
23142
23143# Try/Catch/Finally as an Expression
23144
23145test "return the result of try when no exception is thrown", ->
23146  result = try
23147    nonce
23148  catch err
23149    undefined
23150  finally
23151    undefined
23152  eq nonce, result
23153
23154test "single-line result of try when no exception is thrown", ->
23155  result = try nonce catch err then undefined
23156  eq nonce, result
23157
23158test "return the result of catch when an exception is thrown", ->
23159  fn = ->
23160    try
23161      throw ->
23162    catch err
23163      nonce
23164  doesNotThrow fn
23165  eq nonce, fn()
23166
23167test "single-line result of catch when an exception is thrown", ->
23168  fn = ->
23169    try throw (->) catch err then nonce
23170  doesNotThrow fn
23171  eq nonce, fn()
23172
23173test "optional catch", ->
23174  fn = ->
23175    try throw ->
23176    nonce
23177  doesNotThrow fn
23178  eq nonce, fn()
23179
23180
23181# Try/Catch/Finally Interaction With Other Constructs
23182
23183test "try/catch with empty catch as last statement in a function body", ->
23184  fn = ->
23185    try nonce
23186    catch err
23187  eq nonce, fn()
23188
23189test "#1595: try/catch with a reused variable name", ->
23190  # `catch` shouldn’t lead to broken scoping.
23191  do ->
23192    try
23193      inner = 5
23194    catch inner
23195      # nothing
23196  eq typeof inner, 'undefined'
23197
23198test "#2580: try/catch with destructuring the exception object", ->
23199  result = try
23200    missing.object
23201  catch {message}
23202    message
23203
23204  eq message, 'missing is not defined'
23205
23206test "Try catch finally as implicit arguments", ->
23207  first = (x) -> x
23208
23209  foo = no
23210  try
23211    first try iamwhoiam() finally foo = yes
23212  catch e
23213  eq foo, yes
23214
23215  bar = no
23216  try
23217    first try iamwhoiam() catch e finally
23218    bar = yes
23219  catch e
23220  eq bar, yes
23221
23222test "#2900: parameter-less catch clause", ->
23223  # `catch` should not require a parameter.
23224  try
23225    throw new Error 'failed'
23226  catch
23227    ok true
23228
23229  try throw new Error 'failed' catch finally ok true
23230
23231  ok try throw new Error 'failed' catch then true
23232
23233test "#3709: throwing an if statement", ->
23234  # `throw if` should return a closure around the `if` block, so that the
23235  # output is valid JavaScript.
23236  try
23237    throw if no
23238        new Error 'drat!'
23239      else
23240        new Error 'no escape!'
23241  catch err
23242    eq err.message, 'no escape!'
23243
23244  try
23245    throw if yes then new Error 'huh?' else null
23246  catch err
23247    eq err.message, 'huh?'
23248
23249test "#3709: throwing a switch statement", ->
23250  i = 3
23251  try
23252    throw switch i
23253      when 2
23254        new Error 'not this one'
23255      when 3
23256        new Error 'oh no!'
23257  catch err
23258    eq err.message, 'oh no!'
23259
23260test "#3709: throwing a for loop", ->
23261  # `throw for` should return a closure around the `for` block, so that the
23262  # output is valid JavaScript.
23263  try
23264    throw for i in [0..3]
23265      i * 2
23266  catch err
23267    arrayEq err, [0, 2, 4, 6]
23268
23269test "#3709: throwing a while loop", ->
23270  i = 0
23271  try
23272    throw while i < 3
23273      i++
23274  catch err
23275    eq i, 3
23276
23277test "#3789: throwing a throw", ->
23278  try
23279    throw throw throw new Error 'whoa!'
23280  catch err
23281    eq err.message, 'whoa!'
23282
23283</script>
vendor: 1 bytes, line 23283
23283
23284<script type="text/x-coffeescript" class="test" id="exponentiation">
23285# The `**` and `**=` operators are only supported in Node 7.5+, so the tests
23286# for these exponentiation operators are split out into their own file to be
23287# loaded only by supported runtimes.
23288
23289test "exponentiation operator", ->
23290  eq 27, 3 ** 3
23291
23292test "exponentiation operator has higher precedence than other maths operators", ->
23293  eq 55, 1 + 3 ** 3 * 2
23294  eq -4, -2 ** 2
23295  eq 0, (!2) ** 2
23296
23297test "exponentiation operator is right associative", ->
23298  eq 2, 2 ** 1 ** 3
23299
23300test "exponentiation operator compound assignment", ->
23301  a = 2
23302  a **= 3
23303  eq 8, a
23304
23305</script>
vendor: 1 bytes, line 23305
23305
23306<script type="text/x-coffeescript" class="test" id="formatting">
23307# Formatting
23308# ----------
23309
23310# TODO: maybe this file should be split up into their respective sections:
23311#   operators -> operators
23312#   array literals -> array literals
23313#   string literals -> string literals
23314#   function invocations -> function invocations
23315
23316doesNotThrowCompileError "a = then b"
23317
23318test "multiple semicolon-separated statements in parentheticals", ->
23319  nonce = {}
23320  eq nonce, (1; 2; nonce)
23321  eq nonce, (-> return (1; 2; nonce))()
23322
23323# * Line Continuation
23324#   * Property Accesss
23325#   * Operators
23326#   * Array Literals
23327#   * Function Invocations
23328#   * String Literals
23329
23330# Property Access
23331
23332test "chained accesses split on period/newline, backwards and forwards", ->
23333  str = 'abc'
23334  result = str.
23335    split('').
23336    reverse().
23337    reverse().
23338    reverse()
23339  arrayEq ['c','b','a'], result
23340  arrayEq ['c','b','a'], str.
23341    split('').
23342    reverse().
23343    reverse().
23344    reverse()
23345  result = str
23346    .split('')
23347    .reverse()
23348    .reverse()
23349    .reverse()
23350  arrayEq ['c','b','a'], result
23351  arrayEq ['c','b','a'],
23352    str
23353    .split('')
23354    .reverse()
23355    .reverse()
23356    .reverse()
23357  arrayEq ['c','b','a'],
23358    str.
23359    split('')
23360    .reverse().
23361    reverse()
23362    .reverse()
23363
23364# Operators
23365
23366test "newline suppression for operators", ->
23367  six =
23368    1 +
23369    2 +
23370    3
23371  eq 6, six
23372
23373test "`?.` and `::` should continue lines", ->
23374  ok not (
23375    Date
23376    ::
23377    ?.foo
23378  )
23379
23380  ok not (
23381    Date
23382    ?::
23383    ?.foo
23384  )
23385  #eq Object::toString, Date?.
23386  #prototype
23387  #::
23388  #?.foo
23389
23390doesNotThrowCompileError """
23391  oh. yes
23392  oh?. true
23393  oh:: return
23394  """
23395
23396doesNotThrowCompileError """
23397  a?[b..]
23398  a?[...b]
23399  a?[b..c]
23400  """
23401
23402test "#1768: space between `::` and index is ignored", ->
23403  eq 'function', typeof String:: ['toString']
23404
23405# Array Literals
23406
23407test "indented array literals don't trigger whitespace rewriting", ->
23408  getArgs = -> arguments
23409  result = getArgs(
23410    [[[[[],
23411                  []],
23412                [[]]]],
23413      []])
23414  eq 1, result.length
23415
23416# Function Invocations
23417
23418doesNotThrowCompileError """
23419  obj = then fn 1,
23420    1: 1
23421    a:
23422      b: ->
23423        fn c,
23424          d: e
23425    f: 1
23426  """
23427
23428# String Literals
23429
23430test "indented heredoc", ->
23431  result = ((_) -> _)(
23432                """
23433                abc
23434                """)
23435  eq "abc", result
23436
23437# Chaining - all open calls are closed by property access starting a new line
23438# * chaining after
23439#   * indented argument
23440#   * function block
23441#   * indented object
23442#
23443#   * single line arguments
23444#   * inline function literal
23445#   * inline object literal
23446#
23447# * chaining inside
23448#   * implicit object literal
23449
23450test "chaining after outdent", ->
23451  id = (x) -> x
23452
23453  # indented argument
23454  ff = id parseInt "ff",
23455    16
23456  .toString()
23457  eq '255', ff
23458
23459  # function block
23460  str = 'abc'
23461  zero = parseInt str.replace /\w/, (letter) ->
23462    0
23463  .toString()
23464  eq '0', zero
23465
23466  # indented object
23467  a = id id
23468    a: 1
23469  .a
23470  eq 1, a
23471
23472test "#1495, method call chaining", ->
23473  str = 'abc'
23474
23475  result = str.split ''
23476              .join ', '
23477  eq 'a, b, c', result
23478
23479  result = str
23480  .split ''
23481  .join ', '
23482  eq 'a, b, c', result
23483
23484  eq 'a, b, c', (str
23485    .split ''
23486    .join ', '
23487  )
23488
23489  eq 'abc',
23490    'aaabbbccc'.replace /(\w)\1\1/g, '$1$1'
23491               .replace /([abc])\1/g, '$1'
23492
23493  # Nested calls
23494  result = [1..3]
23495    .slice Math.max 0, 1
23496    .concat [3]
23497  arrayEq [2, 3, 3], result
23498
23499  # Single line function arguments
23500  result = [1..6]
23501    .map (x) -> x * x
23502    .filter (x) -> x % 2 is 0
23503    .reverse()
23504  arrayEq [36, 16, 4], result
23505
23506  # Single line implicit objects
23507  id = (x) -> x
23508  result = id a: 1
23509    .a
23510  eq 1, result
23511
23512  # The parens are forced
23513  result = str.split(''.
23514    split ''
23515    .join ''
23516  ).join ', '
23517  eq 'a, b, c', result
23518
23519test "chaining should not wrap spilling ternary", ->
23520  throwsCompileError """
23521    if 0 then 1 else g
23522      a: 42
23523    .h()
23524  """
23525
23526test "chaining should wrap calls containing spilling ternary", ->
23527  f = (x) -> h: x
23528  id = (x) -> x
23529  result = f if true then 42 else id
23530      a: 2
23531  .h
23532  eq 42, result
23533
23534test "chaining should work within spilling ternary", ->
23535  f = (x) -> h: x
23536  id = (x) -> x
23537  result = f if false then 1 else id
23538      a: 3
23539      .a
23540  eq 3, result.h
23541
23542test "method call chaining inside objects", ->
23543  f = (x) -> c: 42
23544  result =
23545    a: f 1
23546    b: f a: 1
23547      .c
23548  eq 42, result.b
23549
23550test "#4568: refine sameLine implicit object tagging", ->
23551  condition = yes
23552  fn = -> yes
23553
23554  x =
23555    fn bar: {
23556      foo: 123
23557    } if not condition
23558  eq x, undefined
23559
23560# Nested blocks caused by paren unwrapping
23561test "#1492: Nested blocks don't cause double semicolons", ->
23562  js = CoffeeScript.compile '(0;0)'
23563  eq -1, js.indexOf ';;'
23564
23565test "#1195 Ignore trailing semicolons (before newlines or as the last char in a program)", ->
23566  preNewline = (numSemicolons) ->
23567    """
23568    nonce = {}; nonce2 = {}
23569    f = -> nonce#{Array(numSemicolons+1).join(';')}
23570    nonce2
23571    unless f() is nonce then throw new Error('; before linebreak should = newline')
23572    """
23573  CoffeeScript.run(preNewline(n), bare: true) for n in [1,2,3]
23574
23575  lastChar = '-> lastChar;'
23576  doesNotThrowCompileError lastChar, bare: true
23577
23578test "#1299: Disallow token misnesting", ->
23579  try
23580    CoffeeScript.compile '''
23581      [{
23582         ]}
23583    '''
23584    ok no
23585  catch e
23586    eq 'unmatched ]', e.message
23587
23588test "#2981: Enforce initial indentation", ->
23589  try
23590    CoffeeScript.compile '  a\nb-'
23591    ok no
23592  catch e
23593    eq 'missing indentation', e.message
23594
23595test "'single-line' expression containing multiple lines", ->
23596  doesNotThrowCompileError """
23597    (a, b) -> if a
23598      -a
23599    else if b
23600    then -b
23601    else null
23602  """
23603
23604test "#1275: allow indentation before closing brackets", ->
23605  array = [
23606      1
23607      2
23608      3
23609    ]
23610  eq array, array
23611  do ->
23612  (
23613    a = 1
23614   )
23615  eq 1, a
23616
23617test "don’t allow mixing of spaces and tabs for indentation", ->
23618  try
23619    CoffeeScript.compile '''
23620      new Layer
23621       x: 0
23622      	y: 1
23623    '''
23624    ok no
23625  catch e
23626    eq 'indentation mismatch', e.message
23627
23628test "each code block that starts at indentation 0 can use a different style", ->
23629  doesNotThrowCompileError '''
23630      new Layer
23631       x: 0
23632       y: 1
23633      new Layer
23634      	x: 0
23635      	y: 1
23636    '''
23637
23638test "tabs and spaces cannot be mixed for indentation", ->
23639  try
23640    CoffeeScript.compile '''
23641      new Layer
23642      	 x: 0
23643      	 y: 1
23644    '''
23645    ok no
23646  catch e
23647    eq 'mixed indentation', e.message
23648
23649test "#4487: Handle unusual outdentation", ->
23650  a =
23651    switch 1
23652      when 2
23653          no
23654         when 3 then no
23655      when 1 then yes
23656  eq yes, a
23657
23658  b = do ->
23659    if no
23660      if no
23661            1
23662       2
23663      3
23664  eq b, undefined
23665
23666test "#3906: handle further indentation inside indented chain", ->
23667  eq 1, CoffeeScript.eval '''
23668    z = b: -> d: 2
23669    e = ->
23670    f = 3
23671
23672    z
23673        .b ->
23674            c
23675        .d
23676
23677    e(
23678        f
23679    )
23680
23681    1
23682  '''
23683
23684  eq 1, CoffeeScript.eval '''
23685    z = -> b: -> e: ->
23686
23687    z()
23688        .b
23689            c: 'd'
23690        .e()
23691
23692    f = [
23693        'g'
23694    ]
23695
23696    1
23697  '''
23698
23699  eq 1, CoffeeScript.eval '''
23700    z = -> c: -> c: ->
23701
23702    z('b')
23703      .c 'a',
23704        {b: 'a'}
23705      .c()
23706    z(
23707      'b'
23708    )
23709    1
23710  '''
23711
23712test "#3199: throw multiline implicit object", ->
23713  x = do ->
23714    if no then throw
23715      type: 'a'
23716      msg: 'b'
23717  eq undefined, x
23718
23719  y = do ->
23720    if no then return
23721      type: 'a'
23722      msg: 'b'
23723  eq undefined, y
23724
23725  y = do ->
23726    yield
23727      type: 'a'
23728      msg: 'b'
23729
23730    if no then yield
23731      type: 'c'
23732      msg: 'd'
23733
23734    1
23735  {value, done} = y.next()
23736  ok value.type is 'a' and done is no
23737
23738  {value, done} = y.next()
23739  ok value is 1 and done is yes
23740
23741test "#4576: multiple row function chaining", ->
23742  ->
23743    eq @a, 3
23744  .call a: 3
23745
23746test "#4576: function chaining on separate rows", ->
23747  do ->
23748    Promise
23749    .resolve()
23750    .then ->
23751      yes
23752    .then ok
23753
23754test "#3736: chaining after do IIFE", ->
23755  eq 3,
23756    do ->
23757      a: 3
23758    .a
23759
23760  eq 3,
23761    do (b = (c) -> c) -> a: 3
23762    ?.a
23763
23764  b = 3
23765  eq 3,
23766    do (
23767      b
23768      {d} = {}
23769    ) ->
23770      a: b
23771    .a
23772
23773  # preserve existing chaining behavior for non-IIFE `do`
23774  b = c: -> 4
23775  eq 4,
23776    do b
23777    .c
23778
23779test "#5168: allow indented property index", ->
23780  a = b: 3
23781
23782  eq 3, a[
23783    if yes
23784      'b'
23785    else
23786      'c'
23787  ]
23788
23789  d = [1, 2, 3]
23790  arrayEq [1, 2], d[
23791    ...2
23792  ]
23793
23794  class A
23795    b: -> 3
23796
23797  class B extends A
23798    c: ->
23799      super[
23800        'b'
23801      ]()
23802
23803  eq 3, new B().c()
23804
23805</script>
vendor: 1 bytes, line 23805
23805
23806<script type="text/x-coffeescript" class="test" id="function_invocation">
23807# Function Invocation
23808# -------------------
23809
23810# * Function Invocation
23811# * Splats in Function Invocations
23812# * Implicit Returns
23813# * Explicit Returns
23814
23815# shared identity function
23816id = (_) -> if arguments.length is 1 then _ else [arguments...]
23817
23818test "basic argument passing", ->
23819
23820  a = {}
23821  b = {}
23822  c = {}
23823  eq 1, (id 1)
23824  eq 2, (id 1, 2)[1]
23825  eq a, (id a)
23826  eq c, (id a, b, c)[2]
23827
23828
23829test "passing arguments on separate lines", ->
23830
23831  a = {}
23832  b = {}
23833  c = {}
23834  ok(id(
23835    a
23836    b
23837    c
23838  )[1] is b)
23839  eq(0, id(
23840    0
23841    10
23842  )[0])
23843  eq(a,id(
23844    a
23845  ))
23846  eq b,
23847  (id b)
23848
23849
23850test "optional parens can be used in a nested fashion", ->
23851
23852  call = (func) -> func()
23853  add = (a,b) -> a + b
23854  result = call ->
23855    inner = call ->
23856      add 5, 5
23857  ok result is 10
23858
23859
23860test "hanging commas and semicolons in argument list", ->
23861
23862  fn = () -> arguments.length
23863  eq 2, fn(0,1,)
23864  eq 3, fn 0, 1,
23865  2
23866  eq 2, fn(0, 1;)
23867  # TODO: this test fails (the string compiles), but should it?
23868  #throwsCompileError "fn(0,1,;)"
23869  throwsCompileError "fn(0,1,;;)"
23870  throwsCompileError "fn(0, 1;,)"
23871  throwsCompileError "fn(,0)"
23872  throwsCompileError "fn(;0)"
23873
23874
23875test "function invocation", ->
23876
23877  func = ->
23878    return if true
23879  eq undefined, func()
23880
23881  result = ("hello".slice) 3
23882  ok result is 'lo'
23883
23884
23885test "And even with strange things like this:", ->
23886
23887  funcs  = [((x) -> x), ((x) -> x * x)]
23888  result = funcs[1] 5
23889  ok result is 25
23890
23891
23892test "More fun with optional parens.", ->
23893
23894  fn = (arg) -> arg
23895  ok fn(fn {prop: 101}).prop is 101
23896
23897  okFunc = (f) -> ok(f())
23898  okFunc -> true
23899
23900
23901test "chained function calls", ->
23902  nonce = {}
23903  identityWrap = (x) ->
23904    -> x
23905  eq nonce, identityWrap(identityWrap(nonce))()()
23906  eq nonce, (identityWrap identityWrap nonce)()()
23907
23908
23909test "Multi-blocks with optional parens.", ->
23910
23911  fn = (arg) -> arg
23912  result = fn( ->
23913    fn ->
23914      "Wrapped"
23915  )
23916  ok result()() is 'Wrapped'
23917
23918
23919test "method calls", ->
23920
23921  fnId = (fn) -> -> fn.apply this, arguments
23922  math = {
23923    add: (a, b) -> a + b
23924    anonymousAdd: (a, b) -> a + b
23925    fastAdd: fnId (a, b) -> a + b
23926  }
23927  ok math.add(5, 5) is 10
23928  ok math.anonymousAdd(10, 10) is 20
23929  ok math.fastAdd(20, 20) is 40
23930
23931
23932test "Ensure that functions can have a trailing comma in their argument list", ->
23933
23934  mult = (x, mids..., y) ->
23935    x *= n for n in mids
23936    x *= y
23937  #ok mult(1, 2,) is 2
23938  #ok mult(1, 2, 3,) is 6
23939  ok mult(10, (i for i in [1..6])...) is 7200
23940
23941
23942test "`@` and `this` should both be able to invoke a method", ->
23943  nonce = {}
23944  fn          = (arg) -> eq nonce, arg
23945  fn.withAt   = -> @ nonce
23946  fn.withThis = -> this nonce
23947  fn.withAt()
23948  fn.withThis()
23949
23950
23951test "Trying an implicit object call with a trailing function.", ->
23952
23953  a = null
23954  meth = (arg, obj, func) -> a = [obj.a, arg, func()].join ' '
23955  meth 'apple', b: 1, a: 13, ->
23956    'orange'
23957  ok a is '13 apple orange'
23958
23959
23960test "Ensure that empty functions don't return mistaken values.", ->
23961
23962  obj =
23963    func: (@param, @rest...) ->
23964  ok obj.func(101, 102, 103, 104) is undefined
23965  ok obj.param is 101
23966  ok obj.rest.join(' ') is '102 103 104'
23967
23968
23969test "Passing multiple functions without paren-wrapping is legal, and should compile.", ->
23970
23971  sum = (one, two) -> one() + two()
23972  result = sum ->
23973    7 + 9
23974  , ->
23975    1 + 3
23976  ok result is 20
23977
23978
23979test "Implicit call with a trailing if statement as a param.", ->
23980
23981  func = -> arguments[1]
23982  result = func 'one', if false then 100 else 13
23983  ok result is 13
23984
23985
23986test "Test more function passing:", ->
23987
23988  sum = (one, two) -> one() + two()
23989
23990  result = sum( ->
23991    1 + 2
23992  , ->
23993    2 + 1
23994  )
23995  ok result is 6
23996
23997  sum = (a, b) -> a + b
23998  result = sum(1
23999  , 2)
24000  ok result is 3
24001
24002
24003test "Chained blocks, with proper indentation levels:", ->
24004
24005  counter =
24006    results: []
24007    tick: (func) ->
24008      @results.push func()
24009      this
24010  counter
24011    .tick ->
24012      3
24013    .tick ->
24014      2
24015    .tick ->
24016      1
24017  arrayEq [3,2,1], counter.results
24018
24019
24020test "This is a crazy one.", ->
24021
24022  x = (obj, func) -> func obj
24023  ident = (x) -> x
24024  result = x {one: ident 1}, (obj) ->
24025    inner = ident(obj)
24026    ident inner
24027  ok result.one is 1
24028
24029
24030test "More paren compilation tests:", ->
24031
24032  reverse = (obj) -> obj.reverse()
24033  ok reverse([1, 2].concat 3).join(' ') is '3 2 1'
24034
24035
24036test "Test for inline functions with parentheses and implicit calls.", ->
24037
24038  combine = (func, num) -> func() * num
24039  result  = combine (-> 1 + 2), 3
24040  ok result is 9
24041
24042
24043test "Test for calls/parens/multiline-chains.", ->
24044
24045  f = (x) -> x
24046  result = (f 1).toString()
24047    .length
24048  ok result is 1
24049
24050
24051test "Test implicit calls in functions in parens:", ->
24052
24053  result = ((val) ->
24054    [].push val
24055    val
24056  )(10)
24057  ok result is 10
24058
24059
24060test "Ensure that chained calls with indented implicit object literals below are alright.", ->
24061
24062  result = null
24063  obj =
24064    method: (val)  -> this
24065    second: (hash) -> result = hash.three
24066  obj
24067    .method(
24068      101
24069    ).second(
24070      one:
24071        two: 2
24072      three: 3
24073    )
24074  eq result, 3
24075
24076
24077test "Test newline-supressed call chains with nested functions.", ->
24078
24079  obj  =
24080    call: -> this
24081  func = ->
24082    obj
24083      .call ->
24084        one two
24085      .call ->
24086        three four
24087    101
24088  eq func(), 101
24089
24090
24091test "Implicit objects with number arguments.", ->
24092
24093  func = (x, y) -> y
24094  obj =
24095    prop: func "a", 1
24096  ok obj.prop is 1
24097
24098
24099test "Non-spaced unary and binary operators should cause a function call.", ->
24100
24101  func = (val) -> val + 1
24102  ok (func +5) is 6
24103  ok (func -5) is -4
24104
24105
24106test "Prefix unary assignment operators are allowed in parenless calls.", ->
24107
24108  func = (val) -> val + 1
24109  val = 5
24110  ok (func --val) is 5
24111
24112test "#855: execution context for `func arr...` should be `null`", ->
24113  contextTest = -> eq @, if window? then window else global
24114  array = []
24115  contextTest array
24116  contextTest.apply null, array
24117  contextTest array...
24118
24119test "#904: Destructuring function arguments with same-named variables in scope", ->
24120  a = b = nonce = {}
24121  fn = ([a,b]) -> {a:a,b:b}
24122  result = fn([c={},d={}])
24123  eq c, result.a
24124  eq d, result.b
24125  eq nonce, a
24126  eq nonce, b
24127
24128test "Simple Destructuring function arguments with same-named variables in scope", ->
24129  x = 1
24130  f = ([x]) -> x
24131  eq f([2]), 2
24132  eq x, 1
24133
24134test "#4843: Bad output when assigning to @prop in destructuring assignment with defaults", ->
24135  works = "maybe"
24136  drinks = "beer"
24137  class A
24138    constructor: ({@works = 'no', @drinks = 'wine'}) ->
24139  a = new A {works: 'yes', drinks: 'coffee'}
24140  eq a.works, 'yes'
24141  eq a.drinks, 'coffee'
24142
24143test "caching base value", ->
24144
24145  obj =
24146    index: 0
24147    0: {method: -> this is obj[0]}
24148  ok obj[obj.index++].method([]...)
24149
24150
24151test "passing splats to functions", ->
24152  arrayEq [0..4], id id [0..4]...
24153  fn = (a, b, c..., d) -> [a, b, c, d]
24154  range = [0..3]
24155  [first, second, others, last] = fn range..., 4, [5...8]...
24156  eq 0, first
24157  eq 1, second
24158  arrayEq [2..6], others
24159  eq 7, last
24160
24161  # Should not trigger implicit call, e.g. rest ... => rest(...)
24162  arrayEq [0..4], id id [0..4] ...
24163  fn = (a, b, c ..., d) -> [a, b, c, d]
24164  range = [0..3]
24165  [first, second, others, last] = fn range ..., 4, [5 ... 8] ...
24166  eq 0, first
24167  eq 1, second
24168  arrayEq [2..6], others
24169  eq 7, last
24170
24171test "splat variables are local to the function", ->
24172  outer = "x"
24173  clobber = (avar, outer...) -> outer
24174  clobber "foo", "bar"
24175  eq "x", outer
24176
24177test "Issue 4631: left and right spread dots with preceding space", ->
24178  a = []
24179  f = (a) -> a
24180  eq yes, (f ...a) is (f ... a) is (f a...) is (f a ...) is f(a...) is f(...a) is f(a ...) is f(... a)
24181
24182test "Issue 894: Splatting against constructor-chained functions.", ->
24183
24184  x = null
24185  class Foo
24186    bar: (y) -> x = y
24187  new Foo().bar([101]...)
24188  eq x, 101
24189
24190
24191test "Functions with splats being called with too few arguments.", ->
24192
24193  pen = null
24194  method = (first, variable..., penultimate, ultimate) ->
24195    pen = penultimate
24196  method 1, 2, 3, 4, 5, 6, 7, 8, 9
24197  ok pen is 8
24198  method 1, 2, 3
24199  ok pen is 2
24200  method 1, 2
24201  ok pen is 2
24202
24203
24204test "splats with super() within classes.", ->
24205
24206  class Parent
24207    meth: (args...) ->
24208      args
24209  class Child extends Parent
24210    meth: ->
24211      nums = [3, 2, 1]
24212      super nums...
24213  ok (new Child).meth().join(' ') is '3 2 1'
24214
24215  # Should not trigger implicit call, e.g. rest ... => rest(...)
24216  class Parent
24217    meth: (args ...) ->
24218      args
24219  class Child extends Parent
24220    meth: ->
24221      nums = [3, 2, 1]
24222      super nums ...
24223  ok (new Child).meth().join(' ') is '3 2 1'
24224
24225
24226test "#1011: passing a splat to a method of a number", ->
24227  eq '1011', 11.toString [2]...
24228  eq '1011', (31).toString [3]...
24229  eq '1011', 69.0.toString [4]...
24230  eq '1011', (131.0).toString [5]...
24231
24232  # Should not trigger implicit call, e.g. rest ... => rest(...)
24233  eq '1011', 11.toString [2] ...
24234  eq '1011', (31).toString [3] ...
24235  eq '1011', 69.0.toString [4] ...
24236  eq '1011', (131.0).toString [5] ...
24237
24238test "splats and the `new` operator: functions that return `null` should construct their instance", ->
24239  args = []
24240  child = new (constructor = -> null) args...
24241  ok child instanceof constructor
24242
24243  # Should not trigger implicit call, e.g. rest ... => rest(...)
24244  child = new (constructor = -> null) args ...
24245  ok child instanceof constructor
24246
24247test "splats and the `new` operator: functions that return functions should construct their return value", ->
24248  args = []
24249  fn = ->
24250  child = new (constructor = -> fn) args...
24251  ok child not instanceof constructor
24252  eq fn, child
24253
24254test "implicit return", ->
24255
24256  eq ok, new ->
24257    ok
24258    ### Should `return` implicitly   ###
24259    ### even with trailing comments. ###
24260
24261
24262test "implicit returns with multiple branches", ->
24263  nonce = {}
24264  fn = ->
24265    if false
24266      for a in b
24267        return c if d
24268    else
24269      nonce
24270  eq nonce, fn()
24271
24272
24273test "implicit returns with switches", ->
24274  nonce = {}
24275  fn = ->
24276    switch nonce
24277      when nonce then nonce
24278      else return undefined
24279  eq nonce, fn()
24280
24281
24282test "preserve context when generating closure wrappers for expression conversions", ->
24283  nonce = {}
24284  obj =
24285    property: nonce
24286    method: ->
24287      this.result = if false
24288        10
24289      else
24290        "a"
24291        "b"
24292        this.property
24293  eq nonce, obj.method()
24294  eq nonce, obj.property
24295
24296
24297test "don't wrap 'pure' statements in a closure", ->
24298  nonce = {}
24299  items = [0, 1, 2, 3, nonce, 4, 5]
24300  fn = (items) ->
24301    for item in items
24302      return item if item is nonce
24303  eq nonce, fn items
24304
24305
24306test "usage of `new` is careful about where the invocation parens end up", ->
24307  eq 'object', typeof new try Array
24308  eq 'object', typeof new do -> ->
24309  a = b: ->
24310  eq 'object', typeof new (do -> a).b
24311
24312
24313test "implicit call against control structures", ->
24314  result = null
24315  save   = (obj) -> result = obj
24316
24317  save switch id false
24318    when true
24319      'true'
24320    when false
24321      'false'
24322
24323  eq result, 'false'
24324
24325  save if id false
24326    'false'
24327  else
24328    'true'
24329
24330  eq result, 'true'
24331
24332  save unless id false
24333    'true'
24334  else
24335    'false'
24336
24337  eq result, 'true'
24338
24339  save try
24340    doesnt exist
24341  catch error
24342    'caught'
24343
24344  eq result, 'caught'
24345
24346  save try doesnt(exist) catch error then 'caught2'
24347
24348  eq result, 'caught2'
24349
24350
24351test "#1420: things like `(fn() ->)`; there are no words for this one", ->
24352  fn = -> (f) -> f()
24353  nonce = {}
24354  eq nonce, (fn() -> nonce)
24355
24356test "#1416: don't omit one 'new' when compiling 'new new'", ->
24357  nonce = {}
24358  obj = new new -> -> {prop: nonce}
24359  eq obj.prop, nonce
24360
24361test "#1416: don't omit one 'new' when compiling 'new new fn()()'", ->
24362  nonce = {}
24363  argNonceA = {}
24364  argNonceB = {}
24365  fn = (a) -> (b) -> {a, b, prop: nonce}
24366  obj = new new fn(argNonceA)(argNonceB)
24367  eq obj.prop, nonce
24368  eq obj.a, argNonceA
24369  eq obj.b, argNonceB
24370
24371test "#1840: accessing the `prototype` after function invocation should compile", ->
24372  doesNotThrowCompileError 'fn()::prop'
24373
24374  nonce = {}
24375  class Test then id: nonce
24376
24377  dotAccess = -> Test::
24378  protoAccess = -> Test
24379
24380  eq dotAccess().id, nonce
24381  eq protoAccess()::id, nonce
24382
24383test "#960: improved 'do'", ->
24384
24385  do (nonExistent = 'one') ->
24386    eq nonExistent, 'one'
24387
24388  overridden = 1
24389  do (overridden = 2) ->
24390    eq overridden, 2
24391
24392  two = 2
24393  do (one = 1, two, three = 3) ->
24394    eq one, 1
24395    eq two, 2
24396    eq three, 3
24397
24398  ret = do func = (two) ->
24399    eq two, 2
24400    func
24401  eq ret, func
24402
24403test "#2617: implicit call before unrelated implicit object", ->
24404  pass = ->
24405    true
24406
24407  result = if pass 1
24408    one: 1
24409  eq result.one, 1
24410
24411test "#2292, b: f (z),(x)", ->
24412  f = (x, y) -> y
24413  one = 1
24414  two = 2
24415  o = b: f (one),(two)
24416  eq o.b, 2
24417
24418test "#2297, Different behaviors on interpreting literal", ->
24419  foo = (x, y) -> y
24420  bar =
24421    baz: foo 100, on
24422
24423  eq bar.baz, on
24424
24425  qux = (x) -> x
24426  quux = qux
24427    corge: foo 100, true
24428
24429  eq quux.corge, on
24430
24431  xyzzy =
24432    e: 1
24433    f: foo
24434      a: 1
24435      b: 2
24436    ,
24437      one: 1
24438      two: 2
24439      three: 3
24440    g:
24441      a: 1
24442      b: 2
24443      c: foo 2,
24444        one: 1
24445        two: 2
24446        three: 3
24447      d: 3
24448    four: 4
24449    h: foo one: 1, two: 2, three: three: three: 3,
24450      2
24451
24452  eq xyzzy.f.two, 2
24453  eq xyzzy.g.c.three, 3
24454  eq xyzzy.four, 4
24455  eq xyzzy.h, 2
24456
24457test "#2715, Chained implicit calls", ->
24458  first  = (x)    -> x
24459  second = (x, y) -> y
24460
24461  foo = first first
24462    one: 1
24463  eq foo.one, 1
24464
24465  bar = first second
24466    one: 1, 2
24467  eq bar, 2
24468
24469  baz = first second
24470    one: 1,
24471    2
24472  eq baz, 2
24473
24474test "Implicit calls and new", ->
24475  first = (x) -> x
24476  foo = (@x) ->
24477  bar = first new foo first 1
24478  eq bar.x, 1
24479
24480  third = (x, y, z) -> z
24481  baz = first new foo new foo third
24482        one: 1
24483        two: 2
24484        1
24485        three: 3
24486        2
24487  eq baz.x.x.three, 3
24488
24489test "Loose tokens inside of explicit call lists", ->
24490  first = (x) -> x
24491  second = (x, y) -> y
24492  one = 1
24493
24494  foo = second( one
24495                2)
24496  eq foo, 2
24497
24498  bar = first( first
24499               one: 1)
24500  eq bar.one, 1
24501
24502test "Non-callable literals shouldn't compile", ->
24503  throwsCompileError '1(2)'
24504  throwsCompileError '1 2'
24505  throwsCompileError '/t/(2)'
24506  throwsCompileError '/t/ 2'
24507  throwsCompileError '///t///(2)'
24508  throwsCompileError '///t/// 2'
24509  throwsCompileError "''(2)"
24510  throwsCompileError "'' 2"
24511  throwsCompileError '""(2)'
24512  throwsCompileError '"" 2'
24513  throwsCompileError '""""""(2)'
24514  throwsCompileError '"""""" 2'
24515  throwsCompileError '{}(2)'
24516  throwsCompileError '{} 2'
24517  throwsCompileError '[](2)'
24518  throwsCompileError '[] 2'
24519  throwsCompileError '[2..9] 2'
24520  throwsCompileError '[2..9](2)'
24521  throwsCompileError '[1..10][2..9] 2'
24522  throwsCompileError '[1..10][2..9](2)'
24523
24524test "implicit invocation with implicit object literal", ->
24525  f = (obj) -> eq 1, obj.a
24526
24527  f
24528    a: 1
24529  obj =
24530    if f
24531      a: 2
24532    else
24533      a: 1
24534  eq 2, obj.a
24535
24536  f
24537    "a": 1
24538  obj =
24539    if f
24540      "a": 2
24541    else
24542      "a": 1
24543  eq 2, obj.a
24544
24545  # #3935: Implicit call when the first key of an implicit object has interpolation.
24546  a = 'a'
24547  f
24548    "#{a}": 1
24549  obj =
24550    if f
24551      "#{a}": 2
24552    else
24553      "#{a}": 1
24554  eq 2, obj.a
24555
24556test "get and set can be used as function names when not ambiguous with `get`/`set` keywords", ->
24557  get = (val) -> val
24558  set = (val) -> val
24559  eq 2, get(2)
24560  eq 3, set(3)
24561  eq 'a', get('a')
24562  eq 'b', set('b')
24563  eq 4, get 4
24564  eq 5, set 5
24565  eq 'c', get 'c'
24566  eq 'd', set 'd'
24567
24568  @get = get
24569  @set = set
24570  eq 6, @get 6
24571  eq 7, @set 7
24572
24573  get = ({val}) -> val
24574  set = ({val}) -> val
24575  eq 8, get({val: 8})
24576  eq 9, set({val: 9})
24577  eq 'e', get({val: 'e'})
24578  eq 'f', set({val: 'f'})
24579  eq 10, get {val: 10}
24580  eq 11, set {val: 11}
24581  eq 'g', get {val: 'g'}
24582  eq 'h', set {val: 'h'}
24583
24584test "get and set can be used as variable and property names", ->
24585  get = 2
24586  set = 3
24587  eq 2, get
24588  eq 3, set
24589
24590  {get} = {get: 4}
24591  {set} = {set: 5}
24592  eq 4, get
24593  eq 5, set
24594
24595test "get and set can be used as class method names", ->
24596  class A
24597    get: -> 2
24598    set: -> 3
24599
24600  a = new A()
24601  eq 2, a.get()
24602  eq 3, a.set()
24603
24604  class B
24605    @get = -> 4
24606    @set = -> 5
24607
24608  eq 4, B.get()
24609  eq 5, B.set()
24610
24611test "#4524: functions named get or set can be used without parentheses when attached to an object", ->
24612  obj =
24613    get: (x) -> x + 2
24614    set: (x) -> x + 3
24615
24616  class A
24617    get: (x) -> x + 4
24618    set: (x) -> x + 5
24619
24620  a = new A()
24621
24622  class B
24623    get: (x) -> x.value + 6
24624    set: (x) -> x.value + 7
24625
24626  b = new B()
24627
24628  eq 12, obj.get 10
24629  eq 13, obj.set 10
24630  eq 12, obj?.get 10
24631  eq 13, obj?.set 10
24632
24633  eq 14, a.get 10
24634  eq 15, a.set 10
24635
24636  @ten = 10
24637
24638  eq 12, obj.get @ten
24639  eq 13, obj.set @ten
24640
24641  eq 14, a.get @ten
24642  eq 15, a.set @ten
24643
24644  obj.obj = obj
24645
24646  eq 12, obj.obj.get @ten
24647  eq 13, obj.obj.set @ten
24648
24649  eq 16, b.get value: 10
24650  eq 17, b.set value: 10
24651
24652  eq 16, b.get value: @ten
24653  eq 17, b.set value: @ten
24654
24655test "#4836: functions named get or set can be used without parentheses when attached to this or @", ->
24656  @get = (x) -> x + 2
24657  @set = (x) -> x + 3
24658  @a = 4
24659
24660  eq 12, this.get 10
24661  eq 13, this.set 10
24662  eq 12, this?.get 10
24663  eq 13, this?.set 10
24664  eq 6, this.get @a
24665  eq 7, this.set @a
24666  eq 6, this?.get @a
24667  eq 7, this?.set @a
24668
24669  eq 12, @get 10
24670  eq 13, @set 10
24671  eq 12, @?.get 10
24672  eq 13, @?.set 10
24673  eq 6, @get @a
24674  eq 7, @set @a
24675  eq 6, @?.get @a
24676  eq 7, @?.set @a
24677
24678test "#4852: functions named get or set can be used without parentheses when attached to this or @, with an argument of an implicit object", ->
24679  @get = ({ x }) -> x + 2
24680  @set = ({ x }) -> x + 3
24681
24682  eq 12, @get x: 10
24683  eq 13, @set x: 10
24684  eq 12, @?.get x: 10
24685  eq 13, @?.set x: 10
24686  eq 12, this?.get x: 10
24687  eq 13, this?.set x: 10
24688
24689test "#4473: variable scope in chained calls", ->
24690  obj =
24691    foo: -> this
24692    bar: (a) ->
24693      a()
24694      this
24695
24696  obj.foo(a = 1).bar(-> a = 2)
24697  eq a, 2
24698
24699  obj.bar(-> b = 2).foo(b = 1)
24700  eq b, 1
24701
24702  obj.foo(c = 1).bar(-> c = 2).foo(c = 3)
24703  eq c, 3
24704
24705  obj.foo([d, e] = [1, 2]).bar(-> d = 4)
24706  eq d, 4
24707
24708  obj.foo({f} = {f: 1}).bar(-> f = 5)
24709  eq f, 5
24710
24711test "#5052: implicit call of class with no body", ->
24712  doesNotThrowCompileError 'f class'
24713  doesNotThrowCompileError 'f class A'
24714  doesNotThrowCompileError 'f class A extends B'
24715
24716  f = (args...) -> args
24717  a = 1
24718
24719  [klass, shouldBeA] = f class A, a
24720  eq shouldBeA, a
24721
24722  [shouldBeA] = f a, class A
24723  eq shouldBeA, a
24724
24725  [obj, klass, shouldBeA] =
24726    f
24727      b: 1
24728      class A
24729      a
24730  eq shouldBeA, a
24731
24732</script>
vendor: 1 bytes, line 24732
24732
24733<script type="text/x-coffeescript" class="test" id="functions">
24734# Function Literals
24735# -----------------
24736
24737# TODO: add indexing and method invocation tests: (->)[0], (->).call()
24738
24739# * Function Definition
24740# * Bound Function Definition
24741# * Parameter List Features
24742#   * Splat Parameters
24743#   * Context (@) Parameters
24744#   * Parameter Destructuring
24745#   * Default Parameters
24746
24747# Function Definition
24748
24749x = 1
24750y = {}
24751y.x = -> 3
24752ok x is 1
24753ok typeof(y.x) is 'function'
24754ok y.x instanceof Function
24755ok y.x() is 3
24756
24757# The empty function should not cause a syntax error.
24758->
24759() ->
24760
24761# Multiple nested function declarations mixed with implicit calls should not
24762# cause a syntax error.
24763(one) -> (two) -> three four, (five) -> six seven, eight, (nine) ->
24764
24765# with multiple single-line functions on the same line.
24766func = (x) -> (x) -> (x) -> x
24767ok func(1)(2)(3) is 3
24768
24769# Make incorrect indentation safe.
24770func = ->
24771  obj = {
24772          key: 10
24773        }
24774  obj.key - 5
24775eq func(), 5
24776
24777# Ensure that functions with the same name don't clash with helper functions.
24778del = -> 5
24779ok del() is 5
24780
24781
24782# Bound Function Definition
24783
24784obj =
24785  bound: ->
24786    (=> this)()
24787  unbound: ->
24788    (-> this)()
24789  nested: ->
24790    (=>
24791      (=>
24792        (=> this)()
24793      )()
24794    )()
24795eq obj, obj.bound()
24796ok obj isnt obj.unbound()
24797eq obj, obj.nested()
24798
24799
24800test "even more fancy bound functions", ->
24801  obj =
24802    one: ->
24803      do =>
24804        return this.two()
24805    two: ->
24806      do =>
24807        do =>
24808          do =>
24809            return this.three
24810    three: 3
24811
24812  eq obj.one(), 3
24813
24814
24815test "arguments in bound functions inherit from parent function", ->
24816  # The `arguments` object in an ES arrow function refers to the `arguments`
24817  # of the parent scope, just like `this`. In the CoffeeScript 1.x
24818  # implementation of `=>`, the `arguments` object referred to the arguments
24819  # of the arrow function; but per the ES2015 spec, `arguments` should refer
24820  # to the parent.
24821  arrayEq ((a...) -> a)([1, 2, 3]), ((a...) => a)([1, 2, 3])
24822
24823  parent = (a, b, c) ->
24824    (bound = =>
24825      [arguments[0], arguments[1], arguments[2]]
24826    )()
24827  arrayEq [1, 2, 3], parent(1, 2, 3)
24828
24829
24830test "self-referencing functions", ->
24831  changeMe = ->
24832    changeMe = 2
24833
24834  changeMe()
24835  eq changeMe, 2
24836
24837
24838# Parameter List Features
24839
24840test "splats", ->
24841  arrayEq [0, 1, 2], (((splat...) -> splat) 0, 1, 2)
24842  arrayEq [2, 3], (((_, _1, splat...) -> splat) 0, 1, 2, 3)
24843  arrayEq [0, 1], (((splat..., _, _1) -> splat) 0, 1, 2, 3)
24844  arrayEq [2], (((_, _1, splat..., _2) -> splat) 0, 1, 2, 3)
24845
24846  # Should not trigger implicit call, e.g. rest ... => rest(...)
24847  arrayEq [0, 1, 2], (((splat ...) -> splat) 0, 1, 2)
24848  arrayEq [2, 3], (((_, _1, splat ...) -> splat) 0, 1, 2, 3)
24849  arrayEq [0, 1], (((splat ..., _, _1) -> splat) 0, 1, 2, 3)
24850  arrayEq [2], (((_, _1, splat ..., _2) -> splat) 0, 1, 2, 3)
24851
24852test "destructured splatted parameters", ->
24853  arr = [0,1,2]
24854  splatArray = ([a...]) -> a
24855  splatArrayRest = ([a...],b...) -> arrayEq(a,b); b
24856  arrayEq splatArray(arr), arr
24857  arrayEq splatArrayRest(arr,0,1,2), arr
24858
24859  # Should not trigger implicit call, e.g. rest ... => rest(...)
24860  splatArray = ([a ...]) -> a
24861  splatArrayRest = ([a ...],b ...) -> arrayEq(a,b); b
24862
24863test "#4884: object-destructured splatted parameters", ->
24864  f = ({length}...) -> length
24865  eq f(4, 5, 6), 3
24866  f = ({length: len}...) -> len
24867  eq f(4, 5, 6), 3
24868  f = ({length}..., last) -> [length, last]
24869  arrayEq f(4, 5, 6), [2, 6]
24870  f = ({length: len}..., last) -> [len, last]
24871  arrayEq f(4, 5, 6), [2, 6]
24872
24873test "@-parameters: automatically assign an argument's value to a property of the context", ->
24874  nonce = {}
24875
24876  ((@prop) ->).call context = {}, nonce
24877  eq nonce, context.prop
24878
24879  # Allow splats alongside the special argument
24880  ((splat..., @prop) ->).apply context = {}, [0, 0, nonce]
24881  eq nonce, context.prop
24882
24883  # Should not trigger implicit call, e.g. rest ... => rest(...)
24884  ((splat ..., @prop) ->).apply context = {}, [0, 0, nonce]
24885  eq nonce, context.prop
24886
24887  # Allow the argument itself to be a splat
24888  ((@prop...) ->).call context = {}, 0, nonce, 0
24889  eq nonce, context.prop[1]
24890
24891  # Should not trigger implicit call, e.g. rest ... => rest(...)
24892  ((@prop ...) ->).call context = {}, 0, nonce, 0
24893  eq nonce, context.prop[1]
24894
24895  # The argument should not be able to be referenced normally
24896  code = '((@prop) -> prop).call {}'
24897  doesNotThrowCompileError code
24898  throws (-> CoffeeScript.run code), ReferenceError
24899  code = '((@prop) -> _at_prop).call {}'
24900  doesNotThrowCompileError code
24901  throws (-> CoffeeScript.run code), ReferenceError
24902
24903test "@-parameters and splats with constructors", ->
24904  a = {}
24905  b = {}
24906  class Klass
24907    constructor: (@first, splat..., @last) ->
24908
24909  obj = new Klass a, 0, 0, b
24910  eq a, obj.first
24911  eq b, obj.last
24912
24913  # Should not trigger implicit call, e.g. rest ... => rest(...)
24914  class Klass
24915    constructor: (@first, splat ..., @last) ->
24916
24917  obj = new Klass a, 0, 0, b
24918  eq a, obj.first
24919  eq b, obj.last
24920
24921test "destructuring in function definition", ->
24922  (([{a: [b], c}]...) ->
24923    eq 1, b
24924    eq 2, c
24925  ) {a: [1], c: 2}
24926
24927  # Should not trigger implicit call, e.g. rest ... => rest(...)
24928  (([{a: [b], c}] ...) ->
24929    eq 1, b
24930    eq 2, c
24931  ) {a: [1], c: 2}
24932
24933  context = {}
24934  (([{a: [b, c = 2], @d, e = 4}]...) ->
24935    eq 1, b
24936    eq 2, c
24937    eq @d, 3
24938    eq context.d, 3
24939    eq e, 4
24940  ).call context, {a: [1], d: 3}
24941
24942  (({a: aa = 1, b: bb = 2}) ->
24943    eq 5, aa
24944    eq 2, bb
24945  ) {a: 5}
24946
24947  ajax = (url, {
24948    async = true,
24949    beforeSend = (->),
24950    cache = true,
24951    method = 'get',
24952    data = {}
24953  }) ->
24954    {url, async, beforeSend, cache, method, data}
24955
24956  fn = ->
24957  deepEqual ajax('/home', beforeSend: fn, method: 'post'), {
24958    url: '/home', async: true, beforeSend: fn, cache: true, method: 'post', data: {}
24959  }
24960
24961test "#4005: `([a = {}]..., b) ->` weirdness", ->
24962  fn = ([a = {}]..., b) -> [a, b]
24963  deepEqual fn(5), [{}, 5]
24964
24965  # Should not trigger implicit call, e.g. rest ... => rest(...)
24966  fn = ([a = {}] ..., b) -> [a, b]
24967  deepEqual fn(5), [{}, 5]
24968
24969test "default values", ->
24970  nonceA = {}
24971  nonceB = {}
24972  a = (_,_1,arg=nonceA) -> arg
24973  eq nonceA, a()
24974  eq nonceA, a(0)
24975  eq nonceB, a(0,0,nonceB)
24976  eq nonceA, a(0,0,undefined)
24977  eq null, a(0,0,null) # Per ES2015, `null` doesn’t trigger a parameter default value
24978  eq false , a(0,0,false)
24979  eq nonceB, a(undefined,undefined,nonceB,undefined)
24980  b = (_,arg=nonceA,_1,_2) -> arg
24981  eq nonceA, b()
24982  eq nonceA, b(0)
24983  eq nonceB, b(0,nonceB)
24984  eq nonceA, b(0,undefined)
24985  eq null, b(0,null)
24986  eq false , b(0,false)
24987  eq nonceB, b(undefined,nonceB,undefined)
24988  c = (arg=nonceA,_,_1) -> arg
24989  eq nonceA, c()
24990  eq      0, c(0)
24991  eq nonceB, c(nonceB)
24992  eq nonceA, c(undefined)
24993  eq null, c(null)
24994  eq false , c(false)
24995  eq nonceB, c(nonceB,undefined,undefined)
24996
24997test "default values with @-parameters", ->
24998  a = {}
24999  b = {}
25000  obj = f: (q = a, @p = b) -> q
25001  eq a, obj.f()
25002  eq b, obj.p
25003
25004test "default values with splatted arguments", ->
25005  withSplats = (a = 2, b..., c = 3, d = 5) -> a * (b.length + 1) * c * d
25006  eq 30, withSplats()
25007  eq 15, withSplats(1)
25008  eq  5, withSplats(1,1)
25009  eq  1, withSplats(1,1,1)
25010  eq  2, withSplats(1,1,1,1)
25011
25012  # Should not trigger implicit call, e.g. rest ... => rest(...)
25013  withSplats = (a = 2, b ..., c = 3, d = 5) -> a * (b.length + 1) * c * d
25014  eq 30, withSplats()
25015  eq 15, withSplats(1)
25016  eq  5, withSplats(1,1)
25017  eq  1, withSplats(1,1,1)
25018  eq  2, withSplats(1,1,1,1)
25019
25020test "#156: parameter lists with expansion", ->
25021  expandArguments = (first, ..., lastButOne, last) ->
25022    eq 1, first
25023    eq 4, lastButOne
25024    last
25025  eq 5, expandArguments 1, 2, 3, 4, 5
25026
25027  throwsCompileError "(..., a, b...) ->", null, null, "prohibit expansion and a splat"
25028  throwsCompileError "(...) ->",          null, null, "prohibit lone expansion"
25029
25030test "#156: parameter lists with expansion in array destructuring", ->
25031  expandArray = (..., [..., last]) ->
25032    last
25033  eq 3, expandArray 1, 2, 3, [1, 2, 3]
25034
25035test "#3502: variable definitions and expansion", ->
25036  a = b = 0
25037  f = (a, ..., b) -> [a, b]
25038  arrayEq [1, 5], f 1, 2, 3, 4, 5
25039  eq 0, a
25040  eq 0, b
25041
25042test "variable definitions and splat", ->
25043  a = b = 0
25044  f = (a, middle..., b) -> [a, middle, b]
25045  arrayEq [1, [2, 3, 4], 5], f 1, 2, 3, 4, 5
25046  eq 0, a
25047  eq 0, b
25048
25049  # Should not trigger implicit call, e.g. rest ... => rest(...)
25050  f = (a, middle ..., b) -> [a, middle, b]
25051  arrayEq [1, [2, 3, 4], 5], f 1, 2, 3, 4, 5
25052  eq 0, a
25053  eq 0, b
25054
25055test "default values with function calls", ->
25056  doesNotThrowCompileError "(x = f()) ->"
25057
25058test "arguments vs parameters", ->
25059  doesNotThrowCompileError "f(x) ->"
25060  f = (g) -> g()
25061  eq 5, f (x) -> 5
25062
25063test "reserved keyword as parameters", ->
25064  f = (_case, @case) -> [_case, @case]
25065  [a, b] = f(1, 2)
25066  eq 1, a
25067  eq 2, b
25068
25069  f = (@case, _case...) -> [@case, _case...]
25070  [a, b, c] = f(1, 2, 3)
25071  eq 1, a
25072  eq 2, b
25073  eq 3, c
25074
25075test "reserved keyword at-splat", ->
25076  f = (@case...) -> @case
25077  [a, b] = f(1, 2)
25078  eq 1, a
25079  eq 2, b
25080
25081  # Should not trigger implicit call, e.g. rest ... => rest(...)
25082  f = (@case ...) -> @case
25083  [a, b] = f(1, 2)
25084  eq 1, a
25085  eq 2, b
25086
25087test "#1574: Destructuring and a parameter named _arg", ->
25088  f = ({a, b}, _arg, _arg1) -> [a, b, _arg, _arg1]
25089  arrayEq [1, 2, 3, 4], f a: 1, b: 2, 3, 4
25090
25091test "#1844: bound functions in nested comprehensions causing empty var statements", ->
25092  a = ((=>) for a in [0] for b in [0])
25093  eq 1, a.length
25094
25095test "#1859: inline function bodies shouldn't modify prior postfix ifs", ->
25096  list = [1, 2, 3]
25097  ok true if list.some (x) -> x is 2
25098
25099test "#2258: allow whitespace-style parameter lists in function definitions", ->
25100  func = (
25101    a, b, c
25102  ) -> c
25103  eq func(1, 2, 3), 3
25104
25105  func = (
25106    a
25107    b
25108    c
25109  ) -> b
25110  eq func(1, 2, 3), 2
25111
25112test "#2621: fancy destructuring in parameter lists", ->
25113  func = ({ prop1: { key1 }, prop2: { key2, key3: [a, b, c] } }) ->
25114    eq(key2, 'key2')
25115    eq(a, 'a')
25116
25117  func({prop1: {key1: 'key1'}, prop2: {key2: 'key2', key3: ['a', 'b', 'c']}})
25118
25119test "#1435 Indented property access", ->
25120  rec = -> rec: rec
25121
25122  eq 1, do ->
25123    rec()
25124      .rec ->
25125        rec()
25126          .rec ->
25127            rec.rec()
25128          .rec()
25129    1
25130
25131test "#1038 Optimize trailing return statements", ->
25132  compile = (code) -> CoffeeScript.compile(code, bare: yes).trim().replace(/\s+/g, " ")
25133
25134  eq "(function() {});",                 compile("->")
25135  eq "(function() {});",                 compile("-> return")
25136  eq "(function() { return void 0; });", compile("-> undefined")
25137  eq "(function() { return void 0; });", compile("-> return undefined")
25138  eq "(function() { foo(); });",         compile("""
25139                                                 ->
25140                                                   foo()
25141                                                   return
25142                                                 """)
25143
25144test "#4406 Destructured parameter default evaluation order with incrementing variable", ->
25145  i = 0
25146  f = ({ a = ++i }, b = ++i) -> [a, b]
25147  arrayEq f({}), [1, 2]
25148
25149test "#4406 Destructured parameter default evaluation order with generator function", ->
25150  current = 0
25151  next    = -> ++current
25152  foo = ({ a = next() }, b = next()) -> [ a, b ]
25153  arrayEq foo({}), [1, 2]
25154
25155test "Destructured parameter with default value, that itself has a default value", ->
25156  # Adapted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
25157  draw = ({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}) -> "#{size}-#{coords.x}-#{coords.y}-#{radius}"
25158  output = draw
25159    coords:
25160      x: 18
25161      y: 30
25162    radius: 30
25163  eq output, 'big-18-30-30'
25164
25165test "#4566: destructuring with nested default values", ->
25166  f = ({a: {b = 1}}
25166) ->
25167    b
25168  eq 2, f a: b: 2
25169
25170test "#1043: comma after function glyph", ->
25171  x = (a=->, b=2) ->
25172    a()
25173  eq x(), undefined
25174
25175  f = (a) -> a()
25176  g = f ->, 2
25177  eq g, undefined
25178  h = f(=>, 2)
25179  eq h, undefined
25180
25181test "#3845/#3446: chain after function glyph", ->
25182  angular = module: -> controller: -> controller: ->
25183
25184  eq undefined,
25185    angular.module 'foo'
25186    .controller 'EmailLoginCtrl', ->
25187    .controller 'EmailSignupCtrl', ->
25188
25189  beforeEach = (f) -> f()
25190  getPromise = -> then: -> catch: ->
25191
25192  eq undefined,
25193    beforeEach ->
25194      getPromise()
25195      .then (@result) =>
25196      .catch (@error) =>
25197
25198  doThing = -> then: -> catch: (f) -> f()
25199  handleError = -> 3
25200  eq 3,
25201    doThing()
25202    .then (@result) =>
25203    .catch handleError
25204
25205test "#4413: expressions in function parameters that create generated variables have those variables declared correctly", ->
25206  'use strict'
25207  # We’re in strict mode because we want an error to be thrown if the generated
25208  # variable (`ref`) is assigned before being declared.
25209  foo = -> null
25210  bar = -> 33
25211  f = (a = foo() ? bar()) -> a
25212  g = (a = foo() ? bar()) -> a + 1
25213  eq f(), 33
25214  eq g(), 34
25215
25216test "#4657: destructured array param declarations", ->
25217  a = 1
25218  b = 2
25219  f = ([a..., b]) ->
25220  f [3, 4, 5]
25221  eq a, 1
25222  eq b, 2
25223
25224test "#4657: destructured array parameters", ->
25225  f = ([a..., b]) -> {a, b}
25226  result = f [1, 2, 3, 4]
25227  arrayEq result.a, [1, 2, 3]
25228  eq result.b, 4
25229
25230test "#5128: default parameters of function in binary operation", ->
25231  foo = yes or (a, b = {}) -> null
25232  eq foo, yes
25233
25234test "#5121: array end bracket after function glyph", ->
25235  a = [->]
25236  eq a.length, 1
25237
25238  b = [c: ->]
25239  eq b.length, 1
25240
25241</script>
vendor: 1 bytes, line 25241
25241
25242<script type="text/x-coffeescript" class="test" id="generators">
25243# Generators
25244# -----------------
25245#
25246# * Generator Definition
25247
25248test "most basic generator support", ->
25249  ok -> yield
25250
25251test "empty generator", ->
25252  x = do -> yield return
25253
25254  y = x.next()
25255  ok y.value is undefined and y.done is true
25256
25257test "generator iteration", ->
25258  x = do ->
25259    yield 0
25260    yield
25261    yield 2
25262    3
25263
25264  y = x.next()
25265  ok y.value is 0 and y.done is false
25266
25267  y = x.next()
25268  ok y.value is undefined and y.done is false
25269
25270  y = x.next()
25271  ok y.value is 2 and y.done is false
25272
25273  y = x.next()
25274  ok y.value is 3 and y.done is true
25275
25276test "last line yields are returned", ->
25277  x = do ->
25278    yield 3
25279  y = x.next()
25280  ok y.value is 3 and y.done is false
25281
25282  y = x.next 42
25283  ok y.value is 42 and y.done is true
25284
25285test "yield return can be used anywhere in the function body", ->
25286  x = do ->
25287    if 2 is yield 1
25288      yield return 42
25289    throw new Error "this code shouldn't be reachable"
25290
25291  y = x.next()
25292  ok y.value is 1 and y.done is false
25293
25294  y = x.next 2
25295  ok y.value is 42 and y.done is true
25296
25297test "`yield from` support", ->
25298  x = do ->
25299    yield from do ->
25300      yield i for i in [3..4]
25301
25302  y = x.next()
25303  ok y.value is 3 and y.done is false
25304
25305  y = x.next 1
25306  ok y.value is 4 and y.done is false
25307
25308  y = x.next 2
25309  arrayEq y.value, [1, 2]
25310  ok y.done is true
25311
25312test "error if `yield from` occurs outside of a function", ->
25313  throwsCompileError 'yield from 1'
25314
25315test "`yield from` at the end of a function errors", ->
25316  throwsCompileError 'x = -> x = 1; yield from'
25317
25318test "yield in if statements", ->
25319  x = do -> if 1 is yield 2 then 3 else 4
25320
25321  y = x.next()
25322  ok y.value is 2 and y.done is false
25323
25324  y = x.next 1
25325  ok y.value is 3 and y.done is true
25326
25327test "yielding if statements", ->
25328  x = do -> yield if true then 3 else 4
25329
25330  y = x.next()
25331  ok y.value is 3 and y.done is false
25332
25333  y = x.next 42
25334  ok y.value is 42 and y.done is true
25335
25336test "yield in for loop expressions", ->
25337  x = do ->
25338    y = for i in [1..3]
25339      yield i * 2
25340
25341  z = x.next()
25342  ok z.value is 2 and z.done is false
25343
25344  z = x.next 10
25345  ok z.value is 4 and z.done is false
25346
25347  z = x.next 20
25348  ok z.value is 6 and z.done is false
25349
25350  z = x.next 30
25351  arrayEq z.value, [10, 20, 30]
25352  ok z.done is true
25353
25354test "yield in switch expressions", ->
25355  x = do ->
25356    y = switch yield 1
25357      when 2 then yield 1337
25358      else 1336
25359
25360  z = x.next()
25361  ok z.value is 1 and z.done is false
25362
25363  z = x.next 2
25364  ok z.value is 1337 and z.done is false
25365
25366  z = x.next 3
25367  ok z.value is 3 and z.done is true
25368
25369test "yielding switch expressions", ->
25370  x = do ->
25371    yield switch 1337
25372      when 1337 then 1338
25373      else 1336
25374
25375  y = x.next()
25376  ok y.value is 1338 and y.done is false
25377
25378  y = x.next 42
25379  ok y.value is 42 and y.done is true
25380
25381test "yield in try expressions", ->
25382  x = do ->
25383    try yield 1 catch
25384
25385  y = x.next()
25386  ok y.value is 1 and y.done is false
25387
25388  y = x.next 42
25389  ok y.value is 42 and y.done is true
25390
25391test "yielding try expressions", ->
25392  x = do ->
25393    yield try 1
25394
25395  y = x.next()
25396  ok y.value is 1 and y.done is false
25397
25398  y = x.next 42
25399  ok y.value is 42 and y.done is true
25400
25401test "`yield` can be thrown", ->
25402  x = do ->
25403    throw yield null
25404  x.next()
25405  throws -> x.next new Error "boom"
25406
25407test "`throw` can be yielded", ->
25408  x = do ->
25409    yield throw new Error "boom"
25410  throws -> x.next()
25411
25412test "symbolic operators has precedence over the `yield`", ->
25413  symbolic   = '+ - * / << >> & | || && ^ // or and'.split ' '
25414  compound   = ("#{op}=" for op in symbolic)
25415  relations  = '< > == != <= >= is isnt'.split ' '
25416
25417  operators  = [symbolic..., '=', compound..., relations...]
25418
25419  collect = (gen) -> ref.value until (ref = gen.next()).done
25420
25421  values = [0, 1, 2, 3]
25422  for op in operators
25423    expression = "i #{op} 2"
25424
25425    yielded = CoffeeScript.eval "(arr) ->  yield #{expression} for i in arr"
25426    mapped  = CoffeeScript.eval "(arr) ->       (#{expression} for i in arr)"
25427
25428    arrayEq mapped(values), collect yielded values
25429
25430test "yield handles 'this' correctly", ->
25431  x = ->
25432    yield switch
25433      when true then yield => this
25434    array = for item in [1]
25435      yield => this
25436    yield array
25437    yield if true then yield => this
25438    yield try throw yield => this
25439    throw yield => this
25440
25441  y = x.call [1, 2, 3]
25442
25443  z = y.next()
25444  arrayEq z.value(), [1, 2, 3]
25445  ok z.done is false
25446
25447  z = y.next 123
25448  ok z.value is 123 and z.done is false
25449
25450  z = y.next()
25451  arrayEq z.value(), [1, 2, 3]
25452  ok z.done is false
25453
25454  z = y.next 42
25455  arrayEq z.value, [42]
25456  ok z.done is false
25457
25458  z = y.next()
25459  arrayEq z.value(), [1, 2, 3]
25460  ok z.done is false
25461
25462  z = y.next 456
25463  ok z.value is 456 and z.done is false
25464
25465  z = y.next()
25466  arrayEq z.value(), [1, 2, 3]
25467  ok z.done is false
25468
25469  z = y.next new Error "ignore me"
25470  ok z.value is undefined and z.done is false
25471
25472  z = y.next()
25473  arrayEq z.value(), [1, 2, 3]
25474  ok z.done is false
25475
25476  throws -> y.next new Error "boom"
25477
25478test "for-from loops over generators", ->
25479  array1 = [50, 30, 70, 20]
25480  gen = -> yield from array1
25481
25482  array2 = []
25483  array3 = []
25484  array4 = []
25485
25486  iterator = gen()
25487  for x from iterator
25488    array2.push(x)
25489    break if x is 30
25490
25491  for x from iterator
25492    array3.push(x)
25493
25494  for x from iterator
25495    array4.push(x)
25496
25497  arrayEq array2, [50, 30]
25498  # Different JS engines have different opinions on the value of array3:
25499  # https://github.com/jashkenas/coffeescript/pull/4306#issuecomment-257066877
25500  # As a temporary measure, either result is accepted.
25501  ok array3.length is 0 or array3.join(',') is '70,20'
25502  arrayEq array4, []
25503
25504test "for-from comprehensions over generators", ->
25505  gen = ->
25506    yield from [30, 41, 51, 60]
25507
25508  iterator = gen()
25509  array1 = (x for x from iterator when x %% 2 is 1)
25510  array2 = (x for x from iterator)
25511
25512  ok array1.join(' ') is '41 51'
25513  ok array2.length is 0
25514
25515test "from as an iterable variable name in a for loop declaration", ->
25516  from = [1, 2, 3]
25517  out = []
25518  for i from from
25519    out.push i
25520  arrayEq from, out
25521
25522test "from as an iterator variable name in a for loop declaration", ->
25523  a = [1, 2, 3]
25524  b = []
25525  for from from a
25526    b.push from
25527  arrayEq a, b
25528
25529test "from as a destructured object variable name in a for loop declaration", ->
25530  a = [
25531      from: 1
25532      to: 2
25533    ,
25534      from: 3
25535      to: 4
25536  ]
25537  b = []
25538  for {from, to} in a
25539    b.push from
25540  arrayEq b, [1, 3]
25541
25542  c = []
25543  for {to, from}
25543 in a
25544    c.push from
25545  arrayEq c, [1, 3]
25546
25547test "from as a destructured, aliased object variable name in a for loop declaration", ->
25548  a = [
25549      b: 1
25550      c: 2
25551    ,
25552      b: 3
25553      c: 4
25554  ]
25555  out = []
25556
25557  for {b: from} in a
25558    out.push from
25559  arrayEq out, [1, 3]
25560
25561test "from as a destructured array variable name in a for loop declaration", ->
25562  a = [
25563    [1, 2]
25564    [3, 4]
25565  ]
25566  b = []
25567  for [from, to] from a
25568    b.push from
25569  arrayEq b, [1, 3]
25570
25571test "generator methods in classes", ->
25572  class Base
25573    @static: ->
25574      yield 1
25575    method: ->
25576      yield 2
25577
25578  arrayEq [1], Array.from Base.static()
25579  arrayEq [2], Array.from new Base().method()
25580
25581  class Child extends Base
25582    @static: -> super()
25583    method: -> super()
25584
25585  arrayEq [1], Array.from Child.static()
25586  arrayEq [2], Array.from new Child().method()
25587
25588</script>
vendor: 1 bytes, line 25588
25588
25589<script type="text/x-coffeescript" class="test" id="helpers">
25590# Helpers
25591# -------
25592
25593# pull the helpers from `CoffeeScript.helpers` into local variables
25594{starts, ends, repeat, compact, count, merge, extend, flatten, del, baseFileName} = CoffeeScript.helpers
25595
25596
25597# `starts`
25598
25599test "the `starts` helper tests if a string starts with another string", ->
25600  ok     starts('01234', '012')
25601  ok not starts('01234', '123')
25602
25603test "the `starts` helper can take an optional offset", ->
25604  ok     starts('01234', '34', 3)
25605  ok not starts('01234', '01', 1)
25606
25607
25608# `ends`
25609
25610test "the `ends` helper tests if a string ends with another string", ->
25611  ok     ends('01234', '234')
25612  ok not ends('01234', '012')
25613
25614test "the `ends` helper can take an optional offset", ->
25615  ok     ends('01234', '012', 2)
25616  ok not ends('01234', '234', 6)
25617
25618
25619# `repeat`
25620
25621test "the `repeat` helper concatenates a given number of times", ->
25622  eq 'asdasdasd', repeat('asd', 3)
25623
25624test "`repeat`ing a string 0 times always returns the empty string", ->
25625  eq '', repeat('whatever', 0)
25626
25627
25628# `compact`
25629
25630test "the `compact` helper removes falsey values from an array, preserves truthy ones", ->
25631  allValues = [1, 0, false, obj={}, [], '', ' ', -1, null, undefined, true]
25632  truthyValues = [1, obj, [], ' ', -1, true]
25633  arrayEq truthyValues, compact(allValues)
25634
25635
25636# `count`
25637
25638test "the `count` helper counts the number of occurrences of a string in another string", ->
25639  eq 1/0, count('abc', '')
25640  eq 0, count('abc', 'z')
25641  eq 1, count('abc', 'a')
25642  eq 1, count('abc', 'b')
25643  eq 2, count('abcdc', 'c')
25644  eq 2, count('abcdabcd','abc')
25645
25646
25647# `merge`
25648
25649test "the `merge` helper makes a new object with all properties of the objects given as its arguments", ->
25650  ary = [0, 1, 2, 3, 4]
25651  obj = {}
25652  merged = merge obj, ary
25653  ok merged isnt obj
25654  ok merged isnt ary
25655  for own key, val of ary
25656    eq val, merged[key]
25657
25658
25659# `extend`
25660
25661test "the `extend` helper performs a shallow copy", ->
25662  ary = [0, 1, 2, 3]
25663  obj = {}
25664  # should return the object being extended
25665  eq obj, extend(obj, ary)
25666  # should copy the other object's properties as well (obviously)
25667  eq 2, obj[2]
25668
25669
25670# `flatten`
25671
25672test "the `flatten` helper flattens an array", ->
25673  success = yes
25674  (success and= typeof n is 'number') for n in flatten [0, [[[1]], 2], 3, [4]]
25675  ok success
25676
25677
25678# `del`
25679
25680test "the `del` helper deletes a property from an object and returns the deleted value", ->
25681  obj = [0, 1, 2]
25682  eq 1, del(obj, 1)
25683  ok 1 not of obj
25684
25685
25686# `baseFileName`
25687
25688test "the `baseFileName` helper returns the file name to write to", ->
25689  ext = '.js'
25690  sourceToCompiled =
25691    '.coffee': ext
25692    'a.coffee': 'a' + ext
25693    'b.coffee': 'b' + ext
25694    'coffee.coffee': 'coffee' + ext
25695
25696    '.litcoffee': ext
25697    'a.litcoffee': 'a' + ext
25698    'b.litcoffee': 'b' + ext
25699    'coffee.litcoffee': 'coffee' + ext
25700
25701    '.lit': ext
25702    'a.lit': 'a' + ext
25703    'b.lit': 'b' + ext
25704    'coffee.lit': 'coffee' + ext
25705
25706    '.coffee.md': ext
25707    'a.coffee.md': 'a' + ext
25708    'b.coffee.md': 'b' + ext
25709    'coffee.coffee.md': 'coffee' + ext
25710
25711  for sourceFileName, expectedFileName of sourceToCompiled
25712    name = baseFileName sourceFileName, yes
25713    filename = name + ext
25714    eq filename, expectedFileName
25715
25716</script>
vendor: 1 bytes, line 25716
25716
25717<script type="text/x-coffeescript" class="test" id="import_assertions">
25718# This file is running in CommonJS (in Node) or as a classic Script (in the browser tests) so it can use import() within an async function, but not at the top level; and we can’t use static import.
25719test "dynamic import assertion", ->
25720  try
25721    { default: secret } = await import('data:application/json,{"ofLife":42}', { assert: { type: 'json' } })
25722    eq secret.ofLife, 42
25723  catch exception
25724    # This parses on Node 16.14.x but throws an error because JSON modules aren’t unflagged there yet; remove this try/catch once the unflagging of `--experimental-json-modules` is backported (see https://github.com/nodejs/node/pull/41736#issuecomment-1086738670)
25725    unless exception.message is 'Invalid module "data:application/json,{"ofLife":42}" has an unsupported MIME type "application/json"'
25726      throw exception
25727
25728test "assert keyword", ->
25729  assert = 1
25730
25731  try
25732    { default: assert } = await import('data:application/json,{"thatIAm":42}', { assert: { type: 'json' } })
25733    eq assert.thatIAm, 42
25734  catch exception
25735    # This parses on Node 16.14.x but throws an error because JSON modules aren’t unflagged there yet; remove this try/catch once the unflagging of `--experimental-json-modules` is backported (see https://github.com/nodejs/node/pull/41736#issuecomment-1086738670)
25736    unless exception.message is 'Invalid module "data:application/json,{"thatIAm":42}" has an unsupported MIME type "application/json"'
25737      throw exception
25738
25739  eqJS """
25740    import assert from 'regression-test'
25741  """, """
25742    import assert from 'regression-test';
25743  """
25744
25745test "static import assertion", ->
25746  eqJS """
25747    import 'data:application/json,{"foo":3}' assert { type: 'json' }
25748  """, """
25749    import 'data:application/json,{"foo":3}' assert {
25750      type: 'json'
25751    };
25752  """
25753
25754  eqJS """
25755    import secret from 'data:application/json,{"ofLife":42}' assert { type: 'json' }
25756  """, """
25757    import secret from 'data:application/json,{"ofLife":42}' assert {
25758      type: 'json'
25759    };
25760  """
25761
25762  eqJS """
25763    import * as secret from 'data:application/json,{"ofLife":42}' assert { type: 'json' }
25764  """, """
25765    import * as secret from 'data:application/json,{"ofLife":42}' assert {
25766      type: 'json'
25767    };
25768  """
25769
25770  # The only file types for which import assertions are currently supported are JSON (Node and browsers) and CSS (browsers), neither of which support named exports; however there’s nothing in the JavaScript grammar preventing a future supported file type from providing named exports.
25771  eqJS """
25772    import { foo } from './file.unknown' assert { type: 'unknown' }
25773  """, """
25774    import {
25775      foo
25776    } from './file.unknown' assert {
25777        type: 'unknown'
25778      };
25779  """
25780
25781  eqJS """
25782    import file, { foo } from './file.unknown' assert { type: 'unknown' }
25783  """, """
25784    import file, {
25785      foo
25786    } from './file.unknown' assert {
25787        type: 'unknown'
25788      };
25789  """
25790
25791  eqJS """
25792    import foo from 'bar' assert {}
25793  """, """
25794    import foo from 'bar' assert {};
25795  """
25796
25797test "static export with assertion", ->
25798  eqJS """
25799    export * from 'data:application/json,{"foo":3}' assert { type: 'json' }
25800  """, """
25801    export * from 'data:application/json,{"foo":3}' assert {
25802      type: 'json'
25803    };
25804  """
25805
25806  eqJS """
25807    export { profile } from './user.json' assert { type: 'json' }
25808  """, """
25809    export {
25810      profile
25811    } from './user.json' assert {
25812        type: 'json'
25813      };
25814  """
25815
25816</script>
vendor: 1 bytes, line 25816
25816
25817<script type="text/x-coffeescript" class="test" id="importing">
25818# Importing
25819# ---------
25820
25821unless window? or testingBrowser?
25822  test "coffeescript modules can be imported and executed", ->
25823
25824    magicKey = __filename
25825    magicValue = 0xFFFF
25826
25827    if global[magicKey]?
25828      if exports?
25829        local = magicValue
25830        exports.method = -> local
25831    else
25832      global[magicKey] = {}
25833      if require?.extensions?
25834        ok require(__filename).method() is magicValue
25835      delete global[magicKey]
25836
25837  test "javascript modules can be imported", ->
25838    magicVal = 1
25839    for module in 'import.js import2 .import2 import.extension.js import.unknownextension .coffee .coffee.md'.split ' '
25840      ok require("./importing/#{module}").value?() is magicVal, module
25841
25842  test "coffeescript modules can be imported", ->
25843    magicVal = 2
25844    for module in '.import.coffee import.coffee import.extension.coffee'.split ' '
25845      ok require("./importing/#{module}").value?() is magicVal, module
25846
25847  test "literate coffeescript modules can be imported", ->
25848    magicVal = 3
25849    # Leading space intentional to check for index.coffee.md
25850    for module in ' .import.coffee.md import.coffee.md import.litcoffee import.extension.coffee.md'.split ' '
25851      ok require("./importing/#{module}").value?() is magicVal, module
25852
25853</script>
vendor: 1 bytes, line 25853
25853
25854<script type="text/x-coffeescript" class="test" id="interpolation">
25855# Interpolation
25856# -------------
25857
25858# * String Interpolation
25859# * Regular Expression Interpolation
25860
25861# String Interpolation
25862
25863# TODO: refactor string interpolation tests
25864
25865eq 'multiline nested "interpolations" work', """multiline #{
25866  "nested #{
25867    ok true
25868    "\"interpolations\""
25869  }"
25870} work"""
25871
25872# Issue #923: Tricky interpolation.
25873eq "#{ "{" }", "{"
25874eq "#{ '#{}}' } }", '#{}} }'
25875eq "#{"'#{ ({a: "b#{1}"}['a']) }'"}", "'b1'"
25876
25877# Issue #1150: String interpolation regression
25878eq "#{'"/'}",                '"/'
25879eq "#{"/'"}",                "/'"
25880eq "#{/'"/}",                '/\'"/'
25881eq "#{"'/" + '/"' + /"'/}",  '\'//"/"\'/'
25882eq "#{"'/"}#{'/"'}#{/"'/}",  '\'//"/"\'/'
25883eq "#{6 / 2}",               '3'
25884eq "#{6 / 2}#{6 / 2}",       '33' # parsed as division
25885eq "#{6 + /2}#{6/ + 2}",     '6/2}#{6/2' # parsed as a regex
25886eq "#{6/2}
25887    #{6/2}",                 '3 3' # newline cannot be part of a regex, so it's division
25888eq "#{/// "'/'"/" ///}",     '/"\'\\/\'"\\/"/' # heregex, stuffed with spicy characters
25889eq "#{/\\'/}",               "/\\\\'/"
25890
25891# Issue #2321: Regex/division conflict in interpolation
25892eq "#{4/2}/", '2/'
25893curWidth = 4
25894eq "<i style='left:#{ curWidth/2 }%;'></i>",   "<i style='left:2%;'></i>"
25895throwsCompileError '''
25896   "<i style='left:#{ curWidth /2 }%;'></i>"'''
25897#                 valid regex--^^^^^^^^^^^ ^--unclosed string
25898eq "<i style='left:#{ curWidth/2 }%;'></i>",   "<i style='left:2%;'></i>"
25899eq "<i style='left:#{ curWidth/ 2 }%;'></i>",  "<i style='left:2%;'></i>"
25900eq "<i style='left:#{ curWidth / 2 }%;'></i>", "<i style='left:2%;'></i>"
25901
25902hello = 'Hello'
25903world = 'World'
25904ok '#{hello} #{world}!' is '#{hello} #{world}!'
25905ok "#{hello} #{world}!" is 'Hello World!'
25906ok "[#{hello}#{world}]" is '[HelloWorld]'
25907ok "#{hello}##{world}" is 'Hello#World'
25908ok "Hello #{ 1 + 2 } World" is 'Hello 3 World'
25909ok "#{hello} #{ 1 + 2 } #{world}" is "Hello 3 World"
25910ok 1 + "#{2}px" is '12px'
25911ok isNaN "a#{2}" * 2
25912ok "#{2}" is '2'
25913ok "#{2}#{2}" is '22'
25914
25915[s, t, r, i, n, g] = ['s', 't', 'r', 'i', 'n', 'g']
25916ok "#{s}#{t}#{r}#{i}#{n}#{g}" is 'string'
25917ok "\#{s}\#{t}\#{r}\#{i}\#{n}\#{g}" is '#{s}#{t}#{r}#{i}#{n}#{g}'
25918ok "\#{string}" is '#{string}'
25919
25920ok "\#{Escaping} first" is '#{Escaping} first'
25921ok "Escaping \#{in} middle" is 'Escaping #{in} middle'
25922ok "Escaping \#{last}" is 'Escaping #{last}'
25923
25924ok "##" is '##'
25925ok "#{}" is ''
25926ok "#{}A#{} #{} #{}B#{}" is 'A  B'
25927ok "\\\#{}" is '\\#{}'
25928
25929ok "I won ##{20} last night." is 'I won #20 last night.'
25930ok "I won ##{'#20'} last night." is 'I won ##20 last night.'
25931
25932ok "#{hello + world}" is 'HelloWorld'
25933ok "#{hello + ' ' + world + '!'}" is 'Hello World!'
25934
25935list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
25936ok "values: #{list.join(', ')}, length: #{list.length}." is 'values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, length: 10.'
25937ok "values: #{list.join ' '}" is 'values: 0 1 2 3 4 5 6 7 8 9'
25938
25939obj = {
25940  name: 'Joe'
25941  hi: -> "Hello #{@name}."
25942  cya: -> "Hello #{@name}.".replace('Hello','Goodbye')
25943}
25944ok obj.hi() is "Hello Joe."
25945ok obj.cya() is "Goodbye Joe."
25946
25947ok "With #{"quotes"}" is 'With quotes'
25948ok 'With #{"quotes"}' is 'With #{"quotes"}'
25949
25950ok "Where is #{obj["name"] + '?'}" is 'Where is Joe?'
25951
25952ok "Where is #{"the nested #{obj["name"]}"}?" is 'Where is the nested Joe?'
25953ok "Hello #{world ? "#{hello}"}" is 'Hello World'
25954
25955ok "Hello #{"#{"#{obj["name"]}" + '!'}"}" is 'Hello Joe!'
25956
25957a = """
25958    Hello #{ "Joe" }
25959    """
25960ok a is "Hello Joe"
25961
25962a = 1
25963b = 2
25964c = 3
25965ok "#{a}#{b}#{c}" is '123'
25966
25967result = null
25968stash = (str) -> result = str
25969stash "a #{ ('aa').replace /a/g, 'b' } c"
25970ok result is 'a bb c'
25971
25972foo = "hello"
25973ok "#{foo.replace("\"", "")}" is 'hello'
25974
25975val = 10
25976a = """
25977    basic heredoc #{val}
25978    on two lines
25979    """
25980b = '''
25981    basic heredoc #{val}
25982    on two lines
25983    '''
25984ok a is "basic heredoc 10\non two lines"
25985ok b is "basic heredoc \#{val}\non two lines"
25986
25987eq 'multiline nested "interpolations" work', """multiline #{
25988  "nested #{(->
25989    ok yes
25990    "\"interpolations\""
25991  )()}"
25992} work"""
25993
25994eq 'function(){}', "#{->}".replace /\s/g, ''
25995ok /^a[\s\S]+b$/.test "a#{=>}b"
25996ok /^a[\s\S]+b$/.test "a#{ (x) -> x %% 2 }b"
25997
25998# Regular Expression Interpolation
25999
26000# TODO: improve heregex interpolation tests
26001
26002test "heregex interpolation", ->
26003  eq /\\#{}\\"/ + '', ///
26004   #{
26005     "#{ '\\' }" # normal comment
26006   }
26007   # regex comment
26008   \#{}
26009   \\ "
26010  /// + ''
26011
26012</script>
vendor: 1 bytes, line 26012
26012
26013<script type="text/x-coffeescript" class="test" id="invocation_argument_parsing">
26014return unless require?
26015
26016path = require 'path'
26017{ execFileSync, spawnSync } = require 'child_process'
26018
26019# Get the folder containing the compiled `coffee` executable and make it the
26020# PATH so that `#!/usr/bin/env coffee` resolves to our locally built file.
26021coffeeBinFolder = path.dirname require.resolve '../bin/coffee'
26022# For some reason, Windows requires `coffee` to be executed as `node coffee`.
26023coffeeCommand = if isWindows() then 'node coffee' else 'coffee'
26024spawnOptions =
26025  cwd: coffeeBinFolder
26026  encoding: 'utf8'
26027  env: Object.assign {}, process.env,
26028    PATH: coffeeBinFolder + (if isWindows() then ';' else ':') + process.env.PATH
26029  shell: isWindows()
26030
26031shebangScript = require.resolve './importing/shebang.coffee'
26032initialSpaceScript = require.resolve './importing/shebang_initial_space.coffee'
26033extraArgsScript = require.resolve './importing/shebang_extra_args.coffee'
26034initialSpaceExtraArgsScript = require.resolve './importing/shebang_initial_space_extra_args.coffee'
26035
26036test "parse arguments for shebang scripts correctly (on *nix platforms)", ->
26037  return if isWindows()
26038
26039  stdout = execFileSync shebangScript, ['-abck'], spawnOptions
26040  expectedArgs = ['coffee', shebangScript, '-abck']
26041  realArgs = JSON.parse stdout
26042  arrayEq expectedArgs, realArgs
26043
26044  stdout = execFileSync initialSpaceScript, ['-abck'], spawnOptions
26045  expectedArgs = ['coffee', initialSpaceScript, '-abck']
26046  realArgs = JSON.parse stdout
26047  arrayEq expectedArgs, realArgs
26048
26049test "warn and remove -- if it is the second positional argument", ->
26050  result = spawnSync coffeeCommand, [shebangScript, '--'], spawnOptions
26051  stderr = result.stderr.toString()
26052  arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
26053  ok stderr.match /^coffee was invoked with '--'/m
26054  posArgs = stderr.match(/^The positional arguments were: (.*)$/m)[1]
26055  arrayEq JSON.parse(posArgs), [shebangScript, '--']
26056  ok result.status is 0
26057
26058  result = spawnSync coffeeCommand, ['-b', shebangScript, '--'], spawnOptions
26059  stderr = result.stderr.toString()
26060  arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
26061  ok stderr.match /^coffee was invoked with '--'/m
26062  posArgs = stderr.match(/^The positional arguments were: (.*)$/m)[1]
26063  arrayEq JSON.parse(posArgs), [shebangScript, '--']
26064  ok result.status is 0
26065
26066  result = spawnSync(
26067    coffeeCommand, ['-b', shebangScript, '--', 'ANOTHER'], spawnOptions)
26068  stderr = result.stderr.toString()
26069  arrayEq JSON.parse(result.stdout), ['coffee', shebangScript, 'ANOTHER']
26070  ok stderr.match /^coffee was invoked with '--'/m
26071  posArgs = stderr.match(/^The positional arguments were: (.*)$/m)[1]
26072  arrayEq JSON.parse(posArgs), [shebangScript, '--', 'ANOTHER']
26073  ok result.status is 0
26074
26075  result = spawnSync(
26076    coffeeCommand, ['--', initialSpaceScript, 'arg'], spawnOptions)
26077  expectedArgs = ['coffee', initialSpaceScript, 'arg']
26078  realArgs = JSON.parse result.stdout
26079  arrayEq expectedArgs, realArgs
26080  ok result.stderr.toString() is ''
26081  ok result.status is 0
26082
26083test "warn about non-portable shebang lines", ->
26084  result = spawnSync coffeeCommand, [extraArgsScript, 'arg'], spawnOptions
26085  stderr = result.stderr.toString()
26086  arrayEq JSON.parse(result.stdout), ['coffee', extraArgsScript, 'arg']
26087  ok stderr.match /^The script to be run begins with a shebang line with more than one/m
26088  [_, firstLine, file] = stderr.match(/^The shebang line was: '([^']+)' in file '([^']+)'/m)
26089  ok (firstLine is '#!/usr/bin/env coffee --')
26090  ok (file is extraArgsScript)
26091  args = stderr.match(/^The arguments were: (.*)$/m)[1]
26092  arrayEq JSON.parse(args), ['coffee', '--']
26093  ok result.status is 0
26094
26095  result = spawnSync coffeeCommand, [initialSpaceScript, 'arg'], spawnOptions
26096  stderr = result.stderr.toString()
26097  ok stderr is ''
26098  arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceScript, 'arg']
26099  ok result.status is 0
26100
26101  result = spawnSync(
26102    coffeeCommand, [initialSpaceExtraArgsScript, 'arg'], spawnOptions)
26103  stderr = result.stderr.toString()
26104  arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
26105  ok stderr.match /^The script to be run begins with a shebang line with more than one/m
26106  [_, firstLine, file] = stderr.match(/^The shebang line was: '([^']+)' in file '([^']+)'/m)
26107  ok (firstLine is '#! /usr/bin/env coffee extra')
26108  ok (file is initialSpaceExtraArgsScript)
26109  args = stderr.match(/^The arguments were: (.*)$/m)[1]
26110  arrayEq JSON.parse(args), ['coffee', 'extra']
26111  ok result.status is 0
26112
26113test "both warnings will be shown at once", ->
26114  result = spawnSync(
26115    coffeeCommand, [initialSpaceExtraArgsScript, '--', 'arg'], spawnOptions)
26116  stderr = result.stderr.toString()
26117  arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
26118  ok stderr.match /^The script to be run begins with a shebang line with more than one/m
26119  [_, firstLine, file] = stderr.match(/^The shebang line was: '([^']+)' in file '([^']+)'/m)
26120  ok (firstLine is '#! /usr/bin/env coffee extra')
26121  ok (file is initialSpaceExtraArgsScript)
26122  args = stderr.match(/^The arguments were: (.*)$/m)[1]
26123  arrayEq JSON.parse(args), ['coffee', 'extra']
26124  ok stderr.match /^coffee was invoked with '--'/m
26125  posArgs = stderr.match(/^The positional arguments were: (.*)$/m)[1]
26126  arrayEq JSON.parse(posArgs), [initialSpaceExtraArgsScript, '--', 'arg']
26127  ok result.status is 0
26128
26129</script>
vendor: 1 bytes, line 26129
26129
26130<script type="text/x-coffeescript" class="test" id="javascript_literals">
26131# JavaScript Literals
26132# -------------------
26133
26134test "inline JavaScript is evaluated", ->
26135  eq '\\`', `
26136    // Inline JS
26137    "\\\\\`"
26138  `
26139
26140test "escaped backticks are output correctly", ->
26141  `var a = \`2 + 2 = ${4}\``
26142  eq a, '2 + 2 = 4'
26143
26144test "backslashes before a newline don’t break JavaScript blocks", ->
26145  `var a = \`To be, or not\\
26146  to be.\``
26147  eq a, '''
26148  To be, or not\\
26149    to be.'''
26150
26151test "block inline JavaScript is evaluated", ->
26152  ```
26153  var a = 1;
26154  var b = 2;
26155  ```
26156  c = 3
26157  ```var d = 4;```
26158  eq a + b + c + d, 10
26159
26160test "block inline JavaScript containing backticks", ->
26161  ```
26162  // This is a comment with `backticks`
26163  var a = 42;
26164  var b = `foo ${'bar'}`;
26165  var c = 3;
26166  var d = 'foo`bar`';
26167  ```
26168  eq a + c, 45
26169  eq b, 'foo bar'
26170  eq d, 'foo`bar`'
26171
26172test "block JavaScript can end with an escaped backtick character", ->
26173  ```var a = \`hello\````
26174  ```
26175  var b = \`world${'!'}\````
26176  eq a, 'hello'
26177  eq b, 'world!'
26178
26179test "JavaScript block only escapes backslashes followed by backticks", ->
26180  eq `'\\\n'`, '\\\n'
26181
26182test "escaped JavaScript blocks speed round", ->
26183  # The following has escaped backslashes because they’re required in strings, but the intent is this:
26184  # `hello`                                       → hello;
26185  # `\`hello\``                                   → `hello`;
26186  # `\`Escaping backticks in JS: \\\`hello\\\`\`` → `Escaping backticks in JS: \`hello\``;
26187  # `Single backslash: \ `                        → Single backslash: \ ;
26188  # `Double backslash: \\ `                       → Double backslash: \\ ;
26189  # `Single backslash at EOS: \\`                 → Single backslash at EOS: \;
26190  # `Double backslash at EOS: \\\\`               → Double backslash at EOS: \\;
26191  for [input, output] in [
26192    ['`hello`',                                               'hello;']
26193    ['`\\`hello\\``',                                         '`hello`;']
26194    ['`\\`Escaping backticks in JS: \\\\\\`hello\\\\\\`\\``', '`Escaping backticks in JS: \\`hello\\``;']
26195    ['`Single backslash: \\ `',                               'Single backslash: \\ ;']
26196    ['`Double backslash: \\\\ `',                             'Double backslash: \\\\ ;']
26197    ['`Single backslash at EOS: \\\\`',                       'Single backslash at EOS: \\;']
26198    ['`Double backslash at EOS: \\\\\\\\`',                   'Double backslash at EOS: \\\\;']
26199  ]
26200    eqJS input, output
26201
26202</script>
vendor: 1 bytes, line 26202
26202
26203<script type="text/x-coffeescript" class="test" id="jsx">
26204# We usually do not check the actual JS output from the compiler, but since
26205# JSX is not natively supported by Node, we do it in this case.
26206
26207test 'self closing', ->
26208  eqJS '''
26209    <div />
26210  ''', '''
26211    <div />;
26212  '''
26213
26214test 'self closing formatting', ->
26215  eqJS '''
26216    <div/>
26217  ''', '''
26218    <div />;
26219  '''
26220
26221test 'self closing multiline', ->
26222  eqJS '''
26223    <div
26224    />
26225  ''', '''
26226    <div />;
26227  '''
26228
26229test 'reserved-word self closing', ->
26230  eqJS '''
26231    <static />
26232  ''', '''
26233    <static />;
26234  '''
26235
26236test 'regex attribute', ->
26237  eqJS '''
26238    <div x={/>asds/} />
26239  ''', '''
26240    <div x={/>asds/} />;
26241  '''
26242
26243test 'string attribute', ->
26244  eqJS '''
26245    <div x="a" />
26246  ''', '''
26247    <div x="a" />;
26248  '''
26249
26250test 'simple attribute', ->
26251  eqJS '''
26252    <div x={42} />
26253  ''', '''
26254    <div x={42} />;
26255  '''
26256
26257test 'assignment attribute', ->
26258  eqJS '''
26259    <div x={y = 42} />
26260  ''', '''
26261    var y;
26262
26263    <div x={y = 42} />;
26264  '''
26265
26266test 'object attribute', ->
26267  eqJS '''
26268    <div x={{y: 42}} />
26269  ''', '''
26270    <div x={{
26271      y: 42
26272    }} />;
26273  '''
26274
26275test 'attribute without value', ->
26276  eqJS '''
26277    <div checked x="hello" />
26278  ''', '''
26279    <div checked x="hello" />;
26280  '''
26281
26282test 'reserved-word attribute without value', ->
26283  eqJS '''
26284    <div static x="hello" />
26285  ''', '''
26286    <div static x="hello" />;
26287  '''
26288
26289test 'reserved-word attribute with value', ->
26290  eqJS '''
26291    <div static="yes" x="hello" />
26292  ''', '''
26293    <div static="yes" x="hello" />;
26294  '''
26295
26296test 'attribute with namespace', ->
26297  eqJS '''
26298    <image xlink:href="data:image/png" />
26299  ''', '''
26300    <image xlink:href="data:image/png" />;
26301  '''
26302
26303test 'attribute with double namespace disallowed', ->
26304  throwsCompileError '<image xlink:href:tag="data:image/png" />'
26305
26306test 'attribute with member expression disallowed', ->
26307  throwsCompileError '<image xlink.href="data:image/png" />'
26308
26309test 'paired', ->
26310  eqJS '''
26311    <div></div>
26312  ''', '''
26313    <div></div>;
26314  '''
26315
26316test 'simple content', ->
26317  eqJS '''
26318    <div>Hello world</div>
26319  ''', '''
26320    <div>Hello world</div>;
26321  '''
26322
26323test 'content interpolation', ->
26324  eqJS '''
26325    <div>Hello {42}</div>
26326  ''', '''
26327    <div>Hello {42}</div>;
26328  '''
26329
26330test 'nested tag', ->
26331  eqJS '''
26332    <div><span /></div>
26333  ''', '''
26334    <div><span /></div>;
26335  '''
26336
26337test 'tag inside interpolation formatting', ->
26338  eqJS '''
26339    <div>Hello {<span />}</div>
26340  ''', '''
26341    <div>Hello <span /></div>;
26342  '''
26343
26344test 'tag inside interpolation, tags are callable', ->
26345  eqJS '''
26346    <div>Hello {<span /> x}</div>
26347  ''', '''
26348    <div>Hello {<span />(x)}</div>;
26349  '''
26350
26351test 'tags inside interpolation, tags trigger implicit calls', ->
26352  eqJS '''
26353    <div>Hello {f <span />}</div>
26354  ''', '''
26355    <div>Hello {f(<span />)}</div>;
26356  '''
26357
26358test 'regex in interpolation', ->
26359  eqJS '''
26360    <div x={/>asds/}><div />{/>asdsad</}</div>
26361  ''', '''
26362    <div x={/>asds/}><div />{/>asdsad</}</div>;
26363  '''
26364
26365test 'interpolation in string attribute value', ->
26366  eqJS '''
26367    <div x="Hello #{world}" />
26368  ''', '''
26369    <div x={`Hello ${world}`} />;
26370  '''
26371
26372# Unlike in `coffee-react-transform`.
26373test 'bare numbers not allowed', ->
26374  throwsCompileError '<div x=3 />'
26375
26376test 'bare expressions not allowed', ->
26377  throwsCompileError '<div x=y />'
26378
26379test 'bare complex expressions not allowed', ->
26380  throwsCompileError '<div x=f(3) />'
26381
26382test 'unescaped opening tag angle bracket disallowed', ->
26383  throwsCompileError '<Person><<</Person>'
26384
26385test 'space around equal sign', ->
26386  eqJS '''
26387    <div popular = "yes" />
26388  ''', '''
26389    <div popular="yes" />;
26390  '''
26391
26392# The following tests were adopted from James Friend’s
26393# [https://github.com/jsdf/coffee-react-transform](https://github.com/jsdf/coffee-react-transform).
26394
26395test 'ambiguous tag-like expression', ->
26396  throwsCompileError 'x = a <b > c'
26397
26398test 'ambiguous tag', ->
26399  eqJS '''
26400    a <b > c </b>
26401  ''', '''
26402    a(<b> c </b>);
26403  '''
26404
26405test 'escaped CoffeeScript attribute', ->
26406  eqJS '''
26407    <Person name={if test() then 'yes' else 'no'} />
26408  ''', '''
26409    <Person name={test() ? 'yes' : 'no'} />;
26410  '''
26411
26412test 'escaped CoffeeScript attribute over multiple lines', ->
26413  eqJS '''
26414    <Person name={
26415      if test()
26416        'yes'
26417      else
26418        'no'
26419    } />
26419
26420  ''', '''
26421    <Person name={test() ? 'yes' : 'no'} />;
26422  '''
26423
26424test 'multiple line escaped CoffeeScript with nested JSX', ->
26425  eqJS '''
26426    <Person name={
26427      if test()
26428        'yes'
26429      else
26430        'no'
26431    }>
26432    {
26433
26434      for n in a
26435        <div> a
26436          asf
26437          <li xy={"as"}>{ n+1 }<a /> <a /> </li>
26438        </div>
26439    }
26440
26441    </Person>
26442  ''', '''
26443    var n;
26444
26445    <Person name={test() ? 'yes' : 'no'}>
26446    {(function() {
26447      var i, len, results;
26448      results = [];
26449      for (i = 0, len = a.length; i < len; i++) {
26450        n = a[i];
26451        results.push(<div> a
26452          asf
26453          <li xy={"as"}>{n + 1}<a /> <a /> </li>
26454        </div>);
26455      }
26456      return results;
26457    })()}
26458
26459    </Person>;
26460  '''
26461
26462test 'nested JSX within an attribute, with object attr value', ->
26463  eqJS '''
26464    <Company>
26465      <Person name={<NameComponent attr3={ {'a': {}, b: '{'} } />} />
26466    </Company>
26467  ''', '''
26468    <Company>
26469      <Person name={<NameComponent attr3={{
26470      'a': {},
26471      b: '{'
26472    }} />} />
26473    </Company>;
26474  '''
26475
26476test 'complex nesting', ->
26477  eqJS '''
26478    <div code={someFunc({a:{b:{}, C:'}{}{'}})} />
26479  ''', '''
26480    <div code={someFunc({
26481      a: {
26482        b: {},
26483        C: '}{}{'
26484      }
26485    })} />;
26486  '''
26487
26488test 'multiline tag with nested JSX within an attribute', ->
26489  eqJS '''
26490    <Person
26491      name={
26492        name = formatName(user.name)
26493        <NameComponent name={name.toUppercase()} />
26494      }
26495    >
26496      blah blah blah
26497    </Person>
26498  ''', '''
26499    var name;
26500
26501    <Person name={name = formatName(user.name), <NameComponent name={name.toUppercase()} />}>
26502      blah blah blah
26503    </Person>;
26504  '''
26505
26506test 'escaped CoffeeScript with nested object literals', ->
26507  eqJS '''
26508    <Person>
26509      blah blah blah {
26510        {'a' : {}, 'asd': 'asd'}
26511      }
26512    </Person>
26513  ''', '''
26514    <Person>
26515      blah blah blah {{
26516      'a': {},
26517      'asd': 'asd'
26518    }}
26519    </Person>;
26520  '''
26521
26522test 'multiline tag attributes with escaped CoffeeScript', ->
26523  eqJS '''
26524    <Person name={if isActive() then 'active' else 'inactive'}
26525    someattr='on new line' />
26526  ''', '''
26527    <Person name={isActive() ? 'active' : 'inactive'} someattr='on new line' />;
26528  '''
26529
26530test 'lots of attributes', ->
26531  eqJS '''
26532    <Person eyes={2} friends={getFriends()} popular = "yes"
26533    active={ if isActive() then 'active' else 'inactive' } data-attr='works' checked check={me_out}
26534    />
26535  ''', '''
26536    <Person eyes={2} friends={getFriends()} popular="yes" active={isActive() ? 'active' : 'inactive'} data-attr='works' checked check={me_out} />;
26537  '''
26538
26539# TODO: fix partially indented JSX
26540# test 'multiline elements', ->
26541#   eqJS '''
26542#     <div something={
26543#       do ->
26544#         test = /432/gm # this is a regex
26545#         6 /432/gm # this is division
26546#     }
26547#     >
26548#     <div>
26549#     <div>
26550#     <div>
26551#       <article name={ new Date() } number={203}
26552#        range={getRange()}
26553#       >
26554#       </article>
26555#     </div>
26556#     </div>
26557#     </div>
26558#     </div>
26559#   ''', '''
26560#     bla
26561#   '''
26562
26563test 'complex regex', ->
26564  eqJS '''
26565    <Person />
26566    /\\/\\/<Person \\/>\\>\\//
26567  ''', '''
26568    <Person />;
26569
26570    /\\/\\/<Person \\/>\\>\\//;
26571  '''
26572
26573test 'heregex', ->
26574  eqJS '''
26575    test = /432/gm # this is a regex
26576    6 /432/gm # this is division
26577    <Tag>
26578    {test = /<Tag>/} this is a regex containing something which looks like a tag
26579    </Tag>
26580    <Person />
26581    REGEX = /// ^
26582      (/ (?! [\s=] )   # comment comment <comment>comment</comment>
26583      [^ [ / \n \\ ]*  # comment comment
26584      (?:
26585        <Tag />
26586        (?: \\[\s\S]   # comment comment
26587          | \[         # comment comment
26588               [^ \] \n \\ ]*
26589               (?: \\[\s\S] [^ \] \n \\ ]* )*
26590               <Tag>tag</Tag>
26591             ]
26592        ) [^ [ / \n \\ ]*
26593      )*
26594      /) ([imgy]{0,4}) (?!\w)
26595    ///
26596    <Person />
26597  ''', '''
26598    var REGEX, test;
26599
26600    test = /432/gm; // this is a regex
26601
26602    6 / 432 / gm; // this is division
26603
26604    <Tag>
26605    {test = /<Tag>/} this is a regex containing something which looks like a tag
26606    </Tag>;
26607
26608    <Person />;
26609
26610    REGEX = /^(\\/(?![s=])[^[\\/ ]*(?:<Tag\\/>(?:\\[sS]|[[^] ]*(?:\\[sS][^] ]*)*<Tag>tag<\\/Tag>])[^[\\/ ]*)*\\/)([imgy]{0,4})(?!w)/; // comment comment <comment>comment</comment>
26611    // comment comment
26612    // comment comment
26613    // comment comment
26614
26615    <Person />;
26616  '''
26617
26618test 'comment within JSX is not treated as comment', ->
26619  eqJS '''
26620    <Person>
26621    # i am not a comment
26622    </Person>
26623  ''', '''
26624    <Person>
26625    # i am not a comment
26626    </Person>;
26627  '''
26628
26629test 'comment at start of JSX escape', ->
26630  eqJS '''
26631    <Person>
26632    {# i am a comment
26633      "i am a string"
26634    }
26635    </Person>
26636  ''', '''
26637    <Person>
26638    {// i am a comment
26639    "i am a string"}
26640    </Person>;
26641  '''
26642
26643test 'comment at end of JSX escape', ->
26644  eqJS '''
26645    <Person>
26646    {"i am a string"
26647    # i am a comment
26648    }
26649    </Person>
26650  ''', '''
26651    <Person>
26652    {"i am a string"
26653    // i am a comment
26654    }
26655    </Person>;
26656  '''
26657
26658test 'JSX comment cannot be used inside interpolation', ->
26659  throwsCompileError '''
26660    <Person>
26661    {# i am a comment}
26662    </Person>
26663  '''
26664
26665test 'comment syntax cannot be used inline', ->
26666  throwsCompileError '''
26667    <Person>{#comment inline}</Person>
26668  '''
26669
26670test 'string within JSX is ignored', ->
26671  eqJS '''
26672    <Person> "i am not a string" 'nor am i' </Person>
26673  ''', '''
26674    <Person> "i am not a string" 'nor am i' </Person>;
26675  '''
26676
26677test 'special chars within JSX are ignored', ->
26678  eqJS """
26679    <Person> a,/';][' a\''@$%^&˚¬∑˜˚∆å∂¬˚*()*&^%$>> '"''"'''\'\'m' i </Person>
26680  """, """
26681    <Person> a,/';][' a''@$%^&˚¬∑˜˚∆å∂¬˚*()*&^%$>> '"''"'''''m' i </Person>;
26682  """
26683
26684test 'html entities (name, decimal, hex) within JSX', ->
26685  eqJS '''
26686    <Person>  &&&&euro;  &#8364; &#x20AC;;; </Person>
26687  ''', '''
26688    <Person>  &&&&euro;  &#8364; &#x20AC;;; </Person>;
26689  '''
26690
26691test 'tag with {{}}', ->
26692  eqJS '''
26693    <Person name={{value: item, key, item}} />
26694  ''', '''
26695    <Person name={{
26696      value: item,
26697      key,
26698      item
26699    }} />;
26700  '''
26701
26702test 'tag with member expression', ->
26703  eqJS '''
26704    <Something.Tag></Something.Tag>
26705  ''', '''
26706    <Something.Tag></Something.Tag>;
26707  '''
26708
26709test 'tag with lowercase member expression', ->
26710  eqJS '''
26711    <something.tag></something.tag>
26712  ''', '''
26713    <something.tag></something.tag>;
26714  '''
26715
26716test 'self closing tag with member expression', ->
26717  eqJS '''
26718    <Something.Tag />
26719  ''', '''
26720    <Something.Tag />;
26721  '''
26722
26723test 'self closing tag with multiple member expressions', ->
26724  eqJS '''
26725    <Something.Tag.More />
26726  ''', '''
26727    <Something.Tag.More />;
26728  '''
26729
26730test 'tag with namespace', ->
26731  eqJS '''
26732    <Something:Tag></Something:Tag>
26733  ''', '''
26734    <Something:Tag></Something:Tag>;
26735  '''
26736
26737test 'tag with lowercase namespace', ->
26738  eqJS '''
26739    <something:tag></something:tag>
26740  ''', '''
26741    <something:tag></something:tag>;
26742  '''
26743
26744test 'self closing tag with namespace', ->
26745  eqJS '''
26746    <Something:Tag />
26747  ''', '''
26748    <Something:Tag />;
26749  '''
26750
26751test 'self closing tag with namespace and member expression disallowed', ->
26752  throwsCompileError '''
26753    <Namespace:Something.Tag />
26754  '''
26755
26756test 'self closing tag with spread attribute', ->
26757  eqJS '''
26758    <Component a={b} {x...} b="c" />
26759  ''', '''
26760    <Component a={b} {...x} b="c" />;
26761  '''
26762
26763test 'complex spread attribute', ->
26764  eqJS '''
26765    <Component {x...} a={b} {x...} b="c" {$my_xtraCoolVar123...} />
26766  ''', '''
26767    <Component {...x} a={b} {...x} b="c" {...$my_xtraCoolVar123} />;
26768  '''
26769
26770test 'multiline spread attribute', ->
26771  eqJS '''
26772    <Component {
26773      x...} a={b} {x...} b="c" {z...}>
26774    </Component>
26775  ''', '''
26776    <Component {...x} a={b} {...x} b="c" {...z}>
26777    </Component>;
26778  '''
26779
26780test 'multiline tag with spread attribute', ->
26781  eqJS '''
26782    <Component
26783      z="1"
26784      {x...}
26785      a={b}
26786      b="c"
26787    >
26788    </Component>
26789  ''', '''
26790    <Component z="1" {...x} a={b} b="c">
26791    </Component>;
26792  '''
26793
26794test 'multiline tag with spread attribute first', ->
26795  eqJS '''
26796    <Component
26797      {x...}
26798      z="1"
26799      a={b}
26800      b="c"
26801    >
26802    </Component>
26803  ''', '''
26804    <Component {...x} z="1" a={b} b="c">
26805    </Component>;
26806  '''
26807
26808test 'complex multiline spread attribute', ->
26809  eqJS '''
26810    <Component
26811      {y...
26812      } a={b} {x...} b="c" {z...}>
26813      <div code={someFunc({a:{b:{}, C:'}'}})} />
26814    </Component>
26815  ''', '''
26816    <Component {...y} a={b} {...x} b="c" {...z}>
26817      <div code={someFunc({
26818      a: {
26819        b: {},
26820        C: '}'
26821      }
26822    })} />
26823    </Component>;
26824  '''
26825
26826test 'self closing spread attribute on single line', ->
26827  eqJS '''
26828    <Component a="b" c="d" {@props...} />
26829  ''', '''
26830    <Component a="b" c="d" {...this.props} />;
26831  '''
26832
26833test 'self closing spread attribute on new line', ->
26834  eqJS '''
26835    <Component
26836      a="b"
26837      c="d"
26838      {@props...}
26839    />
26840  ''', '''
26841    <Component a="b" c="d" {...this.props} />;
26842  '''
26843
26844test 'self closing spread attribute on same line', ->
26845  eqJS '''
26846    <Component
26847      a="b"
26848      c="d"
26849      {@props...} />
26850  ''', '''
26851    <Component a="b" c="d" {...this.props} />;
26852  '''
26853
26854test 'self closing spread attribute on next line', ->
26855  eqJS '''
26856    <Component
26857      a="b"
26858      c="d"
26859      {@props...}
26860
26861    />
26862  ''', '''
26863    <Component a="b" c="d" {...this.props} />;
26864  '''
26865
26866test 'empty strings are not converted to true', ->
26867  eqJS '''
26868    <Component val="" />
26869  ''', '''
26870    <Component val="" />;
26871  '''
26872
26873test 'CoffeeScript @ syntax in tag name', ->
26874  throwsCompileError '''
26875    <@Component>
26876      <Component />
26877    </@Component>
26878  '''
26879
26880test 'hyphens in tag names', ->
26881  eqJS '''
26882    <paper-button className="button">{text}</paper-button>
26883  ''', '''
26884    <paper-button className="button">{text}</paper-button>;
26885  '''
26886
26887test 'closing tags must be closed', ->
26888  throwsCompileError '''
26889    <a></a
26890  '''
26891
26892# Tests for allowing less than operator without spaces when ther is no JSX
26893
26894test 'unspaced less than without JSX: identifier', ->
26895  a = 3
26896  div = 5
26897  ok a<div
26898
26899test 'unspaced less than without JSX: number', ->
26900  div = 5
26901  ok 3<div
26902
26903test 'unspaced less than without JSX: paren', ->
26904  div = 5
26905  ok (3)<div
26906
26907test 'unspaced less than without JSX: index', ->
26908  div = 5
26909  a = [3]
26910  ok a[0]<div
26911
26912test 'tag inside JSX works following: identifier', ->
26913  eqJS '''
26914    <span>a<div /></span>
26915  ''', '''
26916    <span>a<div /></span>;
26917  '''
26918
26919test 'tag inside JSX works following: number', ->
26920  eqJS '''
26921    <span>3<div /></span>
26922  ''', '''
26923    <span>3<div /></span>;
26924  '''
26925
26926test 'tag inside JSX works following: paren', ->
26927  eqJS '''
26928    <span>(3)<div /></span>
26929  ''', '''
26930    <span>(3)<div /></span>;
26931  '''
26932
26933test 'tag inside JSX works following: square bracket', ->
26934  eqJS '''
26935    <span>]<div /></span>
26936  ''', '''
26937    <span>]<div /></span>;
26938  '''
26939
26940test 'unspaced less than inside JSX works but is not encouraged', ->
26941  eqJS '''
26942      a = 3
26943      div = 5
26944      html = <span>{a<div}</span>
26945    ''', '''
26946      var a, div, html;
26947
26948      a = 3;
26949
26950      div = 5;
26951
26952      html = <span>{a < div}</span>;
26953    '''
26954
26955test 'unspaced less than before JSX works but is not encouraged', ->
26956  eqJS '''
26957      div = 5
26958      res = 2<div
26959      html = <span />
26960    ''', '''
26961      var div, html, res;
26962
26963      div = 5;
26964
26965      res = 2 < div;
26966
26967      html = <span />;
26968    '''
26969
26970test 'unspaced less than after JSX works but is not encouraged', ->
26971  eqJS '''
26972      div = 5
26973      html = <span />
26974      res = 2<div
26975    ''', '''
26976      var div, html, res;
26977
26978      div = 5;
26979
26980      html = <span />;
26981
26982      res = 2 < div;
26983    '''
26984
26985test '#4686: comments inside interpolations that also contain JSX tags', ->
26986  eqJS '''
26987    <div>
26988      {
26989        # comment
26990        <div />
26991      }
26992    </div>
26993  ''', '''
26994    <div>
26995      {  // comment
26996    <div />}
26997    </div>;
26998  '''
26999
27000test '#4686: comments inside interpolations that also contain JSX attributes', ->
27001  eqJS '''
27002    <div>
27003      <div anAttr={
27004        # comment
27005        "value"
27006      } />
27007    </div>
27008  ''', '''
27009    <div>
27010      {  // comment
27011    <div anAttr={"value"} />}
27012    </div>;
27013  '''
27014
27015test '#5086: comments inside JSX tags but outside interpolations', ->
27016  eqJS '''
27017    <div>
27018      <div ###comment### attribute={value} />
27019    </div>
27020  ''', '''
27021    <div>
27022      <div /*comment*/attribute={value} />
27023    </div>;
27024  '''
27025
27026test '#5086: comments inside JSX attributes but outside interpolations', ->
27027  eqJS '''
27028    <div>
27029      <div attribute={###attr comment### value} />
27030    </div>
27031  ''', '''
27032    <div>
27033      <div attribute={/*attr comment*/value} />
27034    </div>;
27035  '''
27036
27037test '#5086: comments inside nested JSX tags and attributes but outside interpolations', ->
27038  eqJS '''
27039    <div>
27040      <div>
27041        <div>
27042          <div ###comment### attribute={###attr comment### value} />
27043        </div>
27044      </div>
27045    </div>
27046  ''', '''
27047    <div>
27048      <div>
27049        <div>
27050          <div /*comment*/attribute={/*attr comment*/value} />
27051        </div>
27052      </div>
27053    </div>;
27054  '''
27055
27056# https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
27057test 'JSX fragments: empty fragment', ->
27058  eqJS '''
27059    <></>
27060  ''', '''
27061    <></>;
27062  '''
27063
27064test 'JSX fragments: fragment with text nodes', ->
27065  eqJS '''
27066    <>
27067      Some text.
27068      <h2>A heading</h2>
27069      More text.
27070      <h2>Another heading</h2>
27071      Even more text.
27072    </>
27073  ''', '''
27074    <>
27075      Some text.
27076      <h2>A heading</h2>
27077      More text.
27078      <h2>Another heading</h2>
27079      Even more text.
27080    </>;
27081  '''
27082
27083test 'JSX fragments: fragment with component nodes', ->
27084  eqJS '''
27085    Component = (props) =>
27086      <Fragment>
27087        <OtherComponent />
27088        <OtherComponent />
27089      </Fragment>
27090  ''', '''
27091    var Component;
27092
27093    Component = (props) => {
27094      return <Fragment>
27095        <OtherComponent />
27096        <OtherComponent />
27097      </Fragment>;
27098    };
27099  '''
27100
27101test '#5055: JSX expression indentation bug', ->
27102  eqJS '''
27103    <div>
27104      {someCondition &&
27105        <span />
27106      }
27107    </div>
27108  ''', '''
27109    <div>
27110      {someCondition && <span />}
27111    </div>;
27112  '''
27113
27114  eqJS '''
27115    <div>{someString +
27116         "abc"
27117      }
27118    </div>
27119  ''', '''
27120    <div>{someString + "abc"}
27121    </div>;
27122  '''
27123
27124  eqJS '''
27125    <div>
27126      {a ?
27127      <span />
27128      }
27129    </div>
27130  ''', '''
27131    <div>
27132      {typeof a !== "undefined" && a !== null ? a : <span />}
27133    </div>;
27134  '''
27135
27136# JSX is like XML, in that there needs to be a root element; but
27137# technically, adjacent top-level elements where only the last one
27138# is returned (as opposed to a fragment or root element) is permissible
27139# syntax. It’s almost certainly an error, but it’s valid, so need to leave it
27140# to linters to catch. https://github.com/jashkenas/coffeescript/pull/5049
27141test '“Adjacent” tags on separate lines should still compile', ->
27142  eqJS '''
27143    ->
27144      <a />
27145      <b />
27146  ''', '''
27147    (function() {
27148      <a />;
27149      return <b />;
27150    });
27151  '''
27152
27153test '#5352: triple-quoted non-interpolated attribute values', ->
27154  eqJS '''
27155    <div a="""
27156      b
27157      c
27158    """ />
27159  ''', '''
27160    <div a={`b
27161    c`} />;
27162  '''
27163
27164  eqJS """
27165    <div a='''
27166      b
27167      c
27168    ''' />
27169  """, '''
27170    <div a={`b
27171    c`} />;
27172  '''
27173
27174</script>
vendor: 1 bytes, line 27174
27174
27175<script type="text/x-literate-coffeescript" class="test" id="literate">
27176# Literate CoffeeScript Test
27177
27178comment comment
27179
27180    testsCount = 0 # Track the number of tests run in this file, to make sure they all run
27181
27182    test "basic literate CoffeeScript parsing", ->
27183      ok yes
27184      testsCount++
27185
27186now with a...
27187
27188    test "broken up indentation", ->
27189
27190... broken up ...
27191
27192      do ->
27193
27194... nested block.
27195
27196        ok yes
27197        testsCount++
27198
27199Code must be separated from text by a blank line.
27200
27201    test "code blocks must be preceded by a blank line", ->
27202
27203The next line is part of the text and will not be executed.
27204      fail()
27205
27206      ok yes
27207      testsCount++
27208
27209Code in `backticks is not parsed` and...
27210
27211    test "comments in indented blocks work", ->
27212      do ->
27213        do ->
27214          # Regular comment.
27215
27216          ###
27217            Block comment.
27218          ###
27219
27220          ok yes
27221          testsCount++
27222
27223Regular [Markdown](http://example.com/markdown) features, like links
27224and unordered lists, are fine:
27225
27226  * I
27227
27228  * Am
27229
27230  * A
27231
27232  * List
27233
27234---
27235
27236    # keep track of whether code blocks are executed or not
27237    executed = false
27238
27239<p>
27240
27241if true
27242  executed = true # should not execute, this is just HTML para, not code!
27243
27244</p>
27245
27246    test "should ignore code blocks inside HTML", ->
27247      eq executed, false
27248      testsCount++
27249
27250---
27251
27252*   A list item followed by a code block:
27253
27254    test "basic literate CoffeeScript parsing", ->
27255      ok yes
27256      testsCount++
27257
27258---
27259
27260*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
27261    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
27262    viverra nec, fringilla in, laoreet vitae, risus.
27263
27264*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
27265    Suspendisse id sem consectetuer libero luctus adipiscing.
27266
27267---
27268
27269This is [an example][id] reference-style link.
27270[id]: http://example.com/  "Optional Title Here"
27271
27272---
27273
27274    executed = no
27275
272761986. What a great season.
27277
27278    executed = yes
27279
27280and test...
27281
27282    test "should recognize indented code blocks in lists with empty line as separator", ->
27283      ok executed
27284      testsCount++
27285
27286---
27287
27288    executed = no
27289
272901986\. What a great season.
27291           executed = yes
27292
27293and test...
27294
27295    test "should ignore indented code in escaped list like number", ->
27296      eq executed, no
27297      testsCount++
27298
27299one last test!
27300
27301    test "block quotes should render correctly", ->
27302      quote = '''
27303        foo
27304           and bar!
27305      '''
27306      eq quote, 'foo\n   and bar!'
27307      testsCount++
27308
27309and finally, how did we do?
27310
27311    test "all spaced literate CoffeeScript tests executed", ->
27312      eq testsCount, 9
27313
27314</script>
vendor: 1 bytes, line 27314
27314
27315<script type="text/x-literate-coffeescript" class="test" id="literate_tabbed">
27316# Tabbed Literate CoffeeScript Test
27317
27318comment comment
27319
27320	testsCount = 0 # Track the number of tests run in this file, to make sure they all run
27321
27322	test "basic literate CoffeeScript parsing", ->
27323		ok yes
27324		testsCount++
27325
27326now with a...
27327
27328	test "broken up indentation", ->
27329
27330... broken up ...
27331
27332		do ->
27333
27334... nested block.
27335
27336			ok yes
27337			testsCount++
27338
27339Code must be separated from text by a blank line.
27340
27341	test "code blocks must be preceded by a blank line", ->
27342
27343The next line is part of the text and will not be executed.
27344    fail()
27345
27346		ok yes
27347		testsCount++
27348
27349Code in `backticks is not parsed` and...
27350
27351	test "comments in indented blocks work", ->
27352		do ->
27353			do ->
27354				# Regular comment.
27355
27356				###
27357					Block comment.
27358				###
27359
27360				ok yes
27361				testsCount++
27362
27363Regular [Markdown](http://example.com/markdown) features, like links
27364and unordered lists, are fine:
27365
27366  * I
27367
27368  * Am
27369
27370  * A
27371
27372  * List
27373
27374---
27375
27376	# keep track of whether code blocks are executed or not
27377	executed = false
27378
27379<p>
27380
27381if true
27382	executed = true # should not execute, this is just HTML para, not code!
27383
27384</p>
27385
27386	test "should ignore code blocks inside HTML", ->
27387		eq executed, false
27388		testsCount++
27389
27390---
27391
27392*   A list item followed by a code block:
27393
27394	test "basic literate CoffeeScript parsing", ->
27395		ok yes
27396		testsCount++
27397
27398---
27399
27400*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
27401    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
27402    viverra nec, fringilla in, laoreet vitae, risus.
27403
27404*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
27405    Suspendisse id sem consectetuer libero luctus adipiscing.
27406
27407---
27408
27409This is [an example][id] reference-style link.
27410[id]: http://example.com/  "Optional Title Here"
27411
27412---
27413
27414	executed = no
27415
274161986. What a great season.
27417
27418	executed = yes
27419
27420and test...
27421
27422	test "should recognize indented code blocks in lists with empty line as separator", ->
27423		ok executed
27424		testsCount++
27425
27426---
27427
27428	executed = no
27429
274301986\. What a great season.
27431				executed = yes
27432
27433and test...
27434
27435	test "should ignore indented code in escaped list like number", ->
27436		eq executed, no
27437		testsCount++
27438
27439one last test!
27440
27441	test "block quotes should render correctly", ->
27442		quote = '''
27443			foo
27444					and bar!
27445		'''
27446		eq quote, 'foo\n\t\tand bar!'
27447		testsCount++
27448
27449and finally, how did we do?
27450
27451	test "all tabbed literate CoffeeScript tests executed", ->
27452		eq testsCount, 9
27453
27454</script>
vendor: 1 bytes, line 27454
27454
27455<script type="text/x-coffeescript" class="test" id="location">
27456testScript = '''
27457if true
27458  x = 6
27459  console.log "A console #{x + 7} log"
27460
27461foo = "bar"
27462z = /// ^ (a#{foo}) ///
27463
27464x = () ->
27465    try
27466        console.log "foo"
27467    catch err
27468        # Rewriter will generate explicit indentation here.
27469
27470    return null
27471'''
27472
27473test "Verify location of generated tokens", ->
27474  tokens = CoffeeScript.tokens "a = 79"
27475
27476  eq tokens.length, 4
27477  [aToken, equalsToken, numberToken] = tokens
27478
27479  eq aToken[2].first_line, 0
27480  eq aToken[2].first_column, 0
27481  eq aToken[2].last_line, 0
27482  eq aToken[2].last_column, 0
27483
27484  eq equalsToken[2].first_line, 0
27485  eq equalsToken[2].first_column, 2
27486  eq equalsToken[2].last_line, 0
27487  eq equalsToken[2].last_column, 2
27488
27489  eq numberToken[2].first_line, 0
27490  eq numberToken[2].first_column, 4
27491  eq numberToken[2].last_line, 0
27492  eq numberToken[2].last_column, 5
27493
27494test "Verify location of generated tokens (with indented first line)", ->
27495  tokens = CoffeeScript.tokens "  a = 83"
27496
27497  eq tokens.length, 4
27498  [aToken, equalsToken, numberToken] = tokens
27499
27500  eq aToken[2].first_line, 0
27501  eq aToken[2].first_column, 2
27502  eq aToken[2].last_line, 0
27503  eq aToken[2].last_column, 2
27504  eq aToken[2].range[0], 2
27505  eq aToken[2].range[1], 3
27506
27507  eq equalsToken[2].first_line, 0
27508  eq equalsToken[2].first_column, 4
27509  eq equalsToken[2].last_line, 0
27510  eq equalsToken[2].last_column, 4
27511
27512  eq numberToken[2].first_line, 0
27513  eq numberToken[2].first_column, 6
27514  eq numberToken[2].last_line, 0
27515  eq numberToken[2].last_column, 7
27516
27517getMatchingTokens = (str, wantedTokens...) ->
27518  tokens = CoffeeScript.tokens str
27519  matchingTokens = []
27520  i = 0
27521  for token in tokens
27522    if token[1].replace(/^'|'$/g, '"') is wantedTokens[i]
27523      i++
27524      matchingTokens.push token
27525  eq wantedTokens.length, matchingTokens.length
27526  matchingTokens
27527
27528test 'Verify locations in string interpolation (in "string")', ->
27529  [a, b, c] = getMatchingTokens '"a#{b}c"', '"a"', 'b', '"c"'
27530
27531  eq a[2].first_line, 0
27532  eq a[2].first_column, 1
27533  eq a[2].last_line, 0
27534  eq a[2].last_column, 1
27535
27536  eq b[2].first_line, 0
27537  eq b[2].first_column, 4
27538  eq b[2].last_line, 0
27539  eq b[2].last_column, 4
27540
27541  eq c[2].first_line, 0
27542  eq c[2].first_column, 6
27543  eq c[2].last_line, 0
27544  eq c[2].last_column, 6
27545
27546test 'Verify locations in string interpolation (in "string", multiple interpolation)', ->
27547  [a, b, c] = getMatchingTokens '"#{a}b#{c}"', 'a', '"b"', 'c'
27548
27549  eq a[2].first_line, 0
27550  eq a[2].first_column, 3
27551  eq a[2].last_line, 0
27552  eq a[2].last_column, 3
27553
27554  eq b[2].first_line, 0
27555  eq b[2].first_column, 5
27556  eq b[2].last_line, 0
27557  eq b[2].last_column, 5
27558
27559  eq c[2].first_line, 0
27560  eq c[2].first_column, 8
27561  eq c[2].last_line, 0
27562  eq c[2].last_column, 8
27563
27564test 'Verify locations in string interpolation (in "string", multiple interpolation and line breaks)', ->
27565  [a, b, c] = getMatchingTokens '"#{a}\nb\n#{c}"', 'a', '"\nb\n"', 'c'
27566
27567  eq a[2].first_line, 0
27568  eq a[2].first_column, 3
27569  eq a[2].last_line, 0
27570  eq a[2].last_column, 3
27571
27572  eq b[2].first_line, 0
27573  eq b[2].first_column, 5
27574  eq b[2].last_line, 1
27575  eq b[2].last_column, 1
27576
27577  eq c[2].first_line, 2
27578  eq c[2].first_column, 2
27579  eq c[2].last_line, 2
27580  eq c[2].last_column, 2
27581
27582test 'Verify locations in string interpolation (in "string", multiple interpolation and starting with line breaks)', ->
27583  [a, b, c] = getMatchingTokens '"\n#{a}\nb\n#{c}"', 'a', '"\nb\n"', 'c'
27584
27585  eq a[2].first_line, 1
27586  eq a[2].first_column, 2
27587  eq a[2].last_line, 1
27588  eq a[2].last_column, 2
27589
27590  eq b[2].first_line, 1
27591  eq b[2].first_column, 4
27592  eq b[2].last_line, 2
27593  eq b[2].last_column, 1
27594
27595  eq c[2].first_line, 3
27596  eq c[2].first_column, 2
27597  eq c[2].last_line, 3
27598  eq c[2].last_column, 2
27599
27600test 'Verify locations in string interpolation (in "string", multiple interpolation and starting with line breaks)', ->
27601  [a, b, c] = getMatchingTokens '"\n\n#{a}\n\nb\n\n#{c}"', 'a', '"\n\nb\n\n"', 'c'
27602
27603  eq a[2].first_line, 2
27604  eq a[2].first_column, 2
27605  eq a[2].last_line, 2
27606  eq a[2].last_column, 2
27607
27608  eq b[2].first_line, 2
27609  eq b[2].first_column, 4
27610  eq b[2].last_line, 5
27611  eq b[2].last_column, 0
27612
27613  eq c[2].first_line, 6
27614  eq c[2].first_column, 2
27615  eq c[2].last_line, 6
27616  eq c[2].last_column, 2
27617
27618test 'Verify locations in string interpolation (in "string", multiple interpolation and starting with line breaks)', ->
27619  [a, b, c] = getMatchingTokens '"\n\n\n#{a}\n\n\nb\n\n\n#{c}"', 'a', '"\n\n\nb\n\n\n"', 'c'
27620
27621  eq a[2].first_line, 3
27622  eq a[2].first_column, 2
27623  eq a[2].last_line, 3
27624  eq a[2].last_column, 2
27625
27626  eq b[2].first_line, 3
27627  eq b[2].first_column, 4
27628  eq b[2].last_line, 8
27629  eq b[2].last_column, 0
27630
27631  eq c[2].first_line, 9
27632  eq c[2].first_column, 2
27633  eq c[2].last_line, 9
27634  eq c[2].last_column, 2
27635
27636test 'Verify locations in string interpolation (in """string""", line breaks)', ->
27637  [a, b, c] = getMatchingTokens '"""a\n#{b}\nc"""', '"a\n"', 'b', '"\nc"'
27638
27639  eq a[2].first_line, 0
27640  eq a[2].first_column, 3
27641  eq a[2].last_line, 0
27642  eq a[2].last_column, 4
27643
27644  eq b[2].first_line, 1
27645  eq b[2].first_column, 2
27646  eq b[2].last_line, 1
27647  eq b[2].last_column, 2
27648
27649  eq c[2].first_line, 1
27650  eq c[2].first_column, 4
27651  eq c[2].last_line, 2
27652  eq c[2].last_column, 0
27653
27654test 'Verify locations in string interpolation (in """string""", starting with a line break)', ->
27655  [b, c] = getMatchingTokens '"""\n#{b}\nc"""', 'b', '"\nc"'
27656
27657  eq b[2].first_line, 1
27658  eq b[2].first_column, 2
27659  eq b[2].last_line, 1
27660  eq b[2].last_column, 2
27661
27662  eq c[2].first_line, 1
27663  eq c[2].first_column, 4
27664  eq c[2].last_line, 2
27665  eq c[2].last_column, 0
27666
27667test 'Verify locations in string interpolation (in """string""", starting with line breaks)', ->
27668  [a, b, c] = getMatchingTokens '"""\n\n#{b}\nc"""', '"\n\n"', 'b', '"\nc"'
27669
27670  eq a[2].first_line, 0
27671  eq a[2].first_column, 3
27672  eq a[2].last_line, 1
27673  eq a[2].last_column, 0
27674
27675  eq b[2].first_line, 2
27676  eq b[2].first_column, 2
27677  eq b[2].last_line, 2
27678  eq b[2].last_column, 2
27679
27680  eq c[2].first_line, 2
27681  eq c[2].first_column, 4
27682  eq c[2].last_line, 3
27683  eq c[2].last_column, 0
27684
27685test 'Verify locations in string interpolation (in """string""", multiple interpolation)', ->
27686  [a, b, c] = getMatchingTokens '"""#{a}\nb\n#{c}"""', 'a', '"\nb\n"', 'c'
27687
27688  eq a[2].first_line, 0
27689  eq a[2].first_column, 5
27690  eq a[2].last_line, 0
27691  eq a[2].last_column, 5
27692
27693  eq b[2].first_line, 0
27694  eq b[2].first_column, 7
27695  eq b[2].last_line, 1
27696  eq b[2].last_column, 1
27697
27698  eq c[2].first_line, 2
27699  eq c[2].first_column, 2
27700  eq c[2].last_line, 2
27701  eq c[2].last_column, 2
27702
27703test 'Verify locations in string interpolation (in """string""", multiple interpolation, and starting with line breaks)', ->
27704  [a, b, c] = getMatchingTokens '"""\n\n#{a}\n\nb\n\n#{c}"""', 'a', '"\n\nb\n\n"', 'c'
27705
27706  eq a[2].first_line, 2
27707  eq a[2].first_column, 2
27708  eq a[2].last_line, 2
27709  eq a[2].last_column, 2
27710
27711  eq b[2].first_line, 2
27712  eq b[2].first_column, 4
27713  eq b[2].last_line, 5
27714  eq b[2].last_column, 0
27715
27716  eq c[2].first_line, 6
27717  eq c[2].first_column, 2
27718  eq c[2].last_line, 6
27719  eq c[2].last_column, 2
27720
27721test 'Verify locations in string interpolation (in """string""", multiple interpolation, and starting with line breaks)', ->
27722  [a, b, c] = getMatchingTokens '"""\n\n\n#{a}\n\n\nb\n\n\n#{c}"""', 'a', '"\n\n\nb\n\n\n"', 'c'
27723
27724  eq a[2].first_line, 3
27725  eq a[2].first_column, 2
27726  eq a[2].last_line, 3
27727  eq a[2].last_column, 2
27728
27729  eq b[2].first_line, 3
27730  eq b[2].first_column, 4
27731  eq b[2].last_line, 8
27732  eq b[2].last_column, 0
27733
27734  eq c[2].first_line, 9
27735  eq c[2].first_column, 2
27736  eq c[2].last_line, 9
27737  eq c[2].last_column, 2
27738
27739test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation)', ->
27740  [a, b, c] = getMatchingTokens '///#{a}b#{c}///', 'a', '"b"', 'c'
27741
27742  eq a[2].first_line, 0
27743  eq a[2].first_column, 5
27744  eq a[2].last_line, 0
27745  eq a[2].last_column, 5
27746
27747  eq b[2].first_line, 0
27748  eq b[2].first_column, 7
27749  eq b[2].last_line, 0
27750  eq b[2].last_column, 7
27751
27752  eq c[2].first_line, 0
27753  eq c[2].first_column, 10
27754  eq c[2].last_line, 0
27755  eq c[2].last_column, 10
27756
27757test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation)', ->
27758  [a, b, c] = getMatchingTokens '///a#{b}c///', '"a"', 'b', '"c"'
27759
27760  eq a[2].first_line, 0
27761  eq a[2].first_column, 3
27762  eq a[2].last_line, 0
27763  eq a[2].last_column, 3
27764
27765  eq b[2].first_line, 0
27766  eq b[2].first_column, 6
27767  eq b[2].last_line, 0
27768  eq b[2].last_column, 6
27769
27770  eq c[2].first_line, 0
27771  eq c[2].first_column, 8
27772  eq c[2].last_line, 0
27773  eq c[2].last_column, 8
27774
27775test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation and line breaks)', ->
27776  [a, b, c] = getMatchingTokens '///#{a}\nb\n#{c}///', 'a', '"\nb\n"', 'c'
27777
27778  eq a[2].first_line, 0
27779  eq a[2].first_column, 5
27780  eq a[2].last_line, 0
27781  eq a[2].last_column, 5
27782
27783  eq b[2].first_line, 0
27784  eq b[2].first_column, 7
27785  eq b[2].last_line, 1
27786  eq b[2].last_column, 1
27787
27788  eq c[2].first_line, 2
27789  eq c[2].first_column, 2
27790  eq c[2].last_line, 2
27791  eq c[2].last_column, 2
27792
27793test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation and line breaks)', ->
27794  [a, b, c] = getMatchingTokens '///#{a}\n\n\nb\n\n\n#{c}///', 'a', '"\n\n\nb\n\n\n"', 'c'
27795
27796  eq a[2].first_line, 0
27797  eq a[2].first_column, 5
27798  eq a[2].last_line, 0
27799  eq a[2].last_column, 5
27800
27801  eq b[2].first_line, 0
27802  eq b[2].first_column, 7
27803  eq b[2].last_line, 5
27804  eq b[2].last_column, 0
27805
27806  eq c[2].first_line, 6
27807  eq c[2].first_column, 2
27808  eq c[2].last_line, 6
27809  eq c[2].last_column, 2
27810
27811test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation and line breaks)', ->
27812  [a, b, c] = getMatchingTokens '///a\n\n\n#{b}\n\n\nc///', '"a\n\n\n"', 'b', '"\n\n\nc"'
27813
27814  eq a[2].first_line, 0
27815  eq a[2].first_column, 3
27816  eq a[2].last_line, 2
27817  eq a[2].last_column, 0
27818
27819  eq b[2].first_line, 3
27820  eq b[2].first_column, 2
27821  eq b[2].last_line, 3
27822  eq b[2].last_column, 2
27823
27824  eq c[2].first_line, 3
27825  eq c[2].first_column, 4
27826  eq c[2].last_line, 6
27827  eq c[2].last_column, 0
27828
27829test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation and line breaks and starting with linebreak)', ->
27830  [a, b, c] = getMatchingTokens '///\n#{a}\nb\n#{c}///', 'a', '"\nb\n"', 'c'
27831
27832  eq a[2].first_line, 1
27833  eq a[2].first_column, 2
27834  eq a[2].last_line, 1
27835  eq a[2].last_column, 2
27836
27837  eq b[2].first_line, 1
27838  eq b[2].first_column, 4
27839  eq b[2].last_line, 2
27840  eq b[2].last_column, 1
27841
27842  eq c[2].first_line, 3
27843  eq c[2].first_column, 2
27844  eq c[2].last_line, 3
27845  eq c[2].last_column, 2
27846
27847test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation and line breaks and starting with linebreak)', ->
27848  [a, b, c] = getMatchingTokens '///\n\n\n#{a}\n\n\nb\n\n\n#{c}///', 'a', '"\n\n\nb\n\n\n"', 'c'
27849
27850  eq a[2].first_line, 3
27851  eq a[2].first_column, 2
27852  eq a[2].last_line, 3
27853  eq a[2].last_column, 2
27854
27855  eq b[2].first_line, 3
27856  eq b[2].first_column, 4
27857  eq b[2].last_line, 8
27858  eq b[2].last_column, 0
27859
27860  eq c[2].first_line, 9
27861  eq c[2].first_column, 2
27862  eq c[2].last_line, 9
27863  eq c[2].last_column, 2
27864
27865test 'Verify locations in heregex interpolation (in ///regex///, multiple interpolation and line breaks and starting with linebreak)', ->
27866  [a, b, c] = getMatchingTokens '///\n\n\na\n\n\n#{b}\n\n\nc///', '"\n\n\na\n\n\n"', 'b', '"\n\n\nc"'
27867
27868  eq a[2].first_line, 0
27869  eq a[2].first_column, 3
27870  eq a[2].last_line, 5
27871  eq a[2].last_column, 0
27872
27873  eq b[2].first_line, 6
27874  eq b[2].first_column, 2
27875  eq b[2].last_line, 6
27876  eq b[2].last_column, 2
27877
27878  eq c[2].first_line, 6
27879  eq c[2].first_column, 4
27880  eq c[2].last_line, 9
27881  eq c[2].last_column, 0
27882
27883test "#3822: Simple string/regex start/end should include delimiters", ->
27884  [stringToken] = CoffeeScript.tokens "'string'"
27885  eq stringToken[2].first_line, 0
27886  eq stringToken[2].first_column, 0
27887  eq stringToken[2].last_line, 0
27888  eq stringToken[2].last_column, 7
27889
27890  [regexToken] = CoffeeScript.tokens "/regex/"
27891  eq regexToken[2].first_line, 0
27892  eq regexToken[2].first_column, 0
27893  eq regexToken[2].last_line, 0
27894  eq regexToken[2].last_column, 6
27895
27896test "#3621: Multiline regex and manual `Regex` call with interpolation should
27897      result in the same tokens", ->
27898  tokensA = CoffeeScript.tokens '(RegExp(".*#{a}[0-9]"))'
27899  tokensB = CoffeeScript.tokens '///.*#{a}[0-9]///'
27900  eq tokensA.length, tokensB.length
27901  for i in [0...tokensA.length] by 1
27902    tokenA = tokensA[i]
27903    tokenB = tokensB[i]
27904    eq tokenA[0], tokenB[0] unless tokenB[0] in ['REGEX_START', 'REGEX_END']
27905    eq "#{tokenA[1]}", "#{tokenB[1]}"
27906    unless tokenA[0] is 'STRING_START' or tokenB[0] is 'REGEX_START'
27907      eq tokenA.origin?[1], tokenB.origin?[1]
27908    eq tokenA.stringEnd, tokenB.stringEnd
27909
27910test "Verify tokens have locations that are in order", ->
27911  source = '''
27912    a {
27913      b: ->
27914        return c d,
27915          if e
27916            f
27917    }
27918    g
27919  '''
27920  tokens = CoffeeScript.tokens source
27921  lastToken = null
27922  for token in tokens
27923    if lastToken
27924      ok token[2].first_line >= lastToken[2].last_line
27925      if token[2].first_line == lastToken[2].last_line
27926        ok token[2].first_column >= lastToken[2].last_column
27927    lastToken = token
27928
27929test "Verify OUTDENT tokens are located at the end of the previous token", ->
27930  source = '''
27931    SomeArr = [ ->
27932      if something
27933        lol =
27934          count: 500
27935    ]
27936  '''
27937  tokens = CoffeeScript.tokens source
27938  [..., number, curly, outdent1, outdent2, outdent3, bracket, terminator] = tokens
27939  eq number[0], 'NUMBER'
27940  for outdent in [outdent1, outdent2, outdent3]
27941    eq outdent[0], 'OUTDENT'
27942    eq outdent[2].first_line, number[2].last_line
27943    eq outdent[2].first_column, number[2].last_column
27944    eq outdent[2].last_line, number[2].last_line
27945    eq outdent[2].last_column, number[2].last_column
27946
27947test "Verify OUTDENT and CALL_END tokens are located at the end of the previous token", ->
27948  source = '''
27949    a = b {
27950      c: ->
27951        d e,
27952          if f
27953            g {},
27954              if h
27955                i {}
27956    }
27957  '''
27958  tokens = CoffeeScript.tokens source
27959  [..., closeCurly1, callEnd1, outdent1, outdent2, callEnd2, outdent3, outdent4,
27960    callEnd3, outdent5, outdent6, closeCurly2, callEnd4, terminator] = tokens
27961  eq closeCurly1[0], '}'
27962  assertAtCloseCurly = (token) ->
27963    eq token[2].first_line, closeCurly1[2].last_line
27964    eq token[2].first_column, closeCurly1[2].last_column
27965    eq token[2].last_line, closeCurly1[2].last_line
27966    eq token[2].last_column, closeCurly1[2].last_column
27967
27968  for token in [outdent1, outdent2, outdent3, outdent4, outdent5, outdent6]
27969    eq token[0], 'OUTDENT'
27970    assertAtCloseCurly(token)
27971  for token in [callEnd1, callEnd2, callEnd3]
27972    eq token[0], 'CALL_END'
27973    assertAtCloseCurly(token)
27974
27975test "Verify generated } tokens are located at the end of the previous token", ->
27976  source = '''
27977    a(b, ->
27978      c: () ->
27979        if d
27980          e
27981    )
27982  '''
27983  tokens = CoffeeScript.tokens source
27984  [..., identifier, outdent1, outdent2, closeCurly, outdent3, callEnd,
27985    terminator] = tokens
27986  eq identifier[0], 'IDENTIFIER'
27987  assertAtIdentifier = (token) ->
27988    eq token[2].first_line, identifier[2].last_line
27989    eq token[2].first_column, identifier[2].last_column
27990    eq token[2].last_line, identifier[2].last_line
27991    eq token[2].last_column, identifier[2].last_column
27992
27993  for token in [outdent1, outdent2, closeCurly, outdent3]
27994    assertAtIdentifier(token)
27995
27996test "Verify real CALL_END tokens have the right position", ->
27997  source = '''
27998    a()
27999  '''
28000  tokens = CoffeeScript.tokens source
28001  [identifier, callStart, callEnd, terminator] = tokens
28002  startIndex = identifier[2].first_column
28003  eq identifier[2].last_column, startIndex
28004  eq callStart[2].first_column, startIndex + 1
28005  eq callStart[2].last_column, startIndex + 1
28006  eq callEnd[2].first_column, startIndex + 2
28007  eq callEnd[2].last_column, startIndex + 2
28008
28009test "Verify normal heredocs have the right position", ->
28010  source = '''
28011    """
28012    a"""
28013  '''
28014  [stringToken] = CoffeeScript.tokens source
28015  eq stringToken[2].first_line, 0
28016  eq stringToken[2].first_column, 0
28017  eq stringToken[2].last_line, 1
28018  eq stringToken[2].last_column, 3
28019
28020test "Verify heredocs ending with a newline have the right position", ->
28021  source = '''
28022    """
28023    a
28024    """
28025  '''
28026  [stringToken] = CoffeeScript.tokens source
28027  eq stringToken[2].first_line, 0
28028  eq stringToken[2].first_column, 0
28029  eq stringToken[2].last_line, 2
28030  eq stringToken[2].last_column, 2
28031
28032test "Verify indented heredocs have the right position", ->
28033  source = '''
28034    ->
28035      """
28036        a
28037      """
28038  '''
28039  [arrow, indent, stringToken] = CoffeeScript.tokens source
28040  eq stringToken[2].first_line, 1
28041  eq stringToken[2].first_column, 2
28042  eq stringToken[2].last_line, 3
28043  eq stringToken[2].last_column, 4
28044
28045test "Verify heregexes with interpolations have the right ending position", ->
28046  source = '''
28047    [a ///#{b}///g]
28048  '''
28049  [..., stringEnd, comma, flagsString, regexCallEnd, regexEnd, fnCallEnd,
28050    arrayEnd, terminator] = CoffeeScript.tokens source
28051
28052  eq comma[0], ','
28053  eq arrayEnd[0], ']'
28054
28055  assertColumn = (token, column, width = 0) ->
28056    eq token[2].first_line, 0
28057    eq token[2].first_column, column
28058    eq token[2].last_line, 0
28059    eq token[2].last_column, column
28060    eq token[2].last_column_exclusive, column + width
28061
28062  arrayEndColumn = arrayEnd[2].first_column
28063  for token in [comma]
28064    assertColumn token, arrayEndColumn - 2
28065  for token in [flagsString, regexCallEnd]
28066    assertColumn token, arrayEndColumn - 1, 1
28067  for token in [regexEnd, fnCallEnd]
28068    assertColumn token, arrayEndColumn
28069  assertColumn arrayEnd, arrayEndColumn, 1
28070
28071test "Verify all tokens get a location", ->
28072  doesNotThrow ->
28073    tokens = CoffeeScript.tokens testScript
28074    for token in tokens
28075        ok !!token[2]
28076
28077test 'Values with properties end up with a location that includes the properties', ->
28078  source = '''
28079    a.b
28080    a.b.c
28081    a['b']
28082    a[b.c()].d
28083  '''
28084  {body: block} = CoffeeScript.nodes source
28085  [
28086    singleProperty
28087    twoProperties
28088    indexed
28089    complexIndex
28090  ] = block.expressions
28091
28092  eq singleProperty.locationData.first_line, 0
28093  eq singleProperty.locationData.first_column, 0
28094  eq singleProperty.locationData.last_line, 0
28095  eq singleProperty.locationData.last_column, 2
28096
28097  eq twoProperties.locationData.first_line, 1
28098  eq twoProperties.locationData.first_column, 0
28099  eq twoProperties.locationData.last_line, 1
28100  eq twoProperties.locationData.last_column, 4
28101
28102  eq indexed.locationData.first_line, 2
28103  eq indexed.locationData.first_column, 0
28104  eq indexed.locationData.last_line, 2
28105  eq indexed.locationData.last_column, 5
28106
28107  eq complexIndex.locationData.first_line, 3
28108  eq complexIndex.locationData.first_column, 0
28109  eq complexIndex.locationData.last_line, 3
28110  eq complexIndex.locationData.last_column, 9
28111
28112test 'StringWithInterpolations::fromStringLiteral() assigns correct location to tagged template literal', ->
28113  checkLocationData = (source, {stringWithInterpolationsLocationData, stringLocationData}) ->
28114    {body: block} = CoffeeScript.nodes source
28115    taggedTemplateLiteral = block.expressions[0].unwrap()
28116    {args: [stringWithInterpolations]} = taggedTemplateLiteral
28117    {body} = stringWithInterpolations
28118    {expressions: [stringValue]} = body
28119    string = stringValue.unwrap()
28120
28121    for field in ['first_line', 'first_column', 'last_line', 'last_column', 'last_line_exclusive', 'last_column_exclusive']
28122      eq stringWithInterpolations.locationData[field], stringWithInterpolationsLocationData[field]
28123      eq stringValue.locationData[field], stringLocationData[field]
28124      eq string.locationData[field], stringLocationData[field]
28125
28126  checkLocationData 'a"b"',
28127    stringWithInterpolationsLocationData:
28128      first_line: 0
28129      first_column: 1
28130      last_line: 0
28131      last_column: 3
28132      last_line_exclusive: 0
28133      last_column_exclusive: 4
28134    stringLocationData:
28135      first_line: 0
28136      first_column: 2
28137      last_line: 0
28138      last_column: 2
28139      last_line_exclusive: 0
28140      last_column_exclusive: 3
28141
28142  checkLocationData '''
28143    a"""
28144      b
28145    """
28146  ''',
28147    stringWithInterpolationsLocationData:
28148      first_line: 0
28149      first_column: 1
28150      last_line: 2
28151      last_column: 2
28152      last_line_exclusive: 2
28153      last_column_exclusive: 3
28154    stringLocationData:
28155      first_line: 0
28156      first_column: 4
28157      last_line: 1
28158      last_column: 3
28159      last_line_exclusive: 2
28160      last_column_exclusive: 0
28161
28162  checkLocationData '''
28163    a"""b
28164    """
28165  ''',
28166    stringWithInterpolationsLocationData:
28167      first_line: 0
28168      first_column: 1
28169      last_line: 1
28170      last_column: 2
28171      last_line_exclusive: 1
28172      last_column_exclusive: 3
28173    stringLocationData:
28174      first_line: 0
28175      first_column: 4
28176      last_line: 0
28177      last_column: 5
28178      last_line_exclusive: 1
28179      last_column_exclusive: 0
28180
28181test "Verify compound assignment operators have the right position", ->
28182  source = '''
28183    a or= b
28184  '''
28185  [a, operatorToken] = CoffeeScript.tokens source
28186  eq operatorToken[2].first_line, 0
28187  eq operatorToken[2].first_column, 2
28188  eq operatorToken[2].last_line, 0
28189  eq operatorToken[2].last_column, 4
28190  eq operatorToken[2].last_column_exclusive, 5
28191  eq operatorToken[2].range[0], 2
28192  eq operatorToken[2].range[1], 5
28193
28194  source = '''
28195    a and= b
28196  '''
28197  [a, operatorToken] = CoffeeScript.tokens source
28198  eq operatorToken[2].first_line, 0
28199  eq operatorToken[2].first_column, 2
28200  eq operatorToken[2].last_line, 0
28201  eq operatorToken[2].last_column, 5
28202  eq operatorToken[2].last_column_exclusive, 6
28203  eq operatorToken[2].range[0], 2
28204  eq operatorToken[2].range[1], 6
28205
28206test "Verify BOM is accounted for in location data", ->
28207  source = '''
28208    \ufeffa
28209    b
28210  '''
28211  [aToken, terminator, bToken] = CoffeeScript.tokens source
28212  eq aToken[2].first_line, 0
28213  eq aToken[2].first_column, 1
28214  eq aToken[2].last_line, 0
28215  eq aToken[2].last_column, 1
28216  eq aToken[2].last_column_exclusive, 2
28217  eq aToken[2].range[0], 1
28218  eq aToken[2].range[1], 2
28219  eq bToken[2].first_line, 1
28220  eq bToken[2].first_column, 0
28221  eq bToken[2].last_line, 1
28222  eq bToken[2].last_column, 0
28223  eq bToken[2].last_column_exclusive, 1
28224  eq bToken[2].range[0], 3
28225  eq bToken[2].range[1], 4
28226
28227test "Verify carriage returns are accounted for in location data", ->
28228  source = '''
28229    a\r+
28230    b\r\r- c
28231  '''
28232  [aToken, plusToken, bToken, minusToken] = CoffeeScript.tokens source
28233  eq aToken[2].first_line, 0
28234  eq aToken[2].first_column, 0
28235  eq aToken[2].last_line, 0
28236  eq aToken[2].last_column, 0
28237  eq aToken[2].last_column_exclusive, 1
28238  eq aToken[2].range[0], 0
28239  eq aToken[2].range[1], 1
28240  eq plusToken[2].first_line, 0
28241  eq plusToken[2].first_column, 2
28242  eq plusToken[2].last_line, 0
28243  eq plusToken[2].last_column, 2
28244  eq plusToken[2].last_column_exclusive, 3
28245  eq plusToken[2].range[0], 2
28246  eq plusToken[2].range[1], 3
28247  eq bToken[2].first_line, 1
28248  eq bToken[2].first_column, 0
28249  eq bToken[2].last_line, 1
28250  eq bToken[2].last_column, 0
28251  eq bToken[2].last_column_exclusive, 1
28252  eq bToken[2].range[0], 4
28253  eq bToken[2].range[1], 5
28254  eq minusToken[2].first_line, 1
28255  eq minusToken[2].first_column, 3
28256  eq minusToken[2].last_line, 1
28257  eq minusToken[2].last_column, 3
28258  eq minusToken[2].last_column_exclusive, 4
28259  eq minusToken[2].range[0], 7
28260  eq minusToken[2].range[1], 8
28261
28262test "Verify object colon location data", ->
28263  source = '''
28264    a : b
28265  '''
28266  [implicitBraceToken, aToken, colonToken] = CoffeeScript.tokens source
28267  eq colonToken[2].first_line, 0
28268  eq colonToken[2].first_column, 2
28269  eq colonToken[2].last_line, 0
28270  eq colonToken[2].last_column, 2
28271  eq colonToken[2].last_column_exclusive, 3
28272  eq colonToken[2].range[0], 2
28273  eq colonToken[2].range[1], 3
28274
28275</script>
vendor: 1 bytes, line 28275
28275
28276<script type="text/x-coffeescript" class="test" id="modules">
28277# Modules, a.k.a. ES2015 import/export
28278# ------------------------------------
28279#
28280# Remember, we’re not *resolving* modules, just outputting valid ES2015 syntax.
28281
28282
28283# This is the CoffeeScript import and export syntax, closely modeled after the ES2015 syntax
28284# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
28285# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
28286
28287# import "module-name"
28288# import defaultMember from "module-name"
28289# import * as name from "module-name"
28290# import { } from "module-name"
28291# import { member } from "module-name"
28292# import { member as alias } from "module-name"
28293# import { member1, member2 as alias2, … } from "module-name"
28294# import defaultMember, * as name from "module-name"
28295# import defaultMember, { … } from "module-name"
28296
28297# export default expression
28298# export class name
28299# export { }
28300# export { name }
28301# export { name as exportedName }
28302# export { name as default }
28303# export { name1, name2 as exportedName2, name3 as default, … }
28304#
28305# export * from "module-name"
28306# export { … } from "module-name"
28307#
28308# As a subsitute for `export var name = …` and `export function name {}`,
28309# CoffeeScript also supports:
28310# export name = …
28311
28312# CoffeeScript also supports optional commas within `{ … }`.
28313
28314
28315# Import statements
28316
28317test "backticked import statement", ->
28318  eqJS """
28319    if Meteor.isServer
28320      `import { foo, bar as baz } from 'lib'`""",
28321  """
28322    if (Meteor.isServer) {
28323      import { foo, bar as baz } from 'lib';
28324    }"""
28325
28326test "import an entire module for side effects only, without importing any bindings", ->
28327  eqJS "import 'lib'",
28328  "import 'lib';"
28329
28330test "import default member from module, adding the member to the current scope", ->
28331  eqJS """
28332    import foo from 'lib'
28333    foo.fooMethod()""",
28334  """
28335    import foo from 'lib';
28336
28337    foo.fooMethod();"""
28338
28339test "import an entire module's contents as an alias, adding the alias to the current scope", ->
28340  eqJS """
28341    import * as foo from 'lib'
28342    foo.fooMethod()""",
28343  """
28344    import * as foo from 'lib';
28345
28346    foo.fooMethod();"""
28347
28348test "import empty object", ->
28349  eqJS "import { } from 'lib'",
28350  "import {} from 'lib';"
28351
28352test "import empty object", ->
28353  eqJS "import {} from 'lib'",
28354  "import {} from 'lib';"
28355
28356test "import a single member of a module, adding the member to the current scope", ->
28357  eqJS """
28358    import { foo } from 'lib'
28359    foo.fooMethod()""",
28360  """
28361    import {
28362      foo
28363    } from 'lib';
28364
28365    foo.fooMethod();"""
28366
28367test "import a single member of a module as an alias, adding the alias to the current scope", ->
28368  eqJS """
28369    import { foo as bar } from 'lib'
28370    bar.barMethod()""",
28371  """
28372    import {
28373      foo as bar
28374    } from 'lib';
28375
28376    bar.barMethod();"""
28377
28378test "import multiple members of a module, adding the members to the current scope", ->
28379  eqJS """
28380    import { foo, bar } from 'lib'
28381    foo.fooMethod()
28382    bar.barMethod()""",
28383  """
28384    import {
28385      foo,
28386      bar
28387    } from 'lib';
28388
28389    foo.fooMethod();
28390
28391    bar.barMethod();"""
28392
28393test "import multiple members of a module where some are aliased, adding the members or aliases to the current scope", ->
28394  eqJS """
28395    import { foo, bar as baz } from 'lib'
28396    foo.fooMethod()
28397    baz.bazMethod()""",
28398  """
28399    import {
28400      foo,
28401      bar as baz
28402    } from 'lib';
28403
28404    foo.fooMethod();
28405
28406    baz.bazMethod();"""
28407
28408test "import default member and other members of a module, adding the members to the current scope", ->
28409  eqJS """
28410    import foo, { bar, baz as qux } from 'lib'
28411    foo.fooMethod()
28412    bar.barMethod()
28413    qux.quxMethod()""",
28414  """
28415    import foo, {
28416      bar,
28417      baz as qux
28418    } from 'lib';
28419
28420    foo.fooMethod();
28421
28422    bar.barMethod();
28423
28424    qux.quxMethod();"""
28425
28426test "import default member from a module as well as the entire module's contents as an alias, adding the member and alias to the current scope", ->
28427  eqJS """
28428    import foo, * as bar from 'lib'
28429    foo.fooMethod()
28430    bar.barMethod()""",
28431  """
28432    import foo, * as bar from 'lib';
28433
28434    foo.fooMethod();
28435
28436    bar.barMethod();"""
28437
28438test "multiline simple import", ->
28439  eqJS """
28440    import {
28441      foo,
28442      bar as baz
28443    } from 'lib'""",
28444  """
28445    import {
28446      foo,
28447      bar as baz
28448    } from 'lib';"""
28449
28450test "multiline complex import", ->
28451  eqJS """
28452    import foo, {
28453      bar,
28454      baz as qux
28455    } from 'lib'""",
28456  """
28457    import foo, {
28458      bar,
28459      baz as qux
28460    } from 'lib';"""
28461
28462test "import with optional commas", ->
28463  eqJS "import { foo, bar, } from 'lib'",
28464  """
28465    import {
28466      foo,
28467      bar
28468    } from 'lib';"""
28469
28470test "multiline import without commas", ->
28471  eqJS """
28472    import {
28473      foo
28474      bar
28475    } from 'lib'""",
28476  """
28477    import {
28478      foo,
28479      bar
28480    } from 'lib';"""
28481
28482test "multiline import with optional commas", ->
28483  eqJS """
28484    import {
28485      foo,
28486      bar,
28487    } from 'lib'""",
28488  """
28489    import {
28490      foo,
28491      bar
28492    } from 'lib';"""
28493
28494test "a variable can be assigned after an import", ->
28495  eqJS """
28496    import { foo } from 'lib'
28497    bar = 5""",
28498  """
28499    var bar;
28500
28501    import {
28502      foo
28503    } from 'lib';
28504
28505    bar = 5;"""
28506
28507test "variables can be assigned before and after an import", ->
28508  eqJS """
28509    foo = 5
28510    import { bar } from 'lib'
28511    baz = 7""",
28512  """
28513    var baz, foo;
28514
28515    foo = 5;
28516
28517    import {
28518      bar
28519    } from 'lib';
28520
28521    baz = 7;"""
28522
28523# Export statements
28524
28525test "export empty object", ->
28526  eqJS "export { }",
28527  "export {};"
28528
28529test "export empty object", ->
28530  eqJS "export {}",
28531  "export {};"
28532
28533test "export named members within an object", ->
28534  eqJS "export { foo, bar }",
28535  """
28536    export {
28537      foo,
28538      bar
28539    };"""
28540
28541test "export named members as aliases, within an object", ->
28542  eqJS "export { foo as bar, baz as qux }",
28543  """
28544    export {
28545      foo as bar,
28546      baz as qux
28547    };"""
28548
28549test "export named members within an object, with an optional comma", ->
28550  eqJS "export { foo, bar, }",
28551  """
28552    export {
28553      foo,
28554      bar
28555    };"""
28556
28557test "multiline export named members within an object", ->
28558  eqJS """
28559    export {
28560      foo,
28561      bar
28562    }""",
28563  """
28564    export {
28565      foo,
28566      bar
28567    };"""
28568
28569test "multiline export named members within an object, with an optional comma", ->
28570  eqJS """
28571    export {
28572      foo,
28573      bar,
28574    }""",
28575  """
28576    export {
28577      foo,
28578      bar
28579    };"""
28580
28581test "export default string", ->
28582  eqJS "export default 'foo'",
28583  "export default 'foo';"
28584
28585test "export default number", ->
28586  eqJS "export default 5",
28587  "export default 5;"
28588
28589test "export default object", ->
28590  eqJS "export default { foo: 'bar', baz: 'qux' }",
28591  """
28592    export default {
28593      foo: 'bar',
28594      baz: 'qux'
28595    };"""
28596
28597test "export default implicit object", ->
28598  eqJS "export default foo: 'bar', baz: 'qux'",
28599  """
28600    export default {
28601      foo: 'bar',
28602      baz: 'qux'
28603    };"""
28604
28605test "export default multiline implicit object", ->
28606  eqJS """
28607    export default
28608      foo: 'bar'
28609      baz: 'qux'
28610    """,
28611  """
28612    export default {
28613      foo: 'bar',
28614      baz: 'qux'
28615    };"""
28616
28617test "export default multiline implicit object with internal braces", ->
28618  eqJS """
28619    export default
28620      foo: yes
28621      bar: {
28622        baz
28623      }
28624      quz: no
28625    """,
28626  """
28627    export default {
28628      foo: true,
28629      bar: {baz},
28630      quz: false
28631    };"""
28632
28633test "export default assignment expression", ->
28634  eqJS "export default foo = 'bar'",
28635  """
28636    var foo;
28637
28638    export default foo = 'bar';"""
28639
28640test "export assignment expression", ->
28641  eqJS "export foo = 'bar'",
28642  "export var foo = 'bar';"
28643
28644test "export multiline assignment expression", ->
28645  eqJS """
28646    export foo =
28647    'bar'""",
28648    "export var foo = 'bar';"
28649
28650test "export multiline indented assignment expression", ->
28651  eqJS """
28652    export foo =
28653      'bar'""",
28654      "export var foo = 'bar';"
28655
28656test "export default function", ->
28657  eqJS "export default ->",
28658  "export default function() {};"
28659
28660test "export default multiline function", ->
28661  eqJS """
28662    export default (foo) ->
28663      console.log foo""",
28664    """
28665    export default function(foo) {
28666      return console.log(foo);
28667    };"""
28668
28669test "export assignment function", ->
28670  eqJS """
28671    export foo = (bar) ->
28672      console.log bar""",
28673    """
28674    export var foo = function(bar) {
28675      return console.log(bar);
28676    };"""
28677
28678test "export assignment function which contains assignments in its body", ->
28679  eqJS """
28680    export foo = (bar) ->
28681      baz = '!'
28682      console.log bar + baz""",
28683    """
28684    export var foo = function(bar) {
28685      var baz;
28686      baz = '!';
28687      return console.log(bar + baz);
28688    };"""
28689
28690test "export default predefined function", ->
28691  eqJS """
28692    foo = (bar) ->
28693      console.log bar
28694    export default foo""",
28695  """
28696    var foo;
28697
28698    foo = function(bar) {
28699      return console.log(bar);
28700    };
28701
28702    export default foo;"""
28703
28704test "export default class", ->
28705  eqJS """
28706    export default class foo extends bar
28707      baz: ->
28708        console.log 'hello, world!'""",
28709      """
28710    var foo;
28711
28712    export default foo = class foo extends bar {
28713      baz() {
28714        return console.log('hello, world!');
28715      }
28716
28717    };"""
28718
28719test "export class", ->
28720  eqJS """
28721    export class foo
28722      baz: ->
28723        console.log 'hello, world!'""",
28724      """
28725    export var foo = class foo {
28726      baz() {
28727        return console.log('hello, world!');
28728      }
28729
28730    };"""
28731
28732test "export class that extends", ->
28733  eqJS """
28734    export class foo extends bar
28735      baz: ->
28736        console.log 'hello, world!'""",
28737      """
28738    export var foo = class foo extends bar {
28739      baz() {
28740        return console.log('hello, world!');
28741      }
28742
28743    };"""
28744
28745test "export default class that extends", ->
28746  eqJS """
28747    export default class foo extends bar
28748      baz: ->
28749        console.log 'hello, world!'""",
28750      """
28751    var foo;
28752
28753    export default foo = class foo extends bar {
28754      baz() {
28755        return console.log('hello, world!');
28756      }
28757
28758    };"""
28759
28760test "export default named member, within an object", ->
28761  eqJS "export { foo as default, bar }",
28762  """
28763    export {
28764      foo as default,
28765      bar
28766    };"""
28767
28768# Import and export in the same statement
28769
28770test "export an entire module's contents", ->
28771  eqJS "export * from 'lib'",
28772  "export * from 'lib';"
28773
28774test "export members imported from another module", ->
28775  eqJS "export { foo, bar } from 'lib'",
28776  """
28777    export {
28778      foo,
28779      bar
28780    } from 'lib';"""
28781
28782test "export as aliases members imported from another module", ->
28783  eqJS "export { foo as bar, baz as qux } from 'lib'",
28784  """
28785    export {
28786      foo as bar,
28787      baz as qux
28788    } from 'lib';"""
28789
28790test "export list can contain CoffeeScript keywords", ->
28791  eqJS "export { unless, and } from 'lib'",
28792  """
28793    export {
28794      unless,
28795      and
28796    } from 'lib';"""
28797
28798test "export list can contain CoffeeScript keywords when aliasing", ->
28799  eqJS "export { when as bar, baz as unless, and as foo, booze as not } from 'lib'",
28800  """
28801    export {
28802      when as bar,
28803      baz as unless,
28804      and as foo,
28805      booze as not
28806    } from 'lib';"""
28807
28808
28809# Edge cases
28810
28811test "multiline import with comments", ->
28812  eqJS """
28813    import {
28814      foo, # Not as good as bar
28815      bar as baz # I prefer qux
28816    } from 'lib'""",
28817  """
28818    import {
28819      foo, // Not as good as bar
28820      bar as baz // I prefer qux
28821    } from 'lib';"""
28822
28823test "`from` not part of an import or export statement can still be assigned", ->
28824  from = 5
28825  eq 5, from
28826
28827test "a variable named `from` can be assigned after an import", ->
28828  eqJS """
28829    import { foo } from 'lib'
28830    from = 5""",
28831  """
28832    var from;
28833
28834    import {
28835      foo
28836    } from 'lib';
28837
28838    from = 5;"""
28839
28840test "`from` can be assigned after a multiline import", ->
28841  eqJS """
28842    import {
28843      foo
28844    } from 'lib'
28845    from = 5""",
28846  """
28847    var from;
28848
28849    import {
28850      foo
28851    } from 'lib';
28852
28853    from = 5;"""
28854
28855test "`from` can be imported as a member name", ->
28856  eqJS "import { from } from 'lib'",
28857  """
28858    import {
28859      from
28860    } from 'lib';"""
28861
28862test "`from` can be imported as a member name and aliased", ->
28863  eqJS "import { from as foo } from 'lib'",
28864  """
28865    import {
28866      from as foo
28867    } from 'lib';"""
28868
28869test "`from` can be used as an alias name", ->
28870  eqJS "import { foo as from } from 'lib'",
28871  """
28872    import {
28873      foo as from
28874    } from 'lib';"""
28875
28876test "`as` can be imported as a member name", ->
28877  eqJS "import { as } from 'lib'",
28878  """
28879    import {
28880      as
28881    } from 'lib';"""
28882
28883test "`as` can be imported as a member name and aliased", ->
28884  eqJS "import { as as foo } from 'lib'",
28885  """
28886    import {
28887      as as foo
28888    } from 'lib';"""
28889
28890test "`as` can be used as an alias name", ->
28891  eqJS "import { foo as as } from 'lib'",
28892  """
28893    import {
28894      foo as as
28895    } from 'lib';"""
28896
28897test "CoffeeScript keywords can be used as imported names in import lists", ->
28898  eqJS """
28899    import { unless as bar, and as computedAnd } from 'lib'
28900    bar.barMethod()""",
28901  """
28902    import {
28903      unless as bar,
28904      and as computedAnd
28905    } from 'lib';
28906
28907    bar.barMethod();"""
28908
28909test "`*` can be used in an expression on the same line as an export keyword", ->
28910  eqJS "export foo = (x) -> x * x",
28911  """
28912    export var foo = function(x) {
28913      return x * x;
28914    };"""
28915  eqJS "export default foo = (x) -> x * x",
28916  """
28917    var foo;
28918
28919    export default foo = function(x) {
28920      return x * x;
28921    };"""
28922
28923test "`*` and `from` can be used in an export default expression", ->
28924  eqJS """
28925    export default foo.extend
28926      bar: ->
28927        from = 5
28928        from = from * 3""",
28929      """
28930    export default foo.extend({
28931      bar: function() {
28932        var from;
28933        from = 5;
28934        return from = from * 3;
28935      }
28936    });"""
28937
28938test "wrapped members can be imported multiple times if aliased", ->
28939  eqJS "import { foo, foo as bar } from 'lib'",
28940  """
28941    import {
28942      foo,
28943      foo as bar
28944    } from 'lib';"""
28945
28946test "default and wrapped members can be imported multiple times if aliased", ->
28947  eqJS "import foo, { foo as bar } from 'lib'",
28948  """
28949    import foo, {
28950      foo as bar
28951    } from 'lib';"""
28952
28953test "import a member named default", ->
28954  eqJS "import { default } from 'lib'",
28955  """
28956    import {
28957      default
28958    } from 'lib';"""
28959
28960test "import an aliased member named default", ->
28961  eqJS "import { default as def } from 'lib'",
28962  """
28963    import {
28964      default as def
28965    } from 'lib';"""
28966
28967test "export a member named default", ->
28968  eqJS "export { default }",
28969  """
28970    export {
28971      default
28972    };"""
28973
28974test "export an aliased member named default", ->
28975  eqJS "export { def as default }",
28976  """
28977    export {
28978      def as default
28979    };"""
28980
28981test "import an imported member named default", ->
28982  eqJS "import { default } from 'lib'",
28983  """
28984    import {
28985      default
28986    } from 'lib';"""
28987
28988test "import an imported aliased member named default", ->
28989  eqJS "import { default as def } from 'lib'",
28990  """
28991    import {
28992      default as def
28993    } from 'lib';"""
28994
28995test "export an imported member named default", ->
28996  eqJS "export { default } from 'lib'",
28997  """
28998    export {
28999      default
29000    } from 'lib';"""
29001
29002test "export an imported aliased member named default", ->
29003  eqJS "export { default as def } from 'lib'",
29004  """
29005    export {
29006      default as def
29007    } from 'lib';"""
29008
29009test "#4394: export shouldn't prevent variable declarations", ->
29010  eqJS """
29011    x = 1
29012    export { x }
29013  """,
29014  """
29015    var x;
29016
29017    x = 1;
29018
29019    export {
29020      x
29021    };
29022  """
29023
29024test "#4451: `default` in an export statement is only treated as a keyword when it follows `export` or `as`", ->
29025  eqJS "export default { default: 1 }",
29026  """
29027    export default {
29028      default: 1
29029    };
29030  """
29031
29032test "#4491: import- and export-specific lexing should stop after import/export statement", ->
29033  eqJS """
29034    import {
29035      foo,
29036      bar as baz
29037    } from 'lib'
29038
29039    foo as
29040    3 * as 4
29041    from 'foo'
29042    """,
29043  """
29044    import {
29045      foo,
29046      bar as baz
29047    } from 'lib';
29048
29049    foo(as);
29050
29051    3 * as(4);
29052
29053    from('foo');
29054    """
29055
29056  eqJS """
29057    import { foo, bar as baz } from 'lib'
29058
29059    foo as
29060    3 * as 4
29061    from 'foo'
29062    """,
29063  """
29064    import {
29065      foo,
29066      bar as baz
29067    } from 'lib';
29068
29069    foo(as);
29070
29071    3 * as(4);
29072
29073    from('foo');
29074    """
29075
29076  eqJS """
29077    import * as lib from 'lib'
29078
29079    foo as
29080    3 * as 4
29081    from 'foo'
29082    """,
29083  """
29084    import * as lib from 'lib';
29085
29086    foo(as);
29087
29088    3 * as(4);
29089
29090    from('foo');
29091    """
29092
29093  eqJS """
29094    export {
29095      foo,
29096      bar
29097    }
29098
29099    foo as
29100    3 * as 4
29101    from 'foo'
29102    """,
29103  """
29104    export {
29105      foo,
29106      bar
29107    };
29108
29109    foo(as);
29110
29111    3 * as(4);
29112
29113    from('foo');
29114    """
29115
29116  eqJS """
29117    export * from 'lib'
29118
29119    foo as
29120    3 * as 4
29121    from 'foo'
29122    """,
29123  """
29124    export * from 'lib';
29125
29126    foo(as);
29127
29128    3 * as(4);
29129
29130    from('foo');
29131    """
29132
29133# Issue #4874: Backslash not supported in import or export statements
29134test "#4874: backslash `import`", ->
29135
29136  eqJS """
29137    import foo \
29138        from 'lib'
29139
29140    foo a
29141    """,
29142  """
29143    import foo from 'lib';
29144
29145    foo(a);
29146    """
29147
29148  eqJS """
29149    import \
29150                    foo \
29151        from \
29152    'lib'
29153
29154    foo a
29155    """,
29156  """
29157    import foo from 'lib';
29158
29159    foo(a);
29160    """
29161
29162  eqJS """
29163    import \
29164          utilityBelt \
29165    , {
29166      each
29167    } from \
29168    'underscore'
29169    """,
29170  """
29171    import utilityBelt, {
29172      each
29173    } from 'underscore';
29174    """
29175
29176test "#4874: backslash `export`", ->
29177  eqJS """
29178    export \
29179      * \
29180            from \
29181      'underscore'
29182    """,
29183  """
29184    export * from 'underscore';
29185    """
29186
29187  eqJS """
29188    export \
29189        { max, min } \
29190              from \
29191      'underscore'
29192  """,
29193  """
29194    export {
29195      max,
29196      min
29197    } from 'underscore';
29198    """
29199
29200test "#4834: dynamic import", ->
29201  eqJS """
29202    import('module').then ->
29203  """,
29204  """
29205    import('module').then(function() {});
29206  """
29207
29208  eqJS """
29209    foo = ->
29210      bar = await import('bar')
29211  """,
29212  """
29213    var foo;
29214
29215    foo = async function() {
29216      var bar;
29217      return bar = (await import('bar'));
29218    };
29219  """
29220
29221  eqJS """
29222    console.log import('foo')
29223  """,
29224  """
29225    console.log(import('foo'));
29226  """
29227
29228test "#5317: Support import.meta", ->
29229  eqJS """
29230    foo = import.meta
29231  """,
29232  """
29233    var foo;
29234
29235    foo = import.meta;
29236  """
29237
29238  eqJS """
29239    foo = import
29240        .meta
29241  """,
29242  """
29243    var foo;
29244
29245    foo = import.meta;
29246  """
29247
29248  eqJS """
29249    foo = import.
29250        meta
29251  """,
29252  """
29253    var foo;
29254
29255    foo = import.meta;
29256  """
29257
29258  eqJS """
29259    foo = import.meta.bar
29260  """,
29261  """
29262    var foo;
29263
29264    foo = import.meta.bar;
29265  """
29266
29267  eqJS """
29268    foo = import
29269        .meta
29270        .bar
29271  """,
29272  """
29273    var foo;
29274
29275    foo = import.meta.bar;
29276  """
29277
29278  eqJS """
29279    console.log import.meta.url
29280  """,
29281  """
29282    console.log(import.meta.url);
29283  """
29284
29285</script>
vendor: 1 bytes, line 29285
29285
29286<script type="text/x-coffeescript" class="test" id="numbers">
29287# Number Literals
29288# ---------------
29289
29290# * Decimal Integer Literals
29291# * Octal Integer Literals
29292# * Hexadecimal Integer Literals
29293# * Scientific Notation Integer Literals
29294# * Scientific Notation Non-Integer Literals
29295# * Non-Integer Literals
29296# * Binary Integer Literals
29297
29298
29299# Binary Integer Literals
29300# Binary notation is understood as would be decimal notation.
29301
29302test "Parser recognises binary numbers", ->
29303  eq 4, 0b100
29304
29305# Decimal Integer Literals
29306
29307test "call methods directly on numbers", ->
29308  eq 4, 4.valueOf()
29309  eq '11', 4.toString 3
29310  eq '1000', 1_000.toString()
29311
29312eq -1, 3 -4
29313
29314#764: Numbers should be indexable
29315eq Number::toString, 42['toString']
29316
29317eq Number::toString, 42.toString
29318
29319eq Number::toString, 2e308['toString'] # Infinity
29320
29321
29322# Non-Integer Literals
29323
29324# Decimal number literals.
29325value = .25 + .75
29326ok value is 1
29327value = 0.0 + -.25 - -.75 + 0.0
29328ok value is 0.5
29329
29330#764: Numbers should be indexable
29331eq Number::toString,   4['toString']
29332eq Number::toString, 4.2['toString']
29333eq Number::toString, .42['toString']
29334eq Number::toString, (4)['toString']
29335
29336eq Number::toString,   4.toString
29337eq Number::toString, 4.2.toString
29338eq Number::toString, .42.toString
29339eq Number::toString, (4).toString
29340
29341test '#1168: leading floating point suppresses newline', ->
29342  eq 1, do ->
29343    1
29344    .5 + 0.5
29345
29346test "Python-style octal literal notation '0o777'", ->
29347  eq 511, 0o777
29348  eq 1, 0o1
29349  eq 1, 0o00001
29350  eq parseInt('0777', 8), 0o777
29351  eq '777', 0o777.toString 8
29352  eq 4, 0o4.valueOf()
29353  eq Number::toString, 0o777['toString']
29354  eq Number::toString, 0o777.toString
29355
29356test "#2060: Disallow uppercase radix prefixes", ->
29357  for char in ['b', 'o', 'x']
29358    program = "0#{char}0"
29359    doesNotThrowCompileError program, bare: yes
29360    throwsCompileError program.toUpperCase(), bare: yes
29361
29362test "#5164: Allow lowercase and uppercase exponent notation", ->
29363  doesNotThrow -> CoffeeScript.compile "0e0", bare: yes
29364  doesNotThrow -> CoffeeScript.compile "0E0", bare: yes
29365
29366test "#2224: hex literals with 0b or B or E", ->
29367  eq 176, 0x0b0
29368  eq 177, 0x0B1
29369  eq 225, 0xE1
29370
29371test "Infinity", ->
29372  eq Infinity, CoffeeScript.eval "0b#{Array(1024 + 1).join('1')}"
29373  eq Infinity, CoffeeScript.eval "0o#{Array(342 + 1).join('7')}"
29374  eq Infinity, CoffeeScript.eval "0x#{Array(256 + 1).join('f')}"
29375  eq Infinity, CoffeeScript.eval Array(500 + 1).join('9')
29376  eq Infinity, 2e308
29377
29378test "NaN", ->
29379  ok isNaN 1/NaN
29380
29381</script>
vendor: 1 bytes, line 29381
29381
29382<script type="text/x-coffeescript" class="test" id="numbers_bigint">
29383# BigInt Literals
29384# ---------------
29385
29386test "BigInt exists", ->
29387  'object' is typeof BigInt
29388
29389test "Parser recognizes decimal BigInt literals", ->
29390  eq 42n, BigInt 42
29391
29392test "Parser recognizes decimal BigInt literals with separator", ->
29393  eq 1_000n, BigInt 1000
29394
29395test "Parser recognizes binary BigInt literals", ->
29396  eq 42n, 0b101010n
29397
29398test "Parser recognizes octal BigInt literals", ->
29399  eq 42n, 0o52n
29400
29401test "Parser recognizes hexadecimal BigInt literals", ->
29402  eq 42n, 0x2an
29403
29404</script>
vendor: 1 bytes, line 29404
29404
29405<script type="text/x-coffeescript" class="test" id="numeric_literal_separators">
29406# Numeric Literal Separators
29407# --------------------------
29408
29409test 'integer literals with separators', ->
29410  eq 123_456, 123456
29411  eq 12_34_56, 123456
29412
29413test 'decimal literals with separators', ->
29414  eq 1_2.34_5, 12.345
29415  eq 1_0e1_0, 10e10
29416  eq 1_2.34_5e6_7, 12.345e67
29417
29418test 'hexadecimal literals with separators', ->
29419  eq 0x1_2_3_4, 0x1234
29420
29421test 'binary literals with separators', ->
29422  eq 0b10_10, 0b1010
29423
29424test 'octal literals with separators', ->
29425  eq 0o7_7_7, 0o777
29426
29427test 'infinity with separator', ->
29428  eq 2e3_08, Infinity
29429
29430test 'range with separators', ->
29431  range = [10_000...10_002]
29432  eq range.length, 2
29433  eq range[0], 10000
29434
29435test 'property access on a number', ->
29436  # Somehow, `3..toFixed()` is valid JavaScript; though just `3.toFixed()`
29437  # is not. CoffeeScript has long allowed code like `3.toFixed()` to compile
29438  # into `3..toFixed()`.
29439  eq 3.toFixed(), '3'
29440  # Where this can conflict with numeric literal separators is when the
29441  # property name contains an underscore.
29442  Number::_23 = _23 = 'x'
29443  eq 1._23, 'x'
29444  ok 1._34 is undefined
29445  delete Number::_23
29446
29447test 'invalid decimal literal separators do not compile', ->
29448  # `1._23` is a valid property access (see previous test)
29449  throwsCompileError '1_.23'
29450  throwsCompileError '1e_2'
29451  throwsCompileError '1e2_'
29452  throwsCompileError '1_'
29453  throwsCompileError '1__2'
29454
29455test 'invalid hexadecimal literal separators do not compile', ->
29456  throwsCompileError '0x_1234'
29457  throwsCompileError '0x1234_'
29458  throwsCompileError '0x1__34'
29459
29460test 'invalid binary literal separators do not compile', ->
29461  throwsCompileError '0b_100'
29462  throwsCompileError '0b100_'
29463  throwsCompileError '0b1__1'
29464
29465test 'invalid octal literal separators do not compile', ->
29466  throwsCompileError '0o_777'
29467  throwsCompileError '0o777_'
29468  throwsCompileError '0o6__6'
29469
29470</script>
vendor: 1 bytes, line 29470
29470
29471<script type="text/x-coffeescript" class="test" id="object_rest_spread">
29472test "#4798 destructuring of objects with splat within arrays", ->
29473  arr = [1, {a:1, b:2}]
29474  [...,{a, r...}] = arr
29475  eq a, 1
29476  deepEqual r, {b:2}
29477  [b, {q...}] = arr
29478  eq b, 1
29479  deepEqual q, arr[1]
29480  eq q.b, r.b
29481  eq q.a, a
29482
29483  arr2 = [arr[1]]
29484  [{a2...}] = arr2
29485  eq a2.a, arr2[0].a
29486
29487test "destructuring assignment with objects and splats: ES2015", ->
29488  obj = {a: 1, b: 2, c: 3, d: 4, e: 5}
29489  throwsCompileError "{a, r..., s...} = x", null, null, "multiple rest elements are disallowed"
29490  throwsCompileError "{a, r..., s..., b} = x", null, null, "multiple rest elements are disallowed"
29491  prop = "b"
29492  {a, b, r...} = obj
29493  eq a, 1
29494  eq b, 2
29495  eq r.e, obj.e
29496  eq r.a, undefined
29497  {d, c: x, r...} = obj
29498  eq x, 3
29499  eq d, 4
29500  eq r.c, undefined
29501  eq r.b, 2
29502  {a, 'b': z, g = 9, r...} = obj
29503  eq g, 9
29504  eq z, 2
29505  eq r.b, undefined
29506
29507test "destructuring assignment with splats and default values", ->
29508  obj = {}
29509  c = {b: 1}
29510  { a: {b} = c, d...} = obj
29511
29512  eq b, 1
29513  deepEqual d, {}
29514
29515  # Should not trigger implicit call, e.g. rest ... => rest(...)
29516  {
29517    a: {b} = c
29518    d ...
29519  } = obj
29520
29521  eq b, 1
29522  deepEqual d, {}
29523
29524test "destructuring assignment with splat with default value", ->
29525  obj = {}
29526  c = {val: 1}
29527  { a: {b...} = c } = obj
29528
29529  deepEqual b, val: 1
29530
29531test "destructuring assignment with multiple splats in different objects", ->
29532  obj = { a: {val: 1}, b: {val: 2} }
29533  { a: {a...}, b: {b...} } = obj
29534  deepEqual a, val: 1
29535  deepEqual b, val: 2
29536
29537  o = {
29538    props: {
29539      p: {
29540        n: 1
29541        m: 5
29542      }
29543      s: 6
29544    }
29545  }
29546  {p: {m, q..., t = {obj...}}, r...} = o.props
29547  eq m, o.props.p.m
29548  deepEqual r, s: 6
29549  deepEqual q, n: 1
29550  deepEqual t, obj
29551
29552  @props = o.props
29553  {p: {m}, r...} = @props
29554  eq m, @props.p.m
29555  deepEqual r, s: 6
29556
29557  {p: {m}, r...} = {o.props..., p:{m:9}}
29558  eq m, 9
29559
29560  # Should not trigger implicit call, e.g. rest ... => rest(...)
29561  {
29562    a: {
29563      a ...
29564    }
29565    b: {
29566      b ...
29567    }
29568  } = obj
29569  deepEqual a, val: 1
29570  deepEqual b, val: 2
29571
29572test "destructuring assignment with dynamic keys and splats", ->
29573  i = 0
29574  foo = -> ++i
29575
29576  obj = {1: 'a', 2: 'b'}
29577  { "#{foo()}": a, b... } = obj
29578
29579  eq a, 'a'
29580  eq i, 1
29581  deepEqual b, 2: 'b'
29582
29583# Tests from https://babeljs.io/docs/plugins/transform-object-rest-spread/.
29584test "destructuring assignment with objects and splats: Babel tests", ->
29585  # What Babel calls “rest properties:”
29586  { x, y, z... } = { x: 1, y: 2, a: 3, b: 4 }
29587  eq x, 1
29588  eq y, 2
29589  deepEqual z, { a: 3, b: 4 }
29590
29591  # What Babel calls “spread properties:”
29592  n = { x, y, z... }
29593  deepEqual n, { x: 1, y: 2, a: 3, b: 4 }
29594
29595  # Should not trigger implicit call, e.g. rest ... => rest(...)
29596  { x, y, z ... } = { x: 1, y: 2, a: 3, b: 4 }
29597  eq x, 1
29598  eq y, 2
29599  deepEqual z, { a: 3, b: 4 }
29600
29601  n = { x, y, z ... }
29602  deepEqual n, { x: 1, y: 2, a: 3, b: 4 }
29603
29604test "deep destructuring assignment with objects: ES2015", ->
29605  a1={}; b1={}; c1={}; d1={}
29606  obj = {
29607    a: a1
29608    b: {
29609      'c': {
29610        d: {
29611          b1
29612          e: c1
29613          f: d1
29614        }
29615      }
29616    }
29617    b2: {b1, c1}
29618  }
29619  {a: w, b: {c: {d: {b1: bb, r1...}}}, r2...} = obj
29620  eq r1.e, c1
29621  eq r2.b, undefined
29622  eq bb, b1
29623  eq r2.b2, obj.b2
29624
29625  # Should not trigger implicit call, e.g. rest ... => rest(...)
29626  {a: w, b: {c: {d: {b1: bb, r1 ...}}}, r2 ...} = obj
29627  eq r1.e, c1
29628  eq r2.b, undefined
29629  eq bb, b1
29630  eq r2.b2, obj.b2
29631
29632test "deep destructuring assignment with defaults: ES2015", ->
29633  obj =
29634    b: { c: 1, baz: 'qux' }
29635    foo: 'bar'
29636  j =
29637    f: 'world'
29638  i =
29639    some: 'prop'
29640  {
29641    a...
29642    b: { c, d... }
29643    e: {
29644      f: hello
29645      g: { h... } = i
29646    } = j
29647  } = obj
29648
29649  deepEqual a, foo: 'bar'
29650  eq c, 1
29651  deepEqual d, baz: 'qux'
29652  eq hello, 'world'
29653  deepEqual h, some: 'prop'
29654
29655  # Should not trigger implicit call, e.g. rest ... => rest(...)
29656  {
29657    a ...
29658    b: {
29659      c,
29660      d ...
29661    }
29662    e: {
29663      f: hello
29664      g: {
29665        h ...
29666      } = i
29667    } = j
29668  } = obj
29669
29670  deepEqual a, foo: 'bar'
29671  eq c, 1
29672  deepEqual d, baz: 'qux'
29673  eq hello, 'world'
29674  deepEqual h, some: 'prop'
29675
29676test "object spread properties: ES2015", ->
29677  obj = {a: 1, b: 2, c: 3, d: 4, e: 5}
29678  obj2 = {obj..., c:9}
29679  eq obj2.c, 9
29680  eq obj.a, obj2.a
29681
29682  # Should not trigger implicit call, e.g. rest ... => rest(...)
29683  obj2 = {
29684    obj ...
29685    c:9
29686  }
29687  eq obj2.c, 9
29688  eq obj.a, obj2.a
29689
29690  obj2 = {obj..., a: 8, c: 9, obj...}
29691  eq obj2.c, 3
29692  eq obj.a, obj2.a
29693
29694  # Should not trigger implicit call, e.g. rest ... => rest(...)
29695  obj2 = {
29696    obj ...
29697    a: 8
29698    c: 9
29699    obj ...
29700  }
29701  eq obj2.c, 3
29702  eq obj.a, obj2.a
29703
29704  obj3 = {obj..., b: 7, g: {obj2..., c: 1}}
29705  eq obj3.g.c, 1
29706  eq obj3.b, 7
29707  deepEqual obj3.g, {obj..., c: 1}
29708
29709  (({a, b, r...}) ->
29710    eq 1, a
29711    deepEqual r, {c: 3, d: 44, e: 55}
29712  ) {obj2..., d: 44, e: 55}
29713
29714  obj = {a: 1, b: 2, c: {d: 3, e: 4, f: {g: 5}}}
29715  obj4 = {a: 10, obj.c...}
29716  eq obj4.a, 10
29717  eq obj4.d, 3
29718  eq obj4.f.g, 5
29719  deepEqual obj4.f, obj.c.f
29720
29721  # Should not trigger implicit call, e.g. rest ... => rest(...)
29722  (({
29723    a
29724    b
29725    r ...
29726    }) ->
29727    eq 1, a
29728    deepEqual r, {c: 3, d: 44, e: 55}
29729  ) {
29730    obj2 ...
29731    d: 44
29732    e: 55
29733  }
29734
29735  # Should not trigger implicit call, e.g. rest ... => rest(...)
29736  obj4 = {
29737    a: 10
29738    obj.c ...
29739  }
29740  eq obj4.a, 10
29741  eq obj4.d, 3
29742  eq obj4.f.g, 5
29743  deepEqual obj4.f, obj.c.f
29744
29745  obj5 = {obj..., ((k) -> {b: k})(99)...}
29746  eq obj5.b, 99
29747  deepEqual obj5.c, obj.c
29748
29749  # Should not trigger implicit call, e.g. rest ... => rest(...)
29750  obj5 = {
29751    obj ...
29752    ((k) -> {b: k})(99) ...
29753  }
29754  eq obj5.b, 99
29755  deepEqual obj5.c, obj.c
29756
29757  fn = -> {c: {d: 33, e: 44, f: {g: 55}}}
29758  obj6 = {obj..., fn()...}
29759  eq obj6.c.d, 33
29760  deepEqual obj6.c, {d: 33, e: 44, f: {g: 55}}
29761
29762  obj7 = {obj..., fn()..., {c: {d: 55, e: 66, f: {77}}}...}
29763  eq obj7.c.d, 55
29764  deepEqual obj6.c, {d: 33, e: 44, f: {g: 55}}
29765
29766  # Should not trigger implicit call, e.g. rest ... => rest(...)
29767  obj7 = {
29768    obj ...
29769    fn() ...
29770    {c: {d: 55, e: 66, f: {77}}} ...
29771  }
29772  eq obj7.c.d, 55
29773  deepEqual obj6.c, {d: 33, e: 44, f: {g: 55}}
29774
29775  obj =
29776    a:
29777      b:
29778        c:
29779          d:
29780            e: {}
29781  obj9 = {a:1, obj.a.b.c..., g:3}
29782  deepEqual obj9.d, {e: {}}
29783
29784  a = "a"
29785  c = "c"
29786  obj9 = {a:1, obj[a].b[c]..., g:3}
29787  deepEqual obj9.d, {e: {}}
29788
29789  obj9 = {a:1, obj.a["b"].c["d"]..., g:3}
29790  deepEqual obj9["e"], {}
29791
29792test "#4673: complex destructured object spread variables", ->
29793  b = c: 1
29794  {{a...}...} = b
29795  eq a.c, 1
29796
29797  d = {}
29798  {d.e...} = f: 1
29799  eq d.e.f, 1
29800
29801  {{g}...} = g: 1
29802  eq g, 1
29803
29804test "rest element destructuring in function definition", ->
29805  obj = {a: 1, b: 2, c: 3, d: 4, e: 5}
29806
29807  (({a, b, r...}) ->
29808    eq 1, a
29809    eq 2, b,
29810    deepEqual r, {c: 3, d: 4, e: 5}
29811  ) obj
29812
29813  (({a: p, b, r...}, q) ->
29814    eq p, 1
29815    eq q, 9
29816    deepEqual r, {c: 3, d: 4, e: 5}
29817  ) {a:1, b:2, c:3, d:4, e:5}, 9
29818
29819  # Should not trigger implicit call, e.g. rest ... => rest(...)
29820  (({
29821      a: p
29822      b
29823      r ...
29824    }, q) ->
29825    eq p, 1
29826    eq q, 9
29827    deepEqual r, {c: 3, d: 4, e: 5}
29828  ) {a:1, b:2, c:3, d:4, e:5}, 9
29829
29830  a1={}; b1={}; c1={}; d1={}
29831  obj1 = {
29832    a: a1
29833    b: {
29834      'c': {
29835        d: {
29836          b1
29837          e: c1
29838          f: d1
29839        }
29840      }
29841    }
29842    b2: {b1, c1}
29843  }
29844
29845  (({a: w, b: {c: {d: {b1: bb, r1...}}}, r2...}) ->
29846    eq a1, w
29847    eq bb, b1
29848    eq r2.b, undefined
29849    deepEqual r1, {e: c1, f: d1}
29850    deepEqual r2.b2, {b1, c1}
29851  ) obj1
29852
29853  b = 3
29854  f = ({a, b...}) ->
29855  f {}
29856  eq 3, b
29857
29858  (({a, r...} = {}) ->
29859    eq a, undefined
29860    deepEqual r, {}
29861  )()
29862
29863  (({a, r...} = {}) ->
29864    eq a, 1
29865    deepEqual r, {b: 2, c: 3}
29866  ) {a: 1, b: 2, c: 3}
29867
29868  f = ({a, r...} = {}) -> [a, r]
29869  deepEqual [undefined, {}], f()
29870  deepEqual [1, {b: 2}], f {a: 1, b: 2}
29871  deepEqual [1, {}], f {a: 1}
29872
29873  f = ({a, r...} = {a: 1, b: 2}) -> [a, r]
29874  deepEqual [1, {b:2}], f()
29875  deepEqual [2, {}], f {a:2}
29876  deepEqual [3, {c:5}], f {a:3, c:5}
29877
29878  f = ({ a: aa = 0, b: bb = 0 }) -> [aa, bb]
29879  deepEqual [0, 0], f {}
29880  deepEqual [0, 42], f {b:42}
29881  deepEqual [42, 0], f {a:42}
29882  deepEqual [42, 43], f {a:42, b:43}
29883
29884test "#4673: complex destructured object spread variables", ->
29885  f = ({{a...}...}) ->
29886    a
29887  eq f(c: 1).c, 1
29888
29889  g = ({@y...}) ->
29890    eq @y.b, 1
29891  g b: 1
29892
29893test "#4834: dynamic import can technically be object spread", ->
29894  eqJS """
29895    x = {...import('module')}
29896  """,
29897  """
29898    var x;
29899
29900    x = {...import('module')};
29901  """
29902
29903test "#5168: allow indented property index", ->
29904  a = b: c: 3
29905
29906  eq 3, {
29907    ...a[
29908      if yes
29909        'b'
29910      else
29911        'c'
29912    ]
29913  }.c
29914
29915test "#5291: soaks/prototype shorthands in object spread variables", ->
29916  withPrototype =
29917    prototype:
29918      b: {c: 1}
29919  eq {withPrototype::b...}.c, 1
29920  eq {...withPrototype::b}.c, 1
29921
29922  withSoak =
29923    b:
29924      c: 2
29925  eq {withSoak?.b...}.c, 2
29926  eq {...withSoak?.b}.c, 2
29927
29928  soakedCall = ->
29929    b:
29930      c: 3
29931  eq {soakedCall?().b...}.c, 3
29932  eq {...soakedCall?().b}.c, 3
29933
29934  assignToPrototype =
29935    prototype: {}
29936  {...assignToPrototype::b} = c: 4
29937  eq assignToPrototype::b.c, 4
29938
29939</script>
vendor: 1 bytes, line 29939
29939
29940<script type="text/x-coffeescript" class="test" id="objects">
29941# Object Literals
29942# ---------------
29943
29944# TODO: refactor object literal tests
29945# TODO: add indexing and method invocation tests: {a}['a'] is a, {a}.a()
29946
29947trailingComma = {k1: "v1", k2: 4, k3: (-> true),}
29948ok trailingComma.k3() and (trailingComma.k2 is 4) and (trailingComma.k1 is "v1")
29949
29950ok {a: (num) -> num is 10 }.a 10
29951
29952moe = {
29953  name:  'Moe'
29954  greet: (salutation) ->
29955    salutation + " " + @name
29956  hello: ->
29957    @['greet'] "Hello"
29958  10: 'number'
29959}
29960ok moe.hello() is "Hello Moe"
29961ok moe[10] is 'number'
29962moe.hello = ->
29963  this['greet'] "Hello"
29964ok moe.hello() is 'Hello Moe'
29965
29966obj = {
29967  is:     -> yes,
29968  'not':  -> no,
29969}
29970ok obj.is()
29971ok not obj.not()
29972
29973### Top-level object literal... ###
29974obj: 1
29975### ...doesn't break things. ###
29976
29977# Object literals should be able to include keywords.
29978obj = {class: 'höt'}
29979obj.function = 'dog'
29980ok obj.class + obj.function is 'hötdog'
29981
29982# Implicit objects as part of chained calls.
29983pluck = (x) -> x.a
29984eq 100, pluck pluck pluck a: a: a: 100
29985
29986
29987test "YAML-style object literals", ->
29988  obj =
29989    a: 1
29990    b: 2
29991  eq 1, obj.a
29992  eq 2, obj.b
29993
29994  config =
29995    development:
29996      server: 'localhost'
29997      timeout: 10
29998
29999    production:
30000      server: 'dreamboat'
30001      timeout: 1000
30002
30003  ok config.development.server  is 'localhost'
30004  ok config.production.server   is 'dreamboat'
30005  ok config.development.timeout is 10
30006  ok config.production.timeout  is 1000
30007
30008obj =
30009  a: 1,
30010  b: 2,
30011ok obj.a is 1
30012ok obj.b is 2
30013
30014# Implicit objects nesting.
30015obj =
30016  options:
30017    value: yes
30018  fn: ->
30019    {}
30020    null
30021ok obj.options.value is yes
30022ok obj.fn() is null
30023
30024# Implicit objects with wacky indentation:
30025obj =
30026  'reverse': (obj) ->
30027    Array.prototype.reverse.call obj
30028  abc: ->
30029    @reverse(
30030      @reverse @reverse ['a', 'b', 'c'].reverse()
30031    )
30032  one: [1, 2,
30033    a: 'b'
30034  3, 4]
30035  red:
30036    orange:
30037          yellow:
30038                  green: 'blue'
30039    indigo: 'violet'
30040  misdent: [[],
30041  [],
30042                  [],
30043      []]
30044ok obj.abc().join(' ') is 'a b c'
30045ok obj.one.length is 5
30046ok obj.one[4] is 4
30047ok obj.one[2].a is 'b'
30048ok (key for key of obj.red).length is 2
30049ok obj.red.orange.yellow.green is 'blue'
30050ok obj.red.indigo is 'violet'
30051ok obj.misdent.toString() is ',,,'
30052
30053#542: Objects leading expression statement should be parenthesized.
30054{f: -> ok yes }.f() + 1
30055
30056# String-keyed objects shouldn't suppress newlines.
30057one =
30058  '>!': 3
30059six: -> 10
30060ok not one.six
30061
30062# Shorthand objects with property references.
30063obj =
30064  ### comment one ###
30065  ### comment two ###
30066  one: 1
30067  two: 2
30068  object: -> {@one, @two}
30069  list:   -> [@one, @two]
30070result = obj.object()
30071eq result.one, 1
30072eq result.two, 2
30073eq result.two, obj.list()[1]
30074
30075third = (a, b, c) -> c
30076obj =
30077  one: 'one'
30078  two: third 'one', 'two', 'three'
30079ok obj.one is 'one'
30080ok obj.two is 'three'
30081
30082test "invoking functions with implicit object literals", ->
30083  generateGetter = (prop) -> (obj) -> obj[prop]
30084  getA = generateGetter 'a'
30085  getArgs = -> arguments
30086  a = b = 30
30087
30088  result = getA
30089    a: 10
30090  eq 10, result
30091
30092  result = getA
30093    "a": 20
30094  eq 20, result
30095
30096  result = getA a,
30097    b:1
30098  eq undefined, result
30099
30100  result = getA b:1,
30101  a:43
30102  eq 43, result
30103
30104  result = getA b:1,
30105    a:62
30106  eq undefined, result
30107
30108  result = getA
30109    b:1
30110    a
30111  eq undefined, result
30112
30113  result = getA
30114    a:
30115      b:2
30116    b:1
30117  eq 2, result.b
30118
30119  result = getArgs
30120    a:1
30121    b
30122    c:1
30123  ok result.length is 3
30124  ok result[2].c is 1
30125
30126  result = getA b: 13, a: 42, 2
30127  eq 42, result
30128
30129  result = getArgs a:1, (1 + 1)
30130  ok result[1] is 2
30131
30132  result = getArgs a:1, b
30133  ok result.length is 2
30134  ok result[1] is 30
30135
30136  result = getArgs a:1, b, b:1, a
30137  ok result.length is 4
30138  ok result[2].b is 1
30139
30140  throwsCompileError "a = b:1, c"
30141
30142test "some weird indentation in YAML-style object literals", ->
30143  two = (a, b) -> b
30144  obj = then two 1,
30145    1: 1
30146    a:
30147      b: ->
30148        fn c,
30149          d: e
30150    f: 1
30151  eq 1, obj[1]
30152
30153test "#1274: `{} = a()` compiles to `false` instead of `a()`", ->
30154  a = false
30155  fn = -> a = true
30156  {} = fn()
30157  ok a
30158
30159test "#1436: `for` etc. work as normal property names", ->
30160  obj = {}
30161  eq no, obj.hasOwnProperty 'for'
30162  obj.for = 'foo' of obj
30163  eq yes, obj.hasOwnProperty 'for'
30164
30165test "#2706, Un-bracketed object as argument causes inconsistent behavior", ->
30166  foo = (x, y) -> y
30167  bar = baz: yes
30168
30169  eq yes, foo x: 1, bar.baz
30170
30171test "#2608, Allow inline objects in arguments to be followed by more arguments", ->
30172  foo = (x, y) -> y
30173
30174  eq yes, foo x: 1, y: 2, yes
30175
30176test "#2308, a: b = c:1", ->
30177  foo = a: b = c: yes
30178  eq b.c, yes
30179  eq foo.a.c, yes
30180
30181test "#2317, a: b c: 1", ->
30182  foo = (x) -> x
30183  bar = a: foo c: yes
30184  eq bar.a.c, yes
30185
30186test "#1896, a: func b, {c: d}", ->
30187  first = (x) -> x
30188  second = (x, y) -> y
30189  third = (x, y, z) -> z
30190
30191  one = 1
30192  two = 2
30193  three = 3
30194  four = 4
30195
30196  foo = a: second one, {c: two}
30197  eq foo.a.c, two
30198
30199  bar = a: second one, c: two
30200  eq bar.a.c, two
30201
30202  baz = a: second one, {c: two}, e: first first h: three
30203  eq baz.a.c, two
30204
30205  qux = a: third one, {c: two}, e: first first h: three
30206  eq qux.a.e.h, three
30207
30208  quux = a: third one, {c: two}, e: first(three), h: four
30209  eq quux.a.e, three
30210  eq quux.a.h, four
30211
30212  corge = a: third one, {c: two}, e: second three, h: four
30213  eq corge.a.e.h, four
30214
30215test "Implicit objects, functions and arrays", ->
30216  first  = (x) -> x
30217  second = (x, y) -> y
30218
30219  foo = [
30220    1
30221    one: 1
30222    two: 2
30223    three: 3
30224    more:
30225      four: 4
30226      five: 5, six: 6
30227    2, 3, 4
30228    5]
30229  eq foo[2], 2
30230  eq foo[1].more.six, 6
30231
30232  bar = [
30233    1
30234    first first first second 1,
30235      one: 1, twoandthree: twoandthree: two: 2, three: 3
30236      2,
30237    2
30238    one: 1
30239    two: 2
30240    three: first second ->
30241      no
30242    , ->
30243      3
30244    3
30245    4]
30246  eq bar[2], 2
30247  eq bar[1].twoandthree.twoandthree.two, 2
30248  eq bar[3].three(), 3
30249  eq bar[4], 3
30250
30251test "#2549, Brace-less Object Literal as a Second Operand on a New Line", ->
30252  foo = no or
30253    one: 1
30254    two: 2
30255    three: 3
30256  eq foo.one, 1
30257
30258  bar = yes and one: 1
30259  eq bar.one, 1
30260
30261  baz = null ?
30262    one: 1
30263    two: 2
30264  eq baz.two, 2
30265
30266test "#2757, Nested", ->
30267  foo =
30268    bar:
30269      one: 1,
30270  eq foo.bar.one, 1
30271
30272  baz =
30273    qux:
30274      one: 1,
30275    corge:
30276      two: 2,
30277      three: three: three: 3,
30278    xyzzy:
30279      thud:
30280        four:
30281          four: 4,
30282      five: 5,
30283
30284  eq baz.qux.one, 1
30285  eq baz.corge.three.three.three, 3
30286  eq baz.xyzzy.thud.four.four, 4
30287  eq baz.xyzzy.five, 5
30288
30289test "#1865, syntax regression 1.1.3", ->
30290  foo = (x, y) -> y
30291
30292  bar = a: foo (->),
30293    c: yes
30294  eq bar.a.c, yes
30295
30296  baz = a: foo (->), c: yes
30297  eq baz.a.c, yes
30298
30299
30300test "#1322: implicit call against implicit object with block comments", ->
30301  ((obj, arg) ->
30302    eq obj.x * obj.y, 6
30303    ok not arg
30304  )
30305    ###
30306    x
30307    ###
30308    x: 2
30309    ### y ###
30310    y: 3
30311
30312test "#1513: Top level bare objs need to be wrapped in parens for unary and existence ops", ->
30313  doesNotThrow -> CoffeeScript.run "{}?", bare: true
30314  doesNotThrow -> CoffeeScript.run "{}.a++", bare: true
30315
30316test "#1871: Special case for IMPLICIT_END in the middle of an implicit object", ->
30317  result = 'result'
30318  ident = (x) -> x
30319
30320  result = ident one: 1 if false
30321
30322  eq result, 'result'
30323
30324  result = ident
30325    one: 1
30326    two: 2 for i in [1..3]
30327
30328  eq result.two.join(' '), '2 2 2'
30329
30330test "#1871: implicit object closed by IMPLICIT_END in implicit returns", ->
30331  ob = do ->
30332    a: 1 if no
30333  eq ob, undefined
30334
30335  # instead these return an object
30336  func = ->
30337    key:
30338      i for i in [1, 2, 3]
30339
30340  eq func().key.join(' '), '1 2 3'
30341
30342  func = ->
30343    key: (i for i in [1, 2, 3])
30344
30345  eq func().key.join(' '), '1 2 3'
30346
30347test "#1961, #1974, regression with compound assigning to an implicit object", ->
30348
30349  obj = null
30350
30351  obj ?=
30352    one: 1
30353    two: 2
30354
30355  eq obj.two, 2
30356
30357  obj = null
30358
30359  obj or=
30360    three: 3
30361    four: 4
30362
30363  eq obj.four, 4
30364
30365test "#2207: Immediate implicit closes don't close implicit objects", ->
30366  func = ->
30367    key: for i in [1, 2, 3] then i
30368
30369  eq func().key.join(' '), '1 2 3'
30370
30371test "#3216: For loop declaration as a value of an implicit object", ->
30372  test = [0..2]
30373  ob =
30374    a: for v, i in test then i
30375    b: for v, i in test then i
30376    c: for v in test by 1 then v
30377    d: for v in test when true then v
30378  arrayEq ob.a, test
30379  arrayEq ob.b, test
30380  arrayEq ob.c, test
30381  arrayEq ob.d, test
30382  byFirstKey =
30383    a: for v in test by 1 then v
30384  arrayEq byFirstKey.a, test
30385  whenFirstKey =
30386    a: for v in test when true then v
30387  arrayEq whenFirstKey.a, test
30388
30389test 'inline implicit object literals within multiline implicit object literals', ->
30390  x =
30391    a: aa: 0
30392    b: 0
30393  eq 0, x.b
30394  eq 0, x.a.aa
30395
30396test "object keys with interpolations: simple cases", ->
30397  a = 'a'
30398  obj = "#{a}": yes
30399  eq obj.a, yes
30400  obj = {"#{a}": yes}
30401  eq obj.a, yes
30402  obj = {"#{a}"}
30403  eq obj.a, 'a'
30404  obj = {"#{5}"}
30405  eq obj[5], '5' # Note that the value is a string, just like the key.
30406
30407test "object keys with interpolations: commas in implicit object", ->
30408  obj = "#{'a'}": 1, b: 2
30409  deepEqual obj, {a: 1, b: 2}
30410  obj = a: 1, "#{'b'}": 2
30411  deepEqual obj, {a: 1, b: 2}
30412  obj = "#{'a'}": 1, "#{'b'}": 2
30413  deepEqual obj, {a: 1, b: 2}
30414
30415test "object keys with interpolations: commas in explicit object", ->
30416  obj = {"#{'a'}": 1, b: 2}
30417  deepEqual obj, {a: 1, b: 2}
30418  obj = {a: 1, "#{'b'}": 2}
30419  deepEqual obj, {a: 1, b: 2}
30420  obj = {"#{'a'}": 1, "#{'b'}": 2}
30421  deepEqual obj, {a: 1, b: 2}
30422
30423test "object keys with interpolations: commas after key with interpolation", ->
30424  obj = {"#{'a'}": yes,}
30425  eq obj.a, yes
30426  obj = {
30427    "#{'a'}": 1,
30428    "#{'b'}": 2,
30429    ### herecomment ###
30430    "#{'c'}": 3,
30431  }
30432  deepEqual obj, {a: 1, b: 2, c: 3}
30433  obj =
30434    "#{'a'}": 1,
30435    "#{'b'}": 2,
30436    ### herecomment ###
30437    "#{'c'}": 3,
30438  deepEqual obj, {a: 1, b: 2, c: 3}
30439  obj =
30440    "#{'a'}": 1,
30441    "#{'b'}": 2,
30442    ### herecomment ###
30443    "#{'c'}": 3, "#{'d'}": 4,
30444  deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
30445
30446test "object keys with interpolations: key with interpolation mixed with `@prop`", ->
30447  deepEqual (-> {@a, "#{'b'}": 2}).call(a: 1), {a: 1, b: 2}
30448
30449test "object keys with interpolations: evaluate only once", ->
30450  count = 0
30451  a = -> count++; 'a'
30452  obj = {"#{a()}"}
30453  eq obj.a, 'a'
30454  eq count, 1
30455
30456test "object keys with interpolations: evaluation order", ->
30457  arr = []
30458  obj =
30459    a: arr.push 1
30460    b: arr.push 2
30461    "#{'c'}": arr.push 3
30462    "#{'d'}": arr.push 4
30463    e: arr.push 5
30464    "#{'f'}": arr.push 6
30465    g: arr.push 7
30466  arrayEq arr, [1..7]
30467  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
30468
30469test "object keys with interpolations: object starting with dynamic key", ->
30470  obj =
30471    "#{'a'}": 1
30472    b: 2
30473  deepEqual obj, {a: 1, b: 2}
30474
30475test "object keys with interpolations: comments in implicit object", ->
30476  obj =
30477    ### leading comment ###
30478    "#{'a'}": 1
30479
30480    ### middle ###
30481
30482    "#{'b'}": 2
30483    # regular comment
30484    'c': 3
30485    ### foo ###
30486    d: 4
30487    "#{'e'}": 5
30488  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
30489
30490  # Comments in explicit object.
30491  obj = {
30492    ### leading comment ###
30493    "#{'a'}": 1
30494
30495    ### middle ###
30496
30497    "#{'b'}": 2
30498    # regular comment
30499    'c': 3
30500    ### foo ###
30501    d: 4
30502    "#{'e'}": 5
30503  }
30504  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
30505
30506test "object keys with interpolations: more complicated case", ->
30507  obj = {
30508    "#{'interpolated'}":
30509      """
30510        #{ '''nested''' }
30511      """: 123: 456
30512  }
30513  deepEqual obj,
30514    interpolated:
30515      nested:
30516        123: 456
30517
30518test "#4324: Shorthand after interpolated key", ->
30519  a = 2
30520  obj = {"#{1}": 1, a}
30521  eq 1, obj[1]
30522  eq 2, obj.a
30523
30524test "computed property keys: simple cases", ->
30525  a = 'a'
30526  obj = [a]: yes
30527  eq obj.a, yes
30528  obj = {[a]: yes}
30529  eq obj.a, yes
30530  obj = {[a]}
30531  eq obj.a, 'a'
30532  obj = {[5]}
30533  eq obj[5], 5
30534  obj = {['5']}
30535  eq obj['5'], '5'
30536
30537test "computed property keys: commas in implicit object", ->
30538  obj = ['a']: 1, b: 2
30539  deepEqual obj, {a: 1, b: 2}
30540  obj = a: 1, ['b']: 2
30541  deepEqual obj, {a: 1, b: 2}
30542  obj = ['a']: 1, ['b']: 2
30543  deepEqual obj, {a: 1, b: 2}
30544
30545test "computed property keys: commas in explicit object", ->
30546  obj = {['a']: 1, b: 2}
30547  deepEqual obj, {a: 1, b: 2}
30548  obj = {a: 1, ['b']: 2}
30549  deepEqual obj, {a: 1, b: 2}
30550  obj = {['a']: 1, ['b']: 2}
30551  deepEqual obj, {a: 1, b: 2}
30552
30553test "computed property keys: commas after key with interpolation", ->
30554  obj = {['a']: yes,}
30555  eq obj.a, yes
30556  obj = {
30557    ['a']: 1,
30558    ['b']: 2,
30559    ### herecomment ###
30560    ['c']: 3,
30561  }
30562  deepEqual obj, {a: 1, b: 2, c: 3}
30563  obj =
30564    ['a']: 1,
30565    ['b']: 2,
30566    ### herecomment ###
30567    ['c']: 3,
30568  deepEqual obj, {a: 1, b: 2, c: 3}
30569  obj =
30570    ['a']: 1,
30571    ['b']: 2,
30572    ### herecomment ###
30573    ['c']: 3, ['d']: 4,
30574  deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
30575
30576test "computed property keys: key with interpolation mixed with `@prop`", ->
30577  deepEqual (-> {@a, ['b']: 2}).call(a: 1), {a: 1, b: 2}
30578
30579test "computed property keys: evaluate only once", ->
30580  count = 0
30581  a = -> count++; 'a'
30582  obj = {[a()]}
30583  eq obj.a, 'a'
30584  eq count, 1
30585
30586test "computed property keys: evaluation order", ->
30587  arr = []
30588  obj =
30589    a: arr.push 1
30590    b: arr.push 2
30591    ['c']: arr.push 3
30592    ['d']: arr.push 4
30593    e: arr.push 5
30594    ['f']: arr.push 6
30595    g: arr.push 7
30596  arrayEq arr, [1..7]
30597  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
30598
30599test "computed property keys: object starting with dynamic key", ->
30600  obj =
30601    ['a']: 1
30602    b: 2
30603  deepEqual obj, {a: 1, b: 2}
30604
30605test "computed property keys: comments in implicit object", ->
30606  obj =
30607    ### leading comment ###
30608    ['a']: 1
30609
30610    ### middle ###
30611
30612    ['b']: 2
30613    # regular comment
30614    'c': 3
30615    ### foo ###
30616    d: 4
30617    ['e']: 5
30618  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
30619
30620  obj = {
30621    ### leading comment ###
30622    ['a']: 1
30623
30624    ### middle ###
30625
30626    ['b']: 2
30627    # regular comment
30628    'c': 3
30629    ### foo ###
30630    d: 4
30631    ['e']: 5
30632  }
30633  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
30634
30635test "computed property keys: more complicated case", ->
30636  obj = {
30637    ['interpolated']:
30638       ['nested']:
30639         123: 456
30640  }
30641  deepEqual obj,
30642    interpolated:
30643      nested:
30644        123: 456
30645
30646test "computed property keys: empty array as key", ->
30647  o1 = { [[]] }
30648  deepEqual o1, { [[]]: [] }
30649  arrayEq o1[[]], []
30650  o2 = { [[]]: 1 }
30651  deepEqual o2, { [[]]: 1 }
30652  eq o2[[]], 1
30653  o3 = [[]]: 1
30654  deepEqual o3, { [[]]: 1 }
30655  deepEqual o3, { [[]]: 1 }
30656  eq o3[[]], 1
30657  o4 = a: 1, [[]]: 2
30658  deepEqual o4, { a: 1, [[]]: 2 }
30659  eq o4.a, 1,
30660  eq o4[[]], 2
30661  o5 = { a: 1, [[]]: 2 }
30662  deepEqual o5, { a: 1, [[]]: 2 }
30663  eq o5.a, 1,
30664  eq o5[[]], 2
30665
30666test "computed property keys: shorthand after computed property key", ->
30667  a = 2
30668  obj = {[1]: 1, a}
30669  eq 1, obj[1]
30670  eq 2, obj.a
30671
30672test "computed property keys: shorthand computed property key", ->
30673  a = 'b'
30674  o = {[a]}
30675  p = {a}
30676  r = {['a']}
30677  eq o.b, 'b'
30678  eq p.a, o.b
30679  eq r.a, 'a'
30680
30681  foo = -> "a"
30682  obj = { [foo()] }
30683  eq obj.a, 'a'
30684
30685test "computed property keys: arrays", ->
30686  b = 'b'
30687  f = (c) -> "#{c}1"
30688  obj =
30689    ['a']: [1, 2, 3]
30690    [b]: [4, 5, 6]
30691    [f(b)]: [7, 8, 9]
30692  arrayEq obj.a, [1, 2, 3]
30693  arrayEq obj.b, [4, 5, 6]
30694  arrayEq obj.b1, [7, 8, 9]
30695
30696test "computed property keys: examples from developer.mozilla.org (Object initializer)", ->
30697  i = 0
30698  obj =
30699    ['foo' + ++i]: i
30700    ['foo' + ++i]: i
30701    ['foo' + ++i]: i
30702  eq obj.foo1, 1
30703  eq obj.foo2, 2
30704  eq obj.foo3, 3
30705
30706  param = 'size'
30707  config =
30708    [param]: 12,
30709    ['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
30710  deepEqual config, {size: 12,  mobileSize: 4}
30711
30712test "computed property keys: [Symbol.iterator]", ->
30713  obj =
30714    [Symbol.iterator]: ->
30715      yield "hello"
30716      yield "world"
30717  arrayEq [obj...], ['hello', 'world']
30718
30719test "computed property keys: Class property", ->
30720  increment_method = "increment"
30721  decrement_method = "decrement"
30722  class Obs
30723    constructor: (@count) ->
30724    [increment_method]: -> @count += 1
30725    [decrement_method]: -> @count -= 1
30726  ob = new Obs 2
30727  eq ob.increment(), 3
30728  eq ob.decrement(), 2
30729
30730test "#1263: Braceless object return", ->
30731  fn = ->
30732    return
30733      a: 1
30734      b: 2
30735      c: -> 3
30736
30737  obj = fn()
30738  eq 1, obj.a
30739  eq 2, obj.b
30740  eq 3, obj.c()
30741
30742test "#4564: indent should close implicit object", ->
30743  f = (x) -> x
30744
30745  arrayEq ['a'],
30746    for key of f a: 1
30747      key
30748
30749  g = null
30750  if f a: 1
30751    g = 3
30752  eq g, 3
30753
30754  h = null
30755  if a: (i for i in [1, 2, 3])
30756    h = 4
30757  eq h, 4
30758
30759test "#4544: Postfix conditionals in first line of implicit object literals", ->
30760  two =
30761    foo:
30762      bar: 42 if yes
30763      baz: 1337
30764  eq 42, two.foo.bar
30765  eq 1337, two.foo.baz
30766
30767  f = (x) -> x
30768
30769  three =
30770    foo: f
30771      bar: 42 if yes
30772      baz: 1337
30773  eq 42, three.foo.bar
30774  eq 1337, three.foo.baz
30775
30776  four =
30777    f
30778      foo:
30779        bar: 42 if yes
30780      baz: 1337
30781  eq 42, four.foo.bar
30782  eq 1337, four.baz
30783
30784  x = bar: 42 if no
30785  baz: 1337
30786  ok not x?
30787
30788  # Example from #2051
30789  a = null
30790  _alert = (arg) -> a = arg
30791  _alert
30792    val3: "works" if true
30793    val: "hello"
30794    val2: "all good"
30795  eq a.val2, "all good"
30796
30797test "#4579: Postfix for/while/until in first line of implicit object literals", ->
30798  two =
30799    foo:
30800      bar1: x for x in [1, 2, 3]
30801      bar2: x + y for x, y in [1, 2, 3]
30802      baz: 1337
30803  arrayEq [1, 2, 3], two.foo.bar1
30804  arrayEq [1, 3, 5], two.foo.bar2
30805  eq 1337, two.foo.baz
30806
30807  f = (x) -> x
30808
30809  three =
30810    foo: f
30811      bar1: x + y for x, y of a: 'b', c: 'd'
30812      bar2: x + 'c' for x of a: 1, b: 2
30813      baz: 1337
30814  arrayEq ['ab', 'cd'], three.foo.bar1
30815  arrayEq ['ac', 'bc'], three.foo.bar2
30816  eq 1337, three.foo.baz
30817
30818  four =
30819    f
30820      foo:
30821        "bar_#{x}": x for x of a: 1, b: 2
30822      baz: 1337
30823  eq 'a', four.foo[0].bar_a
30824  eq 'b', four.foo[1].bar_b
30825  eq 1337, four.baz
30826
30827  x = bar: 42 for y in [1]
30828  baz: 1337
30829  eq x.bar, 42
30830
30831  i = 5
30832  five =
30833    foo:
30834      bar: i while i-- > 0
30835      baz: 1337
30836  arrayEq [4, 3, 2, 1, 0], five.foo.bar
30837  eq 1337, five.foo.baz
30838
30839  i = 5
30840  six =
30841    foo:
30842      bar: i until i-- <= 0
30843      baz: 1337
30844  arrayEq [4, 3, 2, 1, 0], six.foo.bar
30845  eq 1337, six.foo.baz
30846
30847test "#5204: not parsed as static property", ->
30848  doesNotThrowCompileError "@ [b]: 2"
30849
30850test "#5292: implicit object after line continuer in implicit object property value", ->
30851  a =
30852    b: 0 or
30853      c: 1
30854  eq 1, a.b.c
30855
30856  # following object property
30857  a =
30858    b: null ?
30859      c: 1
30860    d: 2
30861  eq 1, a.b.c
30862  eq 2, a.d
30863
30864  # multiline nested object
30865  a =
30866    b: 0 or
30867      c: 1
30868      d: 2
30869    e: 3
30870  eq 1, a.b.c
30871  eq 2, a.b.d
30872  eq 3, a.e
30873
30874test "#5368: continuing object and array literals", ->
30875  { a
30876    b: { c }
30877  } = {a: 1, b: {c: 2}}
30878  eq a, 1
30879  eq c, 2
30880
30881  [d
30882   e: f
30883  ] = [3, {e: 4}]
30884  eq d, 3
30885  eq f, 4
30886  A =
30887    [d
30888     e: f
30889    ]
30890  eq A[0], 3
30891  eq A[1].e, 4
30892
30893  for obj in [
30894    {a: a
30895     c: c
30896    }
30897    {a: a
30898     c
30899    }
30900    {a
30901     c: c
30902    }
30903    {a
30904     c
30905    }
30906  ]
30907    eq obj.a, 1
30908    eq obj.c, 2
30909
30910</script>
vendor: 1 bytes, line 30910
30910
30911<script type="text/x-coffeescript" class="test" id="operators">
30912# Operators
30913# ---------
30914
30915# * Operators
30916# * Existential Operator (Binary)
30917# * Existential Operator (Unary)
30918# * Aliased Operators
30919# * [not] in/of
30920# * Chained Comparison
30921
30922test "binary (2-ary) math operators do not require spaces", ->
30923  a = 1
30924  b = -1
30925  eq +1, a*-b
30926  eq -1, a*+b
30927  eq +1, a/-b
30928  eq -1, a/+b
30929
30930test "operators should respect new lines as spaced", ->
30931  a = 123 +
30932  456
30933  eq 579, a
30934
30935  b = "1#{2}3" +
30936  "456"
30937  eq '123456', b
30938
30939test "multiple operators should space themselves", ->
30940  eq (+ +1), (- -1)
30941
30942test "compound operators on successive lines", ->
30943  a = 1
30944  a +=
30945  1
30946  eq a, 2
30947
30948test "bitwise operators", ->
30949  eq  2, (10 &   3)
30950  eq 11, (10 |   3)
30951  eq  9, (10 ^   3)
30952  eq 80, (10 <<  3)
30953  eq  1, (10 >>  3)
30954  eq  1, (10 >>> 3)
30955  num = 10; eq  2, (num &=   3)
30956  num = 10; eq 11, (num |=   3)
30957  num = 10; eq  9, (num ^=   3)
30958  num = 10; eq 80, (num <<=  3)
30959  num = 10; eq  1, (num >>=  3)
30960  num = 10; eq  1, (num >>>= 3)
30961
30962test "`instanceof`", ->
30963  ok new String instanceof String
30964  ok new Boolean instanceof Boolean
30965  # `instanceof` supports negation by prefixing the operator with `not`
30966  ok new Number not instanceof String
30967  ok new Array not instanceof Boolean
30968
30969test "use `::` operator on keywords `this` and `@`", ->
30970  nonce = {}
30971  obj =
30972    withAt:   -> @::prop
30973    withThis: -> this::prop
30974  obj.prototype = prop: nonce
30975  eq nonce, obj.withAt()
30976  eq nonce, obj.withThis()
30977
30978
30979# Existential Operator (Binary)
30980
30981test "binary existential operator", ->
30982  nonce = {}
30983
30984  b = a ? nonce
30985  eq nonce, b
30986
30987  a = null
30988  b = undefined
30989  b = a ? nonce
30990  eq nonce, b
30991
30992  a = false
30993  b = a ? nonce
30994  eq false, b
30995
30996  a = 0
30997  b = a ? nonce
30998  eq 0, b
30999
31000test "binary existential operator conditionally evaluates second operand", ->
31001  i = 1
31002  func = -> i -= 1
31003  result = func() ? func()
31004  eq result, 0
31005
31006test "binary existential operator with negative number", ->
31007  a = null ? - 1
31008  eq -1, a
31009
31010
31011# Existential Operator (Unary)
31012
31013test "postfix existential operator", ->
31014  ok (if nonexistent? then false else true)
31015  defined = true
31016  ok defined?
31017  defined = false
31018  ok defined?
31019
31020test "postfix existential operator only evaluates its operand once", ->
31021  semaphore = 0
31022  fn = ->
31023    ok false if semaphore
31024    ++semaphore
31025  ok(if fn()? then true else false)
31026
31027test "negated postfix existential operator", ->
31028  ok !nothing?.value
31029
31030test "postfix existential operator on expressions", ->
31031  eq true, (1 or 0)?, true
31032
31033
31034# `is`,`isnt`,`==`,`!=`
31035
31036test "`==` and `is` should be interchangeable", ->
31037  a = b = 1
31038  ok a is 1 and b == 1
31039  ok a == b
31040  ok a is b
31041
31042test "`!=` and `isnt` should be interchangeable", ->
31043  a = 0
31044  b = 1
31045  ok a isnt 1 and b != 0
31046  ok a != b
31047  ok a isnt b
31048
31049
31050# [not] in/of
31051
31052# - `in` should check if an array contains a value using `indexOf`
31053# - `of` should check if a property is defined on an object using `in`
31054test "in, of", ->
31055  arr = [1]
31056  ok 0 of arr
31057  ok 1 in arr
31058  # prefixing `not` to `in and `of` should negate them
31059  ok 1 not of arr
31060  ok 0 not in arr
31061
31062test "`in` should be able to operate on an array literal", ->
31063  ok 2 in [0, 1, 2, 3]
31064  ok 4 not in [0, 1, 2, 3]
31065  arr = [0, 1, 2, 3]
31066  ok 2 in arr
31067  ok 4 not in arr
31068  # should cache the value used to test the array
31069  arr = [0]
31070  val = 0
31071  ok val++ in arr
31072  ok val++ not in arr
31073  val = 0
31074  ok val++ of arr
31075  ok val++ not of arr
31076
31077test "`of` and `in` should be able to operate on instance variables", ->
31078  obj = {
31079    list: [2,3]
31080    in_list: (value) -> value in @list
31081    not_in_list: (value) -> value not in @list
31082    of_list: (value) -> value of @list
31083    not_of_list: (value) -> value not of @list
31084  }
31085  ok obj.in_list 3
31086  ok obj.not_in_list 1
31087  ok obj.of_list 0
31088  ok obj.not_of_list 2
31089
31090test "#???: `in` with cache and `__indexOf` should work in argument lists", ->
31091  eq 1, [Object() in Array()].length
31092
31093test "#737: `in` should have higher precedence than logical operators", ->
31094  eq 1, 1 in [1] and 1
31095
31096test "#768: `in` should preserve evaluation order", ->
31097  share = 0
31098  a = -> share++ if share is 0
31099  b = -> share++ if share is 1
31100  c = -> share++ if share is 2
31101  ok a() not in [b(),c()]
31102  eq 3, share
31103
31104test "#1099: empty array after `in` should compile to `false`", ->
31105  eq 1, [5 in []].length
31106  eq false, do -> return 0 in []
31107
31108test "#1354: optimized `in` checks should not happen when splats are present", ->
31109  a = [6, 9]
31110  eq 9 in [3, a...], true
31111
31112test "#1100: precedence in or-test compilation of `in`", ->
31113  ok 0 in [1 and 0]
31114  ok 0 in [1, 1 and 0]
31115  ok not (0 in [1, 0 or 1])
31116
31117test "#1630: `in` should check `hasOwnProperty`", ->
31118  ok undefined not in length: 1
31119
31120test "#1714: lexer bug with raw range `for` followed by `in`", ->
31121  0 for [1..2]
31122  ok not ('a' in ['b'])
31123
31124  0 for [1..2]; ok not ('a' in ['b'])
31125
31126  0 for [1..10] # comment ending
31127  ok not ('a' in ['b'])
31128
31129  # lexer state (specifically @seenFor) should be reset before each compilation
31130  CoffeeScript.compile "0 for [1..2]"
31131  CoffeeScript.compile "'a' in ['b']"
31132
31133test "#1099: statically determined `not in []` reporting incorrect result", ->
31134  ok 0 not in []
31135
31136test "#1099: make sure expression tested gets evaluted when array is empty", ->
31137  a = 0
31138  (do -> a = 1) in []
31139  eq a, 1
31140
31141# Chained Comparison
31142
31143test "chainable operators", ->
31144  ok 100 > 10 > 1 > 0 > -1
31145  ok -1 < 0 < 1 < 10 < 100
31146
31147test "`is` and `isnt` may be chained", ->
31148  ok true is not false is true is not false
31149  ok 0 is 0 isnt 1 is 1
31150
31151test "different comparison operators (`>`,`<`,`is`,etc.) may be combined", ->
31152  ok 1 < 2 > 1
31153  ok 10 < 20 > 2+3 is 5
31154
31155test "some chainable operators can be negated by `unless`", ->
31156  ok (true unless 0==10!=100)
31157
31158test "operator precedence: `|` lower than `<`", ->
31159  eq 1, 1 | 2 < 3 < 4
31160
31161test "preserve references", ->
31162  a = b = c = 1
31163  # `a == b <= c` should become `a === b && b <= c`
31164  # (this test does not seem to test for this)
31165  ok a == b <= c
31166
31167test "chained operations should evaluate each value only once", ->
31168  a = 0
31169  ok 1 > a++ < 1
31170
31171test "#891: incorrect inversion of chained comparisons", ->
31172  ok (true unless 0 > 1 > 2)
31173  ok (true unless (this.NaN = 0/0) < 0/0 < this.NaN)
31174
31175test "#1234: Applying a splat to :: applies the splat to the wrong object", ->
31176  nonce = {}
31177  class C
31178    method: -> @nonce
31179    nonce: nonce
31180
31181  arr = []
31182  eq nonce, C::method arr... # should be applied to `C::`
31183
31184test "#1102: String literal prevents line continuation", ->
31185  eq "': '", '' +
31186     "': '"
31187
31188test "#1703, ---x is invalid JS", ->
31189  x = 2
31190  eq (- --x), -1
31191
31192test "Regression with implicit calls against an indented assignment", ->
31193  eq 1, a =
31194    1
31195
31196  eq a, 1
31197
31198test "#2155 ... conditional assignment to a closure", ->
31199  x = null
31200  func = -> x ?= (-> if true then 'hi')
31201  func()
31202  eq x(), 'hi'
31203
31204test "#2197: Existential existential double trouble", ->
31205  counter = 0
31206  func = -> counter++
31207  func()? ? 100
31208  eq counter, 1
31209
31210test "#2567: Optimization of negated existential produces correct result", ->
31211  a = 1
31212  ok !(!a?)
31213  ok !b?
31214
31215test "#2508: Existential access of the prototype", ->
31216  eq NonExistent?::nothing, undefined
31217  eq(
31218    NonExistent
31219    ?::nothing
31220    undefined
31221  )
31222  ok Object?::toString
31223  ok(
31224    Object
31225    ?::toString
31226  )
31227
31228test "floor division operator", ->
31229  eq 2, 7 // 3
31230  eq -3, -7 // 3
31231  eq NaN, 0 // 0
31232
31233test "floor division operator compound assignment", ->
31234  a = 7
31235  a //= 1 + 1
31236  eq 3, a
31237
31238test "modulo operator", ->
31239  check = (a, b, expected) ->
31240    eq expected, a %% b, "expected #{a} %%%% #{b} to be #{expected}"
31241  check 0, 1, 0
31242  check 0, -1, -0
31243  check 1, 0, NaN
31244  check 1, 2, 1
31245  check 1, -2, -1
31246  check 1, 3, 1
31247  check 2, 3, 2
31248  check 3, 3, 0
31249  check 4, 3, 1
31250  check -1, 3, 2
31251  check -2, 3, 1
31252  check -3, 3, 0
31253  check -4, 3, 2
31254  check 5.5, 2.5, 0.5
31255  check -5.5, 2.5, 2.0
31256
31257test "modulo operator compound assignment", ->
31258  a = -2
31259  a %%= 5
31260  eq 3, a
31261
31262test "modulo operator converts arguments to numbers", ->
31263  eq 1, 1 %% '42'
31264  eq 1, '1' %% 42
31265  eq 1, '1' %% '42'
31266
31267test "#3361: Modulo operator coerces right operand once", ->
31268  count = 0
31269  res = 42 %% valueOf: -> count += 1
31270  eq 1, count
31271  eq 0, res
31272
31273test "#3363: Modulo operator coercing order", ->
31274  count = 2
31275  a = valueOf: -> count *= 2
31276  b = valueOf: -> count += 1
31277  eq 4, a %% b
31278  eq 5, count
31279
31280test "#3598: Unary + and - coerce the operand once when it is an identifier", ->
31281  # Unary + and - do not generate `_ref`s when the operand is a number, for
31282  # readability. To make sure that they do when the operand is an identifier,
31283  # test that they are consistent with another unary operator as well as another
31284  # complex expression.
31285  # Tip: Making one of the tests temporarily fail lets you easily inspect the
31286  # compiled JavaScript.
31287
31288  assertOneCoercion = (fn) ->
31289    count = 0
31290    value = valueOf: -> count++; 1
31291    fn value
31292    eq 1, count
31293
31294  eq 1, 1 ? 0
31295  eq 1, +1 ? 0
31296  eq -1, -1 ? 0
31297  assertOneCoercion (a) ->
31298    eq 1, +a ? 0
31299  assertOneCoercion (a) ->
31300    eq -1, -a ? 0
31301  assertOneCoercion (a) ->
31302    eq -2, ~a ? 0
31303  assertOneCoercion (a) ->
31304    eq 0.5, a / 2 ? 0
31305
31306  ok -2 <= 1 < 2
31307  ok -2 <= +1 < 2
31308  ok -2 <= -1 < 2
31309  assertOneCoercion (a) ->
31310    ok -2 <= +a < 2
31311  assertOneCoercion (a) ->
31312    ok -2 <= -a < 2
31313  assertOneCoercion (a) ->
31314    ok -2 <= ~a < 2
31315  assertOneCoercion (a) ->
31316    ok -2 <= a / 2 < 2
31317
31318  arrayEq [0], (n for n in [0] by 1)
31319  arrayEq [0], (n for n in [0] by +1)
31320  arrayEq [0], (n for n in [0] by -1)
31321  assertOneCoercion (a) ->
31322    arrayEq [0], (n for n in [0] by +a)
31323  assertOneCoercion (a) ->
31324    arrayEq [0], (n for n in [0] by -a)
31325  assertOneCoercion (a) ->
31326    arrayEq [0], (n for n in [0] by ~a)
31327  assertOneCoercion (a) ->
31328    arrayEq [0], (n for n in [0] by a * 2 / 2)
31329
31330  ok 1 in [0, 1]
31331  ok +1 in [0, 1]
31332  ok -1 in [0, -1]
31333  assertOneCoercion (a) ->
31334    ok +a in [0, 1]
31335  assertOneCoercion (a) ->
31336    ok -a in [0, -1]
31337  assertOneCoercion (a) ->
31338    ok ~a in [0, -2]
31339  assertOneCoercion (a) ->
31340    ok a / 2 in [0, 0.5]
31341
31342test "'new' target", ->
31343  nonce = {}
31344  ctor  = -> nonce
31345
31346  eq (new ctor), nonce
31347  eq (new ctor()), nonce
31348
31349  ok new class
31350
31351  ctor  = class
31352  ok (new ctor) instanceof ctor
31353  ok (new ctor()) instanceof ctor
31354
31355  # Force an executable class body
31356  ctor  = class then a = 1
31357  ok (new ctor) instanceof ctor
31358
31359  get   = -> ctor
31360  ok (new get()) not instanceof ctor
31361  ok (new (get())()) instanceof ctor
31362
31363  # classes must be called with `new`. In this case `new` applies to `get` only
31364  throws -> new get()()
31365
31366</script>
vendor: 1 bytes, line 31366
31366
31367<script type="text/x-coffeescript" class="test" id="option_parser">
31368# Option Parser
31369# -------------
31370
31371# Ensure that the OptionParser handles arguments correctly.
31372return unless require?
31373{OptionParser} = require './../lib/coffeescript/optparse'
31374
31375flags = [
31376  ['-r', '--required [DIR]',  'desc required']
31377  ['-o', '--optional',        'desc optional']
31378  ['-l', '--list [FILES*]',   'desc list']
31379]
31380
31381banner = '''
31382  banner text
31383'''
31384
31385opt = new OptionParser flags, banner
31386
31387test "basic arguments", ->
31388  args = ['one', 'two', 'three', '-r', 'dir']
31389  result = opt.parse args
31390  arrayEq args, result.arguments
31391  eq undefined, result.required
31392
31393test "boolean and parameterised options", ->
31394  result = opt.parse ['--optional', '-r', 'folder', 'one', 'two']
31395  ok result.optional
31396  eq 'folder', result.required
31397  arrayEq ['one', 'two'], result.arguments
31398
31399test "list options", ->
31400  result = opt.parse ['-l', 'one.txt', '-l', 'two.txt', 'three']
31401  arrayEq ['one.txt', 'two.txt'], result.list
31402  arrayEq ['three'], result.arguments
31403
31404test "-- and interesting combinations", ->
31405  result = opt.parse ['-o','-r','a','-r','b','-o','--','-a','b','--c','d']
31406  arrayEq ['-a', 'b', '--c', 'd'], result.arguments
31407  ok result.optional
31408  eq 'b', result.required
31409
31410  args = ['--','-o','a','-r','c','-o','--','-a','arg0','-b','arg1']
31411  result = opt.parse args
31412  eq undefined, result.optional
31413  eq undefined, result.required
31414  arrayEq args[1..], result.arguments
31415
31416test "throw if multiple flags try to use the same short or long name", ->
31417  throws -> new OptionParser [
31418    ['-r', '--required [DIR]', 'required']
31419    ['-r', '--long',           'switch']
31420  ]
31421
31422  throws -> new OptionParser [
31423    ['-a', '--append [STR]', 'append']
31424    ['-b', '--append',       'append with -b short opt']
31425  ]
31426
31427  throws -> new OptionParser [
31428    ['--just-long', 'desc']
31429    ['--just-long', 'another desc']
31430  ]
31431
31432  throws -> new OptionParser [
31433    ['-j', '--just-long', 'desc']
31434    ['--just-long', 'another desc']
31435  ]
31436
31437  throws -> new OptionParser [
31438    ['--just-long',       'desc']
31439    ['-j', '--just-long', 'another desc']
31440  ]
31441
31442test "outputs expected help text", ->
31443  expectedBanner = '''
31444
31445banner text
31446
31447  -r, --required     desc required
31448  -o, --optional     desc optional
31449  -l, --list         desc list
31450
31451  '''
31452  ok opt.help() is expectedBanner
31453
31454  expected = [
31455    ''
31456    '  -r, --required     desc required'
31457    '  -o, --optional     desc optional'
31458    '  -l, --list         desc list'
31459    ''
31460  ].join('\n')
31461  ok new OptionParser(flags).help() is expected
31462
31463</script>
vendor: 1 bytes, line 31463
31463
31464<script type="text/x-coffeescript" class="test" id="package">
31465return if window? or testingBrowser?
31466
31467{EventEmitter}  = require 'events'
31468{join}          = require 'path'
31469{cwd}           = require 'process'
31470{pathToFileURL} = require 'url'
31471
31472
31473packageEntryPath = join cwd(), 'lib/coffeescript/index.js'
31474packageEntryUrl  = pathToFileURL packageEntryPath
31475
31476
31477test "the coffeescript package exposes all members as named exports in Node", ->
31478
31479  requiredPackage = require packageEntryPath
31480  requiredKeys = Object.keys requiredPackage
31481
31482  importedPackage = await import(packageEntryUrl)
31483  importedKeys = new Set Object.keys(importedPackage)
31484
31485  # In `command.coffee`, CoffeeScript extends a `new EventEmitter`;
31486  # we want to ignore these additional added keys.
31487  eventEmitterKeys = new Set Object.getOwnPropertyNames(Object.getPrototypeOf(new EventEmitter))
31488
31489  for key in requiredKeys when not eventEmitterKeys.has(key)
31490    # Use `eq` test so that missing keys have their names printed in the error message.
31491    eq (if importedKeys.has(key) then key else undefined), key
31492
31493</script>
vendor: 1 bytes, line 31493
31493
31494<script type="text/x-coffeescript" class="test" id="parser">
31495# Parser
31496# ---------
31497
31498test "operator precedence for logical operators", ->
31499  source = '''
31500    a or b and c
31501  '''
31502  {body: block} = CoffeeScript.nodes source
31503  [expression] = block.expressions
31504  eq expression.first.base.value, 'a'
31505  eq expression.operator, '||'
31506  eq expression.second.first.base.value, 'b'
31507  eq expression.second.operator, '&&'
31508  eq expression.second.second.base.value, 'c'
31509
31510test "operator precedence for bitwise operators", ->
31511  source = '''
31512    a | b ^ c & d
31513  '''
31514  {body: block} = CoffeeScript.nodes source
31515  [expression] = block.expressions
31516  eq expression.first.base.value, 'a'
31517  eq expression.operator, '|'
31518  eq expression.second.first.base.value, 'b'
31519  eq expression.second.operator, '^'
31520  eq expression.second.second.first.base.value, 'c'
31521  eq expression.second.second.operator, '&'
31522  eq expression.second.second.second.base.value, 'd'
31523
31524test "operator precedence for binary ? operator", ->
31525  source = '''
31526     a ? b and c
31527  '''
31528  {body: block} = CoffeeScript.nodes source
31529  [expression] = block.expressions
31530  eq expression.first.base.value, 'a'
31531  eq expression.operator, '?'
31532  eq expression.second.first.base.value, 'b'
31533  eq expression.second.operator, '&&'
31534  eq expression.second.second.base.value, 'c'
31535
31536test "new calls have a range including the new", ->
31537  source = '''
31538    a = new B().c(d)
31539  '''
31540  {body: block} = CoffeeScript.nodes source
31541
31542  assertColumnRange = (node, firstColumn, lastColumn) ->
31543    eq node.locationData.first_line, 0
31544    eq node.locationData.first_column, firstColumn
31545    eq node.locationData.last_line, 0
31546    eq node.locationData.last_column, lastColumn
31547
31548  [assign] = block.expressions
31549  outerCall = assign.value.base
31550  innerValue = outerCall.variable
31551  innerCall = innerValue.base
31552
31553  assertColumnRange assign, 0, 15
31554  assertColumnRange outerCall, 4, 15
31555  assertColumnRange innerValue, 4, 12
31556  assertColumnRange innerCall, 4, 10
31557
31558test "location data is properly set for nested `new`", ->
31559  source = '''
31560    new new A()()
31561  '''
31562  {body: block} = CoffeeScript.nodes source
31563
31564  assertColumnRange = (node, firstColumn, lastColumn) ->
31565    eq node.locationData.first_line, 0
31566    eq node.locationData.first_column, firstColumn
31567    eq node.locationData.last_line, 0
31568    eq node.locationData.last_column, lastColumn
31569
31570  [{base: outerCall}] = block.expressions
31571  innerCall = outerCall.variable
31572
31573  assertColumnRange outerCall, 0, 12
31574  assertColumnRange innerCall, 4, 10
31575
31576</script>
vendor: 1 bytes, line 31576
31576
31577<script type="text/x-coffeescript" class="test" id="ranges">
31578# Range Literals
31579# --------------
31580
31581# TODO: add indexing and method invocation tests: [1..4][0] is 1, [0...3].toString()
31582
31583# shared array
31584shared = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
31585
31586test "basic inclusive ranges", ->
31587  arrayEq [1, 2, 3] , [1..3]
31588  arrayEq [0, 1, 2] , [0..2]
31589  arrayEq [0, 1]    , [0..1]
31590  arrayEq [0]       , [0..0]
31591  arrayEq [-1]      , [-1..-1]
31592  arrayEq [-1, 0]   , [-1..0]
31593  arrayEq [-1, 0, 1], [-1..1]
31594
31595test "basic exclusive ranges", ->
31596  arrayEq [1, 2, 3] , [1...4]
31597  arrayEq [0, 1, 2] , [0...3]
31598  arrayEq [0, 1]    , [0...2]
31599  arrayEq [0]       , [0...1]
31600  arrayEq [-1]      , [-1...0]
31601  arrayEq [-1, 0]   , [-1...1]
31602  arrayEq [-1, 0, 1], [-1...2]
31603
31604  arrayEq [], [1...1]
31605  arrayEq [], [0...0]
31606  arrayEq [], [-1...-1]
31607
31608  # Should not trigger implicit call, e.g. rest ... => rest(...)
31609  arrayEq [1, 2, 3] , [1 ... 4]
31610  arrayEq [0, 1, 2] , [0 ... 3]
31611  arrayEq [0, 1]    , [0 ... 2]
31612  arrayEq [0]       , [0 ... 1]
31613  arrayEq [-1]      , [-1 ... 0]
31614  arrayEq [-1, 0]   , [-1 ... 1]
31615  arrayEq [-1, 0, 1], [-1 ... 2]
31616
31617  arrayEq [], [1 ... 1]
31618  arrayEq [], [0 ... 0]
31619  arrayEq [], [-1 ... -1]
31620
31621test "downward ranges", ->
31622  arrayEq shared, [9..0].reverse()
31623  arrayEq [5, 4, 3, 2] , [5..2]
31624  arrayEq [2, 1, 0, -1], [2..-1]
31625
31626  arrayEq [3, 2, 1]  , [3..1]
31627  arrayEq [2, 1, 0]  , [2..0]
31628  arrayEq [1, 0]     , [1..0]
31629  arrayEq [0]        , [0..0]
31630  arrayEq [-1]       , [-1..-1]
31631  arrayEq [0, -1]    , [0..-1]
31632  arrayEq [1, 0, -1] , [1..-1]
31633  arrayEq [0, -1, -2], [0..-2]
31634
31635  arrayEq [4, 3, 2], [4...1]
31636  arrayEq [3, 2, 1], [3...0]
31637  arrayEq [2, 1]   , [2...0]
31638  arrayEq [1]      , [1...0]
31639  arrayEq []       , [0...0]
31640  arrayEq []       , [-1...-1]
31641  arrayEq [0]      , [0...-1]
31642  arrayEq [0, -1]  , [0...-2]
31643  arrayEq [1, 0]   , [1...-1]
31644  arrayEq [2, 1, 0], [2...-1]
31645
31646test "ranges with variables as enpoints", ->
31647  [a, b] = [1, 3]
31648  arrayEq [1, 2, 3], [a..b]
31649  arrayEq [1, 2]   , [a...b]
31650  b = -2
31651  arrayEq [1, 0, -1, -2], [a..b]
31652  arrayEq [1, 0, -1]    , [a...b]
31653
31654test "ranges with expressions as endpoints", ->
31655  [a, b] = [1, 3]
31656  arrayEq [2, 3, 4, 5, 6], [(a+1)..2*b]
31657  arrayEq [2, 3, 4, 5]   , [(a+1)...2*b]
31658
31659  # Should not trigger implicit call, e.g. rest ... => rest(...)
31660  arrayEq [2, 3, 4, 5]   , [(a+1) ... 2*b]
31661
31662test "large ranges are generated with looping constructs", ->
31663  down = [99..0]
31664  eq 100, (len = down.length)
31665  eq   0, down[len - 1]
31666
31667  up = [0...100]
31668  eq 100, (len = up.length)
31669  eq  99, up[len - 1]
31670
31671test "for-from loops over ranges", ->
31672  array1 = []
31673  for x from [20..30]
31674    array1.push(x)
31675    break if x is 25
31676  arrayEq array1, [20, 21, 22, 23, 24, 25]
31677
31678test "for-from comprehensions over ranges", ->
31679  array1 = (x + 10 for x from [20..25])
31680  ok array1.join(' ') is '30 31 32 33 34 35'
31681
31682  array2 = (x for x from [20..30] when x %% 2 == 0)
31683  ok array2.join(' ') is '20 22 24 26 28 30'
31684
31685test "#1012 slices with arguments object", ->
31686  expected = [0..9]
31687  argsAtStart = (-> [arguments[0]..9]) 0
31688  arrayEq expected, argsAtStart
31689  argsAtEnd = (-> [0..arguments[0]]) 9
31690  arrayEq expected, argsAtEnd
31691  argsAtBoth = (-> [arguments[0]..arguments[1]]) 0, 9
31692  arrayEq expected, argsAtBoth
31693
31694test "#1409: creating large ranges outside of a function body", ->
31695  CoffeeScript.eval '[0..100]'
31696
31697test "#2047: Infinite loop possible when `for` loop with `range` uses variables", ->
31698  up = 1
31699  down = -1
31700  a = 1
31701  b = 5
31702
31703  testRange = (arg) ->
31704    [from, to, step, expectedResult] = arg
31705    r = (x for x in [from..to] by step)
31706    arrayEq r, expectedResult
31707
31708  testData = [
31709    [1, 5, 1, [1..5]]
31710    [1, 5, -1, []]
31711    [1, 5, up, [1..5]]
31712    [1, 5, down, []]
31713
31714    [a, 5, 1, [1..5]]
31715    [a, 5, -1, []]
31716    [a, 5, up, [1..5]]
31717    [a, 5, down, []]
31718
31719    [1, b, 1, [1..5]]
31720    [1, b, -1, []]
31721    [1, b, up, [1..5]]
31722    [1, b, down, []]
31723
31724    [a, b, 1, [1..5]]
31725    [a, b, -1, []]
31726    [a, b, up, [1..5]]
31727    [a, b, down, []]
31728
31729    [5, 1, 1, []]
31730    [5, 1, -1, [5..1]]
31731    [5, 1, up, []]
31732    [5, 1, down,  [5..1]]
31733
31734    [5, a, 1, []]
31735    [5, a, -1, [5..1]]
31736    [5, a, up, []]
31737    [5, a, down, [5..1]]
31738
31739    [b, 1, 1, []]
31740    [b, 1, -1, [5..1]]
31741    [b, 1, up, []]
31742    [b, 1, down, [5..1]]
31743
31744    [b, a, 1, []]
31745    [b, a, -1, [5..1]]
31746    [b, a, up, []]
31747    [b, a, down, [5..1]]
31748  ]
31749
31750  testRange d for d in testData
31751
31752test "#2047: from, to and step as variables", ->
31753  up = 1
31754  down = -1
31755  a = 1
31756  b = 5
31757
31758  r = (x for x in [a..b] by up)
31759  arrayEq r, [1..5]
31760
31761  r = (x for x in [a..b] by down)
31762  arrayEq r, []
31763
31764  r = (x for x in [b..a] by up)
31765  arrayEq r, []
31766
31767  r = (x for x in [b..a] by down)
31768  arrayEq r, [5..1]
31769
31770  a = 1
31771  b = -1
31772  step = 0
31773  r = (x for x in [b..a] by step)
31774  arrayEq r, []
31775
31776test "#4884: Range not declaring var for the 'i'", ->
31777  'use strict'
31778  [0..21].forEach (idx) ->
31779    idx + 1
31780
31781  eq global.i, undefined
31782
31783test "#4889: `for` loop unexpected behavior", ->
31784  n = 1
31785  result = []
31786  for i in [0..n]
31787    result.push i
31788    for j in [(i+1)..n]
31789      result.push j
31790
31791  arrayEq result, [0,1,1,2,1]
31792
31793test "#4889: `for` loop unexpected behavior with `by 1` on second loop", ->
31794  n = 1
31795  result = []
31796  for i in [0..n]
31797    result.push i
31798    for j in [(i+1)..n] by 1
31799      result.push j
31800
31801  arrayEq result, [0,1,1]
31802
31803test "countdown example from docs", ->
31804  countdown = (num for num in [10..1])
31805  arrayEq countdown, [10,9,8,7,6,5,4,3,2,1]
31806
31807test "counting up when the range goes down returns an empty array", ->
31808  countdown = (num for num in [10..1] by 1)
31809  arrayEq countdown, []
31810
31811test "counting down when the range goes up returns an empty array", ->
31812  countup = (num for num in [1..10] by -1)
31813  arrayEq countup, []
31814
31815test "counting down by too much returns just the first value", ->
31816  countdown = (num for num in [10..1] by -100)
31817  arrayEq countdown, [10]
31818
31819test "counting up by too much returns just the first value", ->
31820  countup = (num for num in [1..10] by 100)
31821  arrayEq countup, [1]
31822
31823</script>
vendor: 1 bytes, line 31823
31823
31824<script type="text/x-coffeescript" class="test" id="regex">
31825# Regular Expression Literals
31826# ---------------------------
31827
31828# TODO: add method invocation tests: /regex/.toString()
31829
31830# * Regexen
31831# * Heregexen
31832
31833test "basic regular expression literals", ->
31834  ok 'a'.match(/a/)
31835  ok 'a'.match /a/
31836  ok 'a'.match(/a/g)
31837  ok 'a'.match /a/g
31838
31839test "division is not confused for a regular expression", ->
31840  # Any spacing around the slash is allowed when it cannot be a regex.
31841  eq 2, 4 / 2 / 1
31842  eq 2, 4/2/1
31843  eq 2, 4/ 2 / 1
31844  eq 2, 4 /2 / 1
31845  eq 2, 4 / 2/ 1
31846  eq 2, 4 / 2 /1
31847  eq 2, 4 /2/ 1
31848
31849  a = (regex) -> regex.test 'a b c'
31850  a.valueOf = -> 4
31851  b = 2
31852  g = 1
31853
31854  eq 2, a / b/g
31855  eq 2, a/ b/g
31856  eq 2, a / b/ g
31857  eq 2, a	/	b/g # Tabs.
31858  eq 2, a / b/g # Non-breaking spaces.
31859  eq true, a /b/g
31860  # Use parentheses to disambiguate.
31861  eq true, a(/ b/g)
31862  eq true, a(/ b/)
31863  eq true, a (/ b/)
31864  # Escape to disambiguate.
31865  eq true, a /\ b/g
31866  eq false, a	/\	b/g
31867  eq true, a /\ b/
31868
31869  obj = method: -> 2
31870  two = 2
31871  eq 2, (obj.method()/two + obj.method()/two)
31872
31873  i = 1
31874  eq 2, (4)/2/i
31875  eq 1, i/i/i
31876
31877  a = ''
31878  a += ' ' until /   /.test a
31879  eq a, '   '
31880
31881  a = if /=/.test '=' then yes else no
31882  eq a, yes
31883
31884  a = if !/=/.test '=' then yes else no
31885  eq a, no
31886
31887  #3182:
31888  match = 'foo=bar'.match /=/
31889  eq match[0], '='
31890
31891  #3410:
31892  ok ' '.match(/ /)[0] is ' '
31893
31894
31895test "division vs regex after a callable token", ->
31896  b = 2
31897  g = 1
31898  r = (r) -> r.test 'b'
31899
31900  a = 4
31901  eq 2, a / b/g
31902  eq 2, a/b/g
31903  eq 2, a/ b/g
31904  eq true, r /b/g
31905  eq 2, (1 + 3) / b/g
31906  eq 2, (1 + 3)/b/g
31907  eq 2, (1 + 3)/ b/g
31908  eq true, (r) /b/g
31909  eq 2, [4][0] / b/g
31910  eq 2, [4][0]/b/g
31911  eq 2, [4][0]/ b/g
31912  eq true, [r][0] /b/g
31913  eq 0.5, 4? / b/g
31914  eq 0.5, 4?/b/g
31915  eq 0.5, 4?/ b/g
31916  eq true, r? /b/g
31917  (->
31918    eq 2, @ / b/g
31919    eq 2, @/b/g
31920    eq 2, @/ b/g
31921  ).call 4
31922  (->
31923    eq true, @ /b/g
31924  ).call r
31925  (->
31926    eq 2, this / b/g
31927    eq 2, this/b/g
31928    eq 2, this/ b/g
31929  ).call 4
31930  (->
31931    eq true, this /b/g
31932  ).call r
31933  class A
31934    p: (regex) -> if regex then r regex else 4
31935  class B extends A
31936    p: ->
31937      eq 2, super() / b/g
31938      eq 2, super()/b/g
31939      eq 2, super()/ b/g
31940      eq true, super /b/g
31941  new B().p()
31942
31943test "always division and never regex after some tokens", ->
31944  b = 2
31945  g = 1
31946
31947  eq 2, 4 / b/g
31948  eq 2, 4/b/g
31949  eq 2, 4/ b/g
31950  eq 2, 4 /b/g
31951  eq 2, "4" / b/g
31952  eq 2, "4"/b/g
31953  eq 2, "4"/ b/g
31954  eq 2, "4" /b/g
31955  eq 20, "4#{0}" / b/g
31956  eq 20, "4#{0}"/b/g
31957  eq 20, "4#{0}"/ b/g
31958  eq 20, "4#{0}" /b/g
31959  ok isNaN /a/ / b/g
31960  ok isNaN /a/i / b/g
31961  ok isNaN /a//b/g
31962  ok isNaN /a/i/b/g
31963  ok isNaN /a// b/g
31964  ok isNaN /a/i/ b/g
31965  ok isNaN /a/ /b/g
31966  ok isNaN /a/i /b/g
31967  eq 0.5, true / b/g
31968  eq 0.5, true/b/g
31969  eq 0.5, true/ b/g
31970  eq 0.5, true /b/g
31971  eq 0, false / b/g
31972  eq 0, false/b/g
31973  eq 0, false/ b/g
31974  eq 0, false /b/g
31975  eq 0, null / b/g
31976  eq 0, null/b/g
31977  eq 0, null/ b/g
31978  eq 0, null /b/g
31979  ok isNaN undefined / b/g
31980  ok isNaN undefined/b/g
31981  ok isNaN undefined/ b/g
31982  ok isNaN undefined /b/g
31983  ok isNaN {a: 4} / b/g
31984  ok isNaN {a: 4}/b/g
31985  ok isNaN {a: 4}/ b/g
31986  ok isNaN {a: 4} /b/g
31987  o = prototype: 4
31988  eq 2, o:: / b/g
31989  eq 2, o::/b/g
31990  eq 2, o::/ b/g
31991  eq 2, o:: /b/g
31992  i = 4
31993  eq 2.0, i++ / b/g
31994  eq 2.5, i++/b/g
31995  eq 3.0, i++/ b/g
31996  eq 3.5, i++ /b/g
31997  eq 4.0, i-- / b/g
31998  eq 3.5, i--/b/g
31999  eq 3.0, i--/ b/g
32000  eq 2.5, i-- /b/g
32001
32002test "compound division vs regex", ->
32003  c = 4
32004  i = 2
32005
32006  a = 10
32007  b = a /= c / i
32008  eq a, 5
32009
32010  a = 10
32011  b = a /= c /i
32012  eq a, 5
32013
32014  a = 10
32015  b = a	/=	c /i # Tabs.
32016  eq a, 5
32017
32018  a = 10
32019  b = a /= c /i # Non-breaking spaces.
32020  eq a, 5
32021
32022  a = 10
32023  b = a/= c /i
32024  eq a, 5
32025
32026  a = 10
32027  b = a/=c/i
32028  eq a, 5
32029
32030  a = (regex) -> regex.test '=C '
32031  b = a /=c /i
32032  eq b, true
32033
32034  a = (regex) -> regex.test '= C '
32035  # Use parentheses to disambiguate.
32036  b = a(/= c /i)
32037  eq b, true
32038  b = a(/= c /)
32039  eq b, false
32040  b = a (/= c /)
32041  eq b, false
32042  # Escape to disambiguate.
32043  b = a /\= c /i
32044  eq b, true
32045  b = a /\= c /
32046  eq b, false
32047
32048test "#764: regular expressions should be indexable", ->
32049  eq /0/['source'], ///#{0}///['source']
32050
32051test "#584: slashes are allowed unescaped in character classes", ->
32052  ok /^a\/[/]b$/.test 'a//b'
32053
32054test "does not allow to escape newlines", ->
32055  throwsCompileError '/a\\\nb/'
32056
32057
32058# Heregexe(n|s)
32059
32060test "a heregex will ignore whitespace and comments", ->
32061  eq /^I'm\x20+[a]\s+Heregex?\/\/\//gim + '', ///
32062    ^ I'm \x20+ [a] \s+
32063    Heregex? / // # or not
32064  ///gim + ''
32065
32066test "an empty heregex will compile to an empty, non-capturing group", ->
32067  eq /(?:)/ + '', ///  /// + ''
32068  eq /(?:)/ + '', ////// + ''
32069
32070test "heregex starting with slashes", ->
32071  ok /////a/\////.test ' //a// '
32072
32073test '#2388: `///` in heregex interpolations', ->
32074  ok ///a#{///b///}c///.test ' /a/b/c/ '
32075  ws = ' \t'
32076  scan = (regex) -> regex.exec('\t  foo')[0]
32077  eq '/\t  /', /// #{scan /// [#{ws}]* ///} /// + ''
32078
32079test "regexes are not callable", ->
32080  throwsCompileError '/a/()'
32081  throwsCompileError '///a#{b}///()'
32082  throwsCompileError '/a/ 1'
32083  throwsCompileError '///a#{b}/// 1'
32084  throwsCompileError '''
32085    /a/
32086       k: v
32087  '''
32088  throwsCompileError '''
32089    ///a#{b}///
32090       k: v
32091  '''
32092
32093test "backreferences", ->
32094  ok /(a)(b)\2\1/.test 'abba'
32095
32096test "#3795: Escape otherwise invalid characters", ->
32097  ok (/
/).test '\u2028'
32098  ok (/
/).test '\u2029'
32099  ok ///\
///.test '\u2028'
32100  ok ///\
///.test '\u2029'
32101  ok ///a
b///.test 'ab' # The space is U+2028.
32102  ok ///a
b///.test 'ab' # The space is U+2029.
32103  ok ///\0
32104      1///.test '\x001'
32105
32106  a = 'a'
32107  ok ///#{a}
b///.test 'ab' # The space is U+2028.
32108  ok ///#{a}
b///.test 'ab' # The space is U+2029.
32109  ok ///#{a}\
///.test 'a\u2028'
32110  ok ///#{a}\
///.test 'a\u2029'
32111  ok ///#{a}\0
32112      1///.test 'a\x001'
32113
32114test "#4248: Unicode code point escapes", ->
32115  ok /a\u{1ab}c/u.test 'a\u01abc'
32116  ok ///#{ 'a' }\u{000001ab}c///u.test 'a\u{1ab}c'
32117  ok ///a\u{000001ab}c///u.test 'a\u{1ab}c'
32118  ok /a\u{12345}c/u.test 'a\ud808\udf45c'
32119
32120  # and now without u flag
32121  ok /a\u{1ab}c/.test 'a\u01abc'
32122  ok ///#{ 'a' }\u{000001ab}c///.test 'a\u{1ab}c'
32123  ok ///a\u{000001ab}c///.test 'a\u{1ab}c'
32124  ok /a\u{12345}c/.test 'a\ud808\udf45c'
32125
32126  # rewrite code point escapes unless u flag is set
32127  eqJS """
32128    /\\u{bcdef}\\u{abc}/u
32129  """,
32130  """
32131    /\\u{bcdef}\\u{abc}/u;
32132  """
32133
32134  eqJS """
32135    ///#{ 'a' }\\u{bcdef}///
32136  """,
32137  """
32138    /a\\udab3\\uddef/;
32139  """
32140
32141test "#4811, heregex comments with ///", ->
32142  eqJS """
32143    ///
32144      a | # comment with ///
32145      b   # /// 'heregex' in comment will be consumed
32146    ///
32147  """,
32148  """
32149   // comment with ///
32150   // /// 'heregex' in comment will be consumed
32151   /a|b/;
32152  """
32153
32154</script>
vendor: 1 bytes, line 32154
32154
32155<script type="text/x-coffeescript" class="test" id="regex_dotall">
32156# Regex “dotall” flag, or `s`, is only supported in Node 9+, so put tests for
32157# the feature in their own file. The feature detection in `Cakefile` that
32158# causes this test to load is adapted from
32159# https://github.com/tc39/proposal-regexp-dotall-flag#proposed-solution.
32160
32161test "dotall flag", ->
32162  doesNotThrow -> /a.b/s.test 'a\nb'
32163
32164</script>
vendor: 1 bytes, line 32164
32164
32165<script type="text/x-coffeescript" class="test" id="repl">
32166return if global.testingBrowser
32167
32168os = require 'os'
32169fs = require 'fs'
32170path = require 'path'
32171
32172# REPL
32173# ----
32174Stream = require 'stream'
32175
32176class MockInputStream extends Stream
32177  constructor: ->
32178    super()
32179    @readable = true
32180
32181  resume: ->
32182
32183  emitLine: (val) ->
32184    @emit 'data', Buffer.from("#{val}\n")
32185
32186class MockOutputStream extends Stream
32187  constructor: ->
32188    super()
32189    @writable = true
32190    @written = []
32191
32192  write: (data) ->
32193    # console.log 'output write', arguments
32194    @written.push data
32195
32196  lastWrite: (fromEnd = -1) ->
32197    @written[@written.length - 1 + fromEnd].replace /\r?\n$/, ''
32198
32199# Create a dummy history file
32200historyFile = path.join os.tmpdir(), '.coffee_history_test'
32201fs.writeFileSync historyFile, '1 + 2\n'
32202
32203testRepl = (desc, fn) ->
32204  input = new MockInputStream
32205  output = new MockOutputStream
32206  repl = Repl.start {input, output, historyFile}
32207  test desc, -> fn input, output, repl
32208
32209ctrlV = { ctrl: true, name: 'v'}
32210
32211
32212testRepl 'reads history file', (input, output, repl) ->
32213  input.emitLine repl.history[0]
32214  eq '3', output.lastWrite()
32215
32216testRepl "starts with coffee prompt", (input, output) ->
32217  eq 'coffee> ', output.lastWrite(0)
32218
32219testRepl "writes eval to output", (input, output) ->
32220  input.emitLine '1+1'
32221  eq '2', output.lastWrite()
32222
32223testRepl "comments are ignored", (input, output) ->
32224  input.emitLine '1 + 1 #foo'
32225  eq '2', output.lastWrite()
32226
32227testRepl "output in inspect mode", (input, output) ->
32228  input.emitLine '"1 + 1\\n"'
32229  eq "'1 + 1\\n'", output.lastWrite()
32230
32231testRepl "variables are saved", (input, output) ->
32232  input.emitLine "foo = 'foo'"
32233  input.emitLine 'foobar = "#{foo}bar"'
32234  eq "'foobar'", output.lastWrite()
32235
32236testRepl "empty command evaluates to undefined", (input, output) ->
32237  # A regression fixed in Node 5.11.0 broke the handling of pressing enter in
32238  # the Node REPL; see https://github.com/nodejs/node/pull/6090 and
32239  # https://github.com/jashkenas/coffeescript/issues/4502.
32240  # Just skip this test for versions of Node < 6.
32241  return if parseInt(process.versions.node.split('.')[0], 10) < 6
32242  input.emitLine ''
32243  eq 'undefined', output.lastWrite()
32244
32245testRepl "#4763: comment evaluates to undefined", (input, output) ->
32246  input.emitLine '# comment'
32247  eq 'undefined', output.lastWrite()
32248
32249testRepl "#4763: multiple comments evaluate to undefined", (input, output) ->
32250  input.emitLine '### a ### ### b ### # c'
32251  eq 'undefined', output.lastWrite()
32252
32253testRepl "ctrl-v toggles multiline prompt", (input, output) ->
32254  input.emit 'keypress', null, ctrlV
32255  eq '------> ', output.lastWrite(0)
32256  input.emit 'keypress', null, ctrlV
32257  eq 'coffee> ', output.lastWrite(0)
32258
32259testRepl "multiline continuation changes prompt", (input, output) ->
32260  input.emit 'keypress', null, ctrlV
32261  input.emitLine ''
32262  eq '....... ', output.lastWrite(0)
32263
32264testRepl "evaluates multiline", (input, output) ->
32265  # Stubs. Could assert on their use.
32266  output.cursorTo = (pos) ->
32267  output.clearLine = ->
32268
32269  input.emit 'keypress', null, ctrlV
32270  input.emitLine 'do ->'
32271  input.emitLine '  1 + 1'
32272  input.emit 'keypress', null, ctrlV
32273  eq '2', output.lastWrite()
32274
32275testRepl "variables in scope are preserved", (input, output) ->
32276  input.emitLine 'a = 1'
32277  input.emitLine 'do -> a = 2'
32278  input.emitLine 'a'
32279  eq '2', output.lastWrite()
32280
32281testRepl "existential assignment of previously declared variable", (input, output) ->
32282  input.emitLine 'a = null'
32283  input.emitLine 'a ?= 42'
32284  eq '42', output.lastWrite()
32285
32286testRepl "keeps running after runtime error", (input, output) ->
32287  input.emitLine 'a = b'
32288  input.emitLine 'a'
32289  eq 'undefined', output.lastWrite()
32290
32291testRepl "#4604: wraps an async function", (input, output) ->
32292  return unless try new Function 'async () => {}' # Feature detect support for async functions.
32293  input.emitLine 'await new Promise (resolve) -> setTimeout (-> resolve 33), 10'
32294  setTimeout ->
32295    eq '33', output.lastWrite()
32296  , 20
32297
32298testRepl "transpile REPL", (input, output) ->
32299  input.emitLine 'require("./test/importing/transpile_import").getSep()'
32300  eq "'#{path.sep.replace '\\', '\\\\'}'", output.lastWrite()
32301
32302process.on 'exit', ->
32303  try
32304    fs.unlinkSync historyFile
32305  catch exception # Already deleted, nothing else to do.
32306
32307</script>
vendor: 1 bytes, line 32307
32307
32308<script type="text/x-coffeescript" class="test" id="scope">
32309# Scope
32310# -----
32311
32312# * Variable Safety
32313# * Variable Shadowing
32314# * Auto-closure (`do`)
32315# * Global Scope Leaks
32316
32317test "reference `arguments` inside of functions", ->
32318  sumOfArgs = ->
32319    sum = (a,b) -> a + b
32320    sum = 0
32321    sum += num for num in arguments
32322    sum
32323  eq 10, sumOfArgs(0, 1, 2, 3, 4)
32324
32325test "assignment to an Object.prototype-named variable should not leak to outer scope", ->
32326  # FIXME: fails on IE
32327  (->
32328    constructor = 'word'
32329  )()
32330  ok constructor isnt 'word'
32331
32332test "siblings of splat parameters shouldn't leak to surrounding scope", ->
32333  x = 10
32334  oops = (x, args...) ->
32335  oops(20, 1, 2, 3)
32336  eq x, 10
32337
32338test "catch statements should introduce their argument to scope", ->
32339  try throw ''
32340  catch e
32341    do -> e = 5
32342    eq 5, e
32343
32344test "loop variable should be accessible after for-of loop", ->
32345  d = (x for x of {1:'a',2:'b'})
32346  ok x in ['1','2']
32347
32348test "loop variable should be accessible after for-in loop", ->
32349  d = (x for x in [1,2])
32350  eq x, 2
32351
32352test "loop variable should be accessible after for-from loop", ->
32353  d = (x for x from [1,2])
32354  eq x, 2
32355
32356class Array then slice: fail # needs to be global
32357class Object then hasOwnProperty: fail
32358test "#1973: redefining Array/Object constructors shouldn't confuse __X helpers", ->
32359  arr = [1..4]
32360  arrayEq [3, 4], arr[2..]
32361  obj = {arr}
32362  for own k of obj
32363    eq arr, obj[k]
32364
32365test "#2255: global leak with splatted @-params", ->
32366  ok not x?
32367  arrayEq [0], ((@x...) -> @x).call {}, 0
32368  ok not x?
32369
32370test "#1183: super + fat arrows", ->
32371  dolater = (cb) -> cb()
32372
32373  class A
32374    constructor: ->
32375      @_i = 0
32376    foo : (cb) ->
32377      dolater =>
32378        @_i += 1
32379        cb()
32380
32381  class B extends A
32382    constructor : ->
32383      super()
32384    foo : (cb) ->
32385      dolater =>
32386        dolater =>
32387          @_i += 2
32388          super cb
32389
32390  b = new B
32391  b.foo => eq b._i, 3
32392
32393test "#1183: super + wrap", ->
32394  class A
32395    m : -> 10
32396
32397  class B extends A
32398    constructor : -> super()
32399    m: -> r = try super()
32400    m: -> r = super()
32401
32402  eq (new B).m(), 10
32403
32404test "#1183: super + closures", ->
32405  class A
32406    constructor: ->
32407      @i = 10
32408    foo : -> @i
32409
32410  class B extends A
32411    foo : ->
32412      ret = switch 1
32413        when 0 then 0
32414        when 1 then super()
32415      ret
32416  eq (new B).foo(), 10
32417
32418test "#2331: bound super regression", ->
32419  class A
32420    @value = 'A'
32421    method: -> @constructor.value
32422
32423  class B extends A
32424    method: => super()
32425
32426  eq (new B).method(), 'A'
32427
32428test "#3259: leak with @-params within destructured parameters", ->
32429  fn = ({@foo}, [@bar], [{@baz}]) ->
32430    foo = bar = baz = false
32431
32432  fn.call {}, {foo: 'foo'}, ['bar'], [{baz: 'baz'}]
32433
32434  eq 'undefined', typeof foo
32435  eq 'undefined', typeof bar
32436  eq 'undefined', typeof baz
32437
32438</script>
vendor: 1 bytes, line 32438
32438
32439<script type="text/x-coffeescript" class="test" id="slicing_and_splicing">
32440# Slicing and Splicing
32441# --------------------
32442
32443# * Slicing
32444# * Splicing
32445
32446# shared array
32447shared = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
32448
32449# Slicing
32450
32451test "basic slicing", ->
32452  arrayEq [7, 8, 9]   , shared[7..9]
32453  arrayEq [2, 3]      , shared[2...4]
32454  arrayEq [2, 3, 4, 5], shared[2...6]
32455
32456test "slicing with variables as endpoints", ->
32457  [a, b] = [1, 4]
32458  arrayEq [1, 2, 3, 4], shared[a..b]
32459  arrayEq [1, 2, 3]   , shared[a...b]
32460
32461test "slicing with expressions as endpoints", ->
32462  [a, b] = [1, 3]
32463  arrayEq [2, 3, 4, 5, 6], shared[(a+1)..2*b]
32464  arrayEq [2, 3, 4, 5]   , shared[a+1...(2*b)]
32465
32466test "unbounded slicing", ->
32467  arrayEq [7, 8, 9]   , shared[7..]
32468  arrayEq [8, 9]      , shared[-2..]
32469  arrayEq [9]         , shared[-1...]
32470  arrayEq [0, 1, 2]   , shared[...3]
32471  arrayEq [0, 1, 2, 3], shared[..-7]
32472
32473  arrayEq shared      , shared[..-1]
32474  arrayEq shared[0..8], shared[...-1]
32475
32476  for a in [-shared.length..shared.length]
32477    arrayEq shared[a..] , shared[a...]
32478  for a in [-shared.length+1...shared.length]
32479    arrayEq shared[..a][...-1] , shared[...a]
32480
32481  arrayEq [1, 2, 3], [1, 2, 3][..]
32482
32483test "#930, #835, #831, #746 #624: inclusive slices to -1 should slice to end", ->
32484  arrayEq shared, shared[0..-1]
32485  arrayEq shared, shared[..-1]
32486  arrayEq shared.slice(1,shared.length), shared[1..-1]
32487
32488test "string slicing", ->
32489  str = "abcdefghijklmnopqrstuvwxyz"
32490  ok str[1...1] is ""
32491  ok str[1..1] is "b"
32492  ok str[1...5] is "bcde"
32493  ok str[0..4] is "abcde"
32494  ok str[-5..] is "vwxyz"
32495
32496test "#1722: operator precedence in unbounded slice compilation", ->
32497  list = [0..9]
32498  n = 2 # some truthy number in `list`
32499  arrayEq [0..n], list[..n]
32500  arrayEq [0..n], list[..n or 0]
32501  arrayEq [0..n], list[..if n then n else 0]
32502
32503test "#2349: inclusive slicing to numeric strings", ->
32504  arrayEq [0, 1], [0..10][.."1"]
32505
32506test "#4631: slicing with space before and/or after the dots", ->
32507  a = (s) -> s
32508  b = [4, 5, 6]
32509  c = [7, 8, 9]
32510  arrayEq [2, 3, 4], shared[2 ... 5]
32511  arrayEq [3, 4, 5], shared[3... 6]
32512  arrayEq [4, 5, 6], shared[4 ...7]
32513  arrayEq shared[(a b...)...(a c...)]  , shared[(a ...b)...(a ...c)]
32514  arrayEq shared[(a b...) ... (a c...)], shared[(a ...b) ... (a ...c)]
32515  arrayEq shared[(a b...)... (a c...)] , shared[(a ...b)... (a ...c)]
32516  arrayEq shared[(a b...) ...(a c...)] , shared[(a ...b) ...(a ...c)]
32517
32518
32519# Splicing
32520
32521test "basic splicing", ->
32522  ary = [0..9]
32523  ary[5..9] = [0, 0, 0]
32524  arrayEq [0, 1, 2, 3, 4, 0, 0, 0], ary
32525
32526  ary = [0..9]
32527  ary[2...8] = []
32528  arrayEq [0, 1, 8, 9], ary
32529
32530test "unbounded splicing", ->
32531  ary = [0..9]
32532  ary[3..] = [9, 8, 7]
32533  arrayEq [0, 1, 2, 9, 8, 7]. ary
32534
32535  ary[...3] = [7, 8, 9]
32536  arrayEq [7, 8, 9, 9, 8, 7], ary
32537
32538  ary[..] = [1, 2, 3]
32539  arrayEq [1, 2, 3], ary
32540
32541test "splicing with variables as endpoints", ->
32542  [a, b] = [1, 8]
32543
32544  ary = [0..9]
32545  ary[a..b] = [2, 3]
32546  arrayEq [0, 2, 3, 9], ary
32547
32548  ary = [0..9]
32549  ary[a...b] = [5]
32550  arrayEq [0, 5, 8, 9], ary
32551
32552test "splicing with expressions as endpoints", ->
32553  [a, b] = [1, 3]
32554
32555  ary = [0..9]
32556  ary[ a+1 .. 2*b+1 ] = [4]
32557  arrayEq [0, 1, 4, 8, 9], ary
32558
32559  ary = [0..9]
32560  ary[a+1...2*b+1] = [4]
32561  arrayEq [0, 1, 4, 7, 8, 9], ary
32562
32563test "splicing to the end, against a one-time function", ->
32564  ary = null
32565  fn = ->
32566    if ary
32567      throw 'err'
32568    else
32569      ary = [1, 2, 3]
32570
32571  fn()[0..] = 1
32572
32573  arrayEq ary, [1]
32574
32575test "the return value of a splice literal should be the RHS", ->
32576  ary = [0, 0, 0]
32577  eq (ary[0..1] = 2), 2
32578
32579  ary = [0, 0, 0]
32580  eq (ary[0..] = 3), 3
32581
32582  arrayEq [ary[0..0] = 0], [0]
32583
32584test "#1723: operator precedence in unbounded splice compilation", ->
32585  n = 4 # some truthy number in `list`
32586
32587  list = [0..9]
32588  list[..n] = n
32589  arrayEq [n..9], list
32590
32591  list = [0..9]
32592  list[..n or 0] = n
32593  arrayEq [n..9], list
32594
32595  list = [0..9]
32596  list[..if n then n else 0] = n
32597  arrayEq [n..9], list
32598
32599test "#2953: methods on endpoints in assignment from array splice literal", ->
32600  list = [0..9]
32601
32602  Number.prototype.same = -> this
32603  list[1.same()...9.same()] = 5
32604  delete Number.prototype.same
32605
32606  arrayEq [0, 5, 9], list
32607
32608test "#1726: `Op` expression in property access causes unexpected results", ->
32609  a = [0..2]
32610  arrayEq a, a[(!1 in a)..]
32611  arrayEq a, a[!1 in a..]
32612  arrayEq a[(!1 in a)..], a[(!1 in a)..]
32613
32614</script>
vendor: 1 bytes, line 32614
32614
32615<script type="text/x-coffeescript" class="test" id="soaks">
32616# Soaks
32617# -----
32618
32619# * Soaked Property Access
32620# * Soaked Method Invocation
32621# * Soaked Function Invocation
32622
32623
32624# Soaked Property Access
32625
32626test "soaked property access", ->
32627  nonce = {}
32628  obj = a: b: nonce
32629  eq nonce    , obj?.a.b
32630  eq nonce    , obj?['a'].b
32631  eq nonce    , obj.a?.b
32632  eq nonce    , obj?.a?['b']
32633  eq undefined, obj?.a?.non?.existent?.property
32634
32635test "soaked property access caches method calls", ->
32636  nonce ={}
32637  obj = fn: -> a: nonce
32638  eq nonce    , obj.fn()?.a
32639  eq undefined, obj.fn()?.b
32640
32641test "soaked property access caching", ->
32642  nonce = {}
32643  counter = 0
32644  fn = ->
32645    counter++
32646    'self'
32647  obj =
32648    self: -> @
32649    prop: nonce
32650  eq nonce, obj[fn()]()[fn()]()[fn()]()?.prop
32651  eq 3, counter
32652
32653test "method calls on soaked methods", ->
32654  nonce = {}
32655  obj = null
32656  eq undefined, obj?.a().b()
32657  obj = a: -> b: -> nonce
32658  eq nonce    , obj?.a().b()
32659
32660test "postfix existential operator mixes well with soaked property accesses", ->
32661  eq false, nonexistent?.property?
32662
32663test "function invocation with soaked property access", ->
32664  id = (_) -> _
32665  eq undefined, id nonexistent?.method()
32666
32667test "if-to-ternary should safely parenthesize soaked property accesses", ->
32668  ok (if nonexistent?.property then false else true)
32669
32670test "#726: don't check for a property on a conditionally-referenced nonexistent thing", ->
32671  eq undefined, nonexistent?[Date()]
32672
32673test "#756: conditional assignment edge cases", ->
32674  # TODO: improve this test
32675  a = null
32676  ok isNaN      a?.b.c +  1
32677  eq undefined, a?.b.c += 1
32678  eq undefined, ++a?.b.c
32679  eq undefined, delete a?.b.c
32680
32681test "operations on soaked properties", ->
32682  # TODO: improve this test
32683  a = b: {c: 0}
32684  eq 1,   a?.b.c +  1
32685  eq 1,   a?.b.c += 1
32686  eq 2,   ++a?.b.c
32687  eq yes, delete a?.b.c
32688
32689
32690# Soaked Method Invocation
32691
32692test "soaked method invocation", ->
32693  nonce = {}
32694  counter = 0
32695  obj =
32696    self: -> @
32697    increment: -> counter++; @
32698  eq obj      , obj.self?()
32699  eq undefined, obj.method?()
32700  eq nonce    , obj.self?().property = nonce
32701  eq undefined, obj.method?().property = nonce
32702  eq obj      , obj.increment().increment().self?()
32703  eq 2        , counter
32704
32705test "#733: conditional assignments", ->
32706  a = b: {c: null}
32707  eq a.b?.c?(), undefined
32708  a.b?.c or= (it) -> it
32709  eq a.b?.c?(1), 1
32710  eq a.b?.c?([2, 3]...), 2
32711
32712
32713# Soaked Function Invocation
32714
32715test "soaked function invocation", ->
32716  nonce = {}
32717  id = (_) -> _
32718  eq nonce    , id?(nonce)
32719  eq nonce    , (id? nonce)
32720  eq undefined, nonexistent?(nonce)
32721  eq undefined, (nonexistent? nonce)
32722
32723test "soaked function invocation with generated functions", ->
32724  nonce = {}
32725  id = (_) -> _
32726  maybe = (fn, arg) -> if typeof fn is 'function' then () -> fn(arg)
32727  eq maybe(id, nonce)?(), nonce
32728  eq (maybe id, nonce)?(), nonce
32729  eq (maybe false, nonce)?(), undefined
32730
32731test "soaked constructor invocation", ->
32732  eq 42       , +new Number? 42
32733  eq undefined,  new Other?  42
32734
32735test "soaked constructor invocations with caching and property access", ->
32736  semaphore = 0
32737  nonce = {}
32738  class C
32739    constructor: ->
32740      ok false if semaphore
32741      semaphore++
32742    prop: nonce
32743  eq nonce, (new C())?.prop
32744  eq 1, semaphore
32745
32746test "soaked function invocation safe on non-functions", ->
32747  eq undefined, (0)?(1)
32748  eq undefined, (0)? 1, 2
32749
32750</script>
vendor: 1 bytes, line 32750
32750
32751<script type="text/x-coffeescript" class="test" id="sourcemap">
32752return if global.testingBrowser
32753
32754{spawn, fork} = require('child_process')
32755SourceMap = require '../src/sourcemap'
32756
32757vlqEncodedValues = [
32758    [1, 'C'],
32759    [-1, 'D'],
32760    [2, 'E'],
32761    [-2, 'F'],
32762    [0, 'A'],
32763    [16, 'gB'],
32764    [948, 'o7B']
32765]
32766
32767test "encodeVlq tests", ->
32768  for pair in vlqEncodedValues
32769    eq ((new SourceMap).encodeVlq pair[0]), pair[1]
32770
32771test "SourceMap tests", ->
32772  map = new SourceMap
32773  map.add [0, 0], [0, 0]
32774  map.add [1, 5], [2, 4]
32775  map.add [1, 6], [2, 7]
32776  map.add [1, 9], [2, 8]
32777  map.add [3, 0], [3, 4]
32778
32779  testWithFilenames = map.generate {
32780    sourceRoot: ''
32781    sourceFiles: ['source.coffee']
32782    generatedFile: 'source.js'
32783  }
32784
32785  deepEqual testWithFilenames, {
32786    version: 3
32787    file: 'source.js'
32788    sourceRoot: ''
32789    sources: ['source.coffee']
32790    names: []
32791    mappings: 'AAAA;;IACK,GAAC,CAAG;IAET'
32792  }
32793
32794  deepEqual map.generate(), {
32795    version: 3
32796    file: ''
32797    sourceRoot: ''
32798    sources: ['<anonymous>']
32799    names: []
32800    mappings: 'AAAA;;IACK,GAAC,CAAG;IAET'
32801  }
32802
32803  # Look up a generated column - should get back the original source position.
32804  arrayEq map.sourceLocation([2,8]), [1,9]
32805
32806  # Look up a point further along on the same line - should get back the same source position.
32807  arrayEq map.sourceLocation([2,10]), [1,9]
32808
32809test "#3075: v3 source map fields", ->
32810  { js, v3SourceMap, sourceMap } = CoffeeScript.compile 'console.log Date.now()',
32811    filename: 'tempus_fugit.coffee'
32812    sourceMap: yes
32813    sourceRoot: './www_root/coffee/'
32814
32815  v3SourceMap = JSON.parse v3SourceMap
32816  arrayEq v3SourceMap.sources, ['tempus_fugit.coffee']
32817  eq v3SourceMap.sourceRoot, './www_root/coffee/'
32818
32819test "node --enable-source-map built in stack trace mapping", ->
32820  new Promise (resolve, reject) ->
32821    proc = fork './test/importing/error.coffee', [
32822      '--enable-source-maps'
32823    ], stdio: 'pipe'
32824
32825    err = ''
32826    proc.stderr.setEncoding 'utf8'
32827    proc.stderr.on 'data', (str) -> err += str
32828    proc.on 'close', ->
32829      try
32830        match = err.match /error\.coffee:(\d+):(\d+)/
32831        throw new Error err unless match
32832
32833        [_, line, column] = match
32834        equal line, 3 # Mapped source line
32835        equal column, 9 # Mapped source column
32836
32837        resolve()
32838      catch exception
32839        reject exception
32840
32841if Number(process.versions.node.split('.')[0]) >= 14
32842  test "NODE_OPTIONS=--enable-source-maps environment variable stack trace mapping", ->
32843    new Promise (resolve, reject) ->
32844      proc = fork './test/importing/error.coffee', [],
32845        env:
32846          NODE_OPTIONS: '--enable-source-maps'
32847        stdio: 'pipe'
32848
32849      err = ''
32850      proc.stderr.setEncoding 'utf8'
32851      proc.stderr.on 'data', (str) -> err += str
32852      proc.on 'close', ->
32853        try
32854          match = err.match /error\.coffee:(\d+):(\d+)/
32855          throw new Error err unless match
32856
32857          [_, line, column] = match
32858          equal line, 3 # Mapped source line
32859          equal column, 9 # Mapped source column
32860
32861          resolve()
32862        catch exception
32863          reject exception
32864
32865  test "generate correct stack traces with --enable-source-maps from bin/coffee", ->
32866    new Promise (resolve, reject) ->
32867      proc = fork 'test/importing/error.coffee',
32868        ['--enable-source-maps'],
32869        stdio: 'pipe'
32870
32871      err = ""
32872      proc.stderr.setEncoding 'utf8'
32873      proc.stderr.on 'data', (str) -> err += str
32874      proc.on 'close', ->
32875        try
32876          match = err.match /error\.coffee:(\d+):(\d+)/
32877          throw new Error err unless match
32878
32879          [_, line, column] = match
32880          equal line, 3 # Mapped source line
32881          equal column, 9 # Mapped source column
32882
32883          resolve()
32884        catch exception
32885          reject exception
32886
32887test "don't change stack traces if another library has patched `Error.prepareStackTrace`", ->
32888  new Promise (resolve, reject) ->
32889    # This uses `spawn` rather than the preferred `fork` because `fork` requires
32890    # loading code in a separate file. The `--eval` here shows exactly what is
32891    # executing without indirection.
32892    proc = spawn 'node', [
32893      '--eval', """
32894        const patchedPrepareStackTrace = Error.prepareStackTrace = function() {};
32895        require('./register.js');
32896        process.stdout.write(Error.prepareStackTrace === patchedPrepareStackTrace ? 'preserved' : 'overwritten');
32897      """
32898    ]
32899
32900    out = ''
32901    proc.stdout.setEncoding 'utf8'
32902    proc.stdout.on 'data', (str) -> out += str
32903
32904    proc.on 'close', (status) ->
32905      try
32906        equal status, 0
32907        equal out, 'preserved'
32908
32909        resolve()
32910      catch exception
32911        reject exception
32912
32913test "requiring 'CoffeeScript' doesn't change `Error.prepareStackTrace`", ->
32914  new Promise (resolve, reject) ->
32915    # This uses `spawn` rather than the preferred `fork` because `fork` requires
32916    # loading code in a separate file. The `--eval` here shows exactly what is
32917    # executing without indirection.
32918    proc = spawn 'node', [
32919      '--eval', """
32920        require('./lib/coffeescript/coffeescript.js');
32921        process.stdout.write(Error.prepareStackTrace === undefined ? 'unused' : 'defined');
32922      """
32923    ]
32924
32925    out = ''
32926    proc.stdout.setEncoding 'utf8'
32927    proc.stdout.on 'data', (str) -> out += str
32928
32929    proc.on 'close', (status) ->
32930      try
32931        equal status, 0
32932        equal out, 'unused'
32933
32934        resolve()
32935      catch exception
32936        reject exception
32937
32938</script>
vendor: 1 bytes, line 32938
32938
32939<script type="text/x-coffeescript" class="test" id="strict">
32940# Strict Early Errors
32941# -------------------
32942
32943# The following are prohibited under ES5’s `strict` mode
32944# * `Octal Integer Literals`
32945# * `Octal Escape Sequences`
32946# * duplicate property definitions in `Object Literal`s
32947# * duplicate formal parameter
32948# * `delete` operand is a variable
32949# * `delete` operand is a parameter
32950# * `delete` operand is `undefined`
32951# * `Future Reserved Word`s as identifiers: implements, interface, let, package, private, protected, public, static, yield
32952# * `eval` or `arguments` as `catch` identifier
32953# * `eval` or `arguments` as formal parameter
32954# * `eval` or `arguments` as function declaration identifier
32955# * `eval` or `arguments` as LHS of assignment
32956# * `eval` or `arguments` as the operand of a post/pre-fix inc/dec-rement expression
32957
32958# helper to assert that code complies with strict prohibitions
32959strict = (code, msg) ->
32960  throwsCompileError code, null, null, msg ? code
32961strictOk = (code, msg) ->
32962  doesNotThrowCompileError code, null, msg ? code
32963
32964
32965test "octal integer literals prohibited", ->
32966  strict    '01'
32967  strict    '07777'
32968  # decimals with a leading '0' are also prohibited
32969  strict    '09'
32970  strict    '079'
32971  strictOk  '`01`'
32972
32973test "octal escape sequences prohibited", ->
32974  strict    '"\\1"'
32975  strict    '"\\7"'
32976  strict    '"\\001"'
32977  strict    '"\\777"'
32978  strict    '"_\\1"'
32979  strict    '"\\1_"'
32980  strict    '"_\\1_"'
32981  strict    '"\\\\\\1"'
32982  strictOk  '"\\0"'
32983  eq "\x00", "\0"
32984  strictOk  '"\\0\\8"'
32985  eq "\x008", "\0\8"
32986  strictOk  '"\\8"'
32987  eq "8", "\8"
32988  strictOk  '"\\\\1"'
32989  eq "\\" + "1", "\\1"
32990  strictOk  '"\\\\\\\\1"'
32991  eq "\\\\" + "1", "\\\\1"
32992  strictOk  "`'\\1'`"
32993  eq "\\" + "1", `"\\1"`
32994
32995  # Also test other string types.
32996  strict           "'\\\\\\1'"
32997  eq "\\\\" + "1", '\\\\1'
32998  strict           "'''\\\\\\1'''"
32999  eq "\\\\" + "1", '''\\\\1'''
33000  strict           '"""\\\\\\1"""'
33001  eq "\\\\" + "1", """\\\\1"""
33002
33003test "duplicate formal parameters are prohibited", ->
33004  nonce = {}
33005  # a Param can be an Identifier, ThisProperty( @-param ), Array, or Object
33006  # a Param can also be a splat (...) or an assignment (param=value)
33007  # the following function expressions should throw errors
33008  strict '(_,_)->',          'param, param'
33009  strict '(_,_...)->',       'param, param...'
33010  strict '(_,_ = true)->',   'param, param='
33011  strict '(@_,@_)->',        'two @params'
33012  strict '(@case,@case)->',  'two @reserved'
33013  strict '(_,{_})->',        'param, {param}'
33014  strict '(_,{_=true})->',   'param, {param=}'
33015  strict '({_,_})->',        '{param, param}'
33016  strict '({_=true,_})->',   '{param=, param}'
33017  strict '(_,[_])->',        'param, [param]'
33018  strict '(_,[_=true])->',   'param, [param=]'
33019  strict '([_,_])->',        '[param, param]'
33020  strict '([_=true,_])->',   '[param=, param]'
33021  strict '(_,[_]=true)->',   'param, [param]='
33022  strict '(_,[_=true]=true)->', 'param, [param=]='
33023  strict '(_,[@_,{_}])->',   'param, [@param, {param}]'
33024  strict '(_,[_,{@_}])->',   'param, [param, {@param}]'
33025  strict '(_,[_,{@_=true}])->', 'param, [param, {@param=}]'
33026  strict '(_,[_,{_}])->',    'param, [param, {param}]'
33027  strict '(_,[_,{__}])->',   'param, [param, {param2}]'
33028  strict '(_,[__,{_}])->',   'param, [param2, {param}]'
33029  strict '(__,[_,{_}])->',   'param, [param2, {param2}]'
33030  strict '({0:a,1:a})->',    '{0:param,1:param}'
33031  strict '(a=b=true,a)->',   'param=assignment, param'
33032  strict '({a=b=true},a)->', '{param=assignment}, param'
33033  # the following function expressions should **not** throw errors
33034  strictOk '(_,@_)->'
33035  strictOk '(@_,_...)->'
33036  strictOk '(_,@_ = true)->'
33037  strictOk '(@_,{_})->'
33038  strictOk '({_,@_})->'
33039  strictOk '({_,@_ = true})->'
33040  strictOk '([_,@_])->'
33041  strictOk '([_,@_ = true])->'
33042  strictOk '({},_arg)->'
33043  strictOk '({},{})->'
33044  strictOk '([]...,_arg)->'
33045  strictOk '({}...,_arg)->'
33046  strictOk '({}...,[],_arg)->'
33047  strictOk '([]...,{},_arg)->'
33048  strictOk '(@case,_case)->'
33049  strictOk '(@case,_case...)->'
33050  strictOk '(@case...,_case)->'
33051  strictOk '(_case,@case)->'
33052  strictOk '(_case,@case...)->'
33053  strictOk '({a:a})->'
33054  strictOk '({a:a,a:b})->'
33055
33056test "`delete` operand restrictions", ->
33057  strict 'a = 1; delete a'
33058  strictOk 'delete a' #noop
33059  strict '(a) -> delete a'
33060  strict '(a...) -> delete a'
33061  strict '(a = 1) -> delete a'
33062  strict '([a]) -> delete a'
33063  strict '({a}) -> delete a'
33064
33065test "`Future Reserved Word`s, `eval` and `arguments` restrictions", ->
33066
33067  access = (keyword, check = strict) ->
33068    check "#{keyword}.a = 1"
33069    check "#{keyword}[0] = 1"
33070  assign = (keyword, check = strict) ->
33071    check "#{keyword} = 1"
33072    check "#{keyword} += 1"
33073    check "#{keyword} -= 1"
33074    check "#{keyword} *= 1"
33075    check "#{keyword} /= 1"
33076    check "#{keyword} ?= 1"
33077  update = (keyword, check = strict) ->
33078    check "#{keyword}++"
33079    check "++#{keyword}"
33080    check "#{keyword}--"
33081    check "--#{keyword}"
33082  destruct = (keyword, check = strict) ->
33083    check "{#{keyword}}"
33084    check "o = {#{keyword}}"
33085  invoke = (keyword, check = strict) ->
33086    check "#{keyword} yes"
33087    check "do #{keyword}"
33088  fnDecl = (keyword, check = strict) ->
33089    check "class #{keyword}"
33090  param = (keyword, check = strict) ->
33091    check "(#{keyword}) ->"
33092    check "({#{keyword}}) ->"
33093  prop = (keyword, check = strict) ->
33094    check "a.#{keyword} = 1"
33095  tryCatch = (keyword, check = strict) ->
33096    check "try new Error catch #{keyword}"
33097
33098  future = 'implements interface let package private protected public static'.split ' '
33099  for keyword in future
33100    access   keyword
33101    assign   keyword
33102    update   keyword
33103    destruct keyword
33104    invoke   keyword
33105    fnDecl   keyword
33106    param    keyword
33107    prop     keyword, strictOk
33108    tryCatch keyword
33109
33110  for keyword in ['eval', 'arguments']
33111    access   keyword, strictOk
33112    assign   keyword
33113    update   keyword
33114    destruct keyword, strictOk
33115    invoke   keyword, strictOk
33116    fnDecl   keyword
33117    param    keyword
33118    prop     keyword, strictOk
33119    tryCatch keyword
33120
33121</script>
vendor: 1 bytes, line 33121
33121
33122<script type="text/x-coffeescript" class="test" id="strings">
33123# String Literals
33124# ---------------
33125
33126# TODO: refactor string literal tests
33127# TODO: add indexing and method invocation tests: "string"["toString"] is String::toString, "string".toString() is "string"
33128
33129# * Strings
33130# * Heredocs
33131
33132test "backslash escapes", ->
33133  eq "\\/\\\\", /\/\\/.source
33134
33135eq '(((dollars)))', '\(\(\(dollars\)\)\)'
33136eq 'one two three', "one
33137 two
33138 three"
33139eq "four five", 'four
33140
33141 five'
33142
33143test "#3229, multiline strings", ->
33144  # Separate lines by default by a single space in literal strings.
33145  eq 'one
33146      two', 'one two'
33147  eq "one
33148      two", 'one two'
33149  eq '
33150        a
33151        b
33152    ', 'a b'
33153  eq "
33154        a
33155        b
33156    ", 'a b'
33157  eq 'one
33158
33159        two', 'one two'
33160  eq "one
33161
33162        two", 'one two'
33163  eq '
33164    indentation
33165      doesn\'t
33166  matter', 'indentation doesn\'t matter'
33167  eq 'trailing ws      
33168    doesn\'t matter', 'trailing ws doesn\'t matter'
33169
33170  # Use backslashes at the end of a line to specify whitespace between lines.
33171  eq 'a \
33172      b\
33173      c  \
33174      d', 'a bc  d'
33175  eq "a \
33176      b\
33177      c  \
33178      d", 'a bc  d'
33179  eq 'ignore  \  
33180      trailing whitespace', 'ignore  trailing whitespace'
33181
33182  # Backslash at the beginning of a literal string.
33183  eq '\
33184      ok', 'ok'
33185  eq '  \
33186      ok', '  ok'
33187
33188  # #1273, empty strings.
33189  eq '\
33190     ', ''
33191  eq '
33192     ', ''
33193  eq '
33194          ', ''
33195  eq '   ', '   '
33196
33197  # Same behavior in interpolated strings.
33198  eq "interpolation #{1}
33199      follows #{2}  \
33200      too #{3}\
33201      !", 'interpolation 1 follows 2  too 3!'
33202  eq "a #{
33203    'string ' + "inside
33204                 interpolation"
33205    }", "a string inside interpolation"
33206  eq "
33207      #{1}
33208     ", '1'
33209
33210  # Handle escaped backslashes correctly.
33211  eq '\\', `'\\'`
33212  eq 'escaped backslash at EOL\\
33213      next line', 'escaped backslash at EOL\\ next line'
33214  eq '\\
33215      next line', '\\ next line'
33216  eq '\\
33217     ', '\\'
33218  eq '\\\\\\
33219     ', '\\\\\\'
33220  eq "#{1}\\
33221      after interpolation", '1\\ after interpolation'
33222  eq 'escaped backslash before slash\\  \
33223      next line', 'escaped backslash before slash\\  next line'
33224  eq 'triple backslash\\\
33225      next line', 'triple backslash\\next line'
33226  eq 'several escaped backslashes\\\\\\
33227      ok', 'several escaped backslashes\\\\\\ ok'
33228  eq 'several escaped backslashes slash\\\\\\\
33229      ok', 'several escaped backslashes slash\\\\\\ok'
33230  eq 'several escaped backslashes with trailing ws \\\\\\   
33231      ok', 'several escaped backslashes with trailing ws \\\\\\ ok'
33232
33233  # Backslashes at beginning of lines.
33234  eq 'first line
33235      \   backslash at BOL', 'first line \   backslash at BOL'
33236  eq 'first line\
33237      \   backslash at BOL', 'first line\   backslash at BOL'
33238
33239  # Backslashes at end of strings.
33240  eq 'first line \ ', 'first line  '
33241  eq 'first line
33242      second line \
33243      ', 'first line second line '
33244  eq 'first line
33245      second line
33246      \
33247      ', 'first line second line'
33248  eq 'first line
33249      second line
33250
33251        \
33252
33253      ', 'first line second line'
33254
33255  # Edge case.
33256  eq 'lone
33257
33258        \
33259
33260        backslash', 'lone backslash'
33261
33262test "#3249, escape newlines in heredocs with backslashes", ->
33263  # Ignore escaped newlines
33264  eq '''
33265    Set whitespace      \
33266       <- this is ignored\  
33267           none
33268      normal indentation
33269    ''', 'Set whitespace      <- this is ignorednone\n  normal indentation'
33270  eq """
33271    Set whitespace      \
33272       <- this is ignored\  
33273           none
33274      normal indentation
33275    """, 'Set whitespace      <- this is ignorednone\n  normal indentation'
33276
33277  # Changed from #647, trailing backslash.
33278  eq '''
33279  Hello, World\
33280
33281  ''', 'Hello, World'
33282  eq '''
33283    \\
33284  ''', '\\'
33285
33286  # Backslash at the beginning of a literal string.
33287  eq '''\
33288      ok''', 'ok'
33289  eq '''  \
33290      ok''', '  ok'
33291
33292  # Same behavior in interpolated strings.
33293  eq """
33294    interpolation #{1}
33295      follows #{2}  \
33296        too #{3}\
33297    !
33298  """, 'interpolation 1\n  follows 2  too 3!'
33299  eq """
33300
33301    #{1} #{2}
33302
33303    """, '\n1 2\n'
33304
33305  # Handle escaped backslashes correctly.
33306  eq '''
33307    escaped backslash at EOL\\
33308      next line
33309  ''', 'escaped backslash at EOL\\\n  next line'
33310  eq '''\\
33311
33312     ''', '\\\n'
33313
33314  # Backslashes at beginning of lines.
33315  eq '''first line
33316      \   backslash at BOL''', 'first line\n\   backslash at BOL'
33317  eq """first line\
33318      \   backslash at BOL""", 'first line\   backslash at BOL'
33319
33320  # Backslashes at end of strings.
33321  eq '''first line \ ''', 'first line  '
33322  eq '''
33323    first line
33324    second line \
33325  ''', 'first line\nsecond line '
33326  eq '''
33327    first line
33328    second line
33329    \
33330  ''', 'first line\nsecond line'
33331  eq '''
33332    first line
33333    second line
33334
33335      \
33336
33337  ''', 'first line\nsecond line\n'
33338
33339  # Edge cases.
33340  eq '''lone
33341
33342          \
33343
33344
33345
33346        backslash''', 'lone\n\n  backslash'
33347  eq '''\
33348     ''', ''
33349
33350test '#2388: `"""` in heredoc interpolations', ->
33351  eq """a heredoc #{
33352      "inside \
33353        interpolation"
33354    }""", "a heredoc inside interpolation"
33355  eq """a#{"""b"""}c""", 'abc'
33356  eq """#{""""""}""", ''
33357
33358test "trailing whitespace", ->
33359  testTrailing = (str, expected) ->
33360    eq CoffeeScript.eval(str.replace /\|$/gm, ''), expected
33361  testTrailing '''"   |
33362      |
33363    a   |
33364           |
33365  "''', 'a'
33366  testTrailing """'''   |
33367      |
33368    a   |
33369           |
33370  '''""", '  \na   \n       '
33371
33372#647
33373eq "''Hello, World\\''", '''
33374'\'Hello, World\\\''
33375'''
33376eq '""Hello, World\\""', """
33377"\"Hello, World\\\""
33378"""
33379
33380test "#1273, escaping quotes at the end of heredocs.", ->
33381  # """\""" no longer compiles
33382  eq """\\""", '\\'
33383  eq """\\\"""", '\\\"'
33384
33385a = """
33386    basic heredoc
33387    on two lines
33388    """
33389ok a is "basic heredoc\non two lines"
33390
33391a = '''
33392    a
33393      "b
33394    c
33395    '''
33396ok a is "a\n  \"b\nc"
33397
33398a = """
33399a
33400 b
33401  c
33402"""
33403ok a is "a\n b\n  c"
33404
33405a = '''one-liner'''
33406ok a is 'one-liner'
33407
33408a = """
33409      out
33410      here
33411"""
33412ok a is "out\nhere"
33413
33414a = '''
33415       a
33416     b
33417   c
33418    '''
33419ok a is "    a\n  b\nc"
33420
33421a = '''
33422a
33423
33424
33425b c
33426'''
33427ok a is "a\n\n\nb c"
33428
33429a = '''more"than"one"quote'''
33430ok a is 'more"than"one"quote'
33431
33432a = '''here's an apostrophe'''
33433ok a is "here's an apostrophe"
33434
33435a = """""surrounded by two quotes"\""""
33436ok a is '""surrounded by two quotes""'
33437
33438a = '''''surrounded by two apostrophes'\''''
33439ok a is "''surrounded by two apostrophes''"
33440
33441# The indentation detector ignores blank lines without trailing whitespace
33442a = """
33443    one
33444    two
33445
33446    """
33447ok a is "one\ntwo\n"
33448
33449eq ''' line 0
33450  should not be relevant
33451    to the indent level
33452''', ' line 0\nshould not be relevant\n  to the indent level'
33453
33454eq """
33455  interpolation #{
33456 "contents"
33457 }
33458  should not be relevant
33459    to the indent level
33460""", 'interpolation contents\nshould not be relevant\n  to the indent level'
33461
33462eq ''' '\\\' ''', " '\\' "
33463eq """ "\\\" """, ' "\\" '
33464
33465eq '''  <- keep these spaces ->  ''', '  <- keep these spaces ->  '
33466
33467eq '''undefined''', 'undefined'
33468eq """undefined""", 'undefined'
33469
33470
33471test "#1046, empty string interpolations", ->
33472  eq "#{ }", ''
33473
33474test "strings are not callable", ->
33475  throwsCompileError '"a"()'
33476  throwsCompileError '"a#{b}"()'
33477  throwsCompileError '"a" 1'
33478  throwsCompileError '"a#{b}" 1'
33479  throwsCompileError '''
33480    "a"
33481       k: v
33482  '''
33483  throwsCompileError '''
33484    "a#{b}"
33485       k: v
33486  '''
33487
33488test "#3795: Escape otherwise invalid characters", ->
33489  eq '
', '\u2028'
33490  eq '
', '\u2029'
33491  eq '\0\
33492      1', '\x001'
33493  eq "
", '\u2028'
33494  eq "
", '\u2029'
33495  eq "\0\
33496      1", '\x001'
33497  eq "\0\
33498      9", '\x009'
33499  eq "\0#{}0", '\x000'
33500  eq '''
''', '\u2028'
33501  eq '''
''', '\u2029'
33502  eq '''\0\
33503      1''', '\x001'
33504  eq '''\0\
33505      9''', '\x009'
33506  eq """\0#{}1""", '\x001'
33507  eq """
""", '\u2028'
33508  eq """
""", '\u2029'
33509  eq """\0\
33510      1""", '\x001'
33511
33512  a = 'a'
33513  eq "#{a}
", 'a\u2028'
33514  eq "#{a}
", 'a\u2029'
33515  eq "#{a}\0\
33516      1", 'a\0' + '1'
33517  eq """#{a}
""", 'a\u2028'
33518  eq """#{a}
""", 'a\u2029'
33519  eq """#{a}\0\
33520      1""", 'a\0' + '1'
33521
33522test "#4314: Whitespace less than or equal to stripped indentation", ->
33523  # The odd indentation is intentional here, to test 1-space indentation.
33524  eq ' ', """
33525 #{} #{}
33526"""
33527
33528  eq '1 2  3   4    5     end\na 0     b', """
33529    #{1} #{2}  #{3}   #{4}    #{5}     end
33530    a #{0}     b"""
33531
33532test "#4248: Unicode code point escapes", ->
33533  eq '\u01ab\u00cd', '\u{1ab}\u{cd}'
33534  eq '\u01ab', '\u{000001ab}'
33535  eq 'a\u01ab', "#{ 'a' }\u{1ab}"
33536  eq '\u01abc', '''\u{01ab}c'''
33537  eq '\u01abc', """\u{1ab}#{ 'c' }"""
33538  eq '\udab3\uddef', '\u{bcdef}'
33539  eq '\udab3\uddef', '\u{0000bcdef}'
33540  eq 'a\udab3\uddef', "#{ 'a' }\u{bcdef}"
33541  eq '\udab3\uddefc', '''\u{0bcdef}c'''
33542  eq '\udab3\uddefc', """\u{bcdef}#{ 'c' }"""
33543  eq '\\u{123456}', "#{'\\'}#{'u{123456}'}"
33544
33545  # don't rewrite code point escapes
33546  eqJS """
33547    '\\u{bcdef}\\u{abc}'
33548  """,
33549  """
33550    '\\u{bcdef}\\u{abc}';
33551  """
33552
33553  eqJS """
33554    "#{ 'a' }\\u{bcdef}"
33555  """,
33556  """
33557    "a\\u{bcdef}";
33558  """
33559
33560</script>
vendor: 1 bytes, line 33560
33560
33561<script type="text/x-coffeescript" class="test" id="tagged_template_literals">
33562# Tagged template literals
33563# ------------------------
33564
33565# NOTES:
33566# A tagged template literal is a string that is passed to a prefixing function for
33567# post-processing. There's a bunch of different angles that need testing:
33568# - Prefixing function, which can be any form of function call:
33569#   - function: func'Hello'
33570#   - object property with dot notation: outerobj.obj.func'Hello'
33571#   - object property with bracket notation: outerobj['obj']['func']'Hello'
33572# - String form: single quotes, double quotes and block strings
33573# - String is single-line or multi-line
33574# - String is interpolated or not
33575
33576func = (text, expressions...) ->
33577  "text: [#{text.join '|'}] expressions: [#{expressions.join '|'}]"
33578
33579outerobj =
33580  obj:
33581    func: func
33582    f: -> func
33583
33584# Example use
33585test "tagged template literal for html templating", ->
33586  html = (htmlFragments, expressions...) ->
33587    htmlFragments.reduce (fullHtml, htmlFragment, i) ->
33588      fullHtml + "#{expressions[i - 1]}#{htmlFragment}"
33589
33590  state =
33591    name: 'Greg'
33592    adjective: 'awesome'
33593
33594  eq """
33595      <p>
33596        Hi Greg. You're looking awesome!
33597      </p>
33598    """,
33599    html"""
33600      <p>
33601        Hi #{state.name}. You're looking #{state.adjective}!
33602      </p>
33603    """
33604
33605# Simple, non-interpolated strings
33606test "tagged template literal with a single-line single-quote string", ->
33607  eq 'text: [single-line single quotes] expressions: []',
33608  func'single-line single quotes'
33609
33610test "tagged template literal with a single-line double-quote string", ->
33611  eq 'text: [single-line double quotes] expressions: []',
33612  func"single-line double quotes"
33613
33614test "tagged template literal with a single-line single-quote block string", ->
33615  eq 'text: [single-line block string] expressions: []',
33616  func'''single-line block string'''
33617
33618test "tagged template literal with a single-line double-quote block string", ->
33619  eq 'text: [single-line block string] expressions: []',
33620  func"""single-line block string"""
33621
33622test "tagged template literal with a multi-line single-quote string", ->
33623  eq 'text: [multi-line single quotes] expressions: []',
33624  func'multi-line
33625                                                              single quotes'
33626
33627test "tagged template literal with a multi-line double-quote string", ->
33628  eq 'text: [multi-line double quotes] expressions: []',
33629  func"multi-line
33630       double quotes"
33631
33632test "tagged template literal with a multi-line single-quote block string", ->
33633  eq 'text: [multi-line\nblock string] expressions: []',
33634  func'''
33635      multi-line
33636      block string
33637      '''
33638
33639test "tagged template literal with a multi-line double-quote block string", ->
33640  eq 'text: [multi-line\nblock string] expressions: []',
33641  func"""
33642      multi-line
33643      block string
33644      """
33645
33646# Interpolated strings with expressions
33647test "tagged template literal with a single-line double-quote interpolated string", ->
33648  eq 'text: [single-line | double quotes | interpolation] expressions: [36|42]',
33649  func"single-line #{6 * 6} double quotes #{6 * 7} interpolation"
33650
33651test "tagged template literal with a single-line double-quote block interpolated string", ->
33652  eq 'text: [single-line | block string | interpolation] expressions: [incredible|48]',
33653  func"""single-line #{'incredible'} block string #{6 * 8} interpolation"""
33654
33655test "tagged template literal with a multi-line double-quote interpolated string", ->
33656  eq 'text: [multi-line | double quotes | interpolation] expressions: [2|awesome]',
33657  func"multi-line #{4/2}
33658       double quotes #{'awesome'} interpolation"
33659
33660test "tagged template literal with a multi-line double-quote block interpolated string", ->
33661  eq 'text: [multi-line |\nblock string |] expressions: [/abc/|32]',
33662  func"""
33663      multi-line #{/abc/}
33664      block string #{2 * 16}
33665      """
33666
33667
33668# Tagged template literal must use a callable function
33669test "tagged template literal dot notation recognized as a callable function", ->
33670  eq 'text: [dot notation] expressions: []',
33671  outerobj.obj.func'dot notation'
33672
33673test "tagged template literal bracket notation recognized as a callable function", ->
33674  eq 'text: [bracket notation] expressions: []',
33675  outerobj['obj']['func']'bracket notation'
33676
33677test "tagged template literal mixed dot and bracket notation recognized as a callable function", ->
33678  eq 'text: [mixed notation] expressions: []',
33679  outerobj['obj'].func'mixed notation'
33680
33681
33682# Edge cases
33683test "tagged template literal with an empty string", ->
33684  eq 'text: [] expressions: []',
33685  func''
33686
33687test "tagged template literal with an empty interpolated string", ->
33688  eq 'text: [] expressions: []',
33689  func"#{}"
33690
33691test "tagged template literal as single interpolated expression", ->
33692  eq 'text: [|] expressions: [3]',
33693  func"#{3}"
33694
33695test "tagged template literal with an interpolated string that itself contains an interpolated string", ->
33696  eq 'text: [inner | string] expressions: [interpolated]',
33697  func"inner #{"#{'inter'}polated"} string"
33698
33699test "tagged template literal with an interpolated string that contains a tagged template literal", ->
33700  eq 'text: [inner tagged | literal] expressions: [text: [|] expressions: [template]]',
33701  func"inner tagged #{func"#{'template'}"} literal"
33702
33703test "tagged template literal with backticks", ->
33704  eq 'text: [ES template literals look like this: `foo bar`] expressions: []',
33705  func"ES template literals look like this: `foo bar`"
33706
33707test "tagged template literal with escaped backticks", ->
33708  eq 'text: [ES template literals look like this: \\`foo bar\\`] expressions: []',
33709  func"ES template literals look like this: \\`foo bar\\`"
33710
33711test "tagged template literal with unnecessarily escaped backticks", ->
33712  eq 'text: [ES template literals look like this: `foo bar`] expressions: []',
33713  func"ES template literals look like this: \`foo bar\`"
33714
33715test "tagged template literal with ES interpolation", ->
33716  eq 'text: [ES template literals also look like this: `3 + 5 = ${3+5}`] expressions: []',
33717  func"ES template literals also look like this: `3 + 5 = ${3+5}`"
33718
33719test "tagged template literal with both ES and CoffeeScript interpolation", ->
33720  eq "text: [ES template literals also look like this: `3 + 5 = ${3+5}` which equals |] expressions: [8]",
33721  func"ES template literals also look like this: `3 + 5 = ${3+5}` which equals #{3+5}"
33722
33723test "tagged template literal with escaped ES interpolation", ->
33724  eq 'text: [ES template literals also look like this: `3 + 5 = \\${3+5}`] expressions: []',
33725  func"ES template literals also look like this: `3 + 5 = \\${3+5}`"
33726
33727test "tagged template literal with unnecessarily escaped ES interpolation", ->
33728  eq 'text: [ES template literals also look like this: `3 + 5 = ${3+5}`] expressions: []',
33729  func"ES template literals also look like this: `3 + 5 = \${3+5}`"
33730
33731test "tagged template literal special escaping", ->
33732  eq 'text: [` ` \\` \\` \\\\` $ { ${ ${ \\${ \\${ \\\\${ | ` ${] expressions: [1]',
33733  func"` \` \\` \\\` \\\\` $ { ${ \${ \\${ \\\${ \\\\${ #{1} ` ${"
33734
33735test '#4467: tagged template literal call recognized as a callable function', ->
33736  eq 'text: [dot notation] expressions: []',
33737  outerobj.obj.f()'dot notation'
33738
33739
33740</script>
vendor: 66 bytes, lines 33740-33743
33740
33741
33742
33743<script async src="https://www.googletagmanager.com/gtag/js?id=
33743UA-106156830-1
vendor: 12 bytes, line 33743
33743"></script>
33744<script>
33745  window.GA_TRACKING_ID = 'UA-106156830-1';
33746  window.dataLayer = window.dataLayer || [];
33747  function gtag(){dataLayer.push(arguments)};
33748  gtag('js', new Date());
33749  gtag('config', GA_TRACKING_ID);
33750</script>
vendor: 1 bytes, line 33750
33750
33751<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"3bf2bd78e087451ea36567e241d6aa66","r":1,"spa":2}' crossorigin="anonymous"></script>
33751
33752</body>
33753</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.