mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-01-14 17:27:59 -05:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12fcbfc654 | ||
|
|
38f5963b85 | ||
|
|
ffbe51e374 | ||
|
|
926cb8463c | ||
|
|
b1286752b9 | ||
|
|
5eb9dded52 | ||
|
|
7f5ab7eb0d | ||
|
|
5bc85b8f6d | ||
|
|
81d1b511f0 | ||
|
|
2dc3f6c87a | ||
|
|
04959162c6 | ||
|
|
f14c7ffa3f | ||
|
|
64b8dd486a | ||
|
|
7864acabc3 | ||
|
|
9812d28748 | ||
|
|
555c22af58 | ||
|
|
3f4b03bcff | ||
|
|
a706a64a6d | ||
|
|
637fe305a6 | ||
|
|
bd824c73dd |
27
appveyor.yml
Normal file
27
appveyor.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
- nodejs_version: '6'
|
||||||
|
- nodejs_version: '8'
|
||||||
|
- nodejs_version: '' # Installs latest.
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ps: Install-Product node $env:nodejs_version
|
||||||
|
- node --version
|
||||||
|
- npm --version
|
||||||
|
- npm install
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- node_modules
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- node ./bin/cake build:except-parser
|
||||||
|
- node ./bin/cake build:parser
|
||||||
|
- node ./bin/cake build:full
|
||||||
|
- node ./bin/cake build:browser
|
||||||
|
- node ./bin/cake test
|
||||||
|
- node ./bin/cake test:browser
|
||||||
|
- node ./bin/cake test:integrations
|
||||||
|
|
||||||
|
build: off
|
||||||
|
|
||||||
|
version: "{build}"
|
||||||
@@ -480,7 +480,9 @@ is run via the CLI or Node API.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> transpiler = options.transpile.transpile
|
<div class="content"><div class='highlight'><pre> transpiler = options.transpile.transpile
|
||||||
<span class="hljs-keyword">delete</span> options.transpile.transpile</pre></div></div>
|
<span class="hljs-keyword">delete</span> options.transpile.transpile
|
||||||
|
|
||||||
|
transpilerOptions = Object.assign {}, options.transpile</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -497,9 +499,9 @@ and it will return an <em>updated</em> v3 source map object in its output.</p>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> v3SourceMap <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> options.transpile.inputSourceMap?
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> v3SourceMap <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> transpilerOptions.inputSourceMap?
|
||||||
options.transpile.inputSourceMap = v3SourceMap
|
transpilerOptions.inputSourceMap = v3SourceMap
|
||||||
transpilerOutput = transpiler js, options.transpile
|
transpilerOutput = transpiler js, transpilerOptions
|
||||||
js = transpilerOutput.code
|
js = transpilerOutput.code
|
||||||
<span class="hljs-keyword">if</span> v3SourceMap <span class="hljs-keyword">and</span> transpilerOutput.map
|
<span class="hljs-keyword">if</span> v3SourceMap <span class="hljs-keyword">and</span> transpilerOutput.map
|
||||||
v3SourceMap = transpilerOutput.map
|
v3SourceMap = transpilerOutput.map
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ same directory as the <code>.js</code> file.</p>
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">writeJs</span> = <span class="hljs-params">(base, sourcePath, js, jsPath, generatedSourceMap = <span class="hljs-literal">null</span>)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">writeJs</span> = <span class="hljs-params">(base, sourcePath, js, jsPath, generatedSourceMap = <span class="hljs-literal">null</span>)</span> -></span>
|
||||||
sourceMapPath = outputPath sourcePath, base, <span class="hljs-string">".js.map"</span>
|
sourceMapPath = <span class="hljs-string">"<span class="hljs-subst">#{jsPath}</span>.map"</span>
|
||||||
jsDir = path.dirname jsPath
|
jsDir = path.dirname jsPath
|
||||||
<span class="hljs-function"> <span class="hljs-title">compile</span> = -></span>
|
<span class="hljs-function"> <span class="hljs-title">compile</span> = -></span>
|
||||||
<span class="hljs-keyword">if</span> opts.compile
|
<span class="hljs-keyword">if</span> opts.compile
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ the ordinary <strong>Assign</strong> is that these allow numbers and strings as
|
|||||||
o <span class="hljs-string">'Identifier'</span>
|
o <span class="hljs-string">'Identifier'</span>
|
||||||
o <span class="hljs-string">'Property'</span>
|
o <span class="hljs-string">'Property'</span>
|
||||||
o <span class="hljs-string">'ThisProperty'</span>
|
o <span class="hljs-string">'ThisProperty'</span>
|
||||||
|
o <span class="hljs-string">'[ Expression ]'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> ComputedPropertyName $<span class="hljs-number">2</span>
|
||||||
]
|
]
|
||||||
|
|
||||||
ObjAssignable: [
|
ObjAssignable: [
|
||||||
@@ -1007,6 +1008,7 @@ and optional references to the superclass.</p>
|
|||||||
o <span class="hljs-string">'EXPORT Identifier = INDENT Expression OUTDENT'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, <span class="hljs-literal">null</span>,
|
o <span class="hljs-string">'EXPORT Identifier = INDENT Expression OUTDENT'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> Assign $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, <span class="hljs-literal">null</span>,
|
||||||
moduleDeclaration: <span class="hljs-string">'export'</span>
|
moduleDeclaration: <span class="hljs-string">'export'</span>
|
||||||
o <span class="hljs-string">'EXPORT DEFAULT Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportDefaultDeclaration $<span class="hljs-number">3</span>
|
o <span class="hljs-string">'EXPORT DEFAULT Expression'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportDefaultDeclaration $<span class="hljs-number">3</span>
|
||||||
|
o <span class="hljs-string">'EXPORT DEFAULT INDENT Object OUTDENT'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportDefaultDeclaration <span class="hljs-keyword">new</span> Value $<span class="hljs-number">4</span>
|
||||||
o <span class="hljs-string">'EXPORT EXPORT_ALL FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportAllDeclaration <span class="hljs-keyword">new</span> Literal($<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>
|
o <span class="hljs-string">'EXPORT EXPORT_ALL FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportAllDeclaration <span class="hljs-keyword">new</span> Literal($<span class="hljs-number">2</span>), $<span class="hljs-number">4</span>
|
||||||
o <span class="hljs-string">'EXPORT { ExportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList($<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>
|
o <span class="hljs-string">'EXPORT { ExportSpecifierList OptComma } FROM String'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> ExportNamedDeclaration <span class="hljs-keyword">new</span> ExportSpecifierList($<span class="hljs-number">3</span>), $<span class="hljs-number">7</span>
|
||||||
]
|
]
|
||||||
@@ -1132,7 +1134,8 @@ and optional references to the superclass.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> Array: [
|
<div class="content"><div class='highlight'><pre> Array: [
|
||||||
o <span class="hljs-string">'[ ]'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Arr []
|
o <span class="hljs-string">'[ ]'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Arr []
|
||||||
o <span class="hljs-string">'[ ArgList OptComma ]'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Arr $<span class="hljs-number">2</span>
|
o <span class="hljs-string">'[ Elisions ]'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Arr $<span class="hljs-number">2</span>
|
||||||
|
o <span class="hljs-string">'[ ArgElisionList OptElisions ]'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Arr [].concat $<span class="hljs-number">2</span>, $<span class="hljs-number">3</span>
|
||||||
]</pre></div></div>
|
]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -1199,8 +1202,7 @@ and optional references to the superclass.</p>
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-49">¶</a>
|
<a class="pilcrow" href="#section-49">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
|
<p>The <strong>ArgList</strong> is the list of objects passed into a function call
|
||||||
as well as the contents of an array literal
|
|
||||||
(i.e. comma-separated expressions). Newlines work as well.</p>
|
(i.e. comma-separated expressions). Newlines work as well.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -1241,6 +1243,47 @@ as well as the contents of an array literal
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-51">¶</a>
|
<a class="pilcrow" href="#section-51">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
<p>The <strong>ArgElisionList</strong> is the list of objects, contents of an array literal
|
||||||
|
(i.e. comma-separated expressions and elisions). Newlines work as well.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> ArgElisionList: [
|
||||||
|
o <span class="hljs-string">'ArgElision'</span>
|
||||||
|
o <span class="hljs-string">'ArgElisionList , ArgElision'</span>, <span class="hljs-function">-></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">3</span>
|
||||||
|
o <span class="hljs-string">'ArgElisionList OptElisions TERMINATOR ArgElision'</span>, <span class="hljs-function">-></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>
|
||||||
|
o <span class="hljs-string">'INDENT ArgElisionList OptElisions OUTDENT'</span>, <span class="hljs-function">-></span> $<span class="hljs-number">2.</span>concat $<span class="hljs-number">3</span>
|
||||||
|
o <span class="hljs-string">'ArgElisionList OptElisions INDENT ArgElisionList OptElisions OUTDENT'</span>, <span class="hljs-function">-></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">2</span>, $<span class="hljs-number">4</span>, $<span class="hljs-number">5</span>
|
||||||
|
]
|
||||||
|
|
||||||
|
ArgElision: [
|
||||||
|
o <span class="hljs-string">'Arg'</span>, <span class="hljs-function">-></span> [$<span class="hljs-number">1</span>]
|
||||||
|
o <span class="hljs-string">'Elisions Arg'</span>, <span class="hljs-function">-></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">2</span>
|
||||||
|
]
|
||||||
|
|
||||||
|
OptElisions: [
|
||||||
|
o <span class="hljs-string">'OptComma'</span>, <span class="hljs-function">-></span> []
|
||||||
|
o <span class="hljs-string">', Elisions'</span>, <span class="hljs-function">-></span> [].concat $<span class="hljs-number">2</span>
|
||||||
|
]
|
||||||
|
|
||||||
|
Elisions: [
|
||||||
|
o <span class="hljs-string">'Elision'</span>, <span class="hljs-function">-></span> [$<span class="hljs-number">1</span>]
|
||||||
|
o <span class="hljs-string">'Elisions Elision'</span>, <span class="hljs-function">-></span> $<span class="hljs-number">1.</span>concat $<span class="hljs-number">2</span>
|
||||||
|
]
|
||||||
|
|
||||||
|
Elision: [
|
||||||
|
o <span class="hljs-string">','</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Elision
|
||||||
|
]</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-52">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-52">¶</a>
|
||||||
|
</div>
|
||||||
<p>Just simple, comma-separated, required arguments (no fancy syntax). We need
|
<p>Just simple, comma-separated, required arguments (no fancy syntax). We need
|
||||||
this to be separate from the <strong>ArgList</strong> for use in <strong>Switch</strong> blocks, where
|
this to be separate from the <strong>ArgList</strong> for use in <strong>Switch</strong> blocks, where
|
||||||
having the newlines wouldn’t make sense.</p>
|
having the newlines wouldn’t make sense.</p>
|
||||||
@@ -1255,11 +1298,11 @@ having the newlines wouldn’t make sense.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-52">
|
<li id="section-53">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-52">¶</a>
|
<a class="pilcrow" href="#section-53">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The variants of <em>try/catch/finally</em> exception handling blocks.</p>
|
<p>The variants of <em>try/catch/finally</em> exception handling blocks.</p>
|
||||||
|
|
||||||
@@ -1275,11 +1318,11 @@ having the newlines wouldn’t make sense.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-53">
|
<li id="section-54">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-53">¶</a>
|
<a class="pilcrow" href="#section-54">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>A catch clause names its error and runs a block of code.</p>
|
<p>A catch clause names its error and runs a block of code.</p>
|
||||||
|
|
||||||
@@ -1294,11 +1337,11 @@ having the newlines wouldn’t make sense.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-54">
|
<li id="section-55">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-54">¶</a>
|
<a class="pilcrow" href="#section-55">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Throw an exception object.</p>
|
<p>Throw an exception object.</p>
|
||||||
|
|
||||||
@@ -1312,11 +1355,11 @@ having the newlines wouldn’t make sense.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-55">
|
<li id="section-56">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-55">¶</a>
|
<a class="pilcrow" href="#section-56">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
|
<p>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
|
||||||
not an <strong>Expression</strong>, so if you need to use an expression in a place
|
not an <strong>Expression</strong>, so if you need to use an expression in a place
|
||||||
@@ -1333,11 +1376,11 @@ the trick.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-56">
|
<li id="section-57">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-56">¶</a>
|
<a class="pilcrow" href="#section-57">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The condition portion of a while loop.</p>
|
<p>The condition portion of a while loop.</p>
|
||||||
|
|
||||||
@@ -1353,11 +1396,11 @@ the trick.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-57">
|
<li id="section-58">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-57">¶</a>
|
<a class="pilcrow" href="#section-58">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The while loop can either be normal, with a block of expressions to execute,
|
<p>The while loop can either be normal, with a block of expressions to execute,
|
||||||
or postfix, with a single expression. There is no do..while.</p>
|
or postfix, with a single expression. There is no do..while.</p>
|
||||||
@@ -1379,11 +1422,11 @@ or postfix, with a single expression. There is no do..while.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-58">
|
<li id="section-59">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-58">¶</a>
|
<a class="pilcrow" href="#section-59">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Array, object, and range comprehensions, at the most generic level.
|
<p>Array, object, and range comprehensions, at the most generic level.
|
||||||
Comprehensions can either be normal, with a block of expressions to execute,
|
Comprehensions can either be normal, with a block of expressions to execute,
|
||||||
@@ -1411,11 +1454,11 @@ or postfix, with a single expression.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-59">
|
<li id="section-60">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-59">¶</a>
|
<a class="pilcrow" href="#section-60">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>An array of all accepted values for a variable inside the loop.
|
<p>An array of all accepted values for a variable inside the loop.
|
||||||
This enables support for pattern matching.</p>
|
This enables support for pattern matching.</p>
|
||||||
@@ -1432,11 +1475,11 @@ This enables support for pattern matching.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-60">
|
<li id="section-61">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-60">¶</a>
|
<a class="pilcrow" href="#section-61">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>An array or range comprehension has variables for the current element
|
<p>An array or range comprehension has variables for the current element
|
||||||
and (optional) reference to the current index. Or, <em>key, value</em>, in the case
|
and (optional) reference to the current index. Or, <em>key, value</em>, in the case
|
||||||
@@ -1452,11 +1495,11 @@ of object comprehensions.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-61">
|
<li id="section-62">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-61">¶</a>
|
<a class="pilcrow" href="#section-62">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The source of a comprehension is an array or object with an optional guard
|
<p>The source of a comprehension is an array or object with an optional guard
|
||||||
clause. If it’s an array comprehension, you can also choose to step through
|
clause. If it’s an array comprehension, you can also choose to step through
|
||||||
@@ -1491,11 +1534,11 @@ in fixed-size increments.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-62">
|
<li id="section-63">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-62">¶</a>
|
<a class="pilcrow" href="#section-63">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>An individual <strong>When</strong> clause, with action.</p>
|
<p>An individual <strong>When</strong> clause, with action.</p>
|
||||||
|
|
||||||
@@ -1509,11 +1552,11 @@ in fixed-size increments.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-63">
|
<li id="section-64">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-63">¶</a>
|
<a class="pilcrow" href="#section-64">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The most basic form of <em>if</em> is a condition and an action. The following
|
<p>The most basic form of <em>if</em> is a condition and an action. The following
|
||||||
if-related rules are broken up along these lines in order to avoid
|
if-related rules are broken up along these lines in order to avoid
|
||||||
@@ -1529,11 +1572,11 @@ ambiguity.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-64">
|
<li id="section-65">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-64">¶</a>
|
<a class="pilcrow" href="#section-65">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>The full complement of <em>if</em> expressions, including postfix one-liner
|
<p>The full complement of <em>if</em> expressions, including postfix one-liner
|
||||||
<em>if</em> and <em>unless</em>.</p>
|
<em>if</em> and <em>unless</em>.</p>
|
||||||
@@ -1550,11 +1593,11 @@ ambiguity.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-65">
|
<li id="section-66">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-65">¶</a>
|
<a class="pilcrow" href="#section-66">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Arithmetic and logical operators, working on one or more operands.
|
<p>Arithmetic and logical operators, working on one or more operands.
|
||||||
Here they are grouped by order of precedence. The actual precedence rules
|
Here they are grouped by order of precedence. The actual precedence rules
|
||||||
@@ -1581,11 +1624,11 @@ rules are necessary.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-66">
|
<li id="section-67">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-66">¶</a>
|
<a class="pilcrow" href="#section-67">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p><a href="http://coffeescript.org/#existential-operator">The existential operator</a>.</p>
|
<p><a href="http://coffeescript.org/#existential-operator">The existential operator</a>.</p>
|
||||||
|
|
||||||
@@ -1623,26 +1666,14 @@ rules are necessary.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-67">
|
|
||||||
<div class="annotation">
|
|
||||||
|
|
||||||
<div class="pilwrap ">
|
|
||||||
<a class="pilcrow" href="#section-67">¶</a>
|
|
||||||
</div>
|
|
||||||
<h2 id="precedence">Precedence</h2>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li id="section-68">
|
<li id="section-68">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-68">¶</a>
|
<a class="pilcrow" href="#section-68">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
<h2 id="precedence">Precedence</h2>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -1654,6 +1685,18 @@ rules are necessary.</p>
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-69">¶</a>
|
<a class="pilcrow" href="#section-69">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-70">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-70">¶</a>
|
||||||
|
</div>
|
||||||
<p>Operators at the top of this list have higher precedence than the ones lower
|
<p>Operators at the top of this list have higher precedence than the ones lower
|
||||||
down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
|
down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
|
||||||
<pre><code><span class="hljs-number">2</span> + (<span class="hljs-number">3</span> * <span class="hljs-number">4</span>)
|
<pre><code><span class="hljs-number">2</span> + (<span class="hljs-number">3</span> * <span class="hljs-number">4</span>)
|
||||||
@@ -1693,26 +1736,14 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-70">
|
|
||||||
<div class="annotation">
|
|
||||||
|
|
||||||
<div class="pilwrap ">
|
|
||||||
<a class="pilcrow" href="#section-70">¶</a>
|
|
||||||
</div>
|
|
||||||
<h2 id="wrapping-up">Wrapping Up</h2>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li id="section-71">
|
<li id="section-71">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-71">¶</a>
|
<a class="pilcrow" href="#section-71">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
<h2 id="wrapping-up">Wrapping Up</h2>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
@@ -1724,6 +1755,18 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-72">¶</a>
|
<a class="pilcrow" href="#section-72">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-73">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-73">¶</a>
|
||||||
|
</div>
|
||||||
<p>Finally, now that we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
|
<p>Finally, now that we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
|
||||||
our <strong>Jison.Parser</strong>. We do this by processing all of our rules, recording all
|
our <strong>Jison.Parser</strong>. We do this by processing all of our rules, recording all
|
||||||
terminals (every symbol which does not appear as the name of a rule above)
|
terminals (every symbol which does not appear as the name of a rule above)
|
||||||
@@ -1742,11 +1785,11 @@ as “tokens”.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-73">
|
<li id="section-74">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-73">¶</a>
|
<a class="pilcrow" href="#section-74">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
|
<p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
|
||||||
rules, and the name of the root. Reverse the operators because Jison orders
|
rules, and the name of the root. Reverse the operators because Jison orders
|
||||||
|
|||||||
@@ -1121,7 +1121,7 @@ comments that trail it.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> prevChar = <span class="hljs-keyword">if</span> @tokens.length > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> @tokens[@tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
<div class="content"><div class='highlight'><pre> prevChar = <span class="hljs-keyword">if</span> @tokens.length > <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> @tokens[@tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>
|
||||||
<span class="hljs-keyword">if</span> firstChar <span class="hljs-keyword">is</span> <span class="hljs-string">'<'</span>
|
<span class="hljs-keyword">if</span> firstChar <span class="hljs-keyword">is</span> <span class="hljs-string">'<'</span>
|
||||||
match = CSX_IDENTIFIER.exec @chunk[<span class="hljs-number">1.</span>..]
|
match = CSX_IDENTIFIER.exec(@chunk[<span class="hljs-number">1.</span>..]) <span class="hljs-keyword">or</span> CSX_FRAGMENT_IDENTIFIER.exec(@chunk[<span class="hljs-number">1.</span>..])
|
||||||
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span> <span class="hljs-keyword">unless</span> match <span class="hljs-keyword">and</span> (
|
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span> <span class="hljs-keyword">unless</span> match <span class="hljs-keyword">and</span> (
|
||||||
@csxDepth > <span class="hljs-number">0</span> <span class="hljs-keyword">or</span></pre></div></div>
|
@csxDepth > <span class="hljs-number">0</span> <span class="hljs-keyword">or</span></pre></div></div>
|
||||||
|
|
||||||
@@ -1187,8 +1187,8 @@ comments that trail it.</p>
|
|||||||
@matchWithInterpolations INSIDE_CSX, <span class="hljs-string">'>'</span>, <span class="hljs-string">'</'</span>, CSX_INTERPOLATION
|
@matchWithInterpolations INSIDE_CSX, <span class="hljs-string">'>'</span>, <span class="hljs-string">'</'</span>, CSX_INTERPOLATION
|
||||||
@mergeInterpolationTokens tokens, {delimiter: <span class="hljs-string">'"'</span>}, <span class="hljs-function"><span class="hljs-params">(value, i)</span> =></span>
|
@mergeInterpolationTokens tokens, {delimiter: <span class="hljs-string">'"'</span>}, <span class="hljs-function"><span class="hljs-params">(value, i)</span> =></span>
|
||||||
@formatString value, delimiter: <span class="hljs-string">'>'</span>
|
@formatString value, delimiter: <span class="hljs-string">'>'</span>
|
||||||
match = CSX_IDENTIFIER.exec @chunk[end...]
|
match = CSX_IDENTIFIER.exec(@chunk[end...]) <span class="hljs-keyword">or</span> CSX_FRAGMENT_IDENTIFIER.exec(@chunk[end...])
|
||||||
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> match <span class="hljs-keyword">or</span> match[<span class="hljs-number">0</span>] <span class="hljs-keyword">isnt</span> csxTag.name
|
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> match <span class="hljs-keyword">or</span> match[<span class="hljs-number">1</span>] <span class="hljs-keyword">isnt</span> csxTag.name
|
||||||
@error <span class="hljs-string">"expected corresponding CSX closing tag for <span class="hljs-subst">#{csxTag.name}</span>"</span>,
|
@error <span class="hljs-string">"expected corresponding CSX closing tag for <span class="hljs-subst">#{csxTag.name}</span>"</span>,
|
||||||
csxTag.origin[<span class="hljs-number">2</span>]
|
csxTag.origin[<span class="hljs-number">2</span>]
|
||||||
afterTag = end + csxTag.name.length
|
afterTag = end + csxTag.name.length
|
||||||
@@ -2458,6 +2458,23 @@ be used as identifiers or properties.</p>
|
|||||||
CSX_IDENTIFIER = <span class="hljs-regexp">/// ^
|
CSX_IDENTIFIER = <span class="hljs-regexp">/// ^
|
||||||
(?![\d<]) <span class="hljs-comment"># Must not start with `<`.</span>
|
(?![\d<]) <span class="hljs-comment"># Must not start with `<`.</span>
|
||||||
( (?: (?!\s)[\.\-$\w\x7f-\uffff] )+ ) <span class="hljs-comment"># Like `IDENTIFIER`, but includes `-`s and `.`s.</span>
|
( (?: (?!\s)[\.\-$\w\x7f-\uffff] )+ ) <span class="hljs-comment"># Like `IDENTIFIER`, but includes `-`s and `.`s.</span>
|
||||||
|
///</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-98">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-98">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Fragment: <></></p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre>CSX_FRAGMENT_IDENTIFIER = <span class="hljs-regexp">/// ^
|
||||||
|
()> <span class="hljs-comment"># Ends immediately with `>`.</span>
|
||||||
///</span>
|
///</span>
|
||||||
|
|
||||||
CSX_ATTRIBUTE = <span class="hljs-regexp">/// ^
|
CSX_ATTRIBUTE = <span class="hljs-regexp">/// ^
|
||||||
@@ -2497,11 +2514,11 @@ HERE_JSTOKEN = <span class="hljs-regexp">///^ ``` ((?: [^`\\] | \\[\s\S] | `
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-98">
|
<li id="section-99">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-98">¶</a>
|
<a class="pilcrow" href="#section-99">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>String-matching-regexes.</p>
|
<p>String-matching-regexes.</p>
|
||||||
|
|
||||||
@@ -2535,11 +2552,11 @@ HEREDOC_INDENT = <span class="hljs-regexp">/\n+([^\n\S]*)(?=\S)/g</span></pr
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-99">
|
<li id="section-100">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-99">¶</a>
|
<a class="pilcrow" href="#section-100">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Regex-matching-regexes.</p>
|
<p>Regex-matching-regexes.</p>
|
||||||
|
|
||||||
@@ -2558,7 +2575,86 @@ HEREDOC_INDENT = <span class="hljs-regexp">/\n+([^\n\S]*)(?=\S)/g</span></pr
|
|||||||
REGEX_FLAGS = <span class="hljs-regexp">/^\w*/</span>
|
REGEX_FLAGS = <span class="hljs-regexp">/^\w*/</span>
|
||||||
VALID_FLAGS = <span class="hljs-regexp">/^(?!.*(.).*\1)[imguy]*$/</span>
|
VALID_FLAGS = <span class="hljs-regexp">/^(?!.*(.).*\1)[imguy]*$/</span>
|
||||||
|
|
||||||
HEREGEX = <span class="hljs-regexp">/// ^(?: [^\\/<span class="hljs-comment">#] | \\[\s\S] | /(?!//) | \#(?!\{) )* ///</span>
|
HEREGEX = <span class="hljs-regexp">/// ^
|
||||||
|
(?:
|
||||||
|
</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-101">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-101">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Match any character, except those that need special handling below.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> [^\\/<span class="hljs-comment">#\s]</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-102">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-102">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Match <code>\</code> followed by any character.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> | \\[\s\S]</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-103">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-103">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Match any <code>/</code> except <code>///</code>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> | <span class="hljs-regexp">/(?!/</span>/)</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-104">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-104">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Match <code>#</code> which is not part of interpolation, e.g. <code>#{}</code>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> | \<span class="hljs-comment">#(?!\{)</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-105">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-105">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Comments consume everything until the end of the line, including <code>///</code>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> | \s+(?:<span class="hljs-comment">#(?!\{).*)?</span>
|
||||||
|
)*
|
||||||
|
<span class="hljs-regexp">///
|
||||||
|
|
||||||
HEREGEX_OMIT = ///</span>
|
HEREGEX_OMIT = ///</span>
|
||||||
((?:\\\\)+) <span class="hljs-comment"># Consume (and preserve) an even number of backslashes.</span>
|
((?:\\\\)+) <span class="hljs-comment"># Consume (and preserve) an even number of backslashes.</span>
|
||||||
@@ -2573,11 +2669,11 @@ POSSIBLY_DIVISION = <span class="hljs-regexp">/// ^ /=?\s ///</span></pre></di
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-100">
|
<li id="section-106">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-100">¶</a>
|
<a class="pilcrow" href="#section-106">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Other regexes.</p>
|
<p>Other regexes.</p>
|
||||||
|
|
||||||
@@ -2620,11 +2716,11 @@ TRAILING_SPACES = <span class="hljs-regexp">/\s+$/</span></pre></div></div>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-101">
|
<li id="section-107">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-101">¶</a>
|
<a class="pilcrow" href="#section-107">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Compound assignment tokens.</p>
|
<p>Compound assignment tokens.</p>
|
||||||
|
|
||||||
@@ -2638,11 +2734,11 @@ TRAILING_SPACES = <span class="hljs-regexp">/\s+$/</span></pre></div></div>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-102">
|
<li id="section-108">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-102">¶</a>
|
<a class="pilcrow" href="#section-108">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Unary tokens.</p>
|
<p>Unary tokens.</p>
|
||||||
|
|
||||||
@@ -2655,11 +2751,11 @@ UNARY_MATH = [<span class="hljs-string">'!'</span>, <span class="hljs-string">'~
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-103">
|
<li id="section-109">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-103">¶</a>
|
<a class="pilcrow" href="#section-109">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Bit-shifting tokens.</p>
|
<p>Bit-shifting tokens.</p>
|
||||||
|
|
||||||
@@ -2670,11 +2766,11 @@ UNARY_MATH = [<span class="hljs-string">'!'</span>, <span class="hljs-string">'~
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-104">
|
<li id="section-110">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-104">¶</a>
|
<a class="pilcrow" href="#section-110">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Comparison tokens.</p>
|
<p>Comparison tokens.</p>
|
||||||
|
|
||||||
@@ -2685,11 +2781,11 @@ UNARY_MATH = [<span class="hljs-string">'!'</span>, <span class="hljs-string">'~
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-105">
|
<li id="section-111">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-105">¶</a>
|
<a class="pilcrow" href="#section-111">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Mathematical tokens.</p>
|
<p>Mathematical tokens.</p>
|
||||||
|
|
||||||
@@ -2700,11 +2796,11 @@ UNARY_MATH = [<span class="hljs-string">'!'</span>, <span class="hljs-string">'~
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-106">
|
<li id="section-112">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-106">¶</a>
|
<a class="pilcrow" href="#section-112">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Relational tokens that are negatable with <code>not</code> prefix.</p>
|
<p>Relational tokens that are negatable with <code>not</code> prefix.</p>
|
||||||
|
|
||||||
@@ -2715,11 +2811,11 @@ UNARY_MATH = [<span class="hljs-string">'!'</span>, <span class="hljs-string">'~
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-107">
|
<li id="section-113">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-107">¶</a>
|
<a class="pilcrow" href="#section-113">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Boolean tokens.</p>
|
<p>Boolean tokens.</p>
|
||||||
|
|
||||||
@@ -2730,11 +2826,11 @@ UNARY_MATH = [<span class="hljs-string">'!'</span>, <span class="hljs-string">'~
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-108">
|
<li id="section-114">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-108">¶</a>
|
<a class="pilcrow" href="#section-114">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Tokens which could legitimately be invoked or indexed. An opening
|
<p>Tokens which could legitimately be invoked or indexed. An opening
|
||||||
parentheses or bracket following these tokens will be recorded as the start
|
parentheses or bracket following these tokens will be recorded as the start
|
||||||
@@ -2751,11 +2847,11 @@ INDEXABLE = CALLABLE.concat [
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-109">
|
<li id="section-115">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-109">¶</a>
|
<a class="pilcrow" href="#section-115">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Tokens which can be the left-hand side of a less-than comparison, i.e. <code>a<b</code>.</p>
|
<p>Tokens which can be the left-hand side of a less-than comparison, i.e. <code>a<b</code>.</p>
|
||||||
|
|
||||||
@@ -2766,11 +2862,11 @@ INDEXABLE = CALLABLE.concat [
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-110">
|
<li id="section-116">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-110">¶</a>
|
<a class="pilcrow" href="#section-116">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Tokens which a regular expression will never immediately follow (except spaced
|
<p>Tokens which a regular expression will never immediately follow (except spaced
|
||||||
CALLABLEs in some cases), but which a division operator can.</p>
|
CALLABLEs in some cases), but which a division operator can.</p>
|
||||||
@@ -2783,11 +2879,11 @@ CALLABLEs in some cases), but which a division operator can.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-111">
|
<li id="section-117">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-111">¶</a>
|
<a class="pilcrow" href="#section-117">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Tokens that, when immediately preceding a <code>WHEN</code>, indicate that the <code>WHEN</code>
|
<p>Tokens that, when immediately preceding a <code>WHEN</code>, indicate that the <code>WHEN</code>
|
||||||
occurs at the start of a line. We disambiguate these from trailing whens to
|
occurs at the start of a line. We disambiguate these from trailing whens to
|
||||||
@@ -2800,11 +2896,11 @@ avoid an ambiguity in the grammar.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-112">
|
<li id="section-118">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-112">¶</a>
|
<a class="pilcrow" href="#section-118">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Additional indent in front of these is ignored.</p>
|
<p>Additional indent in front of these is ignored.</p>
|
||||||
|
|
||||||
@@ -2815,11 +2911,11 @@ avoid an ambiguity in the grammar.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-113">
|
<li id="section-119">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-113">¶</a>
|
<a class="pilcrow" href="#section-119">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token</p>
|
<p>Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token</p>
|
||||||
|
|
||||||
@@ -2827,7 +2923,7 @@ avoid an ambiguity in the grammar.</p>
|
|||||||
|
|
||||||
<div class="content"><div class='highlight'><pre>UNFINISHED = [<span class="hljs-string">'\\'</span>, <span class="hljs-string">'.'</span>, <span class="hljs-string">'?.'</span>, <span class="hljs-string">'?::'</span>, <span class="hljs-string">'UNARY'</span>, <span class="hljs-string">'MATH'</span>, <span class="hljs-string">'UNARY_MATH'</span>, <span class="hljs-string">'+'</span>, <span class="hljs-string">'-'</span>,
|
<div class="content"><div class='highlight'><pre>UNFINISHED = [<span class="hljs-string">'\\'</span>, <span class="hljs-string">'.'</span>, <span class="hljs-string">'?.'</span>, <span class="hljs-string">'?::'</span>, <span class="hljs-string">'UNARY'</span>, <span class="hljs-string">'MATH'</span>, <span class="hljs-string">'UNARY_MATH'</span>, <span class="hljs-string">'+'</span>, <span class="hljs-string">'-'</span>,
|
||||||
<span class="hljs-string">'**'</span>, <span class="hljs-string">'SHIFT'</span>, <span class="hljs-string">'RELATION'</span>, <span class="hljs-string">'COMPARE'</span>, <span class="hljs-string">'&'</span>, <span class="hljs-string">'^'</span>, <span class="hljs-string">'|'</span>, <span class="hljs-string">'&&'</span>, <span class="hljs-string">'||'</span>,
|
<span class="hljs-string">'**'</span>, <span class="hljs-string">'SHIFT'</span>, <span class="hljs-string">'RELATION'</span>, <span class="hljs-string">'COMPARE'</span>, <span class="hljs-string">'&'</span>, <span class="hljs-string">'^'</span>, <span class="hljs-string">'|'</span>, <span class="hljs-string">'&&'</span>, <span class="hljs-string">'||'</span>,
|
||||||
<span class="hljs-string">'BIN?'</span>, <span class="hljs-string">'EXTENDS'</span>, <span class="hljs-string">'DEFAULT'</span>]</pre></div></div>
|
<span class="hljs-string">'BIN?'</span>, <span class="hljs-string">'EXTENDS'</span>]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
0
docs/v2/annotated-source/public/fonts/roboto-black.eot
Normal file → Executable file
0
docs/v2/annotated-source/public/fonts/roboto-black.eot
Normal file → Executable file
0
docs/v2/annotated-source/public/fonts/roboto-black.ttf
Normal file → Executable file
0
docs/v2/annotated-source/public/fonts/roboto-black.ttf
Normal file → Executable file
0
docs/v2/annotated-source/public/fonts/roboto-black.woff
Normal file → Executable file
0
docs/v2/annotated-source/public/fonts/roboto-black.woff
Normal file → Executable file
@@ -224,11 +224,17 @@ Unwrap that too.</p>
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-7">¶</a>
|
<a class="pilcrow" href="#section-7">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Collect referenced variable names just like in <code>CoffeeScript.compile</code>.</p>
|
<p>Filter out tokens generated just to hold comments.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> referencedVars = (token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span>)</pre></div></div>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tokens.length >= <span class="hljs-number">2</span> <span class="hljs-keyword">and</span> tokens[<span class="hljs-number">0</span>].generated <span class="hljs-keyword">and</span>
|
||||||
|
tokens[<span class="hljs-number">0</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> tokens[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span> <span class="hljs-keyword">and</span>
|
||||||
|
tokens[<span class="hljs-number">1</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'TERMINATOR'</span>
|
||||||
|
tokens = tokens[<span class="hljs-number">2.</span>..]
|
||||||
|
<span class="hljs-keyword">if</span> tokens.length >= <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> tokens[tokens.length - <span class="hljs-number">1</span>].generated <span class="hljs-keyword">and</span>
|
||||||
|
tokens[tokens.length - <span class="hljs-number">1</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> tokens[tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
|
||||||
|
tokens.pop()</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -239,11 +245,11 @@ Unwrap that too.</p>
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-8">¶</a>
|
<a class="pilcrow" href="#section-8">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Generate the AST of the tokens.</p>
|
<p>Collect referenced variable names just like in <code>CoffeeScript.compile</code>.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes tokens</pre></div></div>
|
<div class="content"><div class='highlight'><pre> referencedVars = (token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span>)</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -254,11 +260,11 @@ Unwrap that too.</p>
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-9">¶</a>
|
<a class="pilcrow" href="#section-9">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Add assignment to <code>__</code> variable to force the input to be an expression.</p>
|
<p>Generate the AST of the tokens.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'__'</span>), ast, <span class="hljs-string">'='</span>]</pre></div></div>
|
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes tokens</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -269,6 +275,21 @@ Unwrap that too.</p>
|
|||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="pilcrow" href="#section-10">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
<p>Add assignment to <code>__</code> variable to force the input to be an expression.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'__'</span>), ast, <span class="hljs-string">'='</span>]</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-11">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-11">¶</a>
|
||||||
|
</div>
|
||||||
<p>Wrap the expression in a closure to support top-level <code>await</code>.</p>
|
<p>Wrap the expression in a closure to support top-level <code>await</code>.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -279,11 +300,11 @@ Unwrap that too.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-11">
|
<li id="section-12">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="pilcrow" href="#section-12">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Invoke the wrapping closure.</p>
|
<p>Invoke the wrapping closure.</p>
|
||||||
|
|
||||||
@@ -297,11 +318,11 @@ Unwrap that too.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-12">
|
<li id="section-13">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="pilcrow" href="#section-13">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Strip <code>"use strict"</code>, to avoid an exception on assigning to
|
<p>Strip <code>"use strict"</code>, to avoid an exception on assigning to
|
||||||
undeclared variable <code>__</code>.</p>
|
undeclared variable <code>__</code>.</p>
|
||||||
@@ -314,11 +335,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-13">
|
<li id="section-14">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-13">¶</a>
|
<a class="pilcrow" href="#section-14">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Await an async result, if necessary.</p>
|
<p>Await an async result, if necessary.</p>
|
||||||
|
|
||||||
@@ -335,11 +356,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-14">
|
<li id="section-15">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-14">¶</a>
|
<a class="pilcrow" href="#section-15">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>AST’s <code>compile</code> does not add source code information to syntax errors.</p>
|
<p>AST’s <code>compile</code> does not add source code information to syntax errors.</p>
|
||||||
|
|
||||||
@@ -360,11 +381,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-15">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
<a class="pilcrow" href="#section-16">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
|
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
|
||||||
|
|
||||||
@@ -381,11 +402,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-16">
|
<li id="section-17">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="pilcrow" href="#section-17">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Proxy node’s line listener</p>
|
<p>Proxy node’s line listener</p>
|
||||||
|
|
||||||
@@ -406,11 +427,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-17">
|
<li id="section-18">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-17">¶</a>
|
<a class="pilcrow" href="#section-18">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Handle Ctrl-v</p>
|
<p>Handle Ctrl-v</p>
|
||||||
|
|
||||||
@@ -423,11 +444,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-18">
|
<li id="section-19">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-18">¶</a>
|
<a class="pilcrow" href="#section-19">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
|
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
|
||||||
|
|
||||||
@@ -442,11 +463,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-19">
|
<li id="section-20">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-19">¶</a>
|
<a class="pilcrow" href="#section-20">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>no-op unless the current line is empty</p>
|
<p>no-op unless the current line is empty</p>
|
||||||
|
|
||||||
@@ -457,11 +478,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-20">
|
<li id="section-21">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-20">¶</a>
|
<a class="pilcrow" href="#section-21">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>eval, print, loop</p>
|
<p>eval, print, loop</p>
|
||||||
|
|
||||||
@@ -476,11 +497,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-21">
|
<li id="section-22">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-21">¶</a>
|
<a class="pilcrow" href="#section-22">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>XXX: multiline hack</p>
|
<p>XXX: multiline hack</p>
|
||||||
|
|
||||||
@@ -498,11 +519,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-22">
|
<li id="section-23">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-22">¶</a>
|
<a class="pilcrow" href="#section-23">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Store and load command history from a file</p>
|
<p>Store and load command history from a file</p>
|
||||||
|
|
||||||
@@ -515,11 +536,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-23">
|
<li id="section-24">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-23">¶</a>
|
<a class="pilcrow" href="#section-24">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Get file info and at most maxSize of command history</p>
|
<p>Get file info and at most maxSize of command history</p>
|
||||||
|
|
||||||
@@ -531,11 +552,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-24">
|
<li id="section-25">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-24">¶</a>
|
<a class="pilcrow" href="#section-25">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Read last <code>size</code> bytes from the file</p>
|
<p>Read last <code>size</code> bytes from the file</p>
|
||||||
|
|
||||||
@@ -549,11 +570,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-25">
|
<li id="section-26">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-25">¶</a>
|
<a class="pilcrow" href="#section-26">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Set the history on the interpreter</p>
|
<p>Set the history on the interpreter</p>
|
||||||
|
|
||||||
@@ -564,11 +585,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-26">
|
<li id="section-27">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-26">¶</a>
|
<a class="pilcrow" href="#section-27">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>If the history file was truncated we should pop off a potential partial line</p>
|
<p>If the history file was truncated we should pop off a potential partial line</p>
|
||||||
|
|
||||||
@@ -579,11 +600,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-27">
|
<li id="section-28">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-27">¶</a>
|
<a class="pilcrow" href="#section-28">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Shift off the final blank newline</p>
|
<p>Shift off the final blank newline</p>
|
||||||
|
|
||||||
@@ -601,11 +622,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-28">
|
<li id="section-29">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-28">¶</a>
|
<a class="pilcrow" href="#section-29">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Save the latest command in the file</p>
|
<p>Save the latest command in the file</p>
|
||||||
|
|
||||||
@@ -617,11 +638,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-29">
|
<li id="section-30">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-29">¶</a>
|
<a class="pilcrow" href="#section-30">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>XXX: The SIGINT event from REPLServer is undocumented, so this is a bit fragile</p>
|
<p>XXX: The SIGINT event from REPLServer is undocumented, so this is a bit fragile</p>
|
||||||
|
|
||||||
@@ -633,11 +654,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-30">
|
<li id="section-31">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-30">¶</a>
|
<a class="pilcrow" href="#section-31">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Add a command to show the history stack</p>
|
<p>Add a command to show the history stack</p>
|
||||||
|
|
||||||
@@ -654,11 +675,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-31">
|
<li id="section-32">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-31">¶</a>
|
<a class="pilcrow" href="#section-32">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Node 0.11 changed API, a command such as ‘.help’ is now stored as ‘help’</p>
|
<p>Node 0.11 changed API, a command such as ‘.help’ is now stored as ‘help’</p>
|
||||||
|
|
||||||
@@ -697,11 +718,11 @@ undeclared variable <code>__</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-32">
|
<li id="section-33">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-32">¶</a>
|
<a class="pilcrow" href="#section-33">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Since the REPL compilation path is unique (in <code>eval</code> above), we need
|
<p>Since the REPL compilation path is unique (in <code>eval</code> above), we need
|
||||||
another way to get the <code>options</code> object attached to a module so that
|
another way to get the <code>options</code> object attached to a module so that
|
||||||
@@ -725,11 +746,11 @@ the REPL, the only applicable option is <code>transpile</code>.</p>
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-33">
|
<li id="section-34">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-33">¶</a>
|
<a class="pilcrow" href="#section-34">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Adapt help inherited from the node REPL</p>
|
<p>Adapt help inherited from the node REPL</p>
|
||||||
|
|
||||||
|
|||||||
@@ -916,7 +916,7 @@ e = <span class="hljs-number">2</span>
|
|||||||
</code></pre>
|
</code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">','</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @looksObjectish(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">and</span> inImplicitObject() <span class="hljs-keyword">and</span>
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">','</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> @looksObjectish(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">and</span> inImplicitObject() <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> (@tag(i + <span class="hljs-number">2</span>) <span class="hljs-keyword">in</span> [<span class="hljs-string">'FOROF'</span>, <span class="hljs-string">'FORIN'</span>]) <span class="hljs-keyword">and</span>
|
||||||
(nextTag <span class="hljs-keyword">isnt</span> <span class="hljs-string">'TERMINATOR'</span> <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> @looksObjectish(i + <span class="hljs-number">2</span>))</pre></div></div>
|
(nextTag <span class="hljs-keyword">isnt</span> <span class="hljs-string">'TERMINATOR'</span> <span class="hljs-keyword">or</span> <span class="hljs-keyword">not</span> @looksObjectish(i + <span class="hljs-number">2</span>))</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -646,7 +646,7 @@ div.CodeMirror-cursor {
|
|||||||
<section id="overview">
|
<section id="overview">
|
||||||
<p><strong>CoffeeScript is a little language that compiles into JavaScript.</strong> Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.</p>
|
<p><strong>CoffeeScript is a little language that compiles into JavaScript.</strong> Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.</p>
|
||||||
<p>The golden rule of CoffeeScript is: <em>“It’s just JavaScript.”</em> The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.</p>
|
<p>The golden rule of CoffeeScript is: <em>“It’s just JavaScript.”</em> The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.</p>
|
||||||
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.0.2">2.0.2</a></p>
|
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.1.1">2.1.1</a></p>
|
||||||
<blockquote class="uneditable-code-block"><pre><code class="language-bash"><span class="comment"># Install locally for a project:</span>
|
<blockquote class="uneditable-code-block"><pre><code class="language-bash"><span class="comment"># Install locally for a project:</span>
|
||||||
npm install --save-dev coffeescript
|
npm install --save-dev coffeescript
|
||||||
|
|
||||||
@@ -1343,36 +1343,6 @@ kids = {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</aside>
|
|
||||||
<p>In JavaScript, you can’t use reserved words, like <code>class</code>, as properties of an object, without quoting them as strings. CoffeeScript notices reserved words used as keys in objects and quotes them for you, so you don’t have to worry about it (say, when using jQuery).</p>
|
|
||||||
<aside class="code-example container-fluid bg-ribbed-dark" data-example="objects_reserved">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 coffeescript-input-column">
|
|
||||||
<textarea class="coffeescript-input" id="objects_reserved-coffee">$('.account').prop class: 'active'
|
|
||||||
|
|
||||||
log object.class
|
|
||||||
</textarea>
|
|
||||||
<pre class="placeholder-code"><span class="cm-variable">$</span><span class="cm-punctuation">(</span><span class="cm-string">'.account'</span><span class="cm-punctuation">).</span><span class="cm-property">prop</span> <span class="cm-keyword">class</span><span class="cm-punctuation">:</span> <span class="cm-string">'active'</span>
|
|
||||||
|
|
||||||
<span class="cm-variable">log</span> <span class="cm-variable">object</span><span class="cm-punctuation">.</span><span class="cm-property">class</span>
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 javascript-output-column">
|
|
||||||
<textarea class="javascript-output" id="objects_reserved-js">$('.account').prop({
|
|
||||||
class: 'active'
|
|
||||||
});
|
|
||||||
|
|
||||||
log(object.class);
|
|
||||||
</textarea>
|
|
||||||
<pre class="placeholder-code"><span class="cm-variable">$</span>(<span class="cm-string">'.account'</span>).<span class="cm-property">prop</span>({
|
|
||||||
<span class="cm-property">class</span>: <span class="cm-string">'active'</span>
|
|
||||||
});
|
|
||||||
|
|
||||||
<span class="cm-variable">log</span>(<span class="cm-variable">object</span>.<span class="cm-property">class</span>);
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</aside>
|
</aside>
|
||||||
<p>CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name.</p>
|
<p>CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name.</p>
|
||||||
<aside class="code-example container-fluid bg-ribbed-dark" data-example="objects_shorthand">
|
<aside class="code-example container-fluid bg-ribbed-dark" data-example="objects_shorthand">
|
||||||
@@ -2489,7 +2459,7 @@ alert((function() {
|
|||||||
|
|
||||||
<span class="cm-variable">alert</span>((<span class="cm-keyword">function</span>() {
|
<span class="cm-variable">alert</span>((<span class="cm-keyword">function</span>() {
|
||||||
<span class="cm-keyword">try</span> {
|
<span class="cm-keyword">try</span> {
|
||||||
<span class="cm-keyword">return</span> <span class="cm-variable">nonexistent</span> <span class="cm-operator">/</span> <span class="cm-variable">void</span> <span class="cm-number">0</span>;
|
<span class="cm-keyword">return</span> <span class="cm-variable">nonexistent</span> <span class="cm-operator">/</span> <span class="cm-keyword">void</span> <span class="cm-number">0</span>;
|
||||||
} <span class="cm-keyword">catch</span> (<span class="cm-def">error1</span>) {
|
} <span class="cm-keyword">catch</span> (<span class="cm-def">error1</span>) {
|
||||||
<span class="cm-variable">error</span> <span class="cm-operator">=</span> <span class="cm-variable-2">error1</span>;
|
<span class="cm-variable">error</span> <span class="cm-operator">=</span> <span class="cm-variable-2">error1</span>;
|
||||||
<span class="cm-keyword">return</span> <span class="cm-string-2">`And the error is ... ${</span><span class="cm-variable">error</span><span class="cm-string-2">}`</span>;
|
<span class="cm-keyword">return</span> <span class="cm-string-2">`And the error is ... ${</span><span class="cm-variable">error</span><span class="cm-string-2">}`</span>;
|
||||||
@@ -2523,7 +2493,7 @@ alert((function() {
|
|||||||
<p>As a shortcut for <code>this.property</code>, you can use <code>@property</code>.</p>
|
<p>As a shortcut for <code>this.property</code>, you can use <code>@property</code>.</p>
|
||||||
<p>You can use <code>in</code> to test for array presence, and <code>of</code> to test for JavaScript object-key presence.</p>
|
<p>You can use <code>in</code> to test for array presence, and <code>of</code> to test for JavaScript object-key presence.</p>
|
||||||
<p>In a <code>for</code> loop, <code>from</code> compiles to the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of">ES2015 <code>of</code></a>. (Yes, it’s unfortunate; the CoffeeScript <code>of</code> predates the ES2015 <code>of</code>.)</p>
|
<p>In a <code>for</code> loop, <code>from</code> compiles to the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of">ES2015 <code>of</code></a>. (Yes, it’s unfortunate; the CoffeeScript <code>of</code> predates the ES2015 <code>of</code>.)</p>
|
||||||
<p>To simplify math expressions, <code>**</code> can be used for exponentiation and <code>//</code> performs integer division. <code>%</code> works just like in JavaScript, while <code>%%</code> provides <a href="https://en.wikipedia.org/wiki/Modulo_operation">“dividend dependent modulo”</a>:</p>
|
<p>To simplify math expressions, <code>**</code> can be used for exponentiation and <code>//</code> performs floor division. <code>%</code> works just like in JavaScript, while <code>%%</code> provides <a href="https://en.wikipedia.org/wiki/Modulo_operation">“dividend dependent modulo”</a>:</p>
|
||||||
<aside class="code-example container-fluid bg-ribbed-dark" data-example="modulo">
|
<aside class="code-example container-fluid bg-ribbed-dark" data-example="modulo">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 coffeescript-input-column">
|
<div class="col-md-6 coffeescript-input-column">
|
||||||
@@ -2853,7 +2823,7 @@ zip = typeof lottery.drawWinner === "function" ? (ref = lottery.drawWinner().add
|
|||||||
</textarea>
|
</textarea>
|
||||||
<pre class="placeholder-code"><span class="cm-keyword">var</span> <span class="cm-def">ref</span>, <span class="cm-def">zip</span>;
|
<pre class="placeholder-code"><span class="cm-keyword">var</span> <span class="cm-def">ref</span>, <span class="cm-def">zip</span>;
|
||||||
|
|
||||||
<span class="cm-variable">zip</span> <span class="cm-operator">=</span> <span class="cm-keyword">typeof</span> <span class="cm-variable">lottery</span>.<span class="cm-property">drawWinner</span> <span class="cm-operator">===</span> <span class="cm-string">"function"</span> <span class="cm-operator">?</span> (<span class="cm-variable">ref</span> <span class="cm-operator">=</span> <span class="cm-variable">lottery</span>.<span class="cm-property">drawWinner</span>().<span class="cm-property">address</span>) <span class="cm-operator">!=</span> <span class="cm-atom">null</span> <span class="cm-operator">?</span> <span class="cm-variable">ref</span>.<span class="cm-property">zipcode</span> : <span class="cm-variable">void</span> <span class="cm-number">0</span> : <span class="cm-variable">void</span> <span class="cm-number">0</span>;
|
<span class="cm-variable">zip</span> <span class="cm-operator">=</span> <span class="cm-keyword">typeof</span> <span class="cm-variable">lottery</span>.<span class="cm-property">drawWinner</span> <span class="cm-operator">===</span> <span class="cm-string">"function"</span> <span class="cm-operator">?</span> (<span class="cm-variable">ref</span> <span class="cm-operator">=</span> <span class="cm-variable">lottery</span>.<span class="cm-property">drawWinner</span>().<span class="cm-property">address</span>) <span class="cm-operator">!=</span> <span class="cm-atom">null</span> <span class="cm-operator">?</span> <span class="cm-variable">ref</span>.<span class="cm-property">zipcode</span> : <span class="cm-keyword">void</span> <span class="cm-number">0</span> : <span class="cm-keyword">void</span> <span class="cm-number">0</span>;
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -4754,7 +4724,6 @@ task('build:parser', 'rebuild the Jison parser', function(options) {
|
|||||||
<section id="scripts">
|
<section id="scripts">
|
||||||
<h2><code>"text/coffeescript"</code> Script Tags</h2>
|
<h2><code>"text/coffeescript"</code> Script Tags</h2>
|
||||||
<p>While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using <code><script type="text/coffeescript"></code> tags. The source includes a compressed and minified version of the compiler (<a href="/v2/browser-compiler/coffeescript.js">Download current version here, 51k when gzipped</a>) as <code>docs/v2/browser-compiler/coffeescript.js</code>. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.</p>
|
<p>While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using <code><script type="text/coffeescript"></code> tags. The source includes a compressed and minified version of the compiler (<a href="/v2/browser-compiler/coffeescript.js">Download current version here, 51k when gzipped</a>) as <code>docs/v2/browser-compiler/coffeescript.js</code>. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.</p>
|
||||||
<p>In fact, the little bit of glue script that runs <a href="#try">Try CoffeeScript</a>, as well as the code examples and other interactive parts of this site, is implemented in just this way. View source and look at the bottom of the page to see the example. Including the script also gives you access to <code>CoffeeScript.compile()</code> so you can pop open your JavaScript console and try compiling some strings.</p>
|
|
||||||
<p>The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the <code>window</code> object.</p>
|
<p>The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the <code>window</code> object.</p>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
@@ -4821,7 +4790,7 @@ The CoffeeScript logo is available in SVG for use in presentations.</li>
|
|||||||
</section>
|
</section>
|
||||||
<section id="annotated-source">
|
<section id="annotated-source">
|
||||||
<h2>Annotated Source</h2>
|
<h2>Annotated Source</h2>
|
||||||
<p>You can browse the CoffeeScript 2.0.2 source in readable, annotated form <a href="annotated-source/">here</a>. You can also jump directly to a particular source file:</p>
|
<p>You can browse the CoffeeScript 2.1.1 source in readable, annotated form <a href="annotated-source/">here</a>. You can also jump directly to a particular source file:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="annotated-source/grammar.html">Grammar Rules — src/grammar</a></li>
|
<li><a href="annotated-source/grammar.html">Grammar Rules — src/grammar</a></li>
|
||||||
<li><a href="annotated-source/lexer.html">Lexing Tokens — src/lexer</a></li>
|
<li><a href="annotated-source/lexer.html">Lexing Tokens — src/lexer</a></li>
|
||||||
@@ -5498,6 +5467,38 @@ x = <span class="number">2</span> + <span class="number">2</span>
|
|||||||
</section>
|
</section>
|
||||||
<section id="changelog">
|
<section id="changelog">
|
||||||
<h2>Changelog</h2>
|
<h2>Changelog</h2>
|
||||||
|
<div class="anchor" id="2.1.1"></div>
|
||||||
|
<h2 class="header">
|
||||||
|
<a href="https://github.com/jashkenas/coffeescript/compare/2.1.0...2.1.1">2.1.1</a>
|
||||||
|
<span class="timestamp"> — <time datetime="2017-12-29">December 29, 2017</time></span>
|
||||||
|
</h2><ul>
|
||||||
|
<li>Bugfix to set the correct context for executable class bodies. So in <code>class @B extends @A then @property = 1</code>, the <code>@</code> in <code>@property</code> now refers to the class, not the global object.</li>
|
||||||
|
<li>Bugfix where anonymous classes were getting created using the same automatic variable name. They now each receive unique names, so as not to override each other.</li>
|
||||||
|
</ul>
|
||||||
|
<div class="anchor" id="2.1.0"></div>
|
||||||
|
<h2 class="header">
|
||||||
|
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.3...2.1.0">2.1.0</a>
|
||||||
|
<span class="timestamp"> — <time datetime="2017-12-10">December 10, 2017</time></span>
|
||||||
|
</h2><ul>
|
||||||
|
<li>Computed property keys in object literals are now supported: <code>obj = { ['key' + i]: 42 }</code>, or <code>obj = [Symbol.iterator]: -> yield i++</code>.</li>
|
||||||
|
<li>Skipping of array elements, a.k.a. elision, is now supported: <code>arr = [a, , b]</code>, or <code>[, protocol] = url.match /^(.*):\/\//</code>.</li>
|
||||||
|
<li><a href="https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html">JSX fragments syntax</a> is now supported.</li>
|
||||||
|
<li>Bugfix where <code>///</code> within a <code>#</code> line comment inside a <code>///</code> block regex was erroneously closing the regex, rather than being treated as part of the comment.</li>
|
||||||
|
<li>Bugfix for incorrect output for object rest destructuring inside array destructuring.</li>
|
||||||
|
</ul>
|
||||||
|
<div class="anchor" id="2.0.3"></div>
|
||||||
|
<h2 class="header">
|
||||||
|
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.2...2.0.3">2.0.3</a>
|
||||||
|
<span class="timestamp"> — <time datetime="2017-11-26">November 26, 2017</time></span>
|
||||||
|
</h2><ul>
|
||||||
|
<li>Bugfix for <code>export default</code> followed by an implicit object that contains an explicit object, for example <code>exportedMember: { obj... }</code>.</li>
|
||||||
|
<li>Bugfix for <code>key, val of obj</code> after an implicit object member, e.g. <code>foo: bar for key, val of obj</code>.</li>
|
||||||
|
<li>Bugfix for combining array and object destructuring, e.g. <code>[ ..., {a, b} ] = arr</code>.</li>
|
||||||
|
<li>Bugfix for an edge case where it was possible to create a bound (<code>=></code>) generator function, which should throw an error as such functions aren’t allowed in ES2015.</li>
|
||||||
|
<li>Bugfix for source maps: <code>.map</code> files should always have the same base filename as the requested output filename. So <code>coffee --map --output foo.js test.coffee</code> should generate <code>foo.js</code> and <code>foo.js.map</code>.</li>
|
||||||
|
<li>Bugfix for incorrect source maps generated when using <code>--transpile</code> with <code>--map</code> for multiple input files.</li>
|
||||||
|
<li>Bugfix for comments at the beginning or end of input into the REPL (<code>coffee --interactive</code>).</li>
|
||||||
|
</ul>
|
||||||
<div class="anchor" id="2.0.2"></div>
|
<div class="anchor" id="2.0.2"></div>
|
||||||
<h2 class="header">
|
<h2 class="header">
|
||||||
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.1...2.0.2">2.0.2</a>
|
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.1...2.0.2">2.0.2</a>
|
||||||
|
|||||||
@@ -361,6 +361,94 @@ test "incorrect indentation without commas", ->
|
|||||||
ok result[0][0] is 'a'
|
ok result[0][0] is 'a'
|
||||||
ok result[1]['b'] is 'c'
|
ok result[1]['b'] is 'c'
|
||||||
|
|
||||||
|
# Elisions
|
||||||
|
test "array elisions", ->
|
||||||
|
eq [,1].length, 2
|
||||||
|
eq [,,1,2,,].length, 5
|
||||||
|
arr = [1,,2]
|
||||||
|
eq arr.length, 3
|
||||||
|
eq arr[1], undefined
|
||||||
|
eq [,,].length, 2
|
||||||
|
|
||||||
|
test "array elisions indentation and commas", ->
|
||||||
|
arr1 = [
|
||||||
|
, 1, 2, , , 3,
|
||||||
|
4, 5, 6
|
||||||
|
, , 8, 9,
|
||||||
|
]
|
||||||
|
eq arr1.length, 12
|
||||||
|
eq arr1[5], 3
|
||||||
|
eq arr1[9], undefined
|
||||||
|
arr2 = [, , 1,
|
||||||
|
2, , 3,
|
||||||
|
, 4, 5
|
||||||
|
6
|
||||||
|
, , ,
|
||||||
|
]
|
||||||
|
eq arr2.length, 12
|
||||||
|
eq arr2[8], 5
|
||||||
|
eq arr2[1], undefined
|
||||||
|
|
||||||
|
test "array elisions destructuring", ->
|
||||||
|
arr = [1,2,3,4,5,6,7,8,9]
|
||||||
|
[,a] = arr
|
||||||
|
[,,,b] = arr
|
||||||
|
arrayEq [a,b], [2,4]
|
||||||
|
[,a,,b,,c,,,d] = arr
|
||||||
|
arrayEq [a,b,c,d], [2,4,6,9]
|
||||||
|
[
|
||||||
|
,e,
|
||||||
|
,f,
|
||||||
|
,g,
|
||||||
|
,,h] = arr
|
||||||
|
arrayEq [e,f,g,h], [2,4,6,9]
|
||||||
|
|
||||||
|
test "array elisions destructuring with splats and expansions", ->
|
||||||
|
arr = [1,2,3,4,5,6,7,8,9]
|
||||||
|
[,a,,,b...] = arr
|
||||||
|
arrayEq [a,b], [2,[5,6,7,8,9]]
|
||||||
|
[,c,...,,d,,e] = arr
|
||||||
|
arrayEq [c,d,e], [2,7,9]
|
||||||
|
[...,f,,,g,,,] = arr
|
||||||
|
arrayEq [f,g], [4,7]
|
||||||
|
|
||||||
|
test "array elisions as function parameters", ->
|
||||||
|
arr = [1,2,3,4,5,6,7,8,9]
|
||||||
|
foo = ([,a]) -> a
|
||||||
|
a = foo arr
|
||||||
|
eq a, 2
|
||||||
|
foo = ([,,,a]) -> a
|
||||||
|
a = foo arr
|
||||||
|
eq a, 4
|
||||||
|
foo = ([,a,,b,,c,,,d]) -> [a,b,c,d]
|
||||||
|
[a,b,c,d] = foo arr
|
||||||
|
arrayEq [a,b,c,d], [2,4,6,9]
|
||||||
|
|
||||||
|
test "array elisions nested destructuring", ->
|
||||||
|
arr = [
|
||||||
|
1,
|
||||||
|
[2,3, [4,5,6, [7,8,9] ] ]
|
||||||
|
]
|
||||||
|
[,a] = arr
|
||||||
|
arrayEq a[2][3], [7,8,9]
|
||||||
|
[,[,,[,b,,[,,c]]]] = arr
|
||||||
|
eq b, 5
|
||||||
|
eq c, 9
|
||||||
|
aobj = [
|
||||||
|
{},
|
||||||
|
{x: 2},
|
||||||
|
{},
|
||||||
|
[
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{z:1, w:[1,2,4], p:3, q:4}
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[,d,,[,,{w}]] = aobj
|
||||||
|
deepEqual d, {x:2}
|
||||||
|
arrayEq w, [1,2,4]
|
||||||
|
|
||||||
# Splats in Array Literals
|
# Splats in Array Literals
|
||||||
|
|
||||||
@@ -717,6 +805,24 @@ test "#713: destructuring assignment should return right-hand-side value", ->
|
|||||||
eq nonceB, b
|
eq nonceB, b
|
||||||
eq nonceB, d
|
eq nonceB, d
|
||||||
|
|
||||||
|
test "#4787 destructuring of objects within arrays", ->
|
||||||
|
arr = [1, {a:1, b:2}]
|
||||||
|
[...,{a, b}] = arr
|
||||||
|
eq a, 1
|
||||||
|
eq b, arr[1].b
|
||||||
|
deepEqual {a, b}, arr[1]
|
||||||
|
|
||||||
|
test "#4798 destructuring of objects with splat within arrays", ->
|
||||||
|
arr = [1, {a:1, b:2}]
|
||||||
|
[...,{a, r...}] = arr
|
||||||
|
eq a, 1
|
||||||
|
deepEqual r, {b:2}
|
||||||
|
[b, {q...}] = arr
|
||||||
|
eq b, 1
|
||||||
|
deepEqual q, arr[1]
|
||||||
|
eq q.b, r.b
|
||||||
|
eq q.a, a
|
||||||
|
|
||||||
test "destructuring assignment with splats", ->
|
test "destructuring assignment with splats", ->
|
||||||
a = {}; b = {}; c = {}; d = {}; e = {}
|
a = {}; b = {}; c = {}; d = {}; e = {}
|
||||||
[x,y...,z] = [a,b,c,d,e]
|
[x,y...,z] = [a,b,c,d,e]
|
||||||
@@ -3553,6 +3659,23 @@ test "#4724: backticked expression in a class body with hoisted member", ->
|
|||||||
eq 42, a.x
|
eq 42, a.x
|
||||||
eq 84, a.hoisted
|
eq 84, a.hoisted
|
||||||
|
|
||||||
|
test "#4822: nested anonymous classes use non-conflicting variable names", ->
|
||||||
|
Class = class
|
||||||
|
@a: class
|
||||||
|
@b: 1
|
||||||
|
|
||||||
|
eq Class.a.b, 1
|
||||||
|
|
||||||
|
test "#4827: executable class body wrappers have correct context", ->
|
||||||
|
test = ->
|
||||||
|
class @A
|
||||||
|
class @B extends @A
|
||||||
|
@property = 1
|
||||||
|
|
||||||
|
o = {}
|
||||||
|
test.call o
|
||||||
|
ok typeof o.A is typeof o.B is 'function'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="cluster">
|
<script type="text/x-coffeescript" class="test" id="cluster">
|
||||||
# Cluster Module
|
# Cluster Module
|
||||||
@@ -3939,7 +4062,7 @@ test "#3132: Place block-comments nicely", ->
|
|||||||
|
|
||||||
return DummyClass;
|
return DummyClass;
|
||||||
|
|
||||||
})();"""
|
}).call(this);"""
|
||||||
|
|
||||||
test "#3638: Demand a whitespace after # symbol", ->
|
test "#3638: Demand a whitespace after # symbol", ->
|
||||||
eqJS """
|
eqJS """
|
||||||
@@ -6687,6 +6810,50 @@ test '#4686: comments inside interpolations that also contain CSX attributes', -
|
|||||||
</div>;
|
</div>;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
|
||||||
|
test 'JSX fragments: empty fragment', ->
|
||||||
|
eqJS '''
|
||||||
|
<></>
|
||||||
|
''', '''
|
||||||
|
<></>;
|
||||||
|
'''
|
||||||
|
|
||||||
|
test 'JSX fragments: fragment with text nodes', ->
|
||||||
|
eqJS '''
|
||||||
|
<>
|
||||||
|
Some text.
|
||||||
|
<h2>A heading</h2>
|
||||||
|
More text.
|
||||||
|
<h2>Another heading</h2>
|
||||||
|
Even more text.
|
||||||
|
</>
|
||||||
|
''', '''
|
||||||
|
<>
|
||||||
|
Some text.
|
||||||
|
<h2>A heading</h2>
|
||||||
|
More text.
|
||||||
|
<h2>Another heading</h2>
|
||||||
|
Even more text.
|
||||||
|
</>;
|
||||||
|
'''
|
||||||
|
|
||||||
|
test 'JSX fragments: fragment with component nodes', ->
|
||||||
|
eqJS '''
|
||||||
|
Component = (props) =>
|
||||||
|
<Fragment>
|
||||||
|
<OtherComponent />
|
||||||
|
<OtherComponent />
|
||||||
|
</Fragment>
|
||||||
|
''', '''
|
||||||
|
var Component;
|
||||||
|
|
||||||
|
Component = (props) => {
|
||||||
|
return <Fragment>
|
||||||
|
<OtherComponent />
|
||||||
|
<OtherComponent />
|
||||||
|
</Fragment>;
|
||||||
|
};
|
||||||
|
'''
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="error_messages">
|
<script type="text/x-coffeescript" class="test" id="error_messages">
|
||||||
@@ -6875,9 +7042,9 @@ test "#1096: unexpected generated tokens", ->
|
|||||||
for i in [1]:
|
for i in [1]:
|
||||||
1
|
1
|
||||||
''', '''
|
''', '''
|
||||||
[stdin]:1:10: error: unexpected [
|
[stdin]:2:4: error: unexpected end of input
|
||||||
for i in [1]:
|
1
|
||||||
^
|
^
|
||||||
'''
|
'''
|
||||||
# Unexpected regex
|
# Unexpected regex
|
||||||
assertErrorFormat '{/a/i: val}', '''
|
assertErrorFormat '{/a/i: val}', '''
|
||||||
@@ -7500,29 +7667,8 @@ test "invalid numbers", ->
|
|||||||
^^^
|
^^^
|
||||||
'''
|
'''
|
||||||
|
|
||||||
test "unexpected object keys", ->
|
|
||||||
assertErrorFormat '''
|
|
||||||
{[[]]}
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:2: error: unexpected [
|
|
||||||
{[[]]}
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
assertErrorFormat '''
|
|
||||||
{[[]]: 1}
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:2: error: unexpected [
|
|
||||||
{[[]]: 1}
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
assertErrorFormat '''
|
|
||||||
[[]]: 1
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:1: error: unexpected [
|
|
||||||
[[]]: 1
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
test "unexpected object keys", ->
|
||||||
assertErrorFormat '''
|
assertErrorFormat '''
|
||||||
{(a + "b")}
|
{(a + "b")}
|
||||||
''', '''
|
''', '''
|
||||||
@@ -7544,20 +7690,6 @@ test "unexpected object keys", ->
|
|||||||
(a + "b"): 1
|
(a + "b"): 1
|
||||||
^
|
^
|
||||||
'''
|
'''
|
||||||
assertErrorFormat '''
|
|
||||||
a: 1, [[]]: 2
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:7: error: unexpected [
|
|
||||||
a: 1, [[]]: 2
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
assertErrorFormat '''
|
|
||||||
{a: 1, [[]]: 2}
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:8: error: unexpected [
|
|
||||||
{a: 1, [[]]: 2}
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
|
|
||||||
test "invalid object keys", ->
|
test "invalid object keys", ->
|
||||||
assertErrorFormat '''
|
assertErrorFormat '''
|
||||||
@@ -7889,6 +8021,18 @@ test "bound functions cannot be generators", ->
|
|||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
test "#4790: bound functions cannot be generators, even when we’re creating IIFEs", ->
|
||||||
|
assertErrorFormat '''
|
||||||
|
=>
|
||||||
|
for x in []
|
||||||
|
for y in []
|
||||||
|
yield z
|
||||||
|
''', '''
|
||||||
|
[stdin]:4:7: error: yield cannot occur inside bound (fat arrow) functions
|
||||||
|
yield z
|
||||||
|
^^^^^^^
|
||||||
|
'''
|
||||||
|
|
||||||
test "CoffeeScript keywords cannot be used as unaliased names in import lists", ->
|
test "CoffeeScript keywords cannot be used as unaliased names in import lists", ->
|
||||||
assertErrorFormat """
|
assertErrorFormat """
|
||||||
import { unless, baz as bar } from 'lib'
|
import { unless, baz as bar } from 'lib'
|
||||||
@@ -8484,6 +8628,15 @@ test "#3098: suppressed newline should be unsuppressed by semicolon", ->
|
|||||||
^
|
^
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
test "#4811: '///' inside a heregex comment does not close the heregex", ->
|
||||||
|
assertErrorFormat '''
|
||||||
|
/// .* # comment ///
|
||||||
|
''', '''
|
||||||
|
[stdin]:1:1: error: missing ///
|
||||||
|
/// .* # comment ///
|
||||||
|
^^^
|
||||||
|
'''
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="eval">
|
<script type="text/x-coffeescript" class="test" id="eval">
|
||||||
if vm = require? 'vm'
|
if vm = require? 'vm'
|
||||||
@@ -11256,6 +11409,8 @@ path = require 'path'
|
|||||||
# Get the folder containing the compiled `coffee` executable and make it the
|
# Get the folder containing the compiled `coffee` executable and make it the
|
||||||
# PATH so that `#!/usr/bin/env coffee` resolves to our locally built file.
|
# PATH so that `#!/usr/bin/env coffee` resolves to our locally built file.
|
||||||
coffeeBinFolder = path.dirname require.resolve '../bin/coffee'
|
coffeeBinFolder = path.dirname require.resolve '../bin/coffee'
|
||||||
|
# For some reason, Windows requires `coffee` to be executed as `node coffee`.
|
||||||
|
coffeeCommand = if isWindows() then 'node coffee' else 'coffee'
|
||||||
spawnOptions =
|
spawnOptions =
|
||||||
cwd: coffeeBinFolder
|
cwd: coffeeBinFolder
|
||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
@@ -11268,7 +11423,7 @@ initialSpaceScript = require.resolve './importing/shebang_initial_space.coffee'
|
|||||||
extraArgsScript = require.resolve './importing/shebang_extra_args.coffee'
|
extraArgsScript = require.resolve './importing/shebang_extra_args.coffee'
|
||||||
initialSpaceExtraArgsScript = require.resolve './importing/shebang_initial_space_extra_args.coffee'
|
initialSpaceExtraArgsScript = require.resolve './importing/shebang_initial_space_extra_args.coffee'
|
||||||
|
|
||||||
test "parse arguments for shebang scripts correctly (on unix platforms)", ->
|
test "parse arguments for shebang scripts correctly (on *nix platforms)", ->
|
||||||
return if isWindows()
|
return if isWindows()
|
||||||
|
|
||||||
stdout = execFileSync shebangScript, ['-abck'], spawnOptions
|
stdout = execFileSync shebangScript, ['-abck'], spawnOptions
|
||||||
@@ -11282,7 +11437,7 @@ test "parse arguments for shebang scripts correctly (on unix platforms)", ->
|
|||||||
arrayEq expectedArgs, realArgs
|
arrayEq expectedArgs, realArgs
|
||||||
|
|
||||||
test "warn and remove -- if it is the second positional argument", ->
|
test "warn and remove -- if it is the second positional argument", ->
|
||||||
result = spawnSync 'coffee', [shebangScript, '--'], spawnOptions
|
result = spawnSync coffeeCommand, [shebangScript, '--'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
||||||
ok stderr.match /^coffee was invoked with '--'/m
|
ok stderr.match /^coffee was invoked with '--'/m
|
||||||
@@ -11290,7 +11445,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
arrayEq JSON.parse(posArgs), [shebangScript, '--']
|
arrayEq JSON.parse(posArgs), [shebangScript, '--']
|
||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync 'coffee', ['-b', shebangScript, '--'], spawnOptions
|
result = spawnSync coffeeCommand, ['-b', shebangScript, '--'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
||||||
ok stderr.match /^coffee was invoked with '--'/m
|
ok stderr.match /^coffee was invoked with '--'/m
|
||||||
@@ -11299,7 +11454,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', ['-b', shebangScript, '--', 'ANOTHER'], spawnOptions)
|
coffeeCommand, ['-b', shebangScript, '--', 'ANOTHER'], spawnOptions)
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript, 'ANOTHER']
|
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript, 'ANOTHER']
|
||||||
ok stderr.match /^coffee was invoked with '--'/m
|
ok stderr.match /^coffee was invoked with '--'/m
|
||||||
@@ -11308,7 +11463,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', ['--', initialSpaceScript, 'arg'], spawnOptions)
|
coffeeCommand, ['--', initialSpaceScript, 'arg'], spawnOptions)
|
||||||
expectedArgs = ['coffee', initialSpaceScript, 'arg']
|
expectedArgs = ['coffee', initialSpaceScript, 'arg']
|
||||||
realArgs = JSON.parse result.stdout
|
realArgs = JSON.parse result.stdout
|
||||||
arrayEq expectedArgs, realArgs
|
arrayEq expectedArgs, realArgs
|
||||||
@@ -11316,7 +11471,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
test "warn about non-portable shebang lines", ->
|
test "warn about non-portable shebang lines", ->
|
||||||
result = spawnSync 'coffee', [extraArgsScript, 'arg'], spawnOptions
|
result = spawnSync coffeeCommand, [extraArgsScript, 'arg'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', extraArgsScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', extraArgsScript, 'arg']
|
||||||
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
||||||
@@ -11327,14 +11482,14 @@ test "warn about non-portable shebang lines", ->
|
|||||||
arrayEq JSON.parse(args), ['coffee', '--']
|
arrayEq JSON.parse(args), ['coffee', '--']
|
||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync 'coffee', [initialSpaceScript, 'arg'], spawnOptions
|
result = spawnSync coffeeCommand, [initialSpaceScript, 'arg'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
ok stderr is ''
|
ok stderr is ''
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceScript, 'arg']
|
||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', [initialSpaceExtraArgsScript, 'arg'], spawnOptions)
|
coffeeCommand, [initialSpaceExtraArgsScript, 'arg'], spawnOptions)
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
||||||
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
||||||
@@ -11347,7 +11502,7 @@ test "warn about non-portable shebang lines", ->
|
|||||||
|
|
||||||
test "both warnings will be shown at once", ->
|
test "both warnings will be shown at once", ->
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', [initialSpaceExtraArgsScript, '--', 'arg'], spawnOptions)
|
coffeeCommand, [initialSpaceExtraArgsScript, '--', 'arg'], spawnOptions)
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
||||||
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
||||||
@@ -12700,7 +12855,7 @@ test "export default implicit object", ->
|
|||||||
test "export default multiline implicit object", ->
|
test "export default multiline implicit object", ->
|
||||||
eqJS """
|
eqJS """
|
||||||
export default
|
export default
|
||||||
foo: 'bar',
|
foo: 'bar'
|
||||||
baz: 'qux'
|
baz: 'qux'
|
||||||
""",
|
""",
|
||||||
"""
|
"""
|
||||||
@@ -12709,6 +12864,22 @@ test "export default multiline implicit object", ->
|
|||||||
baz: 'qux'
|
baz: 'qux'
|
||||||
};"""
|
};"""
|
||||||
|
|
||||||
|
test "export default multiline implicit object with internal braces", ->
|
||||||
|
eqJS """
|
||||||
|
export default
|
||||||
|
foo: yes
|
||||||
|
bar: {
|
||||||
|
baz
|
||||||
|
}
|
||||||
|
quz: no
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
export default {
|
||||||
|
foo: true,
|
||||||
|
bar: {baz},
|
||||||
|
quz: false
|
||||||
|
};"""
|
||||||
|
|
||||||
test "export default assignment expression", ->
|
test "export default assignment expression", ->
|
||||||
eqJS "export default foo = 'bar'",
|
eqJS "export default foo = 'bar'",
|
||||||
"""
|
"""
|
||||||
@@ -13757,8 +13928,7 @@ test 'inline implicit object literals within multiline implicit object literals'
|
|||||||
eq 0, x.b
|
eq 0, x.b
|
||||||
eq 0, x.a.aa
|
eq 0, x.a.aa
|
||||||
|
|
||||||
test "object keys with interpolations", ->
|
test "object keys with interpolations: simple cases", ->
|
||||||
# Simple cases.
|
|
||||||
a = 'a'
|
a = 'a'
|
||||||
obj = "#{a}": yes
|
obj = "#{a}": yes
|
||||||
eq obj.a, yes
|
eq obj.a, yes
|
||||||
@@ -13769,7 +13939,7 @@ test "object keys with interpolations", ->
|
|||||||
obj = {"#{5}"}
|
obj = {"#{5}"}
|
||||||
eq obj[5], '5' # Note that the value is a string, just like the key.
|
eq obj[5], '5' # Note that the value is a string, just like the key.
|
||||||
|
|
||||||
# Commas in implicit object.
|
test "object keys with interpolations: commas in implicit object", ->
|
||||||
obj = "#{'a'}": 1, b: 2
|
obj = "#{'a'}": 1, b: 2
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
obj = a: 1, "#{'b'}": 2
|
obj = a: 1, "#{'b'}": 2
|
||||||
@@ -13777,7 +13947,7 @@ test "object keys with interpolations", ->
|
|||||||
obj = "#{'a'}": 1, "#{'b'}": 2
|
obj = "#{'a'}": 1, "#{'b'}": 2
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
# Commas in explicit object.
|
test "object keys with interpolations: commas in explicit object", ->
|
||||||
obj = {"#{'a'}": 1, b: 2}
|
obj = {"#{'a'}": 1, b: 2}
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
obj = {a: 1, "#{'b'}": 2}
|
obj = {a: 1, "#{'b'}": 2}
|
||||||
@@ -13785,7 +13955,7 @@ test "object keys with interpolations", ->
|
|||||||
obj = {"#{'a'}": 1, "#{'b'}": 2}
|
obj = {"#{'a'}": 1, "#{'b'}": 2}
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
# Commas after key with interpolation.
|
test "object keys with interpolations: commas after key with interpolation", ->
|
||||||
obj = {"#{'a'}": yes,}
|
obj = {"#{'a'}": yes,}
|
||||||
eq obj.a, yes
|
eq obj.a, yes
|
||||||
obj = {
|
obj = {
|
||||||
@@ -13808,17 +13978,17 @@ test "object keys with interpolations", ->
|
|||||||
"#{'c'}": 3, "#{'d'}": 4,
|
"#{'c'}": 3, "#{'d'}": 4,
|
||||||
deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
|
||||||
|
|
||||||
# Key with interpolation mixed with `@prop`.
|
test "object keys with interpolations: key with interpolation mixed with `@prop`", ->
|
||||||
deepEqual (-> {@a, "#{'b'}": 2}).call(a: 1), {a: 1, b: 2}
|
deepEqual (-> {@a, "#{'b'}": 2}).call(a: 1), {a: 1, b: 2}
|
||||||
|
|
||||||
# Evaluate only once.
|
test "object keys with interpolations: evaluate only once", ->
|
||||||
count = 0
|
count = 0
|
||||||
b = -> count++; 'b'
|
a = -> count++; 'a'
|
||||||
obj = {"#{b()}"}
|
obj = {"#{a()}"}
|
||||||
eq obj.b, 'b'
|
eq obj.a, 'a'
|
||||||
eq count, 1
|
eq count, 1
|
||||||
|
|
||||||
# Evaluation order.
|
test "object keys with interpolations: evaluation order", ->
|
||||||
arr = []
|
arr = []
|
||||||
obj =
|
obj =
|
||||||
a: arr.push 1
|
a: arr.push 1
|
||||||
@@ -13831,13 +14001,13 @@ test "object keys with interpolations", ->
|
|||||||
arrayEq arr, [1..7]
|
arrayEq arr, [1..7]
|
||||||
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
|
||||||
|
|
||||||
# Object starting with dynamic key.
|
test "object keys with interpolations: object starting with dynamic key", ->
|
||||||
obj =
|
obj =
|
||||||
"#{'a'}": 1
|
"#{'a'}": 1
|
||||||
b: 2
|
b: 2
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
# Comments in implicit object.
|
test "object keys with interpolations: comments in implicit object", ->
|
||||||
obj =
|
obj =
|
||||||
### leading comment ###
|
### leading comment ###
|
||||||
"#{'a'}": 1
|
"#{'a'}": 1
|
||||||
@@ -13868,7 +14038,7 @@ test "object keys with interpolations", ->
|
|||||||
}
|
}
|
||||||
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
||||||
|
|
||||||
# A more complicated case.
|
test "object keys with interpolations: more complicated case", ->
|
||||||
obj = {
|
obj = {
|
||||||
"#{'interpolated'}":
|
"#{'interpolated'}":
|
||||||
"""
|
"""
|
||||||
@@ -13886,6 +14056,212 @@ test "#4324: Shorthand after interpolated key", ->
|
|||||||
eq 1, obj[1]
|
eq 1, obj[1]
|
||||||
eq 2, obj.a
|
eq 2, obj.a
|
||||||
|
|
||||||
|
test "computed property keys: simple cases", ->
|
||||||
|
a = 'a'
|
||||||
|
obj = [a]: yes
|
||||||
|
eq obj.a, yes
|
||||||
|
obj = {[a]: yes}
|
||||||
|
eq obj.a, yes
|
||||||
|
obj = {[a]}
|
||||||
|
eq obj.a, 'a'
|
||||||
|
obj = {[5]}
|
||||||
|
eq obj[5], 5
|
||||||
|
obj = {['5']}
|
||||||
|
eq obj['5'], '5'
|
||||||
|
|
||||||
|
test "computed property keys: commas in implicit object", ->
|
||||||
|
obj = ['a']: 1, b: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = a: 1, ['b']: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = ['a']: 1, ['b']: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: commas in explicit object", ->
|
||||||
|
obj = {['a']: 1, b: 2}
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = {a: 1, ['b']: 2}
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = {['a']: 1, ['b']: 2}
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: commas after key with interpolation", ->
|
||||||
|
obj = {['a']: yes,}
|
||||||
|
eq obj.a, yes
|
||||||
|
obj = {
|
||||||
|
['a']: 1,
|
||||||
|
['b']: 2,
|
||||||
|
### herecomment ###
|
||||||
|
['c']: 3,
|
||||||
|
}
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3}
|
||||||
|
obj =
|
||||||
|
['a']: 1,
|
||||||
|
['b']: 2,
|
||||||
|
### herecomment ###
|
||||||
|
['c']: 3,
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3}
|
||||||
|
obj =
|
||||||
|
['a']: 1,
|
||||||
|
['b']: 2,
|
||||||
|
### herecomment ###
|
||||||
|
['c']: 3, ['d']: 4,
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
|
||||||
|
|
||||||
|
test "computed property keys: key with interpolation mixed with `@prop`", ->
|
||||||
|
deepEqual (-> {@a, ['b']: 2}).call(a: 1), {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: evaluate only once", ->
|
||||||
|
count = 0
|
||||||
|
a = -> count++; 'a'
|
||||||
|
obj = {[a()]}
|
||||||
|
eq obj.a, 'a'
|
||||||
|
eq count, 1
|
||||||
|
|
||||||
|
test "computed property keys: evaluation order", ->
|
||||||
|
arr = []
|
||||||
|
obj =
|
||||||
|
a: arr.push 1
|
||||||
|
b: arr.push 2
|
||||||
|
['c']: arr.push 3
|
||||||
|
['d']: arr.push 4
|
||||||
|
e: arr.push 5
|
||||||
|
['f']: arr.push 6
|
||||||
|
g: arr.push 7
|
||||||
|
arrayEq arr, [1..7]
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
|
||||||
|
|
||||||
|
test "computed property keys: object starting with dynamic key", ->
|
||||||
|
obj =
|
||||||
|
['a']: 1
|
||||||
|
b: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: comments in implicit object", ->
|
||||||
|
obj =
|
||||||
|
### leading comment ###
|
||||||
|
['a']: 1
|
||||||
|
|
||||||
|
### middle ###
|
||||||
|
|
||||||
|
['b']: 2
|
||||||
|
# regular comment
|
||||||
|
'c': 3
|
||||||
|
### foo ###
|
||||||
|
d: 4
|
||||||
|
['e']: 5
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
||||||
|
|
||||||
|
obj = {
|
||||||
|
### leading comment ###
|
||||||
|
['a']: 1
|
||||||
|
|
||||||
|
### middle ###
|
||||||
|
|
||||||
|
['b']: 2
|
||||||
|
# regular comment
|
||||||
|
'c': 3
|
||||||
|
### foo ###
|
||||||
|
d: 4
|
||||||
|
['e']: 5
|
||||||
|
}
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
||||||
|
|
||||||
|
test "computed property keys: more complicated case", ->
|
||||||
|
obj = {
|
||||||
|
['interpolated']:
|
||||||
|
['nested']:
|
||||||
|
123: 456
|
||||||
|
}
|
||||||
|
deepEqual obj,
|
||||||
|
interpolated:
|
||||||
|
nested:
|
||||||
|
123: 456
|
||||||
|
|
||||||
|
test "computed property keys: empty array as key", ->
|
||||||
|
o1 = { [[]] }
|
||||||
|
deepEqual o1, { [[]]: [] }
|
||||||
|
arrayEq o1[[]], []
|
||||||
|
o2 = { [[]]: 1 }
|
||||||
|
deepEqual o2, { [[]]: 1 }
|
||||||
|
eq o2[[]], 1
|
||||||
|
o3 = [[]]: 1
|
||||||
|
deepEqual o3, { [[]]: 1 }
|
||||||
|
deepEqual o3, { [[]]: 1 }
|
||||||
|
eq o3[[]], 1
|
||||||
|
o4 = a: 1, [[]]: 2
|
||||||
|
deepEqual o4, { a: 1, [[]]: 2 }
|
||||||
|
eq o4.a, 1,
|
||||||
|
eq o4[[]], 2
|
||||||
|
o5 = { a: 1, [[]]: 2 }
|
||||||
|
deepEqual o5, { a: 1, [[]]: 2 }
|
||||||
|
eq o5.a, 1,
|
||||||
|
eq o5[[]], 2
|
||||||
|
|
||||||
|
test "computed property keys: shorthand after computed property key", ->
|
||||||
|
a = 2
|
||||||
|
obj = {[1]: 1, a}
|
||||||
|
eq 1, obj[1]
|
||||||
|
eq 2, obj.a
|
||||||
|
|
||||||
|
test "computed property keys: shorthand computed property key", ->
|
||||||
|
a = 'b'
|
||||||
|
o = {[a]}
|
||||||
|
p = {a}
|
||||||
|
r = {['a']}
|
||||||
|
eq o.b, 'b'
|
||||||
|
eq p.a, o.b
|
||||||
|
eq r.a, 'a'
|
||||||
|
|
||||||
|
foo = -> "a"
|
||||||
|
obj = { [foo()] }
|
||||||
|
eq obj.a, 'a'
|
||||||
|
|
||||||
|
test "computed property keys: arrays", ->
|
||||||
|
b = 'b'
|
||||||
|
f = (c) -> "#{c}1"
|
||||||
|
obj =
|
||||||
|
['a']: [1, 2, 3]
|
||||||
|
[b]: [4, 5, 6]
|
||||||
|
[f(b)]: [7, 8, 9]
|
||||||
|
arrayEq obj.a, [1, 2, 3]
|
||||||
|
arrayEq obj.b, [4, 5, 6]
|
||||||
|
arrayEq obj.b1, [7, 8, 9]
|
||||||
|
|
||||||
|
test "computed property keys: examples from developer.mozilla.org (Object initializer)", ->
|
||||||
|
i = 0
|
||||||
|
obj =
|
||||||
|
['foo' + ++i]: i
|
||||||
|
['foo' + ++i]: i
|
||||||
|
['foo' + ++i]: i
|
||||||
|
eq obj.foo1, 1
|
||||||
|
eq obj.foo2, 2
|
||||||
|
eq obj.foo3, 3
|
||||||
|
|
||||||
|
param = 'size'
|
||||||
|
config =
|
||||||
|
[param]: 12,
|
||||||
|
['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
|
||||||
|
deepEqual config, {size: 12, mobileSize: 4}
|
||||||
|
|
||||||
|
test "computed property keys: [Symbol.iterator]", ->
|
||||||
|
obj =
|
||||||
|
[Symbol.iterator]: ->
|
||||||
|
yield "hello"
|
||||||
|
yield "world"
|
||||||
|
arrayEq [obj...], ['hello', 'world']
|
||||||
|
|
||||||
|
test "computed property keys: Class property", ->
|
||||||
|
increment_method = "increment"
|
||||||
|
decrement_method = "decrement"
|
||||||
|
class Obs
|
||||||
|
constructor: (@count) ->
|
||||||
|
[increment_method]: -> @count += 1
|
||||||
|
[decrement_method]: -> @count -= 1
|
||||||
|
ob = new Obs 2
|
||||||
|
eq ob.increment(), 3
|
||||||
|
eq ob.decrement(), 2
|
||||||
|
|
||||||
test "#1263: Braceless object return", ->
|
test "#1263: Braceless object return", ->
|
||||||
fn = ->
|
fn = ->
|
||||||
return
|
return
|
||||||
@@ -13956,20 +14332,22 @@ test "#4544: Postfix conditionals in first line of implicit object literals", ->
|
|||||||
test "#4579: Postfix for/while/until in first line of implicit object literals", ->
|
test "#4579: Postfix for/while/until in first line of implicit object literals", ->
|
||||||
two =
|
two =
|
||||||
foo:
|
foo:
|
||||||
bar: x for x in [1, 2, 3]
|
bar1: x for x in [1, 2, 3]
|
||||||
|
bar2: x + y for x, y in [1, 2, 3]
|
||||||
baz: 1337
|
baz: 1337
|
||||||
arrayEq [1, 2, 3], two.foo.bar
|
arrayEq [1, 2, 3], two.foo.bar1
|
||||||
|
arrayEq [1, 3, 5], two.foo.bar2
|
||||||
eq 1337, two.foo.baz
|
eq 1337, two.foo.baz
|
||||||
|
|
||||||
f = (x) -> x
|
f = (x) -> x
|
||||||
|
|
||||||
three =
|
three =
|
||||||
foo: f
|
foo: f
|
||||||
# Uncomment when #4580 is fixed
|
bar1: x + y for x, y of a: 'b', c: 'd'
|
||||||
# bar: x + y for x, y of a: 'b', c: 'd'
|
bar2: x + 'c' for x of a: 1, b: 2
|
||||||
bar: x + 'c' for x of a: 1, b: 2
|
|
||||||
baz: 1337
|
baz: 1337
|
||||||
arrayEq ['ac', 'bc'], three.foo.bar
|
arrayEq ['ab', 'cd'], three.foo.bar1
|
||||||
|
arrayEq ['ac', 'bc'], three.foo.bar2
|
||||||
eq 1337, three.foo.baz
|
eq 1337, three.foo.baz
|
||||||
|
|
||||||
four =
|
four =
|
||||||
@@ -14001,7 +14379,6 @@ test "#4579: Postfix for/while/until in first line of implicit object literals",
|
|||||||
arrayEq [4, 3, 2, 1, 0], six.foo.bar
|
arrayEq [4, 3, 2, 1, 0], six.foo.bar
|
||||||
eq 1337, six.foo.baz
|
eq 1337, six.foo.baz
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="operators">
|
<script type="text/x-coffeescript" class="test" id="operators">
|
||||||
# Operators
|
# Operators
|
||||||
@@ -15086,6 +15463,19 @@ test "#4248: Unicode code point escapes", ->
|
|||||||
/a\\udab3\\uddef/;
|
/a\\udab3\\uddef/;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
test "#4811, heregex comments with ///", ->
|
||||||
|
eqJS """
|
||||||
|
///
|
||||||
|
a | # comment with ///
|
||||||
|
b # /// 'heregex' in comment will be consumed
|
||||||
|
///
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
// comment with ///
|
||||||
|
// /// 'heregex' in comment will be consumed
|
||||||
|
/a|b/;
|
||||||
|
"""
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="repl">
|
<script type="text/x-coffeescript" class="test" id="repl">
|
||||||
return if global.testingBrowser
|
return if global.testingBrowser
|
||||||
@@ -15167,6 +15557,14 @@ testRepl "empty command evaluates to undefined", (input, output) ->
|
|||||||
input.emitLine ''
|
input.emitLine ''
|
||||||
eq 'undefined', output.lastWrite()
|
eq 'undefined', output.lastWrite()
|
||||||
|
|
||||||
|
testRepl "#4763: comment evaluates to undefined", (input, output) ->
|
||||||
|
input.emitLine '# comment'
|
||||||
|
eq 'undefined', output.lastWrite()
|
||||||
|
|
||||||
|
testRepl "#4763: multiple comments evaluate to undefined", (input, output) ->
|
||||||
|
input.emitLine '### a ### ### b ### # c'
|
||||||
|
eq 'undefined', output.lastWrite()
|
||||||
|
|
||||||
testRepl "ctrl-v toggles multiline prompt", (input, output) ->
|
testRepl "ctrl-v toggles multiline prompt", (input, output) ->
|
||||||
input.emit 'keypress', null, ctrlV
|
input.emit 'keypress', null, ctrlV
|
||||||
eq '------> ', output.lastWrite(0)
|
eq '------> ', output.lastWrite(0)
|
||||||
|
|||||||
@@ -1,5 +1,35 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
```
|
||||||
|
releaseHeader('2017-12-29', '2.1.1', '2.1.0')
|
||||||
|
```
|
||||||
|
|
||||||
|
* Bugfix to set the correct context for executable class bodies. So in `class @B extends @A then @property = 1`, the `@` in `@property` now refers to the class, not the global object.
|
||||||
|
* Bugfix where anonymous classes were getting created using the same automatic variable name. They now each receive unique names, so as not to override each other.
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
releaseHeader('2017-12-10', '2.1.0', '2.0.3')
|
||||||
|
```
|
||||||
|
|
||||||
|
* Computed property keys in object literals are now supported: `obj = { ['key' + i]: 42 }`, or `obj = [Symbol.iterator]: -> yield i++`.
|
||||||
|
* Skipping of array elements, a.k.a. elision, is now supported: `arr = [a, , b]`, or `[, protocol] = url.match /^(.*):\/\//`.
|
||||||
|
* [JSX fragments syntax](https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html) is now supported.
|
||||||
|
* Bugfix where `///` within a `#` line comment inside a `///` block regex was erroneously closing the regex, rather than being treated as part of the comment.
|
||||||
|
* Bugfix for incorrect output for object rest destructuring inside array destructuring.
|
||||||
|
|
||||||
|
```
|
||||||
|
releaseHeader('2017-11-26', '2.0.3', '2.0.2')
|
||||||
|
```
|
||||||
|
|
||||||
|
* Bugfix for `export default` followed by an implicit object that contains an explicit object, for example `exportedMember: { obj... }`.
|
||||||
|
* Bugfix for `key, val of obj` after an implicit object member, e.g. `foo: bar for key, val of obj`.
|
||||||
|
* Bugfix for combining array and object destructuring, e.g. `[ ..., {a, b} ] = arr`.
|
||||||
|
* Bugfix for an edge case where it was possible to create a bound (`=>`) generator function, which should throw an error as such functions aren’t allowed in ES2015.
|
||||||
|
* Bugfix for source maps: `.map` files should always have the same base filename as the requested output filename. So `coffee --map --output foo.js test.coffee` should generate `foo.js` and `foo.js.map`.
|
||||||
|
* Bugfix for incorrect source maps generated when using `--transpile` with `--map` for multiple input files.
|
||||||
|
* Bugfix for comments at the beginning or end of input into the REPL (`coffee --interactive`).
|
||||||
|
|
||||||
```
|
```
|
||||||
releaseHeader('2017-10-26', '2.0.2', '2.0.1')
|
releaseHeader('2017-10-26', '2.0.2', '2.0.1')
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -6,12 +6,6 @@ The CoffeeScript literals for objects and arrays look very similar to their Java
|
|||||||
codeFor('objects_and_arrays', 'song.join(" … ")')
|
codeFor('objects_and_arrays', 'song.join(" … ")')
|
||||||
```
|
```
|
||||||
|
|
||||||
In JavaScript, you can’t use reserved words, like `class`, as properties of an object, without quoting them as strings. CoffeeScript notices reserved words used as keys in objects and quotes them for you, so you don’t have to worry about it (say, when using jQuery).
|
|
||||||
|
|
||||||
```
|
|
||||||
codeFor('objects_reserved')
|
|
||||||
```
|
|
||||||
|
|
||||||
CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name.
|
CoffeeScript has a shortcut for creating objects when you want the key to be set with a variable of the same name.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ You can use `in` to test for array presence, and `of` to test for JavaScript obj
|
|||||||
|
|
||||||
In a `for` loop, `from` compiles to the [ES2015 `of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of). (Yes, it’s unfortunate; the CoffeeScript `of` predates the ES2015 `of`.)
|
In a `for` loop, `from` compiles to the [ES2015 `of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of). (Yes, it’s unfortunate; the CoffeeScript `of` predates the ES2015 `of`.)
|
||||||
|
|
||||||
To simplify math expressions, `**` can be used for exponentiation and `//` performs integer division. `%` works just like in JavaScript, while `%%` provides [“dividend dependent modulo”](https://en.wikipedia.org/wiki/Modulo_operation):
|
To simplify math expressions, `**` can be used for exponentiation and `//` performs floor division. `%` works just like in JavaScript, while `%%` provides [“dividend dependent modulo”](https://en.wikipedia.org/wiki/Modulo_operation):
|
||||||
|
|
||||||
```
|
```
|
||||||
codeFor('modulo')
|
codeFor('modulo')
|
||||||
|
|||||||
@@ -2,6 +2,4 @@
|
|||||||
|
|
||||||
While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using `<script type="text/coffeescript">` tags. The source includes a compressed and minified version of the compiler ([Download current version here, 51k when gzipped](/v<%= majorVersion %>/browser-compiler/coffeescript.js)) as `docs/v<%= majorVersion %>/browser-compiler/coffeescript.js`. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.
|
While it’s not recommended for serious use, CoffeeScripts may be included directly within the browser using `<script type="text/coffeescript">` tags. The source includes a compressed and minified version of the compiler ([Download current version here, 51k when gzipped](/v<%= majorVersion %>/browser-compiler/coffeescript.js)) as `docs/v<%= majorVersion %>/browser-compiler/coffeescript.js`. Include this file on a page with inline CoffeeScript tags, and it will compile and evaluate them in order.
|
||||||
|
|
||||||
In fact, the little bit of glue script that runs [Try CoffeeScript](#try), as well as the code examples and other interactive parts of this site, is implemented in just this way. View source and look at the bottom of the page to see the example. Including the script also gives you access to `CoffeeScript.compile()` so you can pop open your JavaScript console and try compiling some strings.
|
|
||||||
|
|
||||||
The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the `window` object.
|
The usual caveats about CoffeeScript apply — your inline scripts will run within a closure wrapper, so if you want to expose global variables or functions, attach them to the `window` object.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// This **Browser** compatibility layer extends core CoffeeScript functions
|
// This **Browser** compatibility layer extends core CoffeeScript functions
|
||||||
// to make things work smoothly when compiling code directly in the browser.
|
// to make things work smoothly when compiling code directly in the browser.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// `cake` is a simplified version of [Make](http://www.gnu.org/software/make/)
|
// `cake` is a simplified version of [Make](http://www.gnu.org/software/make/)
|
||||||
// ([Rake](http://rake.rubyforge.org/), [Jake](https://github.com/280north/jake))
|
// ([Rake](http://rake.rubyforge.org/), [Jake](https://github.com/280north/jake))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// CoffeeScript can be used both on the server, as a command-line compiler based
|
// CoffeeScript can be used both on the server, as a command-line compiler based
|
||||||
// on Node.js/V8, or to run CoffeeScript directly in the browser. This module
|
// on Node.js/V8, or to run CoffeeScript directly in the browser. This module
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
// object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for
|
// object, where sourceMap is a sourcemap.coffee#SourceMap object, handy for
|
||||||
// doing programmatic lookups.
|
// doing programmatic lookups.
|
||||||
exports.compile = compile = withPrettyErrors(function(code, options = {}) {
|
exports.compile = compile = withPrettyErrors(function(code, options = {}) {
|
||||||
var currentColumn, currentLine, encoded, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, transpiler, transpilerOutput, v3SourceMap;
|
var currentColumn, currentLine, encoded, filename, fragment, fragments, generateSourceMap, header, i, j, js, len, len1, map, newLines, ref, ref1, sourceMapDataURI, sourceURL, token, tokens, transpiler, transpilerOptions, transpilerOutput, v3SourceMap;
|
||||||
// Clone `options`, to avoid mutating the `options` object passed in.
|
// Clone `options`, to avoid mutating the `options` object passed in.
|
||||||
options = Object.assign({}, options);
|
options = Object.assign({}, options);
|
||||||
// Always generate a source map if no filename is passed in, since without a
|
// Always generate a source map if no filename is passed in, since without a
|
||||||
@@ -177,13 +177,14 @@
|
|||||||
// is run via the CLI or Node API.
|
// is run via the CLI or Node API.
|
||||||
transpiler = options.transpile.transpile;
|
transpiler = options.transpile.transpile;
|
||||||
delete options.transpile.transpile;
|
delete options.transpile.transpile;
|
||||||
|
transpilerOptions = Object.assign({}, options.transpile);
|
||||||
// See https://github.com/babel/babel/issues/827#issuecomment-77573107:
|
// See https://github.com/babel/babel/issues/827#issuecomment-77573107:
|
||||||
// Babel can take a v3 source map object as input in `inputSourceMap`
|
// Babel can take a v3 source map object as input in `inputSourceMap`
|
||||||
// and it will return an *updated* v3 source map object in its output.
|
// and it will return an *updated* v3 source map object in its output.
|
||||||
if (v3SourceMap && (options.transpile.inputSourceMap == null)) {
|
if (v3SourceMap && (transpilerOptions.inputSourceMap == null)) {
|
||||||
options.transpile.inputSourceMap = v3SourceMap;
|
transpilerOptions.inputSourceMap = v3SourceMap;
|
||||||
}
|
}
|
||||||
transpilerOutput = transpiler(js, options.transpile);
|
transpilerOutput = transpiler(js, transpilerOptions);
|
||||||
js = transpilerOutput.code;
|
js = transpilerOutput.code;
|
||||||
if (v3SourceMap && transpilerOutput.map) {
|
if (v3SourceMap && transpilerOutput.map) {
|
||||||
v3SourceMap = transpilerOutput.map;
|
v3SourceMap = transpilerOutput.map;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// The `coffee` utility. Handles command-line compilation of CoffeeScript
|
// The `coffee` utility. Handles command-line compilation of CoffeeScript
|
||||||
// into various forms: saved into `.js` files or printed to stdout
|
// into various forms: saved into `.js` files or printed to stdout
|
||||||
@@ -534,7 +534,7 @@
|
|||||||
// same directory as the `.js` file.
|
// same directory as the `.js` file.
|
||||||
writeJs = function(base, sourcePath, js, jsPath, generatedSourceMap = null) {
|
writeJs = function(base, sourcePath, js, jsPath, generatedSourceMap = null) {
|
||||||
var compile, jsDir, sourceMapPath;
|
var compile, jsDir, sourceMapPath;
|
||||||
sourceMapPath = outputPath(sourcePath, base, ".js.map");
|
sourceMapPath = `${jsPath}.map`;
|
||||||
jsDir = path.dirname(jsPath);
|
jsDir = path.dirname(jsPath);
|
||||||
compile = function() {
|
compile = function() {
|
||||||
if (opts.compile) {
|
if (opts.compile) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// The CoffeeScript parser is generated by [Jison](https://github.com/zaach/jison)
|
// The CoffeeScript parser is generated by [Jison](https://github.com/zaach/jison)
|
||||||
// from this grammar file. Jison is a bottom-up parser generator, similar in
|
// from this grammar file. Jison is a bottom-up parser generator, similar in
|
||||||
@@ -282,7 +282,15 @@
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
SimpleObjAssignable: [o('Identifier'), o('Property'), o('ThisProperty')],
|
SimpleObjAssignable: [
|
||||||
|
o('Identifier'),
|
||||||
|
o('Property'),
|
||||||
|
o('ThisProperty'),
|
||||||
|
o('[ Expression ]',
|
||||||
|
function() {
|
||||||
|
return new Value(new ComputedPropertyName($2));
|
||||||
|
})
|
||||||
|
],
|
||||||
ObjAssignable: [o('SimpleObjAssignable'), o('AlphaNumeric')],
|
ObjAssignable: [o('SimpleObjAssignable'), o('AlphaNumeric')],
|
||||||
// Object literal spread properties.
|
// Object literal spread properties.
|
||||||
ObjRestValue: [
|
ObjRestValue: [
|
||||||
@@ -822,6 +830,10 @@
|
|||||||
function() {
|
function() {
|
||||||
return new ExportDefaultDeclaration($3);
|
return new ExportDefaultDeclaration($3);
|
||||||
}),
|
}),
|
||||||
|
o('EXPORT DEFAULT INDENT Object OUTDENT',
|
||||||
|
function() {
|
||||||
|
return new ExportDefaultDeclaration(new Value($4));
|
||||||
|
}),
|
||||||
o('EXPORT EXPORT_ALL FROM String',
|
o('EXPORT EXPORT_ALL FROM String',
|
||||||
function() {
|
function() {
|
||||||
return new ExportAllDeclaration(new Literal($2),
|
return new ExportAllDeclaration(new Literal($2),
|
||||||
@@ -950,9 +962,14 @@
|
|||||||
function() {
|
function() {
|
||||||
return new Arr([]);
|
return new Arr([]);
|
||||||
}),
|
}),
|
||||||
o('[ ArgList OptComma ]',
|
o('[ Elisions ]',
|
||||||
function() {
|
function() {
|
||||||
return new Arr($2);
|
return new Arr($2);
|
||||||
|
}),
|
||||||
|
o('[ ArgElisionList OptElisions ]',
|
||||||
|
function() {
|
||||||
|
return new Arr([].concat($2,
|
||||||
|
$3));
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
// Inclusive and exclusive range dots.
|
// Inclusive and exclusive range dots.
|
||||||
@@ -1002,8 +1019,7 @@
|
|||||||
$1);
|
$1);
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
// The **ArgList** is both the list of objects passed into a function call,
|
// The **ArgList** is the list of objects passed into a function call
|
||||||
// as well as the contents of an array literal
|
|
||||||
// (i.e. comma-separated expressions). Newlines work as well.
|
// (i.e. comma-separated expressions). Newlines work as well.
|
||||||
ArgList: [
|
ArgList: [
|
||||||
o('Arg',
|
o('Arg',
|
||||||
@@ -1036,6 +1052,66 @@
|
|||||||
return new Expansion;
|
return new Expansion;
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
|
// The **ArgElisionList** is the list of objects, contents of an array literal
|
||||||
|
// (i.e. comma-separated expressions and elisions). Newlines work as well.
|
||||||
|
ArgElisionList: [
|
||||||
|
o('ArgElision'),
|
||||||
|
o('ArgElisionList , ArgElision',
|
||||||
|
function() {
|
||||||
|
return $1.concat($3);
|
||||||
|
}),
|
||||||
|
o('ArgElisionList OptElisions TERMINATOR ArgElision',
|
||||||
|
function() {
|
||||||
|
return $1.concat($2,
|
||||||
|
$4);
|
||||||
|
}),
|
||||||
|
o('INDENT ArgElisionList OptElisions OUTDENT',
|
||||||
|
function() {
|
||||||
|
return $2.concat($3);
|
||||||
|
}),
|
||||||
|
o('ArgElisionList OptElisions INDENT ArgElisionList OptElisions OUTDENT',
|
||||||
|
function() {
|
||||||
|
return $1.concat($2,
|
||||||
|
$4,
|
||||||
|
$5);
|
||||||
|
})
|
||||||
|
],
|
||||||
|
ArgElision: [
|
||||||
|
o('Arg',
|
||||||
|
function() {
|
||||||
|
return [$1];
|
||||||
|
}),
|
||||||
|
o('Elisions Arg',
|
||||||
|
function() {
|
||||||
|
return $1.concat($2);
|
||||||
|
})
|
||||||
|
],
|
||||||
|
OptElisions: [
|
||||||
|
o('OptComma',
|
||||||
|
function() {
|
||||||
|
return [];
|
||||||
|
}),
|
||||||
|
o(', Elisions',
|
||||||
|
function() {
|
||||||
|
return [].concat($2);
|
||||||
|
})
|
||||||
|
],
|
||||||
|
Elisions: [
|
||||||
|
o('Elision',
|
||||||
|
function() {
|
||||||
|
return [$1];
|
||||||
|
}),
|
||||||
|
o('Elisions Elision',
|
||||||
|
function() {
|
||||||
|
return $1.concat($2);
|
||||||
|
})
|
||||||
|
],
|
||||||
|
Elision: [
|
||||||
|
o(',',
|
||||||
|
function() {
|
||||||
|
return new Elision;
|
||||||
|
})
|
||||||
|
],
|
||||||
// Just simple, comma-separated, required arguments (no fancy syntax). We need
|
// Just simple, comma-separated, required arguments (no fancy syntax). We need
|
||||||
// this to be separate from the **ArgList** for use in **Switch** blocks, where
|
// this to be separate from the **ArgList** for use in **Switch** blocks, where
|
||||||
// having the newlines wouldn't make sense.
|
// having the newlines wouldn't make sense.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// This file contains the common helper functions that we'd like to share among
|
// This file contains the common helper functions that we'd like to share among
|
||||||
// the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten
|
// the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// Node.js Implementation
|
// Node.js Implementation
|
||||||
var CoffeeScript, ext, fn, fs, helpers, i, len, path, ref, universalCompile, vm,
|
var CoffeeScript, ext, fn, fs, helpers, i, len, path, ref, universalCompile, vm,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
|
// The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
|
||||||
// matches against the beginning of the source code. When a match is found,
|
// matches against the beginning of the source code. When a match is found,
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
// where locationData is {first_line, first_column, last_line, last_column}, which is a
|
// where locationData is {first_line, first_column, last_line, last_column}, which is a
|
||||||
// format that can be fed directly into [Jison](https://github.com/zaach/jison). These
|
// format that can be fed directly into [Jison](https://github.com/zaach/jison). These
|
||||||
// are read by jison in the `parser.lexer` function defined in coffeescript.coffee.
|
// are read by jison in the `parser.lexer` function defined in coffeescript.coffee.
|
||||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARABLE_LEFT_SIDE, COMPARE, COMPOUND_ASSIGN, CSX_ATTRIBUTE, CSX_IDENTIFIER, CSX_INTERPOLATION, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INSIDE_CSX, INVERSES, JSTOKEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, REGEX_INVALID_ESCAPE, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_INVALID_ESCAPE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, UNFINISHED, UNICODE_CODE_POINT_ESCAPE, VALID_FLAGS, WHITESPACE, attachCommentsToNode, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, merge, repeat, starts, throwSyntaxError,
|
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARABLE_LEFT_SIDE, COMPARE, COMPOUND_ASSIGN, CSX_ATTRIBUTE, CSX_FRAGMENT_IDENTIFIER, CSX_IDENTIFIER, CSX_INTERPOLATION, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, HERE_JSTOKEN, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INSIDE_CSX, INVERSES, JSTOKEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, Lexer, MATH, MULTI_DENT, NOT_REGEX, NUMBER, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, REGEX_INVALID_ESCAPE, RELATION, RESERVED, Rewriter, SHIFT, SIMPLE_STRING_OMIT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_INVALID_ESCAPE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, UNFINISHED, UNICODE_CODE_POINT_ESCAPE, VALID_FLAGS, WHITESPACE, attachCommentsToNode, compact, count, invertLiterate, isForFrom, isUnassignable, key, locationDataToString, merge, repeat, starts, throwSyntaxError,
|
||||||
indexOf = [].indexOf;
|
indexOf = [].indexOf;
|
||||||
|
|
||||||
({Rewriter, INVERSES} = require('./rewriter'));
|
({Rewriter, INVERSES} = require('./rewriter'));
|
||||||
@@ -741,7 +741,7 @@
|
|||||||
// Check the previous token to detect if attribute is spread.
|
// Check the previous token to detect if attribute is spread.
|
||||||
prevChar = this.tokens.length > 0 ? this.tokens[this.tokens.length - 1][0] : '';
|
prevChar = this.tokens.length > 0 ? this.tokens[this.tokens.length - 1][0] : '';
|
||||||
if (firstChar === '<') {
|
if (firstChar === '<') {
|
||||||
match = CSX_IDENTIFIER.exec(this.chunk.slice(1));
|
match = CSX_IDENTIFIER.exec(this.chunk.slice(1)) || CSX_FRAGMENT_IDENTIFIER.exec(this.chunk.slice(1));
|
||||||
// Not the right hand side of an unspaced comparison (i.e. `a<b`).
|
// Not the right hand side of an unspaced comparison (i.e. `a<b`).
|
||||||
if (!(match && (this.csxDepth > 0 || !(prev = this.prev()) || prev.spaced || (ref = prev[0], indexOf.call(COMPARABLE_LEFT_SIDE, ref) < 0)))) {
|
if (!(match && (this.csxDepth > 0 || !(prev = this.prev()) || prev.spaced || (ref = prev[0], indexOf.call(COMPARABLE_LEFT_SIDE, ref) < 0)))) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -793,8 +793,8 @@
|
|||||||
delimiter: '>'
|
delimiter: '>'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
match = CSX_IDENTIFIER.exec(this.chunk.slice(end));
|
match = CSX_IDENTIFIER.exec(this.chunk.slice(end)) || CSX_FRAGMENT_IDENTIFIER.exec(this.chunk.slice(end));
|
||||||
if (!match || match[0] !== csxTag.name) {
|
if (!match || match[1] !== csxTag.name) {
|
||||||
this.error(`expected corresponding CSX closing tag for ${csxTag.name}`, csxTag.origin[2]);
|
this.error(`expected corresponding CSX closing tag for ${csxTag.name}`, csxTag.origin[2]);
|
||||||
}
|
}
|
||||||
afterTag = end + csxTag.name.length;
|
afterTag = end + csxTag.name.length;
|
||||||
@@ -1541,6 +1541,9 @@
|
|||||||
CSX_IDENTIFIER = /^(?![\d<])((?:(?!\s)[\.\-$\w\x7f-\uffff])+)/; // Must not start with `<`.
|
CSX_IDENTIFIER = /^(?![\d<])((?:(?!\s)[\.\-$\w\x7f-\uffff])+)/; // Must not start with `<`.
|
||||||
// Like `IDENTIFIER`, but includes `-`s and `.`s.
|
// Like `IDENTIFIER`, but includes `-`s and `.`s.
|
||||||
|
|
||||||
|
// Fragment: <></>
|
||||||
|
CSX_FRAGMENT_IDENTIFIER = /^()>/; // Ends immediately with `>`.
|
||||||
|
|
||||||
CSX_ATTRIBUTE = /^(?!\d)((?:(?!\s)[\-$\w\x7f-\uffff])+)([^\S]*=(?!=))?/; // Like `IDENTIFIER`, but includes `-`s.
|
CSX_ATTRIBUTE = /^(?!\d)((?:(?!\s)[\-$\w\x7f-\uffff])+)([^\S]*=(?!=))?/; // Like `IDENTIFIER`, but includes `-`s.
|
||||||
// Is this an attribute with a value?
|
// Is this an attribute with a value?
|
||||||
|
|
||||||
@@ -1602,7 +1605,12 @@
|
|||||||
|
|
||||||
VALID_FLAGS = /^(?!.*(.).*\1)[imguy]*$/;
|
VALID_FLAGS = /^(?!.*(.).*\1)[imguy]*$/;
|
||||||
|
|
||||||
HEREGEX = /^(?:[^\\\/#]|\\[\s\S]|\/(?!\/\/)|\#(?!\{))*/;
|
// Match any character, except those that need special handling below.
|
||||||
|
// Match `\` followed by any character.
|
||||||
|
// Match any `/` except `///`.
|
||||||
|
// Match `#` which is not part of interpolation, e.g. `#{}`.
|
||||||
|
// Comments consume everything until the end of the line, including `///`.
|
||||||
|
HEREGEX = /^(?:[^\\\/#\s]|\\[\s\S]|\/(?!\/\/)|\#(?!\{)|\s+(?:#(?!\{).*)?)*/;
|
||||||
|
|
||||||
HEREGEX_OMIT = /((?:\\\\)+)|\\(\s)|\s+(?:#.*)?/g; // Consume (and preserve) an even number of backslashes.
|
HEREGEX_OMIT = /((?:\\\\)+)|\\(\s)|\s+(?:#.*)?/g; // Consume (and preserve) an even number of backslashes.
|
||||||
// Preserve escaped whitespace.
|
// Preserve escaped whitespace.
|
||||||
@@ -1685,6 +1693,6 @@
|
|||||||
INDENTABLE_CLOSERS = [')', '}', ']'];
|
INDENTABLE_CLOSERS = [')', '}', ']'];
|
||||||
|
|
||||||
// Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token
|
// Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token
|
||||||
UNFINISHED = ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-', '**', 'SHIFT', 'RELATION', 'COMPARE', '&', '^', '|', '&&', '||', 'BIN?', 'EXTENDS', 'DEFAULT'];
|
UNFINISHED = ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-', '**', 'SHIFT', 'RELATION', 'COMPARE', '&', '^', '|', '&&', '||', 'BIN?', 'EXTENDS'];
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// `nodes.coffee` contains all of the node classes for the syntax tree. Most
|
// `nodes.coffee` contains all of the node classes for the syntax tree. Most
|
||||||
// nodes are created as the result of actions in the [grammar](grammar.html),
|
// nodes are created as the result of actions in the [grammar](grammar.html),
|
||||||
// but some are created by other nodes as a method of code generation. To convert
|
// but some are created by other nodes as a method of code generation. To convert
|
||||||
// the syntax tree into a string of JavaScript code, call `compile()` on the root.
|
// the syntax tree into a string of JavaScript code, call `compile()` on the root.
|
||||||
var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, CSXTag, Call, Class, Code, CodeFragment, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncGlyph, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, JS_FORBIDDEN, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, SIMPLENUM, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, TAB, THIS, TaggedTemplateCall, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, hasLineComments, indentInitial, isLiteralArguments, isLiteralThis, isUnassignable, locationDataToString, merge, moveComments, multident, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility,
|
var Access, Arr, Assign, AwaitReturn, Base, Block, BooleanLiteral, CSXTag, Call, Class, Code, CodeFragment, ComputedPropertyName, Elision, ExecutableClassBody, Existence, Expansion, ExportAllDeclaration, ExportDeclaration, ExportDefaultDeclaration, ExportNamedDeclaration, ExportSpecifier, ExportSpecifierList, Extends, For, FuncGlyph, HereComment, HoistTarget, IdentifierLiteral, If, ImportClause, ImportDeclaration, ImportDefaultSpecifier, ImportNamespaceSpecifier, ImportSpecifier, ImportSpecifierList, In, Index, InfinityLiteral, JS_FORBIDDEN, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, LineComment, Literal, ModuleDeclaration, ModuleSpecifier, ModuleSpecifierList, NEGATE, NO, NaNLiteral, NullLiteral, NumberLiteral, Obj, Op, Param, Parens, PassthroughLiteral, PropertyName, Range, RegexLiteral, RegexWithInterpolations, Return, SIMPLENUM, Scope, Slice, Splat, StatementLiteral, StringLiteral, StringWithInterpolations, Super, SuperCall, Switch, TAB, THIS, TaggedTemplateCall, ThisLiteral, Throw, Try, UTILITIES, UndefinedLiteral, Value, While, YES, YieldReturn, addDataToNode, attachCommentsToNode, compact, del, ends, extend, flatten, fragmentsToText, hasLineComments, indentInitial, isLiteralArguments, isLiteralThis, isUnassignable, locationDataToString, merge, moveComments, multident, shouldCacheOrIsAssignable, some, starts, throwSyntaxError, unfoldSoak, unshiftAfterComments, utility,
|
||||||
indexOf = [].indexOf,
|
indexOf = [].indexOf,
|
||||||
splice = [].splice,
|
splice = [].splice,
|
||||||
slice = [].slice;
|
slice = [].slice;
|
||||||
@@ -543,7 +543,7 @@
|
|||||||
|
|
||||||
return Base;
|
return Base;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### HoistTarget
|
//### HoistTarget
|
||||||
|
|
||||||
@@ -997,7 +997,7 @@
|
|||||||
|
|
||||||
return Block;
|
return Block;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Literal
|
//### Literal
|
||||||
|
|
||||||
@@ -1030,7 +1030,7 @@
|
|||||||
|
|
||||||
return Literal;
|
return Literal;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.NumberLiteral = NumberLiteral = class NumberLiteral extends Literal {};
|
exports.NumberLiteral = NumberLiteral = class NumberLiteral extends Literal {};
|
||||||
|
|
||||||
@@ -1094,7 +1094,7 @@
|
|||||||
|
|
||||||
return IdentifierLiteral;
|
return IdentifierLiteral;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.CSXTag = CSXTag = class CSXTag extends IdentifierLiteral {};
|
exports.CSXTag = CSXTag = class CSXTag extends IdentifierLiteral {};
|
||||||
|
|
||||||
@@ -1105,7 +1105,14 @@
|
|||||||
|
|
||||||
return PropertyName;
|
return PropertyName;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
|
exports.ComputedPropertyName = ComputedPropertyName = class ComputedPropertyName extends PropertyName {
|
||||||
|
compileNode(o) {
|
||||||
|
return [this.makeCode('['), ...this.value.compileToFragments(o, LEVEL_LIST), this.makeCode(']')];
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
exports.StatementLiteral = StatementLiteral = (function() {
|
exports.StatementLiteral = StatementLiteral = (function() {
|
||||||
class StatementLiteral extends Literal {
|
class StatementLiteral extends Literal {
|
||||||
@@ -1130,7 +1137,7 @@
|
|||||||
|
|
||||||
return StatementLiteral;
|
return StatementLiteral;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.ThisLiteral = ThisLiteral = class ThisLiteral extends Literal {
|
exports.ThisLiteral = ThisLiteral = class ThisLiteral extends Literal {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -1224,7 +1231,7 @@
|
|||||||
|
|
||||||
return Return;
|
return Return;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
// `yield return` works exactly like `return`, except that it turns the function
|
// `yield return` works exactly like `return`, except that it turns the function
|
||||||
// into a generator.
|
// into a generator.
|
||||||
@@ -1364,6 +1371,13 @@
|
|||||||
return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
|
return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isElision() {
|
||||||
|
if (!(this.base instanceof Arr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.base.hasElision();
|
||||||
|
}
|
||||||
|
|
||||||
isSplice() {
|
isSplice() {
|
||||||
var lastProp, ref1;
|
var lastProp, ref1;
|
||||||
ref1 = this.properties, lastProp = ref1[ref1.length - 1];
|
ref1 = this.properties, lastProp = ref1[ref1.length - 1];
|
||||||
@@ -1476,7 +1490,7 @@
|
|||||||
|
|
||||||
return Value;
|
return Value;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### HereComment
|
//### HereComment
|
||||||
|
|
||||||
@@ -1737,7 +1751,7 @@
|
|||||||
|
|
||||||
return Call;
|
return Call;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Super
|
//### Super
|
||||||
|
|
||||||
@@ -1775,7 +1789,7 @@
|
|||||||
|
|
||||||
return SuperCall;
|
return SuperCall;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.Super = Super = (function() {
|
exports.Super = Super = (function() {
|
||||||
class Super extends Base {
|
class Super extends Base {
|
||||||
@@ -1823,7 +1837,7 @@
|
|||||||
|
|
||||||
return Super;
|
return Super;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### RegexWithInterpolations
|
//### RegexWithInterpolations
|
||||||
|
|
||||||
@@ -1875,7 +1889,7 @@
|
|||||||
|
|
||||||
return Extends;
|
return Extends;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Access
|
//### Access
|
||||||
|
|
||||||
@@ -1908,7 +1922,7 @@
|
|||||||
|
|
||||||
return Access;
|
return Access;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Index
|
//### Index
|
||||||
|
|
||||||
@@ -1934,7 +1948,7 @@
|
|||||||
|
|
||||||
return Index;
|
return Index;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Range
|
//### Range
|
||||||
|
|
||||||
@@ -2051,7 +2065,7 @@
|
|||||||
|
|
||||||
return Range;
|
return Range;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Slice
|
//### Slice
|
||||||
|
|
||||||
@@ -2089,7 +2103,7 @@
|
|||||||
|
|
||||||
return Slice;
|
return Slice;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Obj
|
//### Obj
|
||||||
|
|
||||||
@@ -2207,6 +2221,18 @@
|
|||||||
key = new PropertyName(key.value);
|
key = new PropertyName(key.value);
|
||||||
}
|
}
|
||||||
prop = new Assign(key, value, 'object');
|
prop = new Assign(key, value, 'object');
|
||||||
|
} else if (key instanceof Value && key.base instanceof ComputedPropertyName) {
|
||||||
|
// `{ [foo()] }` output as `{ [ref = foo()]: ref }`.
|
||||||
|
if (prop.base.value.shouldCache()) {
|
||||||
|
[key, value] = prop.base.value.cache(o);
|
||||||
|
if (key instanceof IdentifierLiteral) {
|
||||||
|
key = new ComputedPropertyName(key.value);
|
||||||
|
}
|
||||||
|
prop = new Assign(key, value, 'object');
|
||||||
|
} else {
|
||||||
|
// `{ [expression] }` output as `{ [expression]: expression }`.
|
||||||
|
prop = new Assign(key, prop.base.value, 'object');
|
||||||
|
}
|
||||||
} else if (!(typeof prop.bareLiteral === "function" ? prop.bareLiteral(IdentifierLiteral) : void 0)) {
|
} else if (!(typeof prop.bareLiteral === "function" ? prop.bareLiteral(IdentifierLiteral) : void 0)) {
|
||||||
prop = new Assign(prop, prop, 'object');
|
prop = new Assign(prop, prop, 'object');
|
||||||
}
|
}
|
||||||
@@ -2322,7 +2348,7 @@
|
|||||||
|
|
||||||
return Obj;
|
return Obj;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Arr
|
//### Arr
|
||||||
|
|
||||||
@@ -2335,6 +2361,18 @@
|
|||||||
this.objects = objs || [];
|
this.objects = objs || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasElision() {
|
||||||
|
var j, len1, obj, ref1;
|
||||||
|
ref1 = this.objects;
|
||||||
|
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||||
|
obj = ref1[j];
|
||||||
|
if (obj instanceof Elision) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
isAssignable() {
|
isAssignable() {
|
||||||
var i, j, len1, obj, ref1;
|
var i, j, len1, obj, ref1;
|
||||||
if (!this.objects.length) {
|
if (!this.objects.length) {
|
||||||
@@ -2358,11 +2396,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileNode(o) {
|
compileNode(o) {
|
||||||
var answer, compiledObjs, fragment, fragmentIndex, fragments, includesLineCommentsOnNonFirstElement, index, j, k, l, len1, len2, len3, len4, len5, obj, objIndex, q, r, ref1, unwrappedObj;
|
var answer, compiledObjs, fragment, fragmentIndex, fragmentIsElision, fragments, includesLineCommentsOnNonFirstElement, index, j, k, l, len1, len2, len3, len4, len5, obj, objIndex, olen, passedElision, q, r, ref1, unwrappedObj;
|
||||||
if (!this.objects.length) {
|
if (!this.objects.length) {
|
||||||
return [this.makeCode('[]')];
|
return [this.makeCode('[]')];
|
||||||
}
|
}
|
||||||
o.indent += TAB;
|
o.indent += TAB;
|
||||||
|
fragmentIsElision = function(fragment) {
|
||||||
|
return fragmentsToText(fragment).trim() === ',';
|
||||||
|
};
|
||||||
|
// Detect if `Elisions` at the beginning of the array are processed (e.g. [, , , a]).
|
||||||
|
passedElision = false;
|
||||||
answer = [];
|
answer = [];
|
||||||
ref1 = this.objects;
|
ref1 = this.objects;
|
||||||
for (objIndex = j = 0, len1 = ref1.length; j < len1; objIndex = ++j) {
|
for (objIndex = j = 0, len1 = ref1.length; j < len1; objIndex = ++j) {
|
||||||
@@ -2393,6 +2436,7 @@
|
|||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
olen = compiledObjs.length;
|
||||||
// If `compiledObjs` includes newlines, we will output this as a multiline
|
// If `compiledObjs` includes newlines, we will output this as a multiline
|
||||||
// array (i.e. with a newline and indentation after the `[`). If an element
|
// array (i.e. with a newline and indentation after the `[`). If an element
|
||||||
// contains line comments, that should also trigger multiline output since
|
// contains line comments, that should also trigger multiline output since
|
||||||
@@ -2411,9 +2455,12 @@
|
|||||||
includesLineCommentsOnNonFirstElement = true;
|
includesLineCommentsOnNonFirstElement = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index !== 0) {
|
// Add ', ' if all `Elisions` from the beginning of the array are processed (e.g. [, , , a]) and
|
||||||
|
// element isn't `Elision` or last element is `Elision` (e.g. [a,,b,,])
|
||||||
|
if (index !== 0 && passedElision && (!fragmentIsElision(fragments) || index === olen - 1)) {
|
||||||
answer.push(this.makeCode(', '));
|
answer.push(this.makeCode(', '));
|
||||||
}
|
}
|
||||||
|
passedElision = passedElision || !fragmentIsElision(fragments);
|
||||||
answer.push(...fragments);
|
answer.push(...fragments);
|
||||||
}
|
}
|
||||||
if (includesLineCommentsOnNonFirstElement || indexOf.call(fragmentsToText(answer), '\n') >= 0) {
|
if (includesLineCommentsOnNonFirstElement || indexOf.call(fragmentsToText(answer), '\n') >= 0) {
|
||||||
@@ -2421,7 +2468,7 @@
|
|||||||
fragment = answer[fragmentIndex];
|
fragment = answer[fragmentIndex];
|
||||||
if (fragment.isHereComment) {
|
if (fragment.isHereComment) {
|
||||||
fragment.code = `${multident(fragment.code, o.indent, false)}\n${o.indent}`;
|
fragment.code = `${multident(fragment.code, o.indent, false)}\n${o.indent}`;
|
||||||
} else if (fragment.code === ', ') {
|
} else if (fragment.code === ', ' && !(fragment != null ? fragment.isElision : void 0)) {
|
||||||
fragment.code = `,\n${o.indent}`;
|
fragment.code = `,\n${o.indent}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2470,7 +2517,7 @@
|
|||||||
|
|
||||||
return Arr;
|
return Arr;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Class
|
//### Class
|
||||||
|
|
||||||
@@ -2756,7 +2803,7 @@
|
|||||||
|
|
||||||
return Class;
|
return Class;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.ExecutableClassBody = ExecutableClassBody = (function() {
|
exports.ExecutableClassBody = ExecutableClassBody = (function() {
|
||||||
class ExecutableClassBody extends Base {
|
class ExecutableClassBody extends Base {
|
||||||
@@ -2774,16 +2821,16 @@
|
|||||||
if (argumentsNode = this.body.contains(isLiteralArguments)) {
|
if (argumentsNode = this.body.contains(isLiteralArguments)) {
|
||||||
argumentsNode.error("Class bodies shouldn't reference arguments");
|
argumentsNode.error("Class bodies shouldn't reference arguments");
|
||||||
}
|
}
|
||||||
this.name = (ref1 = this.class.name) != null ? ref1 : this.defaultClassVariableName;
|
|
||||||
directives = this.walkBody();
|
|
||||||
this.setContext();
|
|
||||||
ident = new IdentifierLiteral(this.name);
|
|
||||||
params = [];
|
params = [];
|
||||||
args = [];
|
args = [new ThisLiteral];
|
||||||
wrapper = new Code(params, this.body);
|
wrapper = new Code(params, this.body);
|
||||||
klass = new Parens(new Call(wrapper, args));
|
klass = new Parens(new Call(new Value(wrapper, [new Access(new PropertyName('call'))]), args));
|
||||||
this.body.spaced = true;
|
this.body.spaced = true;
|
||||||
o.classScope = wrapper.makeScope(o.scope);
|
o.classScope = wrapper.makeScope(o.scope);
|
||||||
|
this.name = (ref1 = this.class.name) != null ? ref1 : o.classScope.freeVariable(this.defaultClassVariableName);
|
||||||
|
ident = new IdentifierLiteral(this.name);
|
||||||
|
directives = this.walkBody();
|
||||||
|
this.setContext();
|
||||||
if (this.class.hasNameClash) {
|
if (this.class.hasNameClash) {
|
||||||
parent = new IdentifierLiteral(o.classScope.freeVariable('superClass'));
|
parent = new IdentifierLiteral(o.classScope.freeVariable('superClass'));
|
||||||
wrapper.params.push(new Param(parent));
|
wrapper.params.push(new Param(parent));
|
||||||
@@ -2900,7 +2947,7 @@
|
|||||||
|
|
||||||
return ExecutableClassBody;
|
return ExecutableClassBody;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Import and Export
|
//### Import and Export
|
||||||
exports.ModuleDeclaration = ModuleDeclaration = (function() {
|
exports.ModuleDeclaration = ModuleDeclaration = (function() {
|
||||||
@@ -2936,7 +2983,7 @@
|
|||||||
|
|
||||||
return ModuleDeclaration;
|
return ModuleDeclaration;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.ImportDeclaration = ImportDeclaration = class ImportDeclaration extends ModuleDeclaration {
|
exports.ImportDeclaration = ImportDeclaration = class ImportDeclaration extends ModuleDeclaration {
|
||||||
compileNode(o) {
|
compileNode(o) {
|
||||||
@@ -2989,7 +3036,7 @@
|
|||||||
|
|
||||||
return ImportClause;
|
return ImportClause;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.ExportDeclaration = ExportDeclaration = class ExportDeclaration extends ModuleDeclaration {
|
exports.ExportDeclaration = ExportDeclaration = class ExportDeclaration extends ModuleDeclaration {
|
||||||
compileNode(o) {
|
compileNode(o) {
|
||||||
@@ -3071,7 +3118,7 @@
|
|||||||
|
|
||||||
return ModuleSpecifierList;
|
return ModuleSpecifierList;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.ImportSpecifierList = ImportSpecifierList = class ImportSpecifierList extends ModuleSpecifierList {};
|
exports.ImportSpecifierList = ImportSpecifierList = class ImportSpecifierList extends ModuleSpecifierList {};
|
||||||
|
|
||||||
@@ -3115,7 +3162,7 @@
|
|||||||
|
|
||||||
return ModuleSpecifier;
|
return ModuleSpecifier;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
exports.ImportSpecifier = ImportSpecifier = class ImportSpecifier extends ModuleSpecifier {
|
exports.ImportSpecifier = ImportSpecifier = class ImportSpecifier extends ModuleSpecifier {
|
||||||
constructor(imported, local) {
|
constructor(imported, local) {
|
||||||
@@ -3184,7 +3231,7 @@
|
|||||||
// we've been assigned to, for correct internal references. If the variable
|
// we've been assigned to, for correct internal references. If the variable
|
||||||
// has not been seen yet within the current scope, declare it.
|
// has not been seen yet within the current scope, declare it.
|
||||||
compileNode(o) {
|
compileNode(o) {
|
||||||
var answer, compiledName, isValue, j, name, objDestructAnswer, properties, prototype, ref1, ref2, ref3, ref4, ref5, val, varBase;
|
var answer, compiledName, hasSplat, isValue, j, name, objDestructAnswer, properties, prototype, ref1, ref2, ref3, ref4, ref5, val, varBase;
|
||||||
isValue = this.variable instanceof Value;
|
isValue = this.variable instanceof Value;
|
||||||
if (isValue) {
|
if (isValue) {
|
||||||
// When compiling `@variable`, remember if it is part of a function parameter.
|
// When compiling `@variable`, remember if it is part of a function parameter.
|
||||||
@@ -3198,12 +3245,14 @@
|
|||||||
// know that, so that those nodes know that they’re assignable as
|
// know that, so that those nodes know that they’re assignable as
|
||||||
// destructured variables.
|
// destructured variables.
|
||||||
this.variable.base.lhs = true;
|
this.variable.base.lhs = true;
|
||||||
if (!this.variable.isAssignable()) {
|
// Check if @variable contains Obj with splats.
|
||||||
|
hasSplat = this.variable.contains(function(node) {
|
||||||
|
return node instanceof Obj && node.hasSplat();
|
||||||
|
});
|
||||||
|
if (!this.variable.isAssignable() || this.variable.isArray() && hasSplat) {
|
||||||
return this.compileDestructuring(o);
|
return this.compileDestructuring(o);
|
||||||
}
|
}
|
||||||
if (this.variable.isObject() && this.variable.contains(function(node) {
|
if (this.variable.isObject() && hasSplat) {
|
||||||
return node instanceof Obj && node.hasSplat();
|
|
||||||
})) {
|
|
||||||
// Object destructuring. Can be removed once ES proposal hits Stage 4.
|
// Object destructuring. Can be removed once ES proposal hits Stage 4.
|
||||||
objDestructAnswer = this.compileObjectDestruct(o);
|
objDestructAnswer = this.compileObjectDestruct(o);
|
||||||
}
|
}
|
||||||
@@ -3286,7 +3335,9 @@
|
|||||||
answer = compiledName.concat(this.makeCode(` ${this.context || '='} `), val);
|
answer = compiledName.concat(this.makeCode(` ${this.context || '='} `), val);
|
||||||
// Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration,
|
// Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration,
|
||||||
// if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
|
// if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
|
||||||
if (o.level > LEVEL_LIST || o.level === LEVEL_TOP && isValue && this.variable.base instanceof Obj && !this.nestedLhs && !(this.param === true)) {
|
// The assignment is wrapped in parentheses if 'o.level' has lower precedence than LEVEL_LIST (3)
|
||||||
|
// (i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we're destructuring object, e.g. {a,b} = obj.
|
||||||
|
if (o.level > LEVEL_LIST || isValue && this.variable.base instanceof Obj && !this.nestedLhs && !(this.param === true)) {
|
||||||
return this.wrapInParentheses(answer);
|
return this.wrapInParentheses(answer);
|
||||||
} else {
|
} else {
|
||||||
return answer;
|
return answer;
|
||||||
@@ -3569,10 +3620,17 @@
|
|||||||
obj.error(message);
|
obj.error(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assigns.push(new Assign(obj, val, null, {
|
if (!(obj instanceof Elision)) {
|
||||||
param: this.param,
|
assigns.push(new Assign(obj, val, null, {
|
||||||
subpattern: true
|
param: this.param,
|
||||||
}).compileToFragments(o, LEVEL_LIST));
|
subpattern: true
|
||||||
|
}).compileToFragments(o, LEVEL_LIST));
|
||||||
|
} else {
|
||||||
|
if (expandedIdx) {
|
||||||
|
// Output `Elision` only if `idx` is `i++`, e.g. expandedIdx.
|
||||||
|
assigns.push(idx.compileToFragments(o, LEVEL_LIST));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!(top || this.subpattern)) {
|
if (!(top || this.subpattern)) {
|
||||||
assigns.push(vvar);
|
assigns.push(vvar);
|
||||||
@@ -3672,7 +3730,7 @@
|
|||||||
|
|
||||||
return Assign;
|
return Assign;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### FuncGlyph
|
//### FuncGlyph
|
||||||
exports.FuncGlyph = FuncGlyph = class FuncGlyph extends Base {
|
exports.FuncGlyph = FuncGlyph = class FuncGlyph extends Base {
|
||||||
@@ -3729,7 +3787,7 @@
|
|||||||
// parameters after the splat, they are declared via expressions in the
|
// parameters after the splat, they are declared via expressions in the
|
||||||
// function body.
|
// function body.
|
||||||
compileNode(o) {
|
compileNode(o) {
|
||||||
var answer, body, boundMethodCheck, comment, condition, exprs, generatedVariables, haveBodyParam, haveSplatParam, i, ifTrue, j, k, l, len1, len2, len3, m, methodScope, modifiers, name, param, paramNames, paramToAddToScope, params, paramsAfterSplat, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, scopeVariablesCount, signature, splatParamName, thisAssignments, wasEmpty;
|
var answer, body, boundMethodCheck, comment, condition, exprs, generatedVariables, haveBodyParam, haveSplatParam, i, ifTrue, j, k, l, len1, len2, len3, m, methodScope, modifiers, name, param, paramNames, paramToAddToScope, params, paramsAfterSplat, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, scopeVariablesCount, signature, splatParamName, thisAssignments, wasEmpty, yieldNode;
|
||||||
if (this.ctor) {
|
if (this.ctor) {
|
||||||
if (this.isAsync) {
|
if (this.isAsync) {
|
||||||
this.name.error('Class constructor may not be async');
|
this.name.error('Class constructor may not be async');
|
||||||
@@ -3939,6 +3997,14 @@
|
|||||||
if (!(wasEmpty || this.noReturn)) {
|
if (!(wasEmpty || this.noReturn)) {
|
||||||
this.body.makeReturn();
|
this.body.makeReturn();
|
||||||
}
|
}
|
||||||
|
// JavaScript doesn’t allow bound (`=>`) functions to also be generators.
|
||||||
|
// This is usually caught via `Op::compileContinuation`, but double-check:
|
||||||
|
if (this.bound && this.isGenerator) {
|
||||||
|
yieldNode = this.body.contains(function(node) {
|
||||||
|
return node instanceof Op && node.operator === 'yield';
|
||||||
|
});
|
||||||
|
(yieldNode || this).error('yield cannot occur inside bound (fat arrow) functions');
|
||||||
|
}
|
||||||
// Assemble the output
|
// Assemble the output
|
||||||
modifiers = [];
|
modifiers = [];
|
||||||
if (this.isMethod && this.isStatic) {
|
if (this.isMethod && this.isStatic) {
|
||||||
@@ -4120,7 +4186,7 @@
|
|||||||
|
|
||||||
return Code;
|
return Code;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Param
|
//### Param
|
||||||
|
|
||||||
@@ -4227,6 +4293,8 @@
|
|||||||
// * simple destructured parameters {foo}
|
// * simple destructured parameters {foo}
|
||||||
iterator(obj.base.value, obj.base, this);
|
iterator(obj.base.value, obj.base, this);
|
||||||
}
|
}
|
||||||
|
} else if (obj instanceof Elision) {
|
||||||
|
obj;
|
||||||
} else if (!(obj instanceof Expansion)) {
|
} else if (!(obj instanceof Expansion)) {
|
||||||
obj.error(`illegal parameter ${obj.compile()}`);
|
obj.error(`illegal parameter ${obj.compile()}`);
|
||||||
}
|
}
|
||||||
@@ -4261,7 +4329,7 @@
|
|||||||
|
|
||||||
return Param;
|
return Param;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Splat
|
//### Splat
|
||||||
|
|
||||||
@@ -4296,7 +4364,7 @@
|
|||||||
|
|
||||||
return Splat;
|
return Splat;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Expansion
|
//### Expansion
|
||||||
|
|
||||||
@@ -4320,7 +4388,39 @@
|
|||||||
|
|
||||||
return Expansion;
|
return Expansion;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
|
//### Elision
|
||||||
|
|
||||||
|
// Array elision element (for example, [,a, , , b, , c, ,]).
|
||||||
|
exports.Elision = Elision = (function() {
|
||||||
|
class Elision extends Base {
|
||||||
|
compileToFragments(o, level) {
|
||||||
|
var fragment;
|
||||||
|
fragment = super.compileToFragments(o, level);
|
||||||
|
fragment.isElision = true;
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
compileNode(o) {
|
||||||
|
return [this.makeCode(', ')];
|
||||||
|
}
|
||||||
|
|
||||||
|
asReference(o) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
eachName(iterator) {}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
Elision.prototype.isAssignable = YES;
|
||||||
|
|
||||||
|
Elision.prototype.shouldCache = NO;
|
||||||
|
|
||||||
|
return Elision;
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
//### While
|
//### While
|
||||||
|
|
||||||
@@ -4407,7 +4507,7 @@
|
|||||||
|
|
||||||
return While;
|
return While;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Op
|
//### Op
|
||||||
|
|
||||||
@@ -4705,7 +4805,7 @@
|
|||||||
|
|
||||||
return Op;
|
return Op;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### In
|
//### In
|
||||||
exports.In = In = (function() {
|
exports.In = In = (function() {
|
||||||
@@ -4783,7 +4883,7 @@
|
|||||||
|
|
||||||
return In;
|
return In;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Try
|
//### Try
|
||||||
|
|
||||||
@@ -4836,7 +4936,7 @@
|
|||||||
|
|
||||||
return Try;
|
return Try;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Throw
|
//### Throw
|
||||||
|
|
||||||
@@ -4870,7 +4970,7 @@
|
|||||||
|
|
||||||
return Throw;
|
return Throw;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Existence
|
//### Existence
|
||||||
|
|
||||||
@@ -4930,7 +5030,7 @@
|
|||||||
|
|
||||||
return Existence;
|
return Existence;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Parens
|
//### Parens
|
||||||
|
|
||||||
@@ -4987,7 +5087,7 @@
|
|||||||
|
|
||||||
return Parens;
|
return Parens;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### StringWithInterpolations
|
//### StringWithInterpolations
|
||||||
exports.StringWithInterpolations = StringWithInterpolations = (function() {
|
exports.StringWithInterpolations = StringWithInterpolations = (function() {
|
||||||
@@ -5113,7 +5213,7 @@
|
|||||||
|
|
||||||
return StringWithInterpolations;
|
return StringWithInterpolations;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### For
|
//### For
|
||||||
|
|
||||||
@@ -5361,7 +5461,7 @@
|
|||||||
|
|
||||||
return For;
|
return For;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### Switch
|
//### Switch
|
||||||
|
|
||||||
@@ -5448,7 +5548,7 @@
|
|||||||
|
|
||||||
return Switch;
|
return Switch;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
//### If
|
//### If
|
||||||
|
|
||||||
@@ -5585,7 +5685,7 @@
|
|||||||
|
|
||||||
return If;
|
return If;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
// ---------
|
// ---------
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat,
|
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat,
|
||||||
slice = [].slice;
|
slice = [].slice;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, getRootModule, helpers, i, len, loadFile, path, ref;
|
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, getRootModule, helpers, i, len, loadFile, path, ref;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, runInContext, sawSIGINT, transpile, updateSyntaxError, vm;
|
var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, runInContext, sawSIGINT, transpile, updateSyntaxError, vm;
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
})(),
|
})(),
|
||||||
historyMaxInputSize: 10240,
|
historyMaxInputSize: 10240,
|
||||||
eval: function(input, context, filename, cb) {
|
eval: function(input, context, filename, cb) {
|
||||||
var Assign, Block, Call, Code, Literal, Value, ast, err, isAsync, js, referencedVars, result, token, tokens;
|
var Assign, Block, Call, Code, Literal, Value, ast, err, isAsync, js, ref, ref1, referencedVars, result, token, tokens;
|
||||||
// XXX: multiline hack.
|
// XXX: multiline hack.
|
||||||
input = input.replace(/\uFF00/g, '\n');
|
input = input.replace(/\uFF00/g, '\n');
|
||||||
// Node's REPL sends the input ending with a newline and then wrapped in
|
// Node's REPL sends the input ending with a newline and then wrapped in
|
||||||
@@ -43,6 +43,13 @@
|
|||||||
try {
|
try {
|
||||||
// Tokenize the clean input.
|
// Tokenize the clean input.
|
||||||
tokens = CoffeeScript.tokens(input);
|
tokens = CoffeeScript.tokens(input);
|
||||||
|
// Filter out tokens generated just to hold comments.
|
||||||
|
if (tokens.length >= 2 && tokens[0].generated && ((ref = tokens[0].comments) != null ? ref.length : void 0) !== 0 && tokens[0][1] === '' && tokens[1][0] === 'TERMINATOR') {
|
||||||
|
tokens = tokens.slice(2);
|
||||||
|
}
|
||||||
|
if (tokens.length >= 1 && tokens[tokens.length - 1].generated && ((ref1 = tokens[tokens.length - 1].comments) != null ? ref1.length : void 0) !== 0 && tokens[tokens.length - 1][1] === '') {
|
||||||
|
tokens.pop();
|
||||||
|
}
|
||||||
// Collect referenced variable names just like in `CoffeeScript.compile`.
|
// Collect referenced variable names just like in `CoffeeScript.compile`.
|
||||||
referencedVars = (function() {
|
referencedVars = (function() {
|
||||||
var i, len, results;
|
var i, len, results;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// The CoffeeScript language has a good deal of optional syntax, implicit syntax,
|
// The CoffeeScript language has a good deal of optional syntax, implicit syntax,
|
||||||
// and shorthand syntax. This can greatly complicate a grammar and bloat
|
// and shorthand syntax. This can greatly complicate a grammar and bloat
|
||||||
@@ -281,7 +281,7 @@
|
|||||||
stack = [];
|
stack = [];
|
||||||
start = null;
|
start = null;
|
||||||
return this.scanTokens(function(token, i, tokens) {
|
return this.scanTokens(function(token, i, tokens) {
|
||||||
var endImplicitCall, endImplicitObject, forward, implicitObjectContinues, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, isImplicit, isImplicitCall, isImplicitObject, k, newLine, nextTag, nextToken, offset, prevTag, prevToken, ref, ref1, s, sameLine, stackIdx, stackItem, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag;
|
var endImplicitCall, endImplicitObject, forward, implicitObjectContinues, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, isImplicit, isImplicitCall, isImplicitObject, k, newLine, nextTag, nextToken, offset, prevTag, prevToken, ref, ref1, ref2, s, sameLine, stackIdx, stackItem, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag;
|
||||||
[tag] = token;
|
[tag] = token;
|
||||||
[prevTag] = prevToken = i > 0 ? tokens[i - 1] : [];
|
[prevTag] = prevToken = i > 0 ? tokens[i - 1] : [];
|
||||||
[nextTag] = nextToken = i < tokens.length - 1 ? tokens[i + 1] : [];
|
[nextTag] = nextToken = i < tokens.length - 1 ? tokens[i + 1] : [];
|
||||||
@@ -539,7 +539,7 @@
|
|||||||
|
|
||||||
// f a, b: c, d: e, f, g: h: i, j
|
// f a, b: c, d: e, f, g: h: i, j
|
||||||
|
|
||||||
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
|
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && !((ref2 = this.tag(i + 2)) === 'FOROF' || ref2 === 'FORIN') && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
|
||||||
// When nextTag is OUTDENT the comma is insignificant and
|
// When nextTag is OUTDENT the comma is insignificant and
|
||||||
// should just be ignored so embed it in the implicit object.
|
// should just be ignored so embed it in the implicit object.
|
||||||
|
|
||||||
@@ -886,7 +886,7 @@
|
|||||||
|
|
||||||
return Rewriter;
|
return Rewriter;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
// ---------
|
// ---------
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// The **Scope** class regulates lexical scoping within CoffeeScript. As you
|
// The **Scope** class regulates lexical scoping within CoffeeScript. As you
|
||||||
// generate code, you create a tree of scopes in the same shape as the nested
|
// generate code, you create a tree of scopes in the same shape as the nested
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by CoffeeScript 2.0.2
|
// Generated by CoffeeScript 2.1.1
|
||||||
(function() {
|
(function() {
|
||||||
// Source maps allow JavaScript runtimes to match running JavaScript back to
|
// Source maps allow JavaScript runtimes to match running JavaScript back to
|
||||||
// the original source code that corresponds to it. This can be minified
|
// the original source code that corresponds to it. This can be minified
|
||||||
@@ -203,7 +203,7 @@
|
|||||||
|
|
||||||
return SourceMap;
|
return SourceMap;
|
||||||
|
|
||||||
})();
|
}).call(this);
|
||||||
|
|
||||||
// Our API for source maps is just the `SourceMap` class.
|
// Our API for source maps is just the `SourceMap` class.
|
||||||
module.exports = SourceMap;
|
module.exports = SourceMap;
|
||||||
|
|||||||
642
package-lock.json
generated
642
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
|||||||
"compiler"
|
"compiler"
|
||||||
],
|
],
|
||||||
"author": "Jeremy Ashkenas",
|
"author": "Jeremy Ashkenas",
|
||||||
"version": "2.0.2",
|
"version": "2.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
@@ -41,15 +41,15 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-core": "~6.26.0",
|
"babel-core": "~6.26.0",
|
||||||
"babel-preset-babili": "~0.1.4",
|
"babel-preset-babili": "~0.1.4",
|
||||||
"babel-preset-env": "~1.6.0",
|
"babel-preset-env": "~1.6.1",
|
||||||
"babel-preset-minify": "^0.2.0",
|
"babel-preset-minify": "^0.2.0",
|
||||||
"codemirror": "^5.29.0",
|
"codemirror": "^5.32.0",
|
||||||
"docco": "~0.7.0",
|
"docco": "~0.7.0",
|
||||||
"highlight.js": "~9.12.0",
|
"highlight.js": "~9.12.0",
|
||||||
"jison": ">=0.4.18",
|
"jison": ">=0.4.18",
|
||||||
"markdown-it": "~8.4.0",
|
"markdown-it": "~8.4.0",
|
||||||
"underscore": "~1.8.3",
|
"underscore": "~1.8.3",
|
||||||
"webpack": "~3.6.0"
|
"webpack": "~3.10.0"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,12 +140,14 @@ exports.compile = compile = withPrettyErrors (code, options = {}) ->
|
|||||||
transpiler = options.transpile.transpile
|
transpiler = options.transpile.transpile
|
||||||
delete options.transpile.transpile
|
delete options.transpile.transpile
|
||||||
|
|
||||||
|
transpilerOptions = Object.assign {}, options.transpile
|
||||||
|
|
||||||
# See https://github.com/babel/babel/issues/827#issuecomment-77573107:
|
# See https://github.com/babel/babel/issues/827#issuecomment-77573107:
|
||||||
# Babel can take a v3 source map object as input in `inputSourceMap`
|
# Babel can take a v3 source map object as input in `inputSourceMap`
|
||||||
# and it will return an *updated* v3 source map object in its output.
|
# and it will return an *updated* v3 source map object in its output.
|
||||||
if v3SourceMap and not options.transpile.inputSourceMap?
|
if v3SourceMap and not transpilerOptions.inputSourceMap?
|
||||||
options.transpile.inputSourceMap = v3SourceMap
|
transpilerOptions.inputSourceMap = v3SourceMap
|
||||||
transpilerOutput = transpiler js, options.transpile
|
transpilerOutput = transpiler js, transpilerOptions
|
||||||
js = transpilerOutput.code
|
js = transpilerOutput.code
|
||||||
if v3SourceMap and transpilerOutput.map
|
if v3SourceMap and transpilerOutput.map
|
||||||
v3SourceMap = transpilerOutput.map
|
v3SourceMap = transpilerOutput.map
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ mkdirp = (dir, fn) ->
|
|||||||
# If `generatedSourceMap` is provided, this will write a `.js.map` file into the
|
# If `generatedSourceMap` is provided, this will write a `.js.map` file into the
|
||||||
# same directory as the `.js` file.
|
# same directory as the `.js` file.
|
||||||
writeJs = (base, sourcePath, js, jsPath, generatedSourceMap = null) ->
|
writeJs = (base, sourcePath, js, jsPath, generatedSourceMap = null) ->
|
||||||
sourceMapPath = outputPath sourcePath, base, ".js.map"
|
sourceMapPath = "#{jsPath}.map"
|
||||||
jsDir = path.dirname jsPath
|
jsDir = path.dirname jsPath
|
||||||
compile = ->
|
compile = ->
|
||||||
if opts.compile
|
if opts.compile
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ grammar =
|
|||||||
o 'Identifier'
|
o 'Identifier'
|
||||||
o 'Property'
|
o 'Property'
|
||||||
o 'ThisProperty'
|
o 'ThisProperty'
|
||||||
|
o '[ Expression ]', -> new Value new ComputedPropertyName $2
|
||||||
]
|
]
|
||||||
|
|
||||||
ObjAssignable: [
|
ObjAssignable: [
|
||||||
@@ -439,6 +440,7 @@ grammar =
|
|||||||
o 'EXPORT Identifier = INDENT Expression OUTDENT', -> new ExportNamedDeclaration new Assign $2, $5, null,
|
o 'EXPORT Identifier = INDENT Expression OUTDENT', -> new ExportNamedDeclaration new Assign $2, $5, null,
|
||||||
moduleDeclaration: 'export'
|
moduleDeclaration: 'export'
|
||||||
o 'EXPORT DEFAULT Expression', -> new ExportDefaultDeclaration $3
|
o 'EXPORT DEFAULT Expression', -> new ExportDefaultDeclaration $3
|
||||||
|
o 'EXPORT DEFAULT INDENT Object OUTDENT', -> new ExportDefaultDeclaration new Value $4
|
||||||
o 'EXPORT EXPORT_ALL FROM String', -> new ExportAllDeclaration new Literal($2), $4
|
o 'EXPORT EXPORT_ALL FROM String', -> new ExportAllDeclaration new Literal($2), $4
|
||||||
o 'EXPORT { ExportSpecifierList OptComma } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7
|
o 'EXPORT { ExportSpecifierList OptComma } FROM String', -> new ExportNamedDeclaration new ExportSpecifierList($3), $7
|
||||||
]
|
]
|
||||||
@@ -492,7 +494,8 @@ grammar =
|
|||||||
# The array literal.
|
# The array literal.
|
||||||
Array: [
|
Array: [
|
||||||
o '[ ]', -> new Arr []
|
o '[ ]', -> new Arr []
|
||||||
o '[ ArgList OptComma ]', -> new Arr $2
|
o '[ Elisions ]', -> new Arr $2
|
||||||
|
o '[ ArgElisionList OptElisions ]', -> new Arr [].concat $2, $3
|
||||||
]
|
]
|
||||||
|
|
||||||
# Inclusive and exclusive range dots.
|
# Inclusive and exclusive range dots.
|
||||||
@@ -514,8 +517,7 @@ grammar =
|
|||||||
o 'RangeDots', -> new Range null, null, $1
|
o 'RangeDots', -> new Range null, null, $1
|
||||||
]
|
]
|
||||||
|
|
||||||
# The **ArgList** is both the list of objects passed into a function call,
|
# The **ArgList** is the list of objects passed into a function call
|
||||||
# as well as the contents of an array literal
|
|
||||||
# (i.e. comma-separated expressions). Newlines work as well.
|
# (i.e. comma-separated expressions). Newlines work as well.
|
||||||
ArgList: [
|
ArgList: [
|
||||||
o 'Arg', -> [$1]
|
o 'Arg', -> [$1]
|
||||||
@@ -532,6 +534,35 @@ grammar =
|
|||||||
o '...', -> new Expansion
|
o '...', -> new Expansion
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# The **ArgElisionList** is the list of objects, contents of an array literal
|
||||||
|
# (i.e. comma-separated expressions and elisions). Newlines work as well.
|
||||||
|
ArgElisionList: [
|
||||||
|
o 'ArgElision'
|
||||||
|
o 'ArgElisionList , ArgElision', -> $1.concat $3
|
||||||
|
o 'ArgElisionList OptElisions TERMINATOR ArgElision', -> $1.concat $2, $4
|
||||||
|
o 'INDENT ArgElisionList OptElisions OUTDENT', -> $2.concat $3
|
||||||
|
o 'ArgElisionList OptElisions INDENT ArgElisionList OptElisions OUTDENT', -> $1.concat $2, $4, $5
|
||||||
|
]
|
||||||
|
|
||||||
|
ArgElision: [
|
||||||
|
o 'Arg', -> [$1]
|
||||||
|
o 'Elisions Arg', -> $1.concat $2
|
||||||
|
]
|
||||||
|
|
||||||
|
OptElisions: [
|
||||||
|
o 'OptComma', -> []
|
||||||
|
o ', Elisions', -> [].concat $2
|
||||||
|
]
|
||||||
|
|
||||||
|
Elisions: [
|
||||||
|
o 'Elision', -> [$1]
|
||||||
|
o 'Elisions Elision', -> $1.concat $2
|
||||||
|
]
|
||||||
|
|
||||||
|
Elision: [
|
||||||
|
o ',', -> new Elision
|
||||||
|
]
|
||||||
|
|
||||||
# Just simple, comma-separated, required arguments (no fancy syntax). We need
|
# Just simple, comma-separated, required arguments (no fancy syntax). We need
|
||||||
# this to be separate from the **ArgList** for use in **Switch** blocks, where
|
# this to be separate from the **ArgList** for use in **Switch** blocks, where
|
||||||
# having the newlines wouldn't make sense.
|
# having the newlines wouldn't make sense.
|
||||||
|
|||||||
@@ -556,7 +556,7 @@ exports.Lexer = class Lexer
|
|||||||
# Check the previous token to detect if attribute is spread.
|
# Check the previous token to detect if attribute is spread.
|
||||||
prevChar = if @tokens.length > 0 then @tokens[@tokens.length - 1][0] else ''
|
prevChar = if @tokens.length > 0 then @tokens[@tokens.length - 1][0] else ''
|
||||||
if firstChar is '<'
|
if firstChar is '<'
|
||||||
match = CSX_IDENTIFIER.exec @chunk[1...]
|
match = CSX_IDENTIFIER.exec(@chunk[1...]) or CSX_FRAGMENT_IDENTIFIER.exec(@chunk[1...])
|
||||||
return 0 unless match and (
|
return 0 unless match and (
|
||||||
@csxDepth > 0 or
|
@csxDepth > 0 or
|
||||||
# Not the right hand side of an unspaced comparison (i.e. `a<b`).
|
# Not the right hand side of an unspaced comparison (i.e. `a<b`).
|
||||||
@@ -596,8 +596,8 @@ exports.Lexer = class Lexer
|
|||||||
@matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION
|
@matchWithInterpolations INSIDE_CSX, '>', '</', CSX_INTERPOLATION
|
||||||
@mergeInterpolationTokens tokens, {delimiter: '"'}, (value, i) =>
|
@mergeInterpolationTokens tokens, {delimiter: '"'}, (value, i) =>
|
||||||
@formatString value, delimiter: '>'
|
@formatString value, delimiter: '>'
|
||||||
match = CSX_IDENTIFIER.exec @chunk[end...]
|
match = CSX_IDENTIFIER.exec(@chunk[end...]) or CSX_FRAGMENT_IDENTIFIER.exec(@chunk[end...])
|
||||||
if not match or match[0] isnt csxTag.name
|
if not match or match[1] isnt csxTag.name
|
||||||
@error "expected corresponding CSX closing tag for #{csxTag.name}",
|
@error "expected corresponding CSX closing tag for #{csxTag.name}",
|
||||||
csxTag.origin[2]
|
csxTag.origin[2]
|
||||||
afterTag = end + csxTag.name.length
|
afterTag = end + csxTag.name.length
|
||||||
@@ -1178,6 +1178,11 @@ CSX_IDENTIFIER = /// ^
|
|||||||
( (?: (?!\s)[\.\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s and `.`s.
|
( (?: (?!\s)[\.\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s and `.`s.
|
||||||
///
|
///
|
||||||
|
|
||||||
|
# Fragment: <></>
|
||||||
|
CSX_FRAGMENT_IDENTIFIER = /// ^
|
||||||
|
()> # Ends immediately with `>`.
|
||||||
|
///
|
||||||
|
|
||||||
CSX_ATTRIBUTE = /// ^
|
CSX_ATTRIBUTE = /// ^
|
||||||
(?!\d)
|
(?!\d)
|
||||||
( (?: (?!\s)[\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s.
|
( (?: (?!\s)[\-$\w\x7f-\uffff] )+ ) # Like `IDENTIFIER`, but includes `-`s.
|
||||||
@@ -1252,7 +1257,20 @@ REGEX = /// ^
|
|||||||
REGEX_FLAGS = /^\w*/
|
REGEX_FLAGS = /^\w*/
|
||||||
VALID_FLAGS = /^(?!.*(.).*\1)[imguy]*$/
|
VALID_FLAGS = /^(?!.*(.).*\1)[imguy]*$/
|
||||||
|
|
||||||
HEREGEX = /// ^(?: [^\\/#] | \\[\s\S] | /(?!//) | \#(?!\{) )* ///
|
HEREGEX = /// ^
|
||||||
|
(?:
|
||||||
|
# Match any character, except those that need special handling below.
|
||||||
|
[^\\/#\s]
|
||||||
|
# Match `\` followed by any character.
|
||||||
|
| \\[\s\S]
|
||||||
|
# Match any `/` except `///`.
|
||||||
|
| /(?!//)
|
||||||
|
# Match `#` which is not part of interpolation, e.g. `#{}`.
|
||||||
|
| \#(?!\{)
|
||||||
|
# Comments consume everything until the end of the line, including `///`.
|
||||||
|
| \s+(?:#(?!\{).*)?
|
||||||
|
)*
|
||||||
|
///
|
||||||
|
|
||||||
HEREGEX_OMIT = ///
|
HEREGEX_OMIT = ///
|
||||||
((?:\\\\)+) # Consume (and preserve) an even number of backslashes.
|
((?:\\\\)+) # Consume (and preserve) an even number of backslashes.
|
||||||
@@ -1354,4 +1372,4 @@ INDENTABLE_CLOSERS = [')', '}', ']']
|
|||||||
# Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token
|
# Tokens that, when appearing at the end of a line, suppress a following TERMINATOR/INDENT token
|
||||||
UNFINISHED = ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
|
UNFINISHED = ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
|
||||||
'**', 'SHIFT', 'RELATION', 'COMPARE', '&', '^', '|', '&&', '||',
|
'**', 'SHIFT', 'RELATION', 'COMPARE', '&', '^', '|', '&&', '||',
|
||||||
'BIN?', 'EXTENDS', 'DEFAULT']
|
'BIN?', 'EXTENDS']
|
||||||
|
|||||||
@@ -765,6 +765,10 @@ exports.CSXTag = class CSXTag extends IdentifierLiteral
|
|||||||
exports.PropertyName = class PropertyName extends Literal
|
exports.PropertyName = class PropertyName extends Literal
|
||||||
isAssignable: YES
|
isAssignable: YES
|
||||||
|
|
||||||
|
exports.ComputedPropertyName = class ComputedPropertyName extends PropertyName
|
||||||
|
compileNode: (o) ->
|
||||||
|
[@makeCode('['), @value.compileToFragments(o, LEVEL_LIST)..., @makeCode(']')]
|
||||||
|
|
||||||
exports.StatementLiteral = class StatementLiteral extends Literal
|
exports.StatementLiteral = class StatementLiteral extends Literal
|
||||||
isStatement: YES
|
isStatement: YES
|
||||||
|
|
||||||
@@ -910,6 +914,10 @@ exports.Value = class Value extends Base
|
|||||||
return no if @properties.length
|
return no if @properties.length
|
||||||
(@base instanceof Obj) and (not onlyGenerated or @base.generated)
|
(@base instanceof Obj) and (not onlyGenerated or @base.generated)
|
||||||
|
|
||||||
|
isElision: ->
|
||||||
|
return no unless @base instanceof Arr
|
||||||
|
@base.hasElision()
|
||||||
|
|
||||||
isSplice: ->
|
isSplice: ->
|
||||||
[..., lastProp] = @properties
|
[..., lastProp] = @properties
|
||||||
lastProp instanceof Slice
|
lastProp instanceof Slice
|
||||||
@@ -1497,6 +1505,15 @@ exports.Obj = class Obj extends Base
|
|||||||
[key, value] = prop.base.cache o
|
[key, value] = prop.base.cache o
|
||||||
key = new PropertyName key.value if key instanceof IdentifierLiteral
|
key = new PropertyName key.value if key instanceof IdentifierLiteral
|
||||||
prop = new Assign key, value, 'object'
|
prop = new Assign key, value, 'object'
|
||||||
|
else if key instanceof Value and key.base instanceof ComputedPropertyName
|
||||||
|
# `{ [foo()] }` output as `{ [ref = foo()]: ref }`.
|
||||||
|
if prop.base.value.shouldCache()
|
||||||
|
[key, value] = prop.base.value.cache o
|
||||||
|
key = new ComputedPropertyName key.value if key instanceof IdentifierLiteral
|
||||||
|
prop = new Assign key, value, 'object'
|
||||||
|
else
|
||||||
|
# `{ [expression] }` output as `{ [expression]: expression }`.
|
||||||
|
prop = new Assign key, prop.base.value, 'object'
|
||||||
else if not prop.bareLiteral?(IdentifierLiteral)
|
else if not prop.bareLiteral?(IdentifierLiteral)
|
||||||
prop = new Assign prop, prop, 'object'
|
prop = new Assign prop, prop, 'object'
|
||||||
if indent then answer.push @makeCode indent
|
if indent then answer.push @makeCode indent
|
||||||
@@ -1561,6 +1578,10 @@ exports.Arr = class Arr extends Base
|
|||||||
|
|
||||||
children: ['objects']
|
children: ['objects']
|
||||||
|
|
||||||
|
hasElision: ->
|
||||||
|
return yes for obj in @objects when obj instanceof Elision
|
||||||
|
no
|
||||||
|
|
||||||
isAssignable: ->
|
isAssignable: ->
|
||||||
return no unless @objects.length
|
return no unless @objects.length
|
||||||
|
|
||||||
@@ -1575,6 +1596,9 @@ exports.Arr = class Arr extends Base
|
|||||||
compileNode: (o) ->
|
compileNode: (o) ->
|
||||||
return [@makeCode '[]'] unless @objects.length
|
return [@makeCode '[]'] unless @objects.length
|
||||||
o.indent += TAB
|
o.indent += TAB
|
||||||
|
fragmentIsElision = (fragment) -> fragmentsToText(fragment).trim() is ','
|
||||||
|
# Detect if `Elisions` at the beginning of the array are processed (e.g. [, , , a]).
|
||||||
|
passedElision = no
|
||||||
|
|
||||||
answer = []
|
answer = []
|
||||||
for obj, objIndex in @objects
|
for obj, objIndex in @objects
|
||||||
@@ -1590,6 +1614,7 @@ exports.Arr = class Arr extends Base
|
|||||||
unwrappedObj.lhs = yes if unwrappedObj instanceof Arr or unwrappedObj instanceof Obj
|
unwrappedObj.lhs = yes if unwrappedObj instanceof Arr or unwrappedObj instanceof Obj
|
||||||
|
|
||||||
compiledObjs = (obj.compileToFragments o, LEVEL_LIST for obj in @objects)
|
compiledObjs = (obj.compileToFragments o, LEVEL_LIST for obj in @objects)
|
||||||
|
olen = compiledObjs.length
|
||||||
# If `compiledObjs` includes newlines, we will output this as a multiline
|
# If `compiledObjs` includes newlines, we will output this as a multiline
|
||||||
# array (i.e. with a newline and indentation after the `[`). If an element
|
# array (i.e. with a newline and indentation after the `[`). If an element
|
||||||
# contains line comments, that should also trigger multiline output since
|
# contains line comments, that should also trigger multiline output since
|
||||||
@@ -1604,14 +1629,17 @@ exports.Arr = class Arr extends Base
|
|||||||
fragment.code = fragment.code.trim()
|
fragment.code = fragment.code.trim()
|
||||||
else if index isnt 0 and includesLineCommentsOnNonFirstElement is no and hasLineComments fragment
|
else if index isnt 0 and includesLineCommentsOnNonFirstElement is no and hasLineComments fragment
|
||||||
includesLineCommentsOnNonFirstElement = yes
|
includesLineCommentsOnNonFirstElement = yes
|
||||||
if index isnt 0
|
# Add ', ' if all `Elisions` from the beginning of the array are processed (e.g. [, , , a]) and
|
||||||
|
# element isn't `Elision` or last element is `Elision` (e.g. [a,,b,,])
|
||||||
|
if index isnt 0 and passedElision and (not fragmentIsElision(fragments) or index is olen - 1)
|
||||||
answer.push @makeCode ', '
|
answer.push @makeCode ', '
|
||||||
|
passedElision = passedElision or not fragmentIsElision fragments
|
||||||
answer.push fragments...
|
answer.push fragments...
|
||||||
if includesLineCommentsOnNonFirstElement or '\n' in fragmentsToText(answer)
|
if includesLineCommentsOnNonFirstElement or '\n' in fragmentsToText(answer)
|
||||||
for fragment, fragmentIndex in answer
|
for fragment, fragmentIndex in answer
|
||||||
if fragment.isHereComment
|
if fragment.isHereComment
|
||||||
fragment.code = "#{multident(fragment.code, o.indent, no)}\n#{o.indent}"
|
fragment.code = "#{multident(fragment.code, o.indent, no)}\n#{o.indent}"
|
||||||
else if fragment.code is ', '
|
else if fragment.code is ', ' and not fragment?.isElision
|
||||||
fragment.code = ",\n#{o.indent}"
|
fragment.code = ",\n#{o.indent}"
|
||||||
answer.unshift @makeCode "[\n#{o.indent}"
|
answer.unshift @makeCode "[\n#{o.indent}"
|
||||||
answer.push @makeCode "\n#{@tab}]"
|
answer.push @makeCode "\n#{@tab}]"
|
||||||
@@ -1843,20 +1871,20 @@ exports.ExecutableClassBody = class ExecutableClassBody extends Base
|
|||||||
if argumentsNode = @body.contains isLiteralArguments
|
if argumentsNode = @body.contains isLiteralArguments
|
||||||
argumentsNode.error "Class bodies shouldn't reference arguments"
|
argumentsNode.error "Class bodies shouldn't reference arguments"
|
||||||
|
|
||||||
@name = @class.name ? @defaultClassVariableName
|
|
||||||
directives = @walkBody()
|
|
||||||
@setContext()
|
|
||||||
|
|
||||||
ident = new IdentifierLiteral @name
|
|
||||||
params = []
|
params = []
|
||||||
args = []
|
args = [new ThisLiteral]
|
||||||
wrapper = new Code params, @body
|
wrapper = new Code params, @body
|
||||||
klass = new Parens new Call wrapper, args
|
klass = new Parens new Call (new Value wrapper, [new Access new PropertyName 'call']), args
|
||||||
|
|
||||||
@body.spaced = true
|
@body.spaced = true
|
||||||
|
|
||||||
o.classScope = wrapper.makeScope o.scope
|
o.classScope = wrapper.makeScope o.scope
|
||||||
|
|
||||||
|
@name = @class.name ? o.classScope.freeVariable @defaultClassVariableName
|
||||||
|
ident = new IdentifierLiteral @name
|
||||||
|
directives = @walkBody()
|
||||||
|
@setContext()
|
||||||
|
|
||||||
if @class.hasNameClash
|
if @class.hasNameClash
|
||||||
parent = new IdentifierLiteral o.classScope.freeVariable 'superClass'
|
parent = new IdentifierLiteral o.classScope.freeVariable 'superClass'
|
||||||
wrapper.params.push new Param parent
|
wrapper.params.push new Param parent
|
||||||
@@ -2141,10 +2169,11 @@ exports.Assign = class Assign extends Base
|
|||||||
# know that, so that those nodes know that they’re assignable as
|
# know that, so that those nodes know that they’re assignable as
|
||||||
# destructured variables.
|
# destructured variables.
|
||||||
@variable.base.lhs = yes
|
@variable.base.lhs = yes
|
||||||
return @compileDestructuring o unless @variable.isAssignable()
|
# Check if @variable contains Obj with splats.
|
||||||
|
hasSplat = @variable.contains (node) -> node instanceof Obj and node.hasSplat()
|
||||||
|
return @compileDestructuring o if not @variable.isAssignable() or @variable.isArray() and hasSplat
|
||||||
# Object destructuring. Can be removed once ES proposal hits Stage 4.
|
# Object destructuring. Can be removed once ES proposal hits Stage 4.
|
||||||
objDestructAnswer = @compileObjectDestruct(o) if @variable.isObject() and @variable.contains (node) ->
|
objDestructAnswer = @compileObjectDestruct(o) if @variable.isObject() and hasSplat
|
||||||
node instanceof Obj and node.hasSplat()
|
|
||||||
return objDestructAnswer if objDestructAnswer
|
return objDestructAnswer if objDestructAnswer
|
||||||
|
|
||||||
return @compileSplice o if @variable.isSplice()
|
return @compileSplice o if @variable.isSplice()
|
||||||
@@ -2209,7 +2238,9 @@ exports.Assign = class Assign extends Base
|
|||||||
answer = compiledName.concat @makeCode(" #{ @context or '=' } "), val
|
answer = compiledName.concat @makeCode(" #{ @context or '=' } "), val
|
||||||
# Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration,
|
# Per https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration,
|
||||||
# if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
|
# if we’re destructuring without declaring, the destructuring assignment must be wrapped in parentheses.
|
||||||
if o.level > LEVEL_LIST or o.level is LEVEL_TOP and isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes)
|
# The assignment is wrapped in parentheses if 'o.level' has lower precedence than LEVEL_LIST (3)
|
||||||
|
# (i.e. LEVEL_COND (4), LEVEL_OP (5) or LEVEL_ACCESS (6)), or if we're destructuring object, e.g. {a,b} = obj.
|
||||||
|
if o.level > LEVEL_LIST or isValue and @variable.base instanceof Obj and not @nestedLhs and not (@param is yes)
|
||||||
@wrapInParentheses answer
|
@wrapInParentheses answer
|
||||||
else
|
else
|
||||||
answer
|
answer
|
||||||
@@ -2438,7 +2469,11 @@ exports.Assign = class Assign extends Base
|
|||||||
if name?
|
if name?
|
||||||
message = isUnassignable name
|
message = isUnassignable name
|
||||||
obj.error message if message
|
obj.error message if message
|
||||||
assigns.push new Assign(obj, val, null, param: @param, subpattern: yes).compileToFragments o, LEVEL_LIST
|
unless obj instanceof Elision
|
||||||
|
assigns.push new Assign(obj, val, null, param: @param, subpattern: yes).compileToFragments o, LEVEL_LIST
|
||||||
|
else
|
||||||
|
# Output `Elision` only if `idx` is `i++`, e.g. expandedIdx.
|
||||||
|
assigns.push idx.compileToFragments o, LEVEL_LIST if expandedIdx
|
||||||
|
|
||||||
assigns.push vvar unless top or @subpattern
|
assigns.push vvar unless top or @subpattern
|
||||||
fragments = @joinFragmentArrays assigns, ', '
|
fragments = @joinFragmentArrays assigns, ', '
|
||||||
@@ -2697,6 +2732,12 @@ exports.Code = class Code extends Base
|
|||||||
@body.expressions.unshift new Call(boundMethodCheck, [new Value(new ThisLiteral), @classVariable])
|
@body.expressions.unshift new Call(boundMethodCheck, [new Value(new ThisLiteral), @classVariable])
|
||||||
@body.makeReturn() unless wasEmpty or @noReturn
|
@body.makeReturn() unless wasEmpty or @noReturn
|
||||||
|
|
||||||
|
# JavaScript doesn’t allow bound (`=>`) functions to also be generators.
|
||||||
|
# This is usually caught via `Op::compileContinuation`, but double-check:
|
||||||
|
if @bound and @isGenerator
|
||||||
|
yieldNode = @body.contains (node) -> node instanceof Op and node.operator is 'yield'
|
||||||
|
(yieldNode or @).error 'yield cannot occur inside bound (fat arrow) functions'
|
||||||
|
|
||||||
# Assemble the output
|
# Assemble the output
|
||||||
modifiers = []
|
modifiers = []
|
||||||
modifiers.push 'static' if @isMethod and @isStatic
|
modifiers.push 'static' if @isMethod and @isStatic
|
||||||
@@ -2882,6 +2923,8 @@ exports.Param = class Param extends Base
|
|||||||
atParam obj
|
atParam obj
|
||||||
# * simple destructured parameters {foo}
|
# * simple destructured parameters {foo}
|
||||||
else iterator obj.base.value, obj.base, @
|
else iterator obj.base.value, obj.base, @
|
||||||
|
else if obj instanceof Elision
|
||||||
|
obj
|
||||||
else if obj not instanceof Expansion
|
else if obj not instanceof Expansion
|
||||||
obj.error "illegal parameter #{obj.compile()}"
|
obj.error "illegal parameter #{obj.compile()}"
|
||||||
return
|
return
|
||||||
@@ -2938,6 +2981,28 @@ exports.Expansion = class Expansion extends Base
|
|||||||
|
|
||||||
eachName: (iterator) ->
|
eachName: (iterator) ->
|
||||||
|
|
||||||
|
#### Elision
|
||||||
|
|
||||||
|
# Array elision element (for example, [,a, , , b, , c, ,]).
|
||||||
|
exports.Elision = class Elision extends Base
|
||||||
|
|
||||||
|
isAssignable: YES
|
||||||
|
|
||||||
|
shouldCache: NO
|
||||||
|
|
||||||
|
compileToFragments: (o, level) ->
|
||||||
|
fragment = super o, level
|
||||||
|
fragment.isElision = yes
|
||||||
|
fragment
|
||||||
|
|
||||||
|
compileNode: (o) ->
|
||||||
|
[@makeCode ', ']
|
||||||
|
|
||||||
|
asReference: (o) ->
|
||||||
|
this
|
||||||
|
|
||||||
|
eachName: (iterator) ->
|
||||||
|
|
||||||
#### While
|
#### While
|
||||||
|
|
||||||
# A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
# A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
||||||
|
|||||||
@@ -30,6 +30,14 @@ replDefaults =
|
|||||||
try
|
try
|
||||||
# Tokenize the clean input.
|
# Tokenize the clean input.
|
||||||
tokens = CoffeeScript.tokens input
|
tokens = CoffeeScript.tokens input
|
||||||
|
# Filter out tokens generated just to hold comments.
|
||||||
|
if tokens.length >= 2 and tokens[0].generated and
|
||||||
|
tokens[0].comments?.length isnt 0 and tokens[0][1] is '' and
|
||||||
|
tokens[1][0] is 'TERMINATOR'
|
||||||
|
tokens = tokens[2...]
|
||||||
|
if tokens.length >= 1 and tokens[tokens.length - 1].generated and
|
||||||
|
tokens[tokens.length - 1].comments?.length isnt 0 and tokens[tokens.length - 1][1] is ''
|
||||||
|
tokens.pop()
|
||||||
# Collect referenced variable names just like in `CoffeeScript.compile`.
|
# Collect referenced variable names just like in `CoffeeScript.compile`.
|
||||||
referencedVars = (token[1] for token in tokens when token[0] is 'IDENTIFIER')
|
referencedVars = (token[1] for token in tokens when token[0] is 'IDENTIFIER')
|
||||||
# Generate the AST of the tokens.
|
# Generate the AST of the tokens.
|
||||||
|
|||||||
@@ -377,7 +377,7 @@ exports.Rewriter = class Rewriter
|
|||||||
#
|
#
|
||||||
# f a, b: c, d: e, f, g: h: i, j
|
# f a, b: c, d: e, f, g: h: i, j
|
||||||
#
|
#
|
||||||
if tag is ',' and not @looksObjectish(i + 1) and inImplicitObject() and
|
if tag is ',' and not @looksObjectish(i + 1) and inImplicitObject() and not (@tag(i + 2) in ['FOROF', 'FORIN']) and
|
||||||
(nextTag isnt 'TERMINATOR' or not @looksObjectish(i + 2))
|
(nextTag isnt 'TERMINATOR' or not @looksObjectish(i + 2))
|
||||||
# When nextTag is OUTDENT the comma is insignificant and
|
# When nextTag is OUTDENT the comma is insignificant and
|
||||||
# should just be ignored so embed it in the implicit object.
|
# should just be ignored so embed it in the implicit object.
|
||||||
|
|||||||
@@ -26,6 +26,94 @@ test "incorrect indentation without commas", ->
|
|||||||
ok result[0][0] is 'a'
|
ok result[0][0] is 'a'
|
||||||
ok result[1]['b'] is 'c'
|
ok result[1]['b'] is 'c'
|
||||||
|
|
||||||
|
# Elisions
|
||||||
|
test "array elisions", ->
|
||||||
|
eq [,1].length, 2
|
||||||
|
eq [,,1,2,,].length, 5
|
||||||
|
arr = [1,,2]
|
||||||
|
eq arr.length, 3
|
||||||
|
eq arr[1], undefined
|
||||||
|
eq [,,].length, 2
|
||||||
|
|
||||||
|
test "array elisions indentation and commas", ->
|
||||||
|
arr1 = [
|
||||||
|
, 1, 2, , , 3,
|
||||||
|
4, 5, 6
|
||||||
|
, , 8, 9,
|
||||||
|
]
|
||||||
|
eq arr1.length, 12
|
||||||
|
eq arr1[5], 3
|
||||||
|
eq arr1[9], undefined
|
||||||
|
arr2 = [, , 1,
|
||||||
|
2, , 3,
|
||||||
|
, 4, 5
|
||||||
|
6
|
||||||
|
, , ,
|
||||||
|
]
|
||||||
|
eq arr2.length, 12
|
||||||
|
eq arr2[8], 5
|
||||||
|
eq arr2[1], undefined
|
||||||
|
|
||||||
|
test "array elisions destructuring", ->
|
||||||
|
arr = [1,2,3,4,5,6,7,8,9]
|
||||||
|
[,a] = arr
|
||||||
|
[,,,b] = arr
|
||||||
|
arrayEq [a,b], [2,4]
|
||||||
|
[,a,,b,,c,,,d] = arr
|
||||||
|
arrayEq [a,b,c,d], [2,4,6,9]
|
||||||
|
[
|
||||||
|
,e,
|
||||||
|
,f,
|
||||||
|
,g,
|
||||||
|
,,h] = arr
|
||||||
|
arrayEq [e,f,g,h], [2,4,6,9]
|
||||||
|
|
||||||
|
test "array elisions destructuring with splats and expansions", ->
|
||||||
|
arr = [1,2,3,4,5,6,7,8,9]
|
||||||
|
[,a,,,b...] = arr
|
||||||
|
arrayEq [a,b], [2,[5,6,7,8,9]]
|
||||||
|
[,c,...,,d,,e] = arr
|
||||||
|
arrayEq [c,d,e], [2,7,9]
|
||||||
|
[...,f,,,g,,,] = arr
|
||||||
|
arrayEq [f,g], [4,7]
|
||||||
|
|
||||||
|
test "array elisions as function parameters", ->
|
||||||
|
arr = [1,2,3,4,5,6,7,8,9]
|
||||||
|
foo = ([,a]) -> a
|
||||||
|
a = foo arr
|
||||||
|
eq a, 2
|
||||||
|
foo = ([,,,a]) -> a
|
||||||
|
a = foo arr
|
||||||
|
eq a, 4
|
||||||
|
foo = ([,a,,b,,c,,,d]) -> [a,b,c,d]
|
||||||
|
[a,b,c,d] = foo arr
|
||||||
|
arrayEq [a,b,c,d], [2,4,6,9]
|
||||||
|
|
||||||
|
test "array elisions nested destructuring", ->
|
||||||
|
arr = [
|
||||||
|
1,
|
||||||
|
[2,3, [4,5,6, [7,8,9] ] ]
|
||||||
|
]
|
||||||
|
[,a] = arr
|
||||||
|
arrayEq a[2][3], [7,8,9]
|
||||||
|
[,[,,[,b,,[,,c]]]] = arr
|
||||||
|
eq b, 5
|
||||||
|
eq c, 9
|
||||||
|
aobj = [
|
||||||
|
{},
|
||||||
|
{x: 2},
|
||||||
|
{},
|
||||||
|
[
|
||||||
|
{},
|
||||||
|
{},
|
||||||
|
{z:1, w:[1,2,4], p:3, q:4}
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[,d,,[,,{w}]] = aobj
|
||||||
|
deepEqual d, {x:2}
|
||||||
|
arrayEq w, [1,2,4]
|
||||||
|
|
||||||
# Splats in Array Literals
|
# Splats in Array Literals
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,24 @@ test "#713: destructuring assignment should return right-hand-side value", ->
|
|||||||
eq nonceB, b
|
eq nonceB, b
|
||||||
eq nonceB, d
|
eq nonceB, d
|
||||||
|
|
||||||
|
test "#4787 destructuring of objects within arrays", ->
|
||||||
|
arr = [1, {a:1, b:2}]
|
||||||
|
[...,{a, b}] = arr
|
||||||
|
eq a, 1
|
||||||
|
eq b, arr[1].b
|
||||||
|
deepEqual {a, b}, arr[1]
|
||||||
|
|
||||||
|
test "#4798 destructuring of objects with splat within arrays", ->
|
||||||
|
arr = [1, {a:1, b:2}]
|
||||||
|
[...,{a, r...}] = arr
|
||||||
|
eq a, 1
|
||||||
|
deepEqual r, {b:2}
|
||||||
|
[b, {q...}] = arr
|
||||||
|
eq b, 1
|
||||||
|
deepEqual q, arr[1]
|
||||||
|
eq q.b, r.b
|
||||||
|
eq q.a, a
|
||||||
|
|
||||||
test "destructuring assignment with splats", ->
|
test "destructuring assignment with splats", ->
|
||||||
a = {}; b = {}; c = {}; d = {}; e = {}
|
a = {}; b = {}; c = {}; d = {}; e = {}
|
||||||
[x,y...,z] = [a,b,c,d,e]
|
[x,y...,z] = [a,b,c,d,e]
|
||||||
|
|||||||
@@ -1857,3 +1857,20 @@ test "#4724: backticked expression in a class body with hoisted member", ->
|
|||||||
a = new A
|
a = new A
|
||||||
eq 42, a.x
|
eq 42, a.x
|
||||||
eq 84, a.hoisted
|
eq 84, a.hoisted
|
||||||
|
|
||||||
|
test "#4822: nested anonymous classes use non-conflicting variable names", ->
|
||||||
|
Class = class
|
||||||
|
@a: class
|
||||||
|
@b: 1
|
||||||
|
|
||||||
|
eq Class.a.b, 1
|
||||||
|
|
||||||
|
test "#4827: executable class body wrappers have correct context", ->
|
||||||
|
test = ->
|
||||||
|
class @A
|
||||||
|
class @B extends @A
|
||||||
|
@property = 1
|
||||||
|
|
||||||
|
o = {}
|
||||||
|
test.call o
|
||||||
|
ok typeof o.A is typeof o.B is 'function'
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ test "#3132: Place block-comments nicely", ->
|
|||||||
|
|
||||||
return DummyClass;
|
return DummyClass;
|
||||||
|
|
||||||
})();"""
|
}).call(this);"""
|
||||||
|
|
||||||
test "#3638: Demand a whitespace after # symbol", ->
|
test "#3638: Demand a whitespace after # symbol", ->
|
||||||
eqJS """
|
eqJS """
|
||||||
|
|||||||
@@ -742,3 +742,47 @@ test '#4686: comments inside interpolations that also contain CSX attributes', -
|
|||||||
</div>;
|
</div>;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
|
||||||
|
test 'JSX fragments: empty fragment', ->
|
||||||
|
eqJS '''
|
||||||
|
<></>
|
||||||
|
''', '''
|
||||||
|
<></>;
|
||||||
|
'''
|
||||||
|
|
||||||
|
test 'JSX fragments: fragment with text nodes', ->
|
||||||
|
eqJS '''
|
||||||
|
<>
|
||||||
|
Some text.
|
||||||
|
<h2>A heading</h2>
|
||||||
|
More text.
|
||||||
|
<h2>Another heading</h2>
|
||||||
|
Even more text.
|
||||||
|
</>
|
||||||
|
''', '''
|
||||||
|
<>
|
||||||
|
Some text.
|
||||||
|
<h2>A heading</h2>
|
||||||
|
More text.
|
||||||
|
<h2>Another heading</h2>
|
||||||
|
Even more text.
|
||||||
|
</>;
|
||||||
|
'''
|
||||||
|
|
||||||
|
test 'JSX fragments: fragment with component nodes', ->
|
||||||
|
eqJS '''
|
||||||
|
Component = (props) =>
|
||||||
|
<Fragment>
|
||||||
|
<OtherComponent />
|
||||||
|
<OtherComponent />
|
||||||
|
</Fragment>
|
||||||
|
''', '''
|
||||||
|
var Component;
|
||||||
|
|
||||||
|
Component = (props) => {
|
||||||
|
return <Fragment>
|
||||||
|
<OtherComponent />
|
||||||
|
<OtherComponent />
|
||||||
|
</Fragment>;
|
||||||
|
};
|
||||||
|
'''
|
||||||
|
|||||||
@@ -183,9 +183,9 @@ test "#1096: unexpected generated tokens", ->
|
|||||||
for i in [1]:
|
for i in [1]:
|
||||||
1
|
1
|
||||||
''', '''
|
''', '''
|
||||||
[stdin]:1:10: error: unexpected [
|
[stdin]:2:4: error: unexpected end of input
|
||||||
for i in [1]:
|
1
|
||||||
^
|
^
|
||||||
'''
|
'''
|
||||||
# Unexpected regex
|
# Unexpected regex
|
||||||
assertErrorFormat '{/a/i: val}', '''
|
assertErrorFormat '{/a/i: val}', '''
|
||||||
@@ -808,29 +808,8 @@ test "invalid numbers", ->
|
|||||||
^^^
|
^^^
|
||||||
'''
|
'''
|
||||||
|
|
||||||
test "unexpected object keys", ->
|
|
||||||
assertErrorFormat '''
|
|
||||||
{[[]]}
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:2: error: unexpected [
|
|
||||||
{[[]]}
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
assertErrorFormat '''
|
|
||||||
{[[]]: 1}
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:2: error: unexpected [
|
|
||||||
{[[]]: 1}
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
assertErrorFormat '''
|
|
||||||
[[]]: 1
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:1: error: unexpected [
|
|
||||||
[[]]: 1
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
test "unexpected object keys", ->
|
||||||
assertErrorFormat '''
|
assertErrorFormat '''
|
||||||
{(a + "b")}
|
{(a + "b")}
|
||||||
''', '''
|
''', '''
|
||||||
@@ -852,20 +831,6 @@ test "unexpected object keys", ->
|
|||||||
(a + "b"): 1
|
(a + "b"): 1
|
||||||
^
|
^
|
||||||
'''
|
'''
|
||||||
assertErrorFormat '''
|
|
||||||
a: 1, [[]]: 2
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:7: error: unexpected [
|
|
||||||
a: 1, [[]]: 2
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
assertErrorFormat '''
|
|
||||||
{a: 1, [[]]: 2}
|
|
||||||
''', '''
|
|
||||||
[stdin]:1:8: error: unexpected [
|
|
||||||
{a: 1, [[]]: 2}
|
|
||||||
^
|
|
||||||
'''
|
|
||||||
|
|
||||||
test "invalid object keys", ->
|
test "invalid object keys", ->
|
||||||
assertErrorFormat '''
|
assertErrorFormat '''
|
||||||
@@ -1197,6 +1162,18 @@ test "bound functions cannot be generators", ->
|
|||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
test "#4790: bound functions cannot be generators, even when we’re creating IIFEs", ->
|
||||||
|
assertErrorFormat '''
|
||||||
|
=>
|
||||||
|
for x in []
|
||||||
|
for y in []
|
||||||
|
yield z
|
||||||
|
''', '''
|
||||||
|
[stdin]:4:7: error: yield cannot occur inside bound (fat arrow) functions
|
||||||
|
yield z
|
||||||
|
^^^^^^^
|
||||||
|
'''
|
||||||
|
|
||||||
test "CoffeeScript keywords cannot be used as unaliased names in import lists", ->
|
test "CoffeeScript keywords cannot be used as unaliased names in import lists", ->
|
||||||
assertErrorFormat """
|
assertErrorFormat """
|
||||||
import { unless, baz as bar } from 'lib'
|
import { unless, baz as bar } from 'lib'
|
||||||
@@ -1791,3 +1768,12 @@ test "#3098: suppressed newline should be unsuppressed by semicolon", ->
|
|||||||
a = ; 5
|
a = ; 5
|
||||||
^
|
^
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
test "#4811: '///' inside a heregex comment does not close the heregex", ->
|
||||||
|
assertErrorFormat '''
|
||||||
|
/// .* # comment ///
|
||||||
|
''', '''
|
||||||
|
[stdin]:1:1: error: missing ///
|
||||||
|
/// .* # comment ///
|
||||||
|
^^^
|
||||||
|
'''
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ path = require 'path'
|
|||||||
# Get the folder containing the compiled `coffee` executable and make it the
|
# Get the folder containing the compiled `coffee` executable and make it the
|
||||||
# PATH so that `#!/usr/bin/env coffee` resolves to our locally built file.
|
# PATH so that `#!/usr/bin/env coffee` resolves to our locally built file.
|
||||||
coffeeBinFolder = path.dirname require.resolve '../bin/coffee'
|
coffeeBinFolder = path.dirname require.resolve '../bin/coffee'
|
||||||
|
# For some reason, Windows requires `coffee` to be executed as `node coffee`.
|
||||||
|
coffeeCommand = if isWindows() then 'node coffee' else 'coffee'
|
||||||
spawnOptions =
|
spawnOptions =
|
||||||
cwd: coffeeBinFolder
|
cwd: coffeeBinFolder
|
||||||
encoding: 'utf8'
|
encoding: 'utf8'
|
||||||
@@ -18,7 +20,7 @@ initialSpaceScript = require.resolve './importing/shebang_initial_space.coffee'
|
|||||||
extraArgsScript = require.resolve './importing/shebang_extra_args.coffee'
|
extraArgsScript = require.resolve './importing/shebang_extra_args.coffee'
|
||||||
initialSpaceExtraArgsScript = require.resolve './importing/shebang_initial_space_extra_args.coffee'
|
initialSpaceExtraArgsScript = require.resolve './importing/shebang_initial_space_extra_args.coffee'
|
||||||
|
|
||||||
test "parse arguments for shebang scripts correctly (on unix platforms)", ->
|
test "parse arguments for shebang scripts correctly (on *nix platforms)", ->
|
||||||
return if isWindows()
|
return if isWindows()
|
||||||
|
|
||||||
stdout = execFileSync shebangScript, ['-abck'], spawnOptions
|
stdout = execFileSync shebangScript, ['-abck'], spawnOptions
|
||||||
@@ -32,7 +34,7 @@ test "parse arguments for shebang scripts correctly (on unix platforms)", ->
|
|||||||
arrayEq expectedArgs, realArgs
|
arrayEq expectedArgs, realArgs
|
||||||
|
|
||||||
test "warn and remove -- if it is the second positional argument", ->
|
test "warn and remove -- if it is the second positional argument", ->
|
||||||
result = spawnSync 'coffee', [shebangScript, '--'], spawnOptions
|
result = spawnSync coffeeCommand, [shebangScript, '--'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
||||||
ok stderr.match /^coffee was invoked with '--'/m
|
ok stderr.match /^coffee was invoked with '--'/m
|
||||||
@@ -40,7 +42,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
arrayEq JSON.parse(posArgs), [shebangScript, '--']
|
arrayEq JSON.parse(posArgs), [shebangScript, '--']
|
||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync 'coffee', ['-b', shebangScript, '--'], spawnOptions
|
result = spawnSync coffeeCommand, ['-b', shebangScript, '--'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
|
||||||
ok stderr.match /^coffee was invoked with '--'/m
|
ok stderr.match /^coffee was invoked with '--'/m
|
||||||
@@ -49,7 +51,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', ['-b', shebangScript, '--', 'ANOTHER'], spawnOptions)
|
coffeeCommand, ['-b', shebangScript, '--', 'ANOTHER'], spawnOptions)
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript, 'ANOTHER']
|
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript, 'ANOTHER']
|
||||||
ok stderr.match /^coffee was invoked with '--'/m
|
ok stderr.match /^coffee was invoked with '--'/m
|
||||||
@@ -58,7 +60,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', ['--', initialSpaceScript, 'arg'], spawnOptions)
|
coffeeCommand, ['--', initialSpaceScript, 'arg'], spawnOptions)
|
||||||
expectedArgs = ['coffee', initialSpaceScript, 'arg']
|
expectedArgs = ['coffee', initialSpaceScript, 'arg']
|
||||||
realArgs = JSON.parse result.stdout
|
realArgs = JSON.parse result.stdout
|
||||||
arrayEq expectedArgs, realArgs
|
arrayEq expectedArgs, realArgs
|
||||||
@@ -66,7 +68,7 @@ test "warn and remove -- if it is the second positional argument", ->
|
|||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
test "warn about non-portable shebang lines", ->
|
test "warn about non-portable shebang lines", ->
|
||||||
result = spawnSync 'coffee', [extraArgsScript, 'arg'], spawnOptions
|
result = spawnSync coffeeCommand, [extraArgsScript, 'arg'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', extraArgsScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', extraArgsScript, 'arg']
|
||||||
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
||||||
@@ -77,14 +79,14 @@ test "warn about non-portable shebang lines", ->
|
|||||||
arrayEq JSON.parse(args), ['coffee', '--']
|
arrayEq JSON.parse(args), ['coffee', '--']
|
||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync 'coffee', [initialSpaceScript, 'arg'], spawnOptions
|
result = spawnSync coffeeCommand, [initialSpaceScript, 'arg'], spawnOptions
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
ok stderr is ''
|
ok stderr is ''
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceScript, 'arg']
|
||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', [initialSpaceExtraArgsScript, 'arg'], spawnOptions)
|
coffeeCommand, [initialSpaceExtraArgsScript, 'arg'], spawnOptions)
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
||||||
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
||||||
@@ -97,7 +99,7 @@ test "warn about non-portable shebang lines", ->
|
|||||||
|
|
||||||
test "both warnings will be shown at once", ->
|
test "both warnings will be shown at once", ->
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', [initialSpaceExtraArgsScript, '--', 'arg'], spawnOptions)
|
coffeeCommand, [initialSpaceExtraArgsScript, '--', 'arg'], spawnOptions)
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceExtraArgsScript, 'arg']
|
||||||
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
ok stderr.match /^The script to be run begins with a shebang line with more than one/m
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ test "export default implicit object", ->
|
|||||||
test "export default multiline implicit object", ->
|
test "export default multiline implicit object", ->
|
||||||
eqJS """
|
eqJS """
|
||||||
export default
|
export default
|
||||||
foo: 'bar',
|
foo: 'bar'
|
||||||
baz: 'qux'
|
baz: 'qux'
|
||||||
""",
|
""",
|
||||||
"""
|
"""
|
||||||
@@ -338,6 +338,22 @@ test "export default multiline implicit object", ->
|
|||||||
baz: 'qux'
|
baz: 'qux'
|
||||||
};"""
|
};"""
|
||||||
|
|
||||||
|
test "export default multiline implicit object with internal braces", ->
|
||||||
|
eqJS """
|
||||||
|
export default
|
||||||
|
foo: yes
|
||||||
|
bar: {
|
||||||
|
baz
|
||||||
|
}
|
||||||
|
quz: no
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
export default {
|
||||||
|
foo: true,
|
||||||
|
bar: {baz},
|
||||||
|
quz: false
|
||||||
|
};"""
|
||||||
|
|
||||||
test "export default assignment expression", ->
|
test "export default assignment expression", ->
|
||||||
eqJS "export default foo = 'bar'",
|
eqJS "export default foo = 'bar'",
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -453,8 +453,7 @@ test 'inline implicit object literals within multiline implicit object literals'
|
|||||||
eq 0, x.b
|
eq 0, x.b
|
||||||
eq 0, x.a.aa
|
eq 0, x.a.aa
|
||||||
|
|
||||||
test "object keys with interpolations", ->
|
test "object keys with interpolations: simple cases", ->
|
||||||
# Simple cases.
|
|
||||||
a = 'a'
|
a = 'a'
|
||||||
obj = "#{a}": yes
|
obj = "#{a}": yes
|
||||||
eq obj.a, yes
|
eq obj.a, yes
|
||||||
@@ -465,7 +464,7 @@ test "object keys with interpolations", ->
|
|||||||
obj = {"#{5}"}
|
obj = {"#{5}"}
|
||||||
eq obj[5], '5' # Note that the value is a string, just like the key.
|
eq obj[5], '5' # Note that the value is a string, just like the key.
|
||||||
|
|
||||||
# Commas in implicit object.
|
test "object keys with interpolations: commas in implicit object", ->
|
||||||
obj = "#{'a'}": 1, b: 2
|
obj = "#{'a'}": 1, b: 2
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
obj = a: 1, "#{'b'}": 2
|
obj = a: 1, "#{'b'}": 2
|
||||||
@@ -473,7 +472,7 @@ test "object keys with interpolations", ->
|
|||||||
obj = "#{'a'}": 1, "#{'b'}": 2
|
obj = "#{'a'}": 1, "#{'b'}": 2
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
# Commas in explicit object.
|
test "object keys with interpolations: commas in explicit object", ->
|
||||||
obj = {"#{'a'}": 1, b: 2}
|
obj = {"#{'a'}": 1, b: 2}
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
obj = {a: 1, "#{'b'}": 2}
|
obj = {a: 1, "#{'b'}": 2}
|
||||||
@@ -481,7 +480,7 @@ test "object keys with interpolations", ->
|
|||||||
obj = {"#{'a'}": 1, "#{'b'}": 2}
|
obj = {"#{'a'}": 1, "#{'b'}": 2}
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
# Commas after key with interpolation.
|
test "object keys with interpolations: commas after key with interpolation", ->
|
||||||
obj = {"#{'a'}": yes,}
|
obj = {"#{'a'}": yes,}
|
||||||
eq obj.a, yes
|
eq obj.a, yes
|
||||||
obj = {
|
obj = {
|
||||||
@@ -504,17 +503,17 @@ test "object keys with interpolations", ->
|
|||||||
"#{'c'}": 3, "#{'d'}": 4,
|
"#{'c'}": 3, "#{'d'}": 4,
|
||||||
deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
|
||||||
|
|
||||||
# Key with interpolation mixed with `@prop`.
|
test "object keys with interpolations: key with interpolation mixed with `@prop`", ->
|
||||||
deepEqual (-> {@a, "#{'b'}": 2}).call(a: 1), {a: 1, b: 2}
|
deepEqual (-> {@a, "#{'b'}": 2}).call(a: 1), {a: 1, b: 2}
|
||||||
|
|
||||||
# Evaluate only once.
|
test "object keys with interpolations: evaluate only once", ->
|
||||||
count = 0
|
count = 0
|
||||||
b = -> count++; 'b'
|
a = -> count++; 'a'
|
||||||
obj = {"#{b()}"}
|
obj = {"#{a()}"}
|
||||||
eq obj.b, 'b'
|
eq obj.a, 'a'
|
||||||
eq count, 1
|
eq count, 1
|
||||||
|
|
||||||
# Evaluation order.
|
test "object keys with interpolations: evaluation order", ->
|
||||||
arr = []
|
arr = []
|
||||||
obj =
|
obj =
|
||||||
a: arr.push 1
|
a: arr.push 1
|
||||||
@@ -527,13 +526,13 @@ test "object keys with interpolations", ->
|
|||||||
arrayEq arr, [1..7]
|
arrayEq arr, [1..7]
|
||||||
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
|
||||||
|
|
||||||
# Object starting with dynamic key.
|
test "object keys with interpolations: object starting with dynamic key", ->
|
||||||
obj =
|
obj =
|
||||||
"#{'a'}": 1
|
"#{'a'}": 1
|
||||||
b: 2
|
b: 2
|
||||||
deepEqual obj, {a: 1, b: 2}
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
# Comments in implicit object.
|
test "object keys with interpolations: comments in implicit object", ->
|
||||||
obj =
|
obj =
|
||||||
### leading comment ###
|
### leading comment ###
|
||||||
"#{'a'}": 1
|
"#{'a'}": 1
|
||||||
@@ -564,7 +563,7 @@ test "object keys with interpolations", ->
|
|||||||
}
|
}
|
||||||
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
||||||
|
|
||||||
# A more complicated case.
|
test "object keys with interpolations: more complicated case", ->
|
||||||
obj = {
|
obj = {
|
||||||
"#{'interpolated'}":
|
"#{'interpolated'}":
|
||||||
"""
|
"""
|
||||||
@@ -582,6 +581,212 @@ test "#4324: Shorthand after interpolated key", ->
|
|||||||
eq 1, obj[1]
|
eq 1, obj[1]
|
||||||
eq 2, obj.a
|
eq 2, obj.a
|
||||||
|
|
||||||
|
test "computed property keys: simple cases", ->
|
||||||
|
a = 'a'
|
||||||
|
obj = [a]: yes
|
||||||
|
eq obj.a, yes
|
||||||
|
obj = {[a]: yes}
|
||||||
|
eq obj.a, yes
|
||||||
|
obj = {[a]}
|
||||||
|
eq obj.a, 'a'
|
||||||
|
obj = {[5]}
|
||||||
|
eq obj[5], 5
|
||||||
|
obj = {['5']}
|
||||||
|
eq obj['5'], '5'
|
||||||
|
|
||||||
|
test "computed property keys: commas in implicit object", ->
|
||||||
|
obj = ['a']: 1, b: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = a: 1, ['b']: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = ['a']: 1, ['b']: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: commas in explicit object", ->
|
||||||
|
obj = {['a']: 1, b: 2}
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = {a: 1, ['b']: 2}
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
obj = {['a']: 1, ['b']: 2}
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: commas after key with interpolation", ->
|
||||||
|
obj = {['a']: yes,}
|
||||||
|
eq obj.a, yes
|
||||||
|
obj = {
|
||||||
|
['a']: 1,
|
||||||
|
['b']: 2,
|
||||||
|
### herecomment ###
|
||||||
|
['c']: 3,
|
||||||
|
}
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3}
|
||||||
|
obj =
|
||||||
|
['a']: 1,
|
||||||
|
['b']: 2,
|
||||||
|
### herecomment ###
|
||||||
|
['c']: 3,
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3}
|
||||||
|
obj =
|
||||||
|
['a']: 1,
|
||||||
|
['b']: 2,
|
||||||
|
### herecomment ###
|
||||||
|
['c']: 3, ['d']: 4,
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
|
||||||
|
|
||||||
|
test "computed property keys: key with interpolation mixed with `@prop`", ->
|
||||||
|
deepEqual (-> {@a, ['b']: 2}).call(a: 1), {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: evaluate only once", ->
|
||||||
|
count = 0
|
||||||
|
a = -> count++; 'a'
|
||||||
|
obj = {[a()]}
|
||||||
|
eq obj.a, 'a'
|
||||||
|
eq count, 1
|
||||||
|
|
||||||
|
test "computed property keys: evaluation order", ->
|
||||||
|
arr = []
|
||||||
|
obj =
|
||||||
|
a: arr.push 1
|
||||||
|
b: arr.push 2
|
||||||
|
['c']: arr.push 3
|
||||||
|
['d']: arr.push 4
|
||||||
|
e: arr.push 5
|
||||||
|
['f']: arr.push 6
|
||||||
|
g: arr.push 7
|
||||||
|
arrayEq arr, [1..7]
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
|
||||||
|
|
||||||
|
test "computed property keys: object starting with dynamic key", ->
|
||||||
|
obj =
|
||||||
|
['a']: 1
|
||||||
|
b: 2
|
||||||
|
deepEqual obj, {a: 1, b: 2}
|
||||||
|
|
||||||
|
test "computed property keys: comments in implicit object", ->
|
||||||
|
obj =
|
||||||
|
### leading comment ###
|
||||||
|
['a']: 1
|
||||||
|
|
||||||
|
### middle ###
|
||||||
|
|
||||||
|
['b']: 2
|
||||||
|
# regular comment
|
||||||
|
'c': 3
|
||||||
|
### foo ###
|
||||||
|
d: 4
|
||||||
|
['e']: 5
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
||||||
|
|
||||||
|
obj = {
|
||||||
|
### leading comment ###
|
||||||
|
['a']: 1
|
||||||
|
|
||||||
|
### middle ###
|
||||||
|
|
||||||
|
['b']: 2
|
||||||
|
# regular comment
|
||||||
|
'c': 3
|
||||||
|
### foo ###
|
||||||
|
d: 4
|
||||||
|
['e']: 5
|
||||||
|
}
|
||||||
|
deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
|
||||||
|
|
||||||
|
test "computed property keys: more complicated case", ->
|
||||||
|
obj = {
|
||||||
|
['interpolated']:
|
||||||
|
['nested']:
|
||||||
|
123: 456
|
||||||
|
}
|
||||||
|
deepEqual obj,
|
||||||
|
interpolated:
|
||||||
|
nested:
|
||||||
|
123: 456
|
||||||
|
|
||||||
|
test "computed property keys: empty array as key", ->
|
||||||
|
o1 = { [[]] }
|
||||||
|
deepEqual o1, { [[]]: [] }
|
||||||
|
arrayEq o1[[]], []
|
||||||
|
o2 = { [[]]: 1 }
|
||||||
|
deepEqual o2, { [[]]: 1 }
|
||||||
|
eq o2[[]], 1
|
||||||
|
o3 = [[]]: 1
|
||||||
|
deepEqual o3, { [[]]: 1 }
|
||||||
|
deepEqual o3, { [[]]: 1 }
|
||||||
|
eq o3[[]], 1
|
||||||
|
o4 = a: 1, [[]]: 2
|
||||||
|
deepEqual o4, { a: 1, [[]]: 2 }
|
||||||
|
eq o4.a, 1,
|
||||||
|
eq o4[[]], 2
|
||||||
|
o5 = { a: 1, [[]]: 2 }
|
||||||
|
deepEqual o5, { a: 1, [[]]: 2 }
|
||||||
|
eq o5.a, 1,
|
||||||
|
eq o5[[]], 2
|
||||||
|
|
||||||
|
test "computed property keys: shorthand after computed property key", ->
|
||||||
|
a = 2
|
||||||
|
obj = {[1]: 1, a}
|
||||||
|
eq 1, obj[1]
|
||||||
|
eq 2, obj.a
|
||||||
|
|
||||||
|
test "computed property keys: shorthand computed property key", ->
|
||||||
|
a = 'b'
|
||||||
|
o = {[a]}
|
||||||
|
p = {a}
|
||||||
|
r = {['a']}
|
||||||
|
eq o.b, 'b'
|
||||||
|
eq p.a, o.b
|
||||||
|
eq r.a, 'a'
|
||||||
|
|
||||||
|
foo = -> "a"
|
||||||
|
obj = { [foo()] }
|
||||||
|
eq obj.a, 'a'
|
||||||
|
|
||||||
|
test "computed property keys: arrays", ->
|
||||||
|
b = 'b'
|
||||||
|
f = (c) -> "#{c}1"
|
||||||
|
obj =
|
||||||
|
['a']: [1, 2, 3]
|
||||||
|
[b]: [4, 5, 6]
|
||||||
|
[f(b)]: [7, 8, 9]
|
||||||
|
arrayEq obj.a, [1, 2, 3]
|
||||||
|
arrayEq obj.b, [4, 5, 6]
|
||||||
|
arrayEq obj.b1, [7, 8, 9]
|
||||||
|
|
||||||
|
test "computed property keys: examples from developer.mozilla.org (Object initializer)", ->
|
||||||
|
i = 0
|
||||||
|
obj =
|
||||||
|
['foo' + ++i]: i
|
||||||
|
['foo' + ++i]: i
|
||||||
|
['foo' + ++i]: i
|
||||||
|
eq obj.foo1, 1
|
||||||
|
eq obj.foo2, 2
|
||||||
|
eq obj.foo3, 3
|
||||||
|
|
||||||
|
param = 'size'
|
||||||
|
config =
|
||||||
|
[param]: 12,
|
||||||
|
['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
|
||||||
|
deepEqual config, {size: 12, mobileSize: 4}
|
||||||
|
|
||||||
|
test "computed property keys: [Symbol.iterator]", ->
|
||||||
|
obj =
|
||||||
|
[Symbol.iterator]: ->
|
||||||
|
yield "hello"
|
||||||
|
yield "world"
|
||||||
|
arrayEq [obj...], ['hello', 'world']
|
||||||
|
|
||||||
|
test "computed property keys: Class property", ->
|
||||||
|
increment_method = "increment"
|
||||||
|
decrement_method = "decrement"
|
||||||
|
class Obs
|
||||||
|
constructor: (@count) ->
|
||||||
|
[increment_method]: -> @count += 1
|
||||||
|
[decrement_method]: -> @count -= 1
|
||||||
|
ob = new Obs 2
|
||||||
|
eq ob.increment(), 3
|
||||||
|
eq ob.decrement(), 2
|
||||||
|
|
||||||
test "#1263: Braceless object return", ->
|
test "#1263: Braceless object return", ->
|
||||||
fn = ->
|
fn = ->
|
||||||
return
|
return
|
||||||
@@ -652,20 +857,22 @@ test "#4544: Postfix conditionals in first line of implicit object literals", ->
|
|||||||
test "#4579: Postfix for/while/until in first line of implicit object literals", ->
|
test "#4579: Postfix for/while/until in first line of implicit object literals", ->
|
||||||
two =
|
two =
|
||||||
foo:
|
foo:
|
||||||
bar: x for x in [1, 2, 3]
|
bar1: x for x in [1, 2, 3]
|
||||||
|
bar2: x + y for x, y in [1, 2, 3]
|
||||||
baz: 1337
|
baz: 1337
|
||||||
arrayEq [1, 2, 3], two.foo.bar
|
arrayEq [1, 2, 3], two.foo.bar1
|
||||||
|
arrayEq [1, 3, 5], two.foo.bar2
|
||||||
eq 1337, two.foo.baz
|
eq 1337, two.foo.baz
|
||||||
|
|
||||||
f = (x) -> x
|
f = (x) -> x
|
||||||
|
|
||||||
three =
|
three =
|
||||||
foo: f
|
foo: f
|
||||||
# Uncomment when #4580 is fixed
|
bar1: x + y for x, y of a: 'b', c: 'd'
|
||||||
# bar: x + y for x, y of a: 'b', c: 'd'
|
bar2: x + 'c' for x of a: 1, b: 2
|
||||||
bar: x + 'c' for x of a: 1, b: 2
|
|
||||||
baz: 1337
|
baz: 1337
|
||||||
arrayEq ['ac', 'bc'], three.foo.bar
|
arrayEq ['ab', 'cd'], three.foo.bar1
|
||||||
|
arrayEq ['ac', 'bc'], three.foo.bar2
|
||||||
eq 1337, three.foo.baz
|
eq 1337, three.foo.baz
|
||||||
|
|
||||||
four =
|
four =
|
||||||
@@ -696,4 +903,3 @@ test "#4579: Postfix for/while/until in first line of implicit object literals",
|
|||||||
baz: 1337
|
baz: 1337
|
||||||
arrayEq [4, 3, 2, 1, 0], six.foo.bar
|
arrayEq [4, 3, 2, 1, 0], six.foo.bar
|
||||||
eq 1337, six.foo.baz
|
eq 1337, six.foo.baz
|
||||||
|
|
||||||
|
|||||||
@@ -313,3 +313,16 @@ test "#4248: Unicode code point escapes", ->
|
|||||||
"""
|
"""
|
||||||
/a\\udab3\\uddef/;
|
/a\\udab3\\uddef/;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
test "#4811, heregex comments with ///", ->
|
||||||
|
eqJS """
|
||||||
|
///
|
||||||
|
a | # comment with ///
|
||||||
|
b # /// 'heregex' in comment will be consumed
|
||||||
|
///
|
||||||
|
""",
|
||||||
|
"""
|
||||||
|
// comment with ///
|
||||||
|
// /// 'heregex' in comment will be consumed
|
||||||
|
/a|b/;
|
||||||
|
"""
|
||||||
|
|||||||
@@ -77,6 +77,14 @@ testRepl "empty command evaluates to undefined", (input, output) ->
|
|||||||
input.emitLine ''
|
input.emitLine ''
|
||||||
eq 'undefined', output.lastWrite()
|
eq 'undefined', output.lastWrite()
|
||||||
|
|
||||||
|
testRepl "#4763: comment evaluates to undefined", (input, output) ->
|
||||||
|
input.emitLine '# comment'
|
||||||
|
eq 'undefined', output.lastWrite()
|
||||||
|
|
||||||
|
testRepl "#4763: multiple comments evaluate to undefined", (input, output) ->
|
||||||
|
input.emitLine '### a ### ### b ### # c'
|
||||||
|
eq 'undefined', output.lastWrite()
|
||||||
|
|
||||||
testRepl "ctrl-v toggles multiline prompt", (input, output) ->
|
testRepl "ctrl-v toggles multiline prompt", (input, output) ->
|
||||||
input.emit 'keypress', null, ctrlV
|
input.emit 'keypress', null, ctrlV
|
||||||
eq '------> ', output.lastWrite(0)
|
eq '------> ', output.lastWrite(0)
|
||||||
|
|||||||
Reference in New Issue
Block a user