1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00
* 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:
Geoffrey Booth 2017-10-26 18:29:45 -07:00 committed by GitHub
parent f3375e798c
commit cbc695b831
34 changed files with 945 additions and 449 deletions

View file

@ -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> = -&gt;</span> <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">compileStdio</span> = -&gt;</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> -&gt;</span> stdin.<span class="hljs-literal">on</span> <span class="hljs-string">'data'</span>, <span class="hljs-function"><span class="hljs-params">(buffer)</span> -&gt;</span>

View file

@ -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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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>

View file

@ -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">&#182;</a> <a class="pilcrow" href="#section-10">&#182;</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">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-12">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-13">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-14">&#182;</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">-&gt;</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">&#182;</a> <a class="pilcrow" href="#section-15">&#182;</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">-&gt;</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> -&gt;</span> CoffeeScript._compileFile = <span class="hljs-function"><span class="hljs-params">(filename, options = {})</span> -&gt;</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">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-16">&#182;</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">&#182;</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>

View file

@ -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">-&gt;</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> -&gt;</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

View file

@ -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> -&gt;</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> -&gt;</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">&#182;</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> -&gt;</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>

View file

@ -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&gt; '</span>, prompt: <span class="hljs-string">'coffee&gt; '</span>,
@ -268,7 +269,7 @@ Unwrap that too.</p>
<div class="pilwrap "> <div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a> <a class="pilcrow" href="#section-10">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-11">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-12">&#182;</a>
</div> </div>
<p>Await an async result, if necessary</p> <p>Strip <code>&quot;use strict&quot;</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">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-14">&#182;</a>
</div> </div>
<p>ASTs <code>compile</code> does not add source code information to syntax errors.</p> <p>ASTs <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">&#182;</a> <a class="pilcrow" href="#section-15">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-16">&#182;</a>
</div> </div>
<p>Proxy nodes line listener</p> <p>Proxy nodes 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">&#182;</a> <a class="pilcrow" href="#section-17">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-18">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-19">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-20">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-21">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-22">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-23">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-24">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-25">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-26">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-27">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-28">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-29">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-30">&#182;</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">&#182;</a> <a class="pilcrow" href="#section-31">&#182;</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">'&lt;repl&gt;'</span></pre></div></div>
</li>
<li id="section-32">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-32">&#182;</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> -&gt;</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">&#182;</a> <a class="pilcrow" href="#section-33">&#182;</a>
</div> </div>
<p>Adapt help inherited from the node REPL</p> <p>Adapt help inherited from the node REPL</p>

View file

@ -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>

View file

@ -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> -&gt;</span> <div class="content"><div class='highlight'><pre> constructor: <span class="hljs-function"><span class="hljs-params">(@parent, @expressions, @method, @referencedVars)</span> -&gt;</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

View file

@ -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>&lt;</code> and <code>&gt;</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>&lt;</code> and <code>&gt;</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>“Its 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>“Its 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">-&gt;</span> <span class="keyword">this</span> <span class="comment"># Throws a compiler error</span>
</code></pre>
</blockquote><p>ES2015 classes dont allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that cant be accommodated is calling a bound method before it is bound:</p> </blockquote><p>ES2015 classes dont allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that cant 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">-&gt;</span> constructor: <span class="function">-&gt;</span>
@ -5177,6 +5174,59 @@ f = function*() {
@::[name] = <span class="function">-&gt;</span> <span class="comment"># This will work; assigns to `A.prototype.method`</span> @::[name] = <span class="function">-&gt;</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">-&gt;</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> -&gt;</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"> &mdash; <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 theyre 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) -&gt; super(@arg)</code>. This isnt 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) -&gt; 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>

View file

@ -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

View file

@ -0,0 +1,4 @@
class B extends A
constructor: (arg) ->
super arg
@arg = arg

View file

@ -9,13 +9,6 @@ Class constructors cant 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 dont allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that cant be accommodated is calling a bound method before it is bound: ES2015 classes dont allow bound (fat arrow) methods. The CoffeeScript compiler goes through some contortions to preserve support for them, but one thing that cant be accommodated is calling a bound method before it is bound:
```coffee ```coffee

View 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')
```

View file

@ -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 theyre 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 isnt 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')
``` ```

View file

@ -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>

View file

@ -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>&lt;</code> and <code>&gt;</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>&lt;</code> and <code>&gt;</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>

View file

@ -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.

View file

@ -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))

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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,

View file

@ -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]);
} }

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"