mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
2.0.2 (#4758)
* Give the notes about `super` and `this` their own section in the docs * 2.0.2 changelog * 2.0.2 release output * Rewrite
This commit is contained in:
parent
f3375e798c
commit
cbc695b831
34 changed files with 945 additions and 449 deletions
|
|
@ -295,6 +295,7 @@ Many flags cause us to divert before compiling anything. Flags passed after
|
||||||
<div class="content"><div class='highlight'><pre> replCliOpts = useGlobal: <span class="hljs-literal">yes</span>
|
<div class="content"><div class='highlight'><pre> replCliOpts = useGlobal: <span class="hljs-literal">yes</span>
|
||||||
opts.prelude = makePrelude opts.<span class="hljs-built_in">require</span> <span class="hljs-keyword">if</span> opts.<span class="hljs-built_in">require</span>
|
opts.prelude = makePrelude opts.<span class="hljs-built_in">require</span> <span class="hljs-keyword">if</span> opts.<span class="hljs-built_in">require</span>
|
||||||
replCliOpts.prelude = opts.prelude
|
replCliOpts.prelude = opts.prelude
|
||||||
|
replCliOpts.transpile = opts.transpile
|
||||||
<span class="hljs-keyword">return</span> forkNode() <span class="hljs-keyword">if</span> opts.nodejs
|
<span class="hljs-keyword">return</span> forkNode() <span class="hljs-keyword">if</span> opts.nodejs
|
||||||
<span class="hljs-keyword">return</span> usage() <span class="hljs-keyword">if</span> opts.help
|
<span class="hljs-keyword">return</span> usage() <span class="hljs-keyword">if</span> opts.help
|
||||||
<span class="hljs-keyword">return</span> version() <span class="hljs-keyword">if</span> opts.version
|
<span class="hljs-keyword">return</span> version() <span class="hljs-keyword">if</span> opts.version
|
||||||
|
|
@ -508,6 +509,9 @@ and write them back to <strong>stdout</strong>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileStdio</span> = -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileStdio</span> = -></span>
|
||||||
|
<span class="hljs-keyword">if</span> opts.map
|
||||||
|
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'--stdio and --map cannot be used together'</span>
|
||||||
|
process.exit <span class="hljs-number">1</span>
|
||||||
buffers = []
|
buffers = []
|
||||||
stdin = process.openStdin()
|
stdin = process.openStdin()
|
||||||
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'data'</span>, <span class="hljs-function"><span class="hljs-params">(buffer)</span> -></span>
|
stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'data'</span>, <span class="hljs-function"><span class="hljs-params">(buffer)</span> -></span>
|
||||||
|
|
|
||||||
|
|
@ -650,7 +650,7 @@ of <strong>Block</strong> preceded by a function arrow, with an optional paramet
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> Code: [
|
<div class="content"><div class='highlight'><pre> Code: [
|
||||||
o <span class="hljs-string">'PARAM_START ParamList PARAM_END FuncGlyph Block'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Code $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, $<span class="hljs-number">4</span>
|
o <span class="hljs-string">'PARAM_START ParamList PARAM_END FuncGlyph Block'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Code $<span class="hljs-number">2</span>, $<span class="hljs-number">5</span>, $<span class="hljs-number">4</span>, LOC(<span class="hljs-number">1</span>)(<span class="hljs-keyword">new</span> Literal $<span class="hljs-number">1</span>)
|
||||||
o <span class="hljs-string">'FuncGlyph Block'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Code [], $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>
|
o <span class="hljs-string">'FuncGlyph Block'</span>, <span class="hljs-function">-></span> <span class="hljs-keyword">new</span> Code [], $<span class="hljs-number">2</span>, $<span class="hljs-number">1</span>
|
||||||
]</pre></div></div>
|
]</pre></div></div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,21 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-10">¶</a>
|
<a class="pilcrow" href="#section-10">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
<p>Save the options for compiling child imports.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> mainModule.options = options</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-11">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-11">¶</a>
|
||||||
|
</div>
|
||||||
<p>Compile.</p>
|
<p>Compile.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -287,11 +302,11 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
|
||||||
</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>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
|
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
|
||||||
The CoffeeScript REPL uses this to run the input.</p>
|
The CoffeeScript REPL uses this to run the input.</p>
|
||||||
|
|
@ -321,11 +336,11 @@ The CoffeeScript REPL uses this to run the input.</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>define module/require only if they chose not to specify their own</p>
|
<p>define module/require only if they chose not to specify their own</p>
|
||||||
|
|
||||||
|
|
@ -342,11 +357,11 @@ The CoffeeScript REPL uses this to run the input.</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>use the same hack node currently uses for their own REPL</p>
|
<p>use the same hack node currently uses for their own REPL</p>
|
||||||
|
|
||||||
|
|
@ -368,11 +383,11 @@ CoffeeScript.register = <span class="hljs-function">-></span> <span class="hl
|
||||||
</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>Throw error with deprecation warning when depending upon implicit <code>require.extensions</code> registration</p>
|
<p>Throw error with deprecation warning when depending upon implicit <code>require.extensions</code> registration</p>
|
||||||
|
|
||||||
|
|
@ -385,41 +400,43 @@ CoffeeScript.register = <span class="hljs-function">-></span> <span class="hl
|
||||||
Use CoffeeScript.register() or require the coffeescript/register module to require <span class="hljs-subst">#{ext}</span> files.
|
Use CoffeeScript.register() or require the coffeescript/register module to require <span class="hljs-subst">#{ext}</span> files.
|
||||||
"""</span>
|
"""</span>
|
||||||
|
|
||||||
CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params">(filename, sourceMap = <span class="hljs-literal">no</span>, inlineMap = <span class="hljs-literal">no</span>)</span> -></span>
|
CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params">(filename, options = {})</span> -></span>
|
||||||
raw = fs.readFileSync filename, <span class="hljs-string">'utf8'</span></pre></div></div>
|
raw = fs.readFileSync filename, <span class="hljs-string">'utf8'</span></pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-15">
|
|
||||||
<div class="annotation">
|
|
||||||
|
|
||||||
<div class="pilwrap ">
|
|
||||||
<a class="pilcrow" href="#section-15">¶</a>
|
|
||||||
</div>
|
|
||||||
<p>Strip the Unicode byte order mark, if this file begins with one.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> stripped = <span class="hljs-keyword">if</span> raw.charCodeAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-number">0xFEFF</span> <span class="hljs-keyword">then</span> raw.substring <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> raw
|
|
||||||
|
|
||||||
<span class="hljs-keyword">try</span>
|
|
||||||
answer = CoffeeScript.compile stripped, {
|
|
||||||
filename, sourceMap, inlineMap
|
|
||||||
sourceFiles: [filename]
|
|
||||||
literate: helpers.isLiterate filename
|
|
||||||
}
|
|
||||||
<span class="hljs-keyword">catch</span> err</pre></div></div>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li id="section-16">
|
<li id="section-16">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-16">¶</a>
|
<a class="pilcrow" href="#section-16">¶</a>
|
||||||
</div>
|
</div>
|
||||||
|
<p>Strip the Unicode byte order mark, if this file begins with one.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> stripped = <span class="hljs-keyword">if</span> raw.charCodeAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-number">0xFEFF</span> <span class="hljs-keyword">then</span> raw.substring <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> raw
|
||||||
|
|
||||||
|
options = Object.assign {}, options,
|
||||||
|
filename: filename
|
||||||
|
literate: helpers.isLiterate filename
|
||||||
|
sourceFiles: [filename]
|
||||||
|
inlineMap: <span class="hljs-literal">yes</span> <span class="hljs-comment"># Always generate a source map, so that stack traces line up.</span>
|
||||||
|
|
||||||
|
<span class="hljs-keyword">try</span>
|
||||||
|
answer = CoffeeScript.compile stripped, options
|
||||||
|
<span class="hljs-keyword">catch</span> err</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-17">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-17">¶</a>
|
||||||
|
</div>
|
||||||
<p>As the filename and code of a dynamically loaded file will be different
|
<p>As the filename and code of a dynamically loaded file will be different
|
||||||
from the original file compiled with CoffeeScript.run, add that
|
from the original file compiled with CoffeeScript.run, add that
|
||||||
information to error so it can be pretty-printed later.</p>
|
information to error so it can be pretty-printed later.</p>
|
||||||
|
|
|
||||||
|
|
@ -372,7 +372,6 @@ though <code>is</code> means <code>===</code> otherwise.</p>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> idLength = id.length
|
<div class="content"><div class='highlight'><pre> idLength = id.length
|
||||||
poppedToken = <span class="hljs-literal">undefined</span>
|
poppedToken = <span class="hljs-literal">undefined</span>
|
||||||
|
|
||||||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'own'</span> <span class="hljs-keyword">and</span> @tag() <span class="hljs-keyword">is</span> <span class="hljs-string">'FOR'</span>
|
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'own'</span> <span class="hljs-keyword">and</span> @tag() <span class="hljs-keyword">is</span> <span class="hljs-string">'FOR'</span>
|
||||||
@token <span class="hljs-string">'OWN'</span>, id
|
@token <span class="hljs-string">'OWN'</span>, id
|
||||||
<span class="hljs-keyword">return</span> id.length
|
<span class="hljs-keyword">return</span> id.length
|
||||||
|
|
@ -382,14 +381,21 @@ though <code>is</code> means <code>===</code> otherwise.</p>
|
||||||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'as'</span> <span class="hljs-keyword">and</span> @seenImport
|
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'as'</span> <span class="hljs-keyword">and</span> @seenImport
|
||||||
<span class="hljs-keyword">if</span> @value() <span class="hljs-keyword">is</span> <span class="hljs-string">'*'</span>
|
<span class="hljs-keyword">if</span> @value() <span class="hljs-keyword">is</span> <span class="hljs-string">'*'</span>
|
||||||
@tokens[@tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">0</span>] = <span class="hljs-string">'IMPORT_ALL'</span>
|
@tokens[@tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">0</span>] = <span class="hljs-string">'IMPORT_ALL'</span>
|
||||||
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @value() <span class="hljs-keyword">in</span> COFFEE_KEYWORDS
|
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @value(<span class="hljs-literal">yes</span>) <span class="hljs-keyword">in</span> COFFEE_KEYWORDS
|
||||||
@tokens[@tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">0</span>] = <span class="hljs-string">'IDENTIFIER'</span>
|
prev = @prev()
|
||||||
|
[prev[<span class="hljs-number">0</span>], prev[<span class="hljs-number">1</span>]] = [<span class="hljs-string">'IDENTIFIER'</span>, @value(<span class="hljs-literal">yes</span>)]
|
||||||
<span class="hljs-keyword">if</span> @tag() <span class="hljs-keyword">in</span> [<span class="hljs-string">'DEFAULT'</span>, <span class="hljs-string">'IMPORT_ALL'</span>, <span class="hljs-string">'IDENTIFIER'</span>]
|
<span class="hljs-keyword">if</span> @tag() <span class="hljs-keyword">in</span> [<span class="hljs-string">'DEFAULT'</span>, <span class="hljs-string">'IMPORT_ALL'</span>, <span class="hljs-string">'IDENTIFIER'</span>]
|
||||||
@token <span class="hljs-string">'AS'</span>, id
|
@token <span class="hljs-string">'AS'</span>, id
|
||||||
<span class="hljs-keyword">return</span> id.length
|
<span class="hljs-keyword">return</span> id.length
|
||||||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'as'</span> <span class="hljs-keyword">and</span> @seenExport <span class="hljs-keyword">and</span> @tag() <span class="hljs-keyword">in</span> [<span class="hljs-string">'IDENTIFIER'</span>, <span class="hljs-string">'DEFAULT'</span>]
|
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'as'</span> <span class="hljs-keyword">and</span> @seenExport
|
||||||
@token <span class="hljs-string">'AS'</span>, id
|
<span class="hljs-keyword">if</span> @tag() <span class="hljs-keyword">in</span> [<span class="hljs-string">'IDENTIFIER'</span>, <span class="hljs-string">'DEFAULT'</span>]
|
||||||
<span class="hljs-keyword">return</span> id.length
|
@token <span class="hljs-string">'AS'</span>, id
|
||||||
|
<span class="hljs-keyword">return</span> id.length
|
||||||
|
<span class="hljs-keyword">if</span> @value(<span class="hljs-literal">yes</span>) <span class="hljs-keyword">in</span> COFFEE_KEYWORDS
|
||||||
|
prev = @prev()
|
||||||
|
[prev[<span class="hljs-number">0</span>], prev[<span class="hljs-number">1</span>]] = [<span class="hljs-string">'IDENTIFIER'</span>, @value(<span class="hljs-literal">yes</span>)]
|
||||||
|
@token <span class="hljs-string">'AS'</span>, id
|
||||||
|
<span class="hljs-keyword">return</span> id.length
|
||||||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'default'</span> <span class="hljs-keyword">and</span> @seenExport <span class="hljs-keyword">and</span> @tag() <span class="hljs-keyword">in</span> [<span class="hljs-string">'EXPORT'</span>, <span class="hljs-string">'AS'</span>]
|
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">is</span> <span class="hljs-string">'default'</span> <span class="hljs-keyword">and</span> @seenExport <span class="hljs-keyword">and</span> @tag() <span class="hljs-keyword">in</span> [<span class="hljs-string">'EXPORT'</span>, <span class="hljs-string">'AS'</span>]
|
||||||
@token <span class="hljs-string">'DEFAULT'</span>, id
|
@token <span class="hljs-string">'DEFAULT'</span>, id
|
||||||
<span class="hljs-keyword">return</span> id.length
|
<span class="hljs-keyword">return</span> id.length
|
||||||
|
|
@ -455,7 +461,7 @@ what CoffeeScript would normally interpret as calls to functions named
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">'PROPERTY'</span> <span class="hljs-keyword">and</span> prev
|
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">'PROPERTY'</span> <span class="hljs-keyword">and</span> prev
|
||||||
<span class="hljs-keyword">if</span> prev.spaced <span class="hljs-keyword">and</span> prev[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> CALLABLE <span class="hljs-keyword">and</span> <span class="hljs-regexp">/^[gs]et$/</span>.test(prev[<span class="hljs-number">1</span>])
|
<span class="hljs-keyword">if</span> prev.spaced <span class="hljs-keyword">and</span> prev[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> CALLABLE <span class="hljs-keyword">and</span> <span class="hljs-regexp">/^[gs]et$/</span>.test(prev[<span class="hljs-number">1</span>]) <span class="hljs-keyword">and</span> @tokens[@tokens.length - <span class="hljs-number">2</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">isnt</span> <span class="hljs-string">'.'</span>
|
||||||
@error <span class="hljs-string">"'<span class="hljs-subst">#{prev[<span class="hljs-number">1</span>]}</span>' cannot be used as a keyword, or as a function call without parentheses"</span>, prev[<span class="hljs-number">2</span>]
|
@error <span class="hljs-string">"'<span class="hljs-subst">#{prev[<span class="hljs-number">1</span>]}</span>' cannot be used as a keyword, or as a function call without parentheses"</span>, prev[<span class="hljs-number">2</span>]
|
||||||
<span class="hljs-keyword">else</span>
|
<span class="hljs-keyword">else</span>
|
||||||
prevprev = @tokens[@tokens.length - <span class="hljs-number">2</span>]
|
prevprev = @tokens[@tokens.length - <span class="hljs-number">2</span>]
|
||||||
|
|
@ -466,7 +472,7 @@ what CoffeeScript would normally interpret as calls to functions named
|
||||||
<span class="hljs-keyword">if</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span> <span class="hljs-keyword">and</span> id <span class="hljs-keyword">in</span> RESERVED
|
<span class="hljs-keyword">if</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">'IDENTIFIER'</span> <span class="hljs-keyword">and</span> id <span class="hljs-keyword">in</span> RESERVED
|
||||||
@error <span class="hljs-string">"reserved word '<span class="hljs-subst">#{id}</span>'"</span>, length: id.length
|
@error <span class="hljs-string">"reserved word '<span class="hljs-subst">#{id}</span>'"</span>, length: id.length
|
||||||
|
|
||||||
<span class="hljs-keyword">unless</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">'PROPERTY'</span>
|
<span class="hljs-keyword">unless</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">'PROPERTY'</span> <span class="hljs-keyword">or</span> @exportSpecifierList
|
||||||
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">in</span> COFFEE_ALIASES
|
<span class="hljs-keyword">if</span> id <span class="hljs-keyword">in</span> COFFEE_ALIASES
|
||||||
alias = id
|
alias = id
|
||||||
id = COFFEE_ALIAS_MAP[id]
|
id = COFFEE_ALIAS_MAP[id]
|
||||||
|
|
@ -1968,9 +1974,12 @@ not specified, the length of <code>value</code> will be used.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> value: <span class="hljs-function">-></span>
|
<div class="content"><div class='highlight'><pre> value: <span class="hljs-function"><span class="hljs-params">(useOrigin = <span class="hljs-literal">no</span>)</span> -></span>
|
||||||
[..., token] = @tokens
|
[..., token] = @tokens
|
||||||
token?[<span class="hljs-number">1</span>]</pre></div></div>
|
<span class="hljs-keyword">if</span> useOrigin <span class="hljs-keyword">and</span> token?.origin?
|
||||||
|
token.origin?[<span class="hljs-number">1</span>]
|
||||||
|
<span class="hljs-keyword">else</span>
|
||||||
|
token?[<span class="hljs-number">1</span>]</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -137,7 +137,8 @@ path = <span class="hljs-built_in">require</span> <span class="hljs-str
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">loadFile</span> = <span class="hljs-params">(<span class="hljs-built_in">module</span>, filename)</span> -></span>
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">loadFile</span> = <span class="hljs-params">(<span class="hljs-built_in">module</span>, filename)</span> -></span>
|
||||||
answer = CoffeeScript._compileFile filename, <span class="hljs-literal">no</span>, <span class="hljs-literal">yes</span>
|
options = <span class="hljs-built_in">module</span>.options <span class="hljs-keyword">or</span> getRootModule(<span class="hljs-built_in">module</span>).options
|
||||||
|
answer = CoffeeScript._compileFile filename, options
|
||||||
<span class="hljs-built_in">module</span>._compile answer, filename</pre></div></div>
|
<span class="hljs-built_in">module</span>._compile answer, filename</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -245,6 +246,22 @@ to fork both CoffeeScript files, and JavaScript files, directly.</p>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-8">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-8">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Utility function to find the <code>options</code> object attached to the topmost module.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">getRootModule</span> = <span class="hljs-params">(<span class="hljs-built_in">module</span>)</span> -></span>
|
||||||
|
<span class="hljs-keyword">if</span> <span class="hljs-built_in">module</span>.parent <span class="hljs-keyword">then</span> getRootModule <span class="hljs-built_in">module</span>.parent <span class="hljs-keyword">else</span> <span class="hljs-built_in">module</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,7 @@ CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-stri
|
||||||
{merge, updateSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
{merge, updateSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
|
||||||
|
|
||||||
sawSIGINT = <span class="hljs-literal">no</span>
|
sawSIGINT = <span class="hljs-literal">no</span>
|
||||||
|
transpile = <span class="hljs-literal">no</span>
|
||||||
|
|
||||||
replDefaults =
|
replDefaults =
|
||||||
prompt: <span class="hljs-string">'coffee> '</span>,
|
prompt: <span class="hljs-string">'coffee> '</span>,
|
||||||
|
|
@ -268,7 +269,7 @@ 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>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>
|
||||||
|
|
||||||
|
|
@ -284,13 +285,14 @@ Unwrap that too.</p>
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-11">¶</a>
|
<a class="pilcrow" href="#section-11">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Invoke the wrapping closure</p>
|
<p>Invoke the wrapping closure.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Call ast]
|
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [<span class="hljs-keyword">new</span> Call ast]
|
||||||
js = ast.compile {bare: <span class="hljs-literal">yes</span>, locals: Object.keys(context), referencedVars, sharedScope: <span class="hljs-literal">yes</span>}
|
js = ast.compile {bare: <span class="hljs-literal">yes</span>, locals: Object.keys(context), referencedVars, sharedScope: <span class="hljs-literal">yes</span>}
|
||||||
result = runInContext js, context, filename</pre></div></div>
|
<span class="hljs-keyword">if</span> transpile
|
||||||
|
js = transpile.transpile(js, transpile.options).code</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
@ -301,7 +303,24 @@ Unwrap that too.</p>
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-12">¶</a>
|
<a class="pilcrow" href="#section-12">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Await an async result, if necessary</p>
|
<p>Strip <code>"use strict"</code>, to avoid an exception on assigning to
|
||||||
|
undeclared variable <code>__</code>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> js = js.replace <span class="hljs-regexp">/^"use strict"|^'use strict'/</span>, <span class="hljs-string">''</span>
|
||||||
|
result = runInContext js, context, filename</pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-13">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-13">¶</a>
|
||||||
|
</div>
|
||||||
|
<p>Await an async result, if necessary.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -316,11 +335,11 @@ Unwrap that too.</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>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>
|
||||||
|
|
||||||
|
|
@ -341,11 +360,11 @@ Unwrap that too.</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>Node 0.11.12 changed API, prompt is now _prompt.</p>
|
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
|
||||||
|
|
||||||
|
|
@ -362,11 +381,11 @@ Unwrap that too.</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>Proxy node’s line listener</p>
|
<p>Proxy node’s line listener</p>
|
||||||
|
|
||||||
|
|
@ -387,11 +406,11 @@ Unwrap that too.</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>Handle Ctrl-v</p>
|
<p>Handle Ctrl-v</p>
|
||||||
|
|
||||||
|
|
@ -404,11 +423,11 @@ Unwrap that too.</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>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>
|
||||||
|
|
||||||
|
|
@ -423,11 +442,11 @@ Unwrap that too.</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>no-op unless the current line is empty</p>
|
<p>no-op unless the current line is empty</p>
|
||||||
|
|
||||||
|
|
@ -438,11 +457,11 @@ Unwrap that too.</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>eval, print, loop</p>
|
<p>eval, print, loop</p>
|
||||||
|
|
||||||
|
|
@ -457,11 +476,11 @@ Unwrap that too.</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>XXX: multiline hack</p>
|
<p>XXX: multiline hack</p>
|
||||||
|
|
||||||
|
|
@ -479,11 +498,11 @@ Unwrap that too.</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>Store and load command history from a file</p>
|
<p>Store and load command history from a file</p>
|
||||||
|
|
||||||
|
|
@ -496,11 +515,11 @@ Unwrap that too.</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>Get file info and at most maxSize of command history</p>
|
<p>Get file info and at most maxSize of command history</p>
|
||||||
|
|
||||||
|
|
@ -512,11 +531,11 @@ Unwrap that too.</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>Read last <code>size</code> bytes from the file</p>
|
<p>Read last <code>size</code> bytes from the file</p>
|
||||||
|
|
||||||
|
|
@ -530,11 +549,11 @@ Unwrap that too.</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>Set the history on the interpreter</p>
|
<p>Set the history on the interpreter</p>
|
||||||
|
|
||||||
|
|
@ -545,11 +564,11 @@ Unwrap that too.</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>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>
|
||||||
|
|
||||||
|
|
@ -560,11 +579,11 @@ Unwrap that too.</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>Shift off the final blank newline</p>
|
<p>Shift off the final blank newline</p>
|
||||||
|
|
||||||
|
|
@ -582,11 +601,11 @@ Unwrap that too.</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>Save the latest command in the file</p>
|
<p>Save the latest command in the file</p>
|
||||||
|
|
||||||
|
|
@ -598,11 +617,11 @@ Unwrap that too.</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>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>
|
||||||
|
|
||||||
|
|
@ -614,11 +633,11 @@ Unwrap that too.</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>Add a command to show the history stack</p>
|
<p>Add a command to show the history stack</p>
|
||||||
|
|
||||||
|
|
@ -635,11 +654,11 @@ Unwrap that too.</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>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>
|
||||||
|
|
||||||
|
|
@ -658,6 +677,44 @@ Unwrap that too.</p>
|
||||||
|
|
||||||
CoffeeScript.register()
|
CoffeeScript.register()
|
||||||
process.argv = [<span class="hljs-string">'coffee'</span>].concat process.argv[<span class="hljs-number">2.</span>.]
|
process.argv = [<span class="hljs-string">'coffee'</span>].concat process.argv[<span class="hljs-number">2.</span>.]
|
||||||
|
<span class="hljs-keyword">if</span> opts.transpile
|
||||||
|
<span class="hljs-keyword">try</span>
|
||||||
|
transpile = {}
|
||||||
|
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'babel-core'</span>).transform
|
||||||
|
<span class="hljs-keyword">catch</span>
|
||||||
|
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
|
||||||
|
To use --transpile with an interactive REPL, babel-core must be installed either in the current folder or globally:
|
||||||
|
npm install --save-dev babel-core
|
||||||
|
or
|
||||||
|
npm install --global babel-core
|
||||||
|
And you must save options to configure Babel in one of the places it looks to find its options.
|
||||||
|
See http://coffeescript.org/#transpilation
|
||||||
|
'''</span>
|
||||||
|
process.exit <span class="hljs-number">1</span>
|
||||||
|
transpile.options =
|
||||||
|
filename: path.resolve process.cwd(), <span class="hljs-string">'<repl>'</span></pre></div></div>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li id="section-32">
|
||||||
|
<div class="annotation">
|
||||||
|
|
||||||
|
<div class="pilwrap ">
|
||||||
|
<a class="pilcrow" href="#section-32">¶</a>
|
||||||
|
</div>
|
||||||
|
<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
|
||||||
|
it knows later on whether it needs to be transpiled. In the case of
|
||||||
|
the REPL, the only applicable option is <code>transpile</code>.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content"><div class='highlight'><pre> Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
|
||||||
|
originalModuleLoad = Module::load
|
||||||
|
Module::load = <span class="hljs-function"><span class="hljs-params">(filename)</span> -></span>
|
||||||
|
@options = transpile: transpile.options
|
||||||
|
originalModuleLoad.call @, filename
|
||||||
opts = merge replDefaults, opts
|
opts = merge replDefaults, opts
|
||||||
repl = nodeREPL.start opts
|
repl = nodeREPL.start opts
|
||||||
runInContext opts.prelude, repl.context, <span class="hljs-string">'prelude'</span> <span class="hljs-keyword">if</span> opts.prelude
|
runInContext opts.prelude, repl.context, <span class="hljs-string">'prelude'</span> <span class="hljs-keyword">if</span> opts.prelude
|
||||||
|
|
@ -668,11 +725,11 @@ Unwrap that too.</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
||||||
<li id="section-31">
|
<li id="section-33">
|
||||||
<div class="annotation">
|
<div class="annotation">
|
||||||
|
|
||||||
<div class="pilwrap ">
|
<div class="pilwrap ">
|
||||||
<a class="pilcrow" href="#section-31">¶</a>
|
<a class="pilcrow" href="#section-33">¶</a>
|
||||||
</div>
|
</div>
|
||||||
<p>Adapt help inherited from the node REPL</p>
|
<p>Adapt help inherited from the node REPL</p>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1596,8 +1596,8 @@ the node that becomes <code>StringWithInterpolations</code>, and therefore
|
||||||
<div class="content"><div class='highlight'><pre>DISCARDED = [<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">'.'</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">'?'</span>,
|
<div class="content"><div class='highlight'><pre>DISCARDED = [<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">'.'</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">'?'</span>,
|
||||||
<span class="hljs-string">'AS'</span>, <span class="hljs-string">'AWAIT'</span>, <span class="hljs-string">'CALL_START'</span>, <span class="hljs-string">'CALL_END'</span>, <span class="hljs-string">'DEFAULT'</span>, <span class="hljs-string">'ELSE'</span>, <span class="hljs-string">'EXTENDS'</span>, <span class="hljs-string">'EXPORT'</span>,
|
<span class="hljs-string">'AS'</span>, <span class="hljs-string">'AWAIT'</span>, <span class="hljs-string">'CALL_START'</span>, <span class="hljs-string">'CALL_END'</span>, <span class="hljs-string">'DEFAULT'</span>, <span class="hljs-string">'ELSE'</span>, <span class="hljs-string">'EXTENDS'</span>, <span class="hljs-string">'EXPORT'</span>,
|
||||||
<span class="hljs-string">'FORIN'</span>, <span class="hljs-string">'FOROF'</span>, <span class="hljs-string">'FORFROM'</span>, <span class="hljs-string">'IMPORT'</span>, <span class="hljs-string">'INDENT'</span>, <span class="hljs-string">'INDEX_SOAK'</span>, <span class="hljs-string">'LEADING_WHEN'</span>,
|
<span class="hljs-string">'FORIN'</span>, <span class="hljs-string">'FOROF'</span>, <span class="hljs-string">'FORFROM'</span>, <span class="hljs-string">'IMPORT'</span>, <span class="hljs-string">'INDENT'</span>, <span class="hljs-string">'INDEX_SOAK'</span>, <span class="hljs-string">'LEADING_WHEN'</span>,
|
||||||
<span class="hljs-string">'OUTDENT'</span>, <span class="hljs-string">'PARAM_START'</span>, <span class="hljs-string">'PARAM_END'</span>, <span class="hljs-string">'REGEX_START'</span>, <span class="hljs-string">'REGEX_END'</span>, <span class="hljs-string">'RETURN'</span>,
|
<span class="hljs-string">'OUTDENT'</span>, <span class="hljs-string">'PARAM_END'</span>, <span class="hljs-string">'REGEX_START'</span>, <span class="hljs-string">'REGEX_END'</span>, <span class="hljs-string">'RETURN'</span>, <span class="hljs-string">'STRING_END'</span>, <span class="hljs-string">'THROW'</span>,
|
||||||
<span class="hljs-string">'STRING_END'</span>, <span class="hljs-string">'THROW'</span>, <span class="hljs-string">'UNARY'</span>, <span class="hljs-string">'YIELD'</span>
|
<span class="hljs-string">'UNARY'</span>, <span class="hljs-string">'YIELD'</span>
|
||||||
].concat IMPLICIT_UNSPACED_CALL.concat IMPLICIT_END.concat CALL_CLOSERS.concat CONTROL_IN_IMPLICIT</pre></div></div>
|
].concat IMPLICIT_UNSPACED_CALL.concat IMPLICIT_END.concat CALL_CLOSERS.concat CONTROL_IN_IMPLICIT</pre></div></div>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -139,12 +139,14 @@ with external scopes.</p>
|
||||||
as well as a reference to the <strong>Block</strong> node it belongs to, which is
|
as well as a reference to the <strong>Block</strong> node it belongs to, which is
|
||||||
where it should declare its variables, a reference to the function that
|
where it should declare its variables, a reference to the function that
|
||||||
it belongs to, and a list of variables referenced in the source code
|
it belongs to, and a list of variables referenced in the source code
|
||||||
and therefore should be avoided when generating variables.</p>
|
and therefore should be avoided when generating variables. Also track comments
|
||||||
|
that should be output as part of variable declarations.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(@parent, @expressions, @method, @referencedVars)</span> -></span>
|
<div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(@parent, @expressions, @method, @referencedVars)</span> -></span>
|
||||||
@variables = [{name: <span class="hljs-string">'arguments'</span>, type: <span class="hljs-string">'arguments'</span>}]
|
@variables = [{name: <span class="hljs-string">'arguments'</span>, type: <span class="hljs-string">'arguments'</span>}]
|
||||||
|
@comments = {}
|
||||||
@positions = {}
|
@positions = {}
|
||||||
@utilities = {} <span class="hljs-keyword">unless</span> @parent</pre></div></div>
|
@utilities = {} <span class="hljs-keyword">unless</span> @parent</pre></div></div>
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -619,6 +619,7 @@ div.CodeMirror-cursor {
|
||||||
<a href="#breaking-changes-default-values" class="nav-link" data-action="sidebar-nav">Default Values</a>
|
<a href="#breaking-changes-default-values" class="nav-link" data-action="sidebar-nav">Default Values</a>
|
||||||
<a href="#breaking-changes-bound-generator-functions" class="nav-link" data-action="sidebar-nav">Bound Generator Functions</a>
|
<a href="#breaking-changes-bound-generator-functions" class="nav-link" data-action="sidebar-nav">Bound Generator Functions</a>
|
||||||
<a href="#breaking-changes-classes" class="nav-link" data-action="sidebar-nav">Classes</a>
|
<a href="#breaking-changes-classes" class="nav-link" data-action="sidebar-nav">Classes</a>
|
||||||
|
<a href="#breaking-changes-super-this" class="nav-link" data-action="sidebar-nav"><code>super</code> and <code>this</code></a>
|
||||||
<a href="#breaking-changes-super-extends" class="nav-link" data-action="sidebar-nav"><code>super</code> and <code>extends</code></a>
|
<a href="#breaking-changes-super-extends" class="nav-link" data-action="sidebar-nav"><code>super</code> and <code>extends</code></a>
|
||||||
<a href="#breaking-changes-jsx-and-the-less-than-and-greater-than-operators" class="nav-link" data-action="sidebar-nav">JSX and the <code><</code> and <code>></code> Operators</a>
|
<a href="#breaking-changes-jsx-and-the-less-than-and-greater-than-operators" class="nav-link" data-action="sidebar-nav">JSX and the <code><</code> and <code>></code> Operators</a>
|
||||||
<a href="#breaking-changes-literate-coffeescript" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript Parsing</a>
|
<a href="#breaking-changes-literate-coffeescript" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript Parsing</a>
|
||||||
|
|
@ -645,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.1">2.0.1</a></p>
|
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.0.2">2.0.2</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
|
||||||
|
|
||||||
|
|
@ -4634,25 +4635,25 @@ fn = (str ###: string ###, obj ###: Obj ###) ###: string ### ->
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 javascript-output-column">
|
<div class="col-md-6 javascript-output-column">
|
||||||
<textarea class="javascript-output" id="type_annotations-js">// @flow
|
<textarea class="javascript-output" id="type_annotations-js">// @flow
|
||||||
var fn;
|
|
||||||
|
|
||||||
/*::
|
/*::
|
||||||
type Obj = {
|
type Obj = {
|
||||||
num: number,
|
num: number,
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
var fn;
|
||||||
|
|
||||||
fn = function(str/*: string */, obj/*: Obj */)/*: string */ {
|
fn = function(str/*: string */, obj/*: Obj */)/*: string */ {
|
||||||
return str + obj.num;
|
return str + obj.num;
|
||||||
};
|
};
|
||||||
</textarea>
|
</textarea>
|
||||||
<pre class="placeholder-code"><span class="cm-comment">// @flow</span>
|
<pre class="placeholder-code"><span class="cm-comment">// @flow</span>
|
||||||
<span class="cm-keyword">var</span> <span class="cm-def">fn</span>;
|
|
||||||
|
|
||||||
<span class="cm-comment">/*::</span>
|
<span class="cm-comment">/*::</span>
|
||||||
<span class="cm-comment">type Obj = {</span>
|
<span class="cm-comment">type Obj = {</span>
|
||||||
<span class="cm-comment"> num: number,</span>
|
<span class="cm-comment"> num: number,</span>
|
||||||
<span class="cm-comment">};</span>
|
<span class="cm-comment">};</span>
|
||||||
<span class="cm-comment">*/</span>
|
<span class="cm-comment">*/</span>
|
||||||
|
<span class="cm-keyword">var</span> <span class="cm-def">fn</span>;
|
||||||
|
|
||||||
<span class="cm-variable">fn</span> <span class="cm-operator">=</span> <span class="cm-keyword">function</span>(<span class="cm-def">str</span><span class="cm-comment">/*: string */</span>, <span class="cm-def">obj</span><span class="cm-comment">/*: Obj */</span>)<span class="cm-comment">/*: string */</span> {
|
<span class="cm-variable">fn</span> <span class="cm-operator">=</span> <span class="cm-keyword">function</span>(<span class="cm-def">str</span><span class="cm-comment">/*: string */</span>, <span class="cm-def">obj</span><span class="cm-comment">/*: Obj */</span>)<span class="cm-comment">/*: string */</span> {
|
||||||
<span class="cm-keyword">return</span> <span class="cm-variable-2">str</span> <span class="cm-operator">+</span> <span class="cm-variable-2">obj</span>.<span class="cm-property">num</span>;
|
<span class="cm-keyword">return</span> <span class="cm-variable-2">str</span> <span class="cm-operator">+</span> <span class="cm-variable-2">obj</span>.<span class="cm-property">num</span>;
|
||||||
};
|
};
|
||||||
|
|
@ -4820,7 +4821,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.1 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.0.2 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>
|
||||||
|
|
@ -5150,10 +5151,6 @@ f = function*() {
|
||||||
<blockquote class="uneditable-code-block"><pre><code class="language-coffee">(<span class="class"><span class="keyword">class</span>)()</span>
|
<blockquote class="uneditable-code-block"><pre><code class="language-coffee">(<span class="class"><span class="keyword">class</span>)()</span>
|
||||||
<span class="comment"># Throws a TypeError at runtime</span>
|
<span class="comment"># Throws a TypeError at runtime</span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</blockquote><p>Derived (extended) class <code>constructor</code>s cannot use <code>this</code> before calling <code>super</code>:</p>
|
|
||||||
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span></span>
|
|
||||||
constructor: <span class="function">-></span> <span class="keyword">this</span> <span class="comment"># Throws a compiler error</span>
|
|
||||||
</code></pre>
|
|
||||||
</blockquote><p>ES2015 classes don’t allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that can’t be accommodated is calling a bound method before it is bound:</p>
|
</blockquote><p>ES2015 classes don’t allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that can’t be accommodated is calling a bound method before it is bound:</p>
|
||||||
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">Base</span></span>
|
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">Base</span></span>
|
||||||
constructor: <span class="function">-></span>
|
constructor: <span class="function">-></span>
|
||||||
|
|
@ -5177,6 +5174,59 @@ f = function*() {
|
||||||
@::[name] = <span class="function">-></span> <span class="comment"># This will work; assigns to `A.prototype.method`</span>
|
@::[name] = <span class="function">-></span> <span class="comment"># This will work; assigns to `A.prototype.method`</span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
</section>
|
||||||
|
<section id="breaking-changes-super-this">
|
||||||
|
<h3><code>super</code> and <code>this</code></h3>
|
||||||
|
<p>In the constructor of a derived class (a class that <code>extends</code> another class), <code>this</code> cannot be used before calling <code>super</code>:</p>
|
||||||
|
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span></span>
|
||||||
|
constructor: <span class="function">-></span> <span class="keyword">this</span> <span class="comment"># Throws a compiler error</span>
|
||||||
|
</code></pre>
|
||||||
|
</blockquote><p>This also means you cannot pass a reference to <code>this</code> as an argument to <code>super</code> in the constructor of a derived class:</p>
|
||||||
|
<blockquote class="uneditable-code-block"><pre><code class="language-coffee"><span class="class"><span class="keyword">class</span> <span class="title">B</span> <span class="keyword">extends</span> <span class="title">A</span></span>
|
||||||
|
constructor: <span class="function"><span class="params">(@arg)</span> -></span>
|
||||||
|
<span class="keyword">super</span> @arg <span class="comment"># Throws a compiler error</span>
|
||||||
|
</code></pre>
|
||||||
|
</blockquote><p>This is a limitation of ES2015 classes. As a workaround, assign to <code>this</code> after the <code>super</code> call:</p>
|
||||||
|
<aside class="code-example container-fluid bg-ribbed-dark" data-example="breaking_change_super_this">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 coffeescript-input-column">
|
||||||
|
<textarea class="coffeescript-input" id="breaking_change_super_this-coffee">class B extends A
|
||||||
|
constructor: (arg) ->
|
||||||
|
super arg
|
||||||
|
@arg = arg
|
||||||
|
</textarea>
|
||||||
|
<pre class="placeholder-code"><span class="cm-keyword">class</span> <span class="cm-variable">B</span> <span class="cm-keyword">extends</span> <span class="cm-variable">A</span>
|
||||||
|
<span class="cm-variable">constructor</span><span class="cm-punctuation">:</span> <span class="cm-punctuation">(</span><span class="cm-variable">arg</span><span class="cm-punctuation">)</span> <span class="cm-operator">-></span>
|
||||||
|
<span class="cm-variable">super</span> <span class="cm-variable">arg</span>
|
||||||
|
<span class="cm-property">@arg</span> <span class="cm-punctuation">=</span> <span class="cm-variable">arg</span>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 javascript-output-column">
|
||||||
|
<textarea class="javascript-output" id="breaking_change_super_this-js">var B;
|
||||||
|
|
||||||
|
B = class B extends A {
|
||||||
|
constructor(arg) {
|
||||||
|
super(arg);
|
||||||
|
this.arg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
</textarea>
|
||||||
|
<pre class="placeholder-code"><span class="cm-keyword">var</span> <span class="cm-def">B</span>;
|
||||||
|
|
||||||
|
<span class="cm-variable">B</span> <span class="cm-operator">=</span> <span class="cm-keyword">class</span> <span class="cm-def">B</span> <span class="cm-keyword">extends</span> <span class="cm-variable">A</span> {
|
||||||
|
<span class="cm-property">constructor</span>(<span class="cm-def">arg</span>) {
|
||||||
|
<span class="cm-keyword">super</span>(<span class="cm-variable-2">arg</span>);
|
||||||
|
<span class="cm-keyword">this</span>.<span class="cm-property">arg</span> <span class="cm-operator">=</span> <span class="cm-variable-2">arg</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</aside>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
<section id="breaking-changes-super-extends">
|
<section id="breaking-changes-super-extends">
|
||||||
<h3><code>super</code> and <code>extends</code></h3>
|
<h3><code>super</code> and <code>extends</code></h3>
|
||||||
|
|
@ -5448,6 +5498,21 @@ 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.0.2"></div>
|
||||||
|
<h2 class="header">
|
||||||
|
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.1...2.0.2">2.0.2</a>
|
||||||
|
<span class="timestamp"> — <time datetime="2017-10-26">October 26, 2017</time></span>
|
||||||
|
</h2><ul>
|
||||||
|
<li><code>--transpile</code> now also applies to <code>require</code>d or <code>import</code>ed CoffeeScript files.</li>
|
||||||
|
<li><code>--transpile</code> can be used with the REPL: <code>coffee --interactive --transpile</code>.</li>
|
||||||
|
<li>Improvements to comments output that should now cover all of the <a href="https://flow.org/en/docs/types/comments/">Flow comment-based syntax</a>. Inline <code>###</code> comments near <a href="https://flow.org/en/docs/types/variables/">variable</a> initial assignments are now output in the variable declaration statement, and <code>###</code> comments near a <a href="https://flow.org/en/docs/types/generics/">class and method names</a> are now output where Flow expects them.</li>
|
||||||
|
<li>Importing CoffeeScript keywords is now allowed, so long as they’re aliased: <code>import { and as andFn } from 'lib'</code>. (You could also do <code>import lib from 'lib'</code> and then reference <code>lib.and</code>.)</li>
|
||||||
|
<li>Calls to functions named <code>get</code> and <code>set</code> no longer throw an error when given a bracketless object literal as an argument: <code>obj.set propertyName: propertyValue</code>.</li>
|
||||||
|
<li>In the constructor of a derived class (a class that <code>extends</code> another class), you cannot call <code>super</code> with an argument that references <code>this</code>: <code>class Child extends Parent then constructor: (@arg) -> super(@arg)</code>. This isn’t allowed in JavaScript, and now the CoffeeScript compiler will throw an error. Instead, assign to <code>this</code> after calling <code>super</code>: <code>(arg) -> super(arg); @arg = arg</code>.</li>
|
||||||
|
<li>Bugfix for incorrect output when backticked statements and hoisted expressions were both in the same class body. This allows a backticked line like <code>`field = 3`</code>, for people using the experimental <a href="https://github.com/tc39/proposal-class-fields">class fields</a> syntax, in the same class along with traditional class body expressions like <code>prop: 3</code> that CoffeeScript outputs as part of the class prototype.</li>
|
||||||
|
<li>Bugfix for comments not output before a complex <code>?</code> operation, e.g. <code>@a ? b</code>.</li>
|
||||||
|
<li>All tests now pass in Windows.</li>
|
||||||
|
</ul>
|
||||||
<div class="anchor" id="2.0.1"></div>
|
<div class="anchor" id="2.0.1"></div>
|
||||||
<h2 class="header">
|
<h2 class="header">
|
||||||
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.0...2.0.1">2.0.1</a>
|
<a href="https://github.com/jashkenas/coffeescript/compare/2.0.0...2.0.1">2.0.1</a>
|
||||||
|
|
|
||||||
|
|
@ -3544,6 +3544,15 @@ test "#4464: backticked expressions in class body", ->
|
||||||
eq 42, b.x
|
eq 42, b.x
|
||||||
eq 84, b.y
|
eq 84, b.y
|
||||||
|
|
||||||
|
test "#4724: backticked expression in a class body with hoisted member", ->
|
||||||
|
class A
|
||||||
|
`get x() { return 42; }`
|
||||||
|
hoisted: 84
|
||||||
|
|
||||||
|
a = new A
|
||||||
|
eq 42, a.x
|
||||||
|
eq 84, a.hoisted
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="cluster">
|
<script type="text/x-coffeescript" class="test" id="cluster">
|
||||||
# Cluster Module
|
# Cluster Module
|
||||||
|
|
@ -4540,6 +4549,153 @@ test "Flow comment-based syntax support", ->
|
||||||
return str + num;
|
return str + num;
|
||||||
};'''
|
};'''
|
||||||
|
|
||||||
|
test "#4706: Flow comments around function parameters", ->
|
||||||
|
eqJS '''
|
||||||
|
identity = ###::<T>### (value ###: T ###) ###: T ### ->
|
||||||
|
value
|
||||||
|
''', '''
|
||||||
|
var identity;
|
||||||
|
|
||||||
|
identity = function/*::<T>*/(value/*: T */)/*: T */ {
|
||||||
|
return value;
|
||||||
|
};'''
|
||||||
|
|
||||||
|
test "#4706: Flow comments around function parameters", ->
|
||||||
|
eqJS '''
|
||||||
|
copy = arr.map(###:: <T> ###(item ###: T ###) ###: T ### => item)
|
||||||
|
''', '''
|
||||||
|
var copy;
|
||||||
|
|
||||||
|
copy = arr.map(/*:: <T> */(item/*: T */)/*: T */ => {
|
||||||
|
return item;
|
||||||
|
});'''
|
||||||
|
|
||||||
|
test "#4706: Flow comments after class name", ->
|
||||||
|
eqJS '''
|
||||||
|
class Container ###::<T> ###
|
||||||
|
method: ###::<U> ### () -> true
|
||||||
|
''', '''
|
||||||
|
var Container;
|
||||||
|
|
||||||
|
Container = class Container/*::<T> */ {
|
||||||
|
method() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};'''
|
||||||
|
|
||||||
|
test "#4706: Identifiers with comments wrapped in parentheses remain wrapped", ->
|
||||||
|
eqJS '(arr ###: Array<number> ###)', '(arr/*: Array<number> */);'
|
||||||
|
eqJS 'other = (arr ###: any ###)', '''
|
||||||
|
var other;
|
||||||
|
|
||||||
|
other = (arr/*: any */);'''
|
||||||
|
|
||||||
|
test "#4706: Flow comments before class methods", ->
|
||||||
|
eqJS '''
|
||||||
|
class Container
|
||||||
|
###::
|
||||||
|
method: (number) => string;
|
||||||
|
method: (string) => number;
|
||||||
|
###
|
||||||
|
method: -> true
|
||||||
|
''', '''
|
||||||
|
var Container;
|
||||||
|
|
||||||
|
Container = class Container {
|
||||||
|
/*::
|
||||||
|
method: (number) => string;
|
||||||
|
method: (string) => number;
|
||||||
|
*/
|
||||||
|
method() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};'''
|
||||||
|
|
||||||
|
test "#4706: Flow comments for class method params", ->
|
||||||
|
eqJS '''
|
||||||
|
class Container
|
||||||
|
method: (param ###: string ###) -> true
|
||||||
|
''', '''
|
||||||
|
var Container;
|
||||||
|
|
||||||
|
Container = class Container {
|
||||||
|
method(param/*: string */) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};'''
|
||||||
|
|
||||||
|
test "#4706: Flow comments for class method returns", ->
|
||||||
|
eqJS '''
|
||||||
|
class Container
|
||||||
|
method: () ###: string ### -> true
|
||||||
|
''', '''
|
||||||
|
var Container;
|
||||||
|
|
||||||
|
Container = class Container {
|
||||||
|
method()/*: string */ {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};'''
|
||||||
|
|
||||||
|
test "#4706: Flow comments for function spread", ->
|
||||||
|
eqJS '''
|
||||||
|
method = (...rest ###: Array<string> ###) =>
|
||||||
|
''', '''
|
||||||
|
var method;
|
||||||
|
|
||||||
|
method = (...rest/*: Array<string> */) => {};'''
|
||||||
|
|
||||||
|
test "#4747: Flow comments for local variable declaration", ->
|
||||||
|
eqJS 'a ###: number ### = 1', '''
|
||||||
|
var a/*: number */;
|
||||||
|
|
||||||
|
a = 1;
|
||||||
|
'''
|
||||||
|
|
||||||
|
test "#4747: Flow comments for local variable declarations", ->
|
||||||
|
eqJS '''
|
||||||
|
a ###: number ### = 1
|
||||||
|
b ###: string ### = 'c'
|
||||||
|
''', '''
|
||||||
|
var a/*: number */, b/*: string */;
|
||||||
|
|
||||||
|
a = 1;
|
||||||
|
|
||||||
|
b = 'c';
|
||||||
|
'''
|
||||||
|
|
||||||
|
test "#4747: Flow comments for local variable declarations with reassignment", ->
|
||||||
|
eqJS '''
|
||||||
|
a ###: number ### = 1
|
||||||
|
b ###: string ### = 'c'
|
||||||
|
a ### some other comment ### = 2
|
||||||
|
''', '''
|
||||||
|
var a/*: number */, b/*: string */;
|
||||||
|
|
||||||
|
a = 1;
|
||||||
|
|
||||||
|
b = 'c';
|
||||||
|
|
||||||
|
a/* some other comment */ = 2;
|
||||||
|
'''
|
||||||
|
|
||||||
|
test "#4756: Comment before ? operation", ->
|
||||||
|
eqJS '''
|
||||||
|
do ->
|
||||||
|
### Comment ###
|
||||||
|
@foo ? 42
|
||||||
|
''', '''
|
||||||
|
(function() {
|
||||||
|
var ref;
|
||||||
|
/* Comment */
|
||||||
|
return (ref = this.foo) != null ? ref : 42;
|
||||||
|
})();
|
||||||
|
'''
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="compilation">
|
<script type="text/x-coffeescript" class="test" id="compilation">
|
||||||
# Compilation
|
# Compilation
|
||||||
|
|
@ -4711,6 +4867,10 @@ test "using transpile from the Node API requires an object", ->
|
||||||
catch exception
|
catch exception
|
||||||
eq exception.message, 'The transpile option must be given an object with options to pass to Babel'
|
eq exception.message, 'The transpile option must be given an object with options to pass to Babel'
|
||||||
|
|
||||||
|
test "transpile option applies to imported .coffee files", ->
|
||||||
|
return if global.testingBrowser
|
||||||
|
doesNotThrow -> transpile 'run', "import { getSep } from './test/importing/transpile_import'\ngetSep()"
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="comprehensions">
|
<script type="text/x-coffeescript" class="test" id="comprehensions">
|
||||||
# Comprehensions
|
# Comprehensions
|
||||||
|
|
@ -6597,7 +6757,7 @@ if require?
|
||||||
|
|
||||||
try
|
try
|
||||||
assertErrorFormat """
|
assertErrorFormat """
|
||||||
require '#{tempFile}'
|
require '#{tempFile.replace /\\/g, '\\\\'}'
|
||||||
""",
|
""",
|
||||||
"""
|
"""
|
||||||
#{fs.realpathSync tempFile}:1:15: error: unexpected in
|
#{fs.realpathSync tempFile}:1:15: error: unexpected in
|
||||||
|
|
@ -7871,6 +8031,20 @@ test "derived constructors can't use @params without calling super", ->
|
||||||
^^
|
^^
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
test "derived constructors can't call super with @params", ->
|
||||||
|
assertErrorFormat 'class extends A then constructor: (@a) -> super(@a)', '''
|
||||||
|
[stdin]:1:49: error: Can't call super with @params in derived class constructors
|
||||||
|
class extends A then constructor: (@a) -> super(@a)
|
||||||
|
^^
|
||||||
|
'''
|
||||||
|
|
||||||
|
test "derived constructors can't call super with buried @params", ->
|
||||||
|
assertErrorFormat 'class extends A then constructor: (@a) -> super((=> @a)())', '''
|
||||||
|
[stdin]:1:53: error: Can't call super with @params in derived class constructors
|
||||||
|
class extends A then constructor: (@a) -> super((=> @a)())
|
||||||
|
^^
|
||||||
|
'''
|
||||||
|
|
||||||
test "'super' is not allowed in constructor parameter defaults", ->
|
test "'super' is not allowed in constructor parameter defaults", ->
|
||||||
assertErrorFormat 'class extends A then constructor: (a = super()) ->', '''
|
assertErrorFormat 'class extends A then constructor: (a = super()) ->', '''
|
||||||
[stdin]:1:40: error: 'super' is not allowed in constructor parameter defaults
|
[stdin]:1:40: error: 'super' is not allowed in constructor parameter defaults
|
||||||
|
|
@ -9793,6 +9967,12 @@ test "functions named get or set can be used without parentheses when attached t
|
||||||
|
|
||||||
a = new A()
|
a = new A()
|
||||||
|
|
||||||
|
class B
|
||||||
|
get: (x) -> x.value + 6
|
||||||
|
set: (x) -> x.value + 7
|
||||||
|
|
||||||
|
b = new B()
|
||||||
|
|
||||||
eq 12, obj.get 10
|
eq 12, obj.get 10
|
||||||
eq 13, obj.set 10
|
eq 13, obj.set 10
|
||||||
|
|
||||||
|
|
@ -9812,6 +9992,11 @@ test "functions named get or set can be used without parentheses when attached t
|
||||||
eq 12, obj.obj.get @ten
|
eq 12, obj.obj.get @ten
|
||||||
eq 13, obj.obj.set @ten
|
eq 13, obj.obj.set @ten
|
||||||
|
|
||||||
|
eq 16, b.get value: 10
|
||||||
|
eq 17, b.set value: 10
|
||||||
|
|
||||||
|
eq 16, b.get value: @ten
|
||||||
|
eq 17, b.set value: @ten
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<script type="text/x-coffeescript" class="test" id="functions">
|
<script type="text/x-coffeescript" class="test" id="functions">
|
||||||
|
|
@ -11066,13 +11251,17 @@ test "heregex interpolation", ->
|
||||||
return unless require?
|
return unless require?
|
||||||
|
|
||||||
path = require 'path'
|
path = require 'path'
|
||||||
{spawnSync, execFileSync} = require 'child_process'
|
{ execFileSync, spawnSync } = require 'child_process'
|
||||||
|
|
||||||
# Get directory containing the compiled `coffee` executable and prepend it to
|
# Get the folder containing the compiled `coffee` executable and make it the
|
||||||
# the path so `#!/usr/bin/env coffee` resolves to our locally built file.
|
# PATH so that `#!/usr/bin/env coffee` resolves to our locally built file.
|
||||||
coffeeBinDir = path.dirname require.resolve('../bin/coffee')
|
coffeeBinFolder = path.dirname require.resolve '../bin/coffee'
|
||||||
patchedPath = "#{coffeeBinDir}:#{process.env.PATH}"
|
spawnOptions =
|
||||||
patchedEnv = Object.assign {}, process.env, {PATH: patchedPath}
|
cwd: coffeeBinFolder
|
||||||
|
encoding: 'utf8'
|
||||||
|
env:
|
||||||
|
PATH: coffeeBinFolder + (if isWindows() then ';' else ':') + process.env.PATH
|
||||||
|
shell: isWindows()
|
||||||
|
|
||||||
shebangScript = require.resolve './importing/shebang.coffee'
|
shebangScript = require.resolve './importing/shebang.coffee'
|
||||||
initialSpaceScript = require.resolve './importing/shebang_initial_space.coffee'
|
initialSpaceScript = require.resolve './importing/shebang_initial_space.coffee'
|
||||||
|
|
@ -11082,18 +11271,18 @@ initialSpaceExtraArgsScript = require.resolve './importing/shebang_initial_space
|
||||||
test "parse arguments for shebang scripts correctly (on unix platforms)", ->
|
test "parse arguments for shebang scripts correctly (on unix platforms)", ->
|
||||||
return if isWindows()
|
return if isWindows()
|
||||||
|
|
||||||
stdout = execFileSync shebangScript, ['-abck'], {env: patchedEnv}
|
stdout = execFileSync shebangScript, ['-abck'], spawnOptions
|
||||||
expectedArgs = ['coffee', shebangScript, '-abck']
|
expectedArgs = ['coffee', shebangScript, '-abck']
|
||||||
realArgs = JSON.parse stdout
|
realArgs = JSON.parse stdout
|
||||||
arrayEq expectedArgs, realArgs
|
arrayEq expectedArgs, realArgs
|
||||||
|
|
||||||
stdout = execFileSync initialSpaceScript, ['-abck'], {env: patchedEnv}
|
stdout = execFileSync initialSpaceScript, ['-abck'], spawnOptions
|
||||||
expectedArgs = ['coffee', initialSpaceScript, '-abck']
|
expectedArgs = ['coffee', initialSpaceScript, '-abck']
|
||||||
realArgs = JSON.parse stdout
|
realArgs = JSON.parse stdout
|
||||||
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, '--'], {env: patchedEnv}
|
result = spawnSync 'coffee', [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
|
||||||
|
|
@ -11101,7 +11290,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, '--'], {env: patchedEnv}
|
result = spawnSync 'coffee', ['-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
|
||||||
|
|
@ -11110,16 +11299,16 @@ 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 ONE'], {env: patchedEnv})
|
'coffee', ['-b', shebangScript, '--', 'ANOTHER'], spawnOptions)
|
||||||
stderr = result.stderr.toString()
|
stderr = result.stderr.toString()
|
||||||
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript, 'ANOTHER ONE']
|
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript, 'ANOTHER']
|
||||||
ok stderr.match /^coffee was invoked with '--'/m
|
ok stderr.match /^coffee was invoked with '--'/m
|
||||||
posArgs = stderr.match(/^The positional arguments were: (.*)$/m)[1]
|
posArgs = stderr.match(/^The positional arguments were: (.*)$/m)[1]
|
||||||
arrayEq JSON.parse(posArgs), [shebangScript, '--', 'ANOTHER ONE']
|
arrayEq JSON.parse(posArgs), [shebangScript, '--', 'ANOTHER']
|
||||||
ok result.status is 0
|
ok result.status is 0
|
||||||
|
|
||||||
result = spawnSync(
|
result = spawnSync(
|
||||||
'coffee', ['--', initialSpaceScript, 'arg'], {env: patchedEnv})
|
'coffee', ['--', 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
|
||||||
|
|
@ -11127,7 +11316,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'], {env: patchedEnv}
|
result = spawnSync 'coffee', [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
|
||||||
|
|
@ -11138,14 +11327,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'], {env: patchedEnv}
|
result = spawnSync 'coffee', [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'], {env: patchedEnv})
|
'coffee', [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
|
||||||
|
|
@ -11158,7 +11347,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'], {env: patchedEnv})
|
'coffee', [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
|
||||||
|
|
@ -12655,7 +12844,6 @@ test "export default named member, within an object", ->
|
||||||
bar
|
bar
|
||||||
};"""
|
};"""
|
||||||
|
|
||||||
|
|
||||||
# Import and export in the same statement
|
# Import and export in the same statement
|
||||||
|
|
||||||
test "export an entire module's contents", ->
|
test "export an entire module's contents", ->
|
||||||
|
|
@ -12679,18 +12867,21 @@ test "export as aliases members imported from another module", ->
|
||||||
} from 'lib';"""
|
} from 'lib';"""
|
||||||
|
|
||||||
test "export list can contain CoffeeScript keywords", ->
|
test "export list can contain CoffeeScript keywords", ->
|
||||||
eqJS "export { unless } from 'lib'",
|
eqJS "export { unless, and } from 'lib'",
|
||||||
"""
|
"""
|
||||||
export {
|
export {
|
||||||
unless
|
unless,
|
||||||
|
and
|
||||||
} from 'lib';"""
|
} from 'lib';"""
|
||||||
|
|
||||||
test "export list can contain CoffeeScript keywords when aliasing", ->
|
test "export list can contain CoffeeScript keywords when aliasing", ->
|
||||||
eqJS "export { when as bar, baz as unless } from 'lib'",
|
eqJS "export { when as bar, baz as unless, and as foo, booze as not } from 'lib'",
|
||||||
"""
|
"""
|
||||||
export {
|
export {
|
||||||
when as bar,
|
when as bar,
|
||||||
baz as unless
|
baz as unless,
|
||||||
|
and as foo,
|
||||||
|
booze as not
|
||||||
} from 'lib';"""
|
} from 'lib';"""
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12784,11 +12975,12 @@ test "`as` can be used as an alias name", ->
|
||||||
|
|
||||||
test "CoffeeScript keywords can be used as imported names in import lists", ->
|
test "CoffeeScript keywords can be used as imported names in import lists", ->
|
||||||
eqJS """
|
eqJS """
|
||||||
import { unless as bar } from 'lib'
|
import { unless as bar, and as computedAnd } from 'lib'
|
||||||
bar.barMethod()""",
|
bar.barMethod()""",
|
||||||
"""
|
"""
|
||||||
import {
|
import {
|
||||||
unless as bar
|
unless as bar,
|
||||||
|
and as computedAnd
|
||||||
} from 'lib';
|
} from 'lib';
|
||||||
|
|
||||||
bar.barMethod();"""
|
bar.barMethod();"""
|
||||||
|
|
@ -15020,6 +15212,10 @@ testRepl "#4604: wraps an async function", (input, output) ->
|
||||||
eq '33', output.lastWrite()
|
eq '33', output.lastWrite()
|
||||||
, 20
|
, 20
|
||||||
|
|
||||||
|
testRepl "transpile REPL", (input, output) ->
|
||||||
|
input.emitLine 'require("./test/importing/transpile_import").getSep()'
|
||||||
|
eq "'#{path.sep.replace '\\', '\\\\'}'", output.lastWrite()
|
||||||
|
|
||||||
process.on 'exit', ->
|
process.on 'exit', ->
|
||||||
try
|
try
|
||||||
fs.unlinkSync historyFile
|
fs.unlinkSync historyFile
|
||||||
|
|
|
||||||
4
documentation/examples/breaking_change_super_this.coffee
Normal file
4
documentation/examples/breaking_change_super_this.coffee
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
class B extends A
|
||||||
|
constructor: (arg) ->
|
||||||
|
super arg
|
||||||
|
@arg = arg
|
||||||
|
|
@ -9,13 +9,6 @@ Class constructors can’t be invoked without `new`:
|
||||||
# Throws a TypeError at runtime
|
# Throws a TypeError at runtime
|
||||||
```
|
```
|
||||||
|
|
||||||
Derived (extended) class `constructor`s cannot use `this` before calling `super`:
|
|
||||||
|
|
||||||
```coffee
|
|
||||||
class B extends A
|
|
||||||
constructor: -> this # Throws a compiler error
|
|
||||||
```
|
|
||||||
|
|
||||||
ES2015 classes don’t allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that can’t be accommodated is calling a bound method before it is bound:
|
ES2015 classes don’t allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that can’t be accommodated is calling a bound method before it is bound:
|
||||||
|
|
||||||
```coffee
|
```coffee
|
||||||
|
|
|
||||||
20
documentation/sections/breaking_changes_super_this.md
Normal file
20
documentation/sections/breaking_changes_super_this.md
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
### `super` and `this`
|
||||||
|
|
||||||
|
In the constructor of a derived class (a class that `extends` another class), `this` cannot be used before calling `super`:
|
||||||
|
|
||||||
|
```coffee
|
||||||
|
class B extends A
|
||||||
|
constructor: -> this # Throws a compiler error
|
||||||
|
```
|
||||||
|
This also means you cannot pass a reference to `this` as an argument to `super` in the constructor of a derived class:
|
||||||
|
|
||||||
|
```coffee
|
||||||
|
class B extends A
|
||||||
|
constructor: (@arg) ->
|
||||||
|
super @arg # Throws a compiler error
|
||||||
|
```
|
||||||
|
This is a limitation of ES2015 classes. As a workaround, assign to `this` after the `super` call:
|
||||||
|
|
||||||
|
```
|
||||||
|
codeFor('breaking_change_super_this')
|
||||||
|
```
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
```
|
||||||
|
releaseHeader('2017-10-26', '2.0.2', '2.0.1')
|
||||||
|
```
|
||||||
|
* `--transpile` now also applies to `require`d or `import`ed CoffeeScript files.
|
||||||
|
* `--transpile` can be used with the REPL: `coffee --interactive --transpile`.
|
||||||
|
* Improvements to comments output that should now cover all of the [Flow comment-based syntax](https://flow.org/en/docs/types/comments/). Inline `###` comments near [variable](https://flow.org/en/docs/types/variables/) initial assignments are now output in the variable declaration statement, and `###` comments near a [class and method names](https://flow.org/en/docs/types/generics/) are now output where Flow expects them.
|
||||||
|
* Importing CoffeeScript keywords is now allowed, so long as they’re aliased: `import { and as andFn } from 'lib'`. (You could also do `import lib from 'lib'` and then reference `lib.and`.)
|
||||||
|
* Calls to functions named `get` and `set` no longer throw an error when given a bracketless object literal as an argument: `obj.set propertyName: propertyValue`.
|
||||||
|
* In the constructor of a derived class (a class that `extends` another class), you cannot call `super` with an argument that references `this`: `class Child extends Parent then constructor: (@arg) -> super(@arg)`. This isn’t allowed in JavaScript, and now the CoffeeScript compiler will throw an error. Instead, assign to `this` after calling `super`: `(arg) -> super(arg); @arg = arg`.
|
||||||
|
* Bugfix for incorrect output when backticked statements and hoisted expressions were both in the same class body. This allows a backticked line like `` `field = 3` ``, for people using the experimental [class fields](https://github.com/tc39/proposal-class-fields) syntax, in the same class along with traditional class body expressions like `prop: 3` that CoffeeScript outputs as part of the class prototype.
|
||||||
|
* Bugfix for comments not output before a complex `?` operation, e.g. `@a ? b`.
|
||||||
|
* All tests now pass in Windows.
|
||||||
|
|
||||||
```
|
```
|
||||||
releaseHeader('2017-09-26', '2.0.1', '2.0.0')
|
releaseHeader('2017-09-26', '2.0.1', '2.0.0')
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,9 @@
|
||||||
<section id="breaking-changes-classes">
|
<section id="breaking-changes-classes">
|
||||||
<%= htmlFor('breaking_changes_classes') %>
|
<%= htmlFor('breaking_changes_classes') %>
|
||||||
</section>
|
</section>
|
||||||
|
<section id="breaking-changes-super-this">
|
||||||
|
<%= htmlFor('breaking_changes_super_this') %>
|
||||||
|
</section>
|
||||||
<section id="breaking-changes-super-extends">
|
<section id="breaking-changes-super-extends">
|
||||||
<%= htmlFor('breaking_changes_super_extends') %>
|
<%= htmlFor('breaking_changes_super_extends') %>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@
|
||||||
<a href="#breaking-changes-default-values" class="nav-link" data-action="sidebar-nav">Default Values</a>
|
<a href="#breaking-changes-default-values" class="nav-link" data-action="sidebar-nav">Default Values</a>
|
||||||
<a href="#breaking-changes-bound-generator-functions" class="nav-link" data-action="sidebar-nav">Bound Generator Functions</a>
|
<a href="#breaking-changes-bound-generator-functions" class="nav-link" data-action="sidebar-nav">Bound Generator Functions</a>
|
||||||
<a href="#breaking-changes-classes" class="nav-link" data-action="sidebar-nav">Classes</a>
|
<a href="#breaking-changes-classes" class="nav-link" data-action="sidebar-nav">Classes</a>
|
||||||
|
<a href="#breaking-changes-super-this" class="nav-link" data-action="sidebar-nav"><code>super</code> and <code>this</code></a>
|
||||||
<a href="#breaking-changes-super-extends" class="nav-link" data-action="sidebar-nav"><code>super</code> and <code>extends</code></a>
|
<a href="#breaking-changes-super-extends" class="nav-link" data-action="sidebar-nav"><code>super</code> and <code>extends</code></a>
|
||||||
<a href="#breaking-changes-jsx-and-the-less-than-and-greater-than-operators" class="nav-link" data-action="sidebar-nav">JSX and the <code><</code> and <code>></code> Operators</a>
|
<a href="#breaking-changes-jsx-and-the-less-than-and-greater-than-operators" class="nav-link" data-action="sidebar-nav">JSX and the <code><</code> and <code>></code> Operators</a>
|
||||||
<a href="#breaking-changes-literate-coffeescript" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript Parsing</a>
|
<a href="#breaking-changes-literate-coffeescript" class="nav-link" data-action="sidebar-nav">Literate CoffeeScript Parsing</a>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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),
|
||||||
|
|
@ -1266,6 +1266,8 @@
|
||||||
this[tag] = true;
|
this[tag] = true;
|
||||||
}
|
}
|
||||||
this.isDefaultValue = isDefaultValue;
|
this.isDefaultValue = isDefaultValue;
|
||||||
|
// If this is a `@foo =` assignment, if there are comments on `@` move them
|
||||||
|
// to be on `foo`.
|
||||||
if (((ref1 = this.base) != null ? ref1.comments : void 0) && this.base instanceof ThisLiteral && (((ref2 = this.properties[0]) != null ? ref2.name : void 0) != null)) {
|
if (((ref1 = this.base) != null ? ref1.comments : void 0) && this.base instanceof ThisLiteral && (((ref2 = this.properties[0]) != null ? ref2.name : void 0) != null)) {
|
||||||
moveComments(this.base, this.properties[0].name);
|
moveComments(this.base, this.properties[0].name);
|
||||||
}
|
}
|
||||||
|
|
@ -1568,6 +1570,10 @@
|
||||||
this.variable.error("literal is not a function");
|
this.variable.error("literal is not a function");
|
||||||
}
|
}
|
||||||
this.csx = this.variable.base instanceof CSXTag;
|
this.csx = this.variable.base instanceof CSXTag;
|
||||||
|
// `@variable` never gets output as a result of this node getting created as
|
||||||
|
// part of `RegexWithInterpolations`, so for that case move any comments to
|
||||||
|
// the `args` property that gets passed into `RegexWithInterpolations` via
|
||||||
|
// the grammar.
|
||||||
if (((ref1 = this.variable.base) != null ? ref1.value : void 0) === 'RegExp' && this.args.length !== 0) {
|
if (((ref1 = this.variable.base) != null ? ref1.value : void 0) === 'RegExp' && this.args.length !== 0) {
|
||||||
moveComments(this.variable, this.args[0]);
|
moveComments(this.variable, this.args[0]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 2.0.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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.1
|
// Generated by CoffeeScript 2.0.2
|
||||||
(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
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"compiler"
|
"compiler"
|
||||||
],
|
],
|
||||||
"author": "Jeremy Ashkenas",
|
"author": "Jeremy Ashkenas",
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue