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>
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.transpile = opts.transpile
<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> version() <span class="hljs-keyword">if</span> opts.version
@ -508,6 +509,9 @@ and write them back to <strong>stdout</strong>.</p>
</div>
<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 = []
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>

View file

@ -650,7 +650,7 @@ of <strong>Block</strong> preceded by a function arrow, with an optional paramet
</div>
<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>
]</pre></div></div>

View file

@ -274,6 +274,21 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</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>
</div>
@ -287,11 +302,11 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
</li>
<li id="section-11">
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
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 id="section-12">
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<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 id="section-13">
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<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 id="section-14">
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<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.
"""</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>
</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">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#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
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
from the original file compiled with CoffeeScript.run, add that
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
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>
@token <span class="hljs-string">'OWN'</span>, id
<span class="hljs-keyword">return</span> id.length
@ -382,12 +381,19 @@ 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> @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>
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @value() <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>
<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
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>]
@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">'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
<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>]
@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>]
@ -455,7 +461,7 @@ what CoffeeScript would normally interpret as calls to functions named
</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
<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>]
<span class="hljs-keyword">else</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
@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
alias = id
id = COFFEE_ALIAS_MAP[id]
@ -1968,8 +1974,11 @@ not specified, the length of <code>value</code> will be used.</p>
</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
<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>

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 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>
</li>
@ -245,6 +246,22 @@ to fork both CoffeeScript files, and JavaScript files, directly.</p>
</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>
</div>
</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>
sawSIGINT = <span class="hljs-literal">no</span>
transpile = <span class="hljs-literal">no</span>
replDefaults =
prompt: <span class="hljs-string">'coffee&gt; '</span>,
@ -268,7 +269,7 @@ Unwrap that too.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Wrap the expression in a closure to support top-level <code>await</code></p>
<p>Wrap the expression in a closure to support top-level <code>await</code>.</p>
</div>
@ -284,13 +285,14 @@ Unwrap that too.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Invoke the wrapping closure</p>
<p>Invoke the wrapping closure.</p>
</div>
<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>}
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>
@ -301,7 +303,24 @@ Unwrap that too.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</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>
@ -316,11 +335,11 @@ Unwrap that too.</p>
</li>
<li id="section-13">
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<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 id="section-14">
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
@ -362,11 +381,11 @@ Unwrap that too.</p>
</li>
<li id="section-15">
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Proxy nodes line listener</p>
@ -387,11 +406,11 @@ Unwrap that too.</p>
</li>
<li id="section-16">
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Handle Ctrl-v</p>
@ -404,11 +423,11 @@ Unwrap that too.</p>
</li>
<li id="section-17">
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
@ -423,11 +442,11 @@ Unwrap that too.</p>
</li>
<li id="section-18">
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>no-op unless the current line is empty</p>
@ -438,11 +457,11 @@ Unwrap that too.</p>
</li>
<li id="section-19">
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>eval, print, loop</p>
@ -457,11 +476,11 @@ Unwrap that too.</p>
</li>
<li id="section-20">
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>XXX: multiline hack</p>
@ -479,11 +498,11 @@ Unwrap that too.</p>
</li>
<li id="section-21">
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Store and load command history from a file</p>
@ -496,11 +515,11 @@ Unwrap that too.</p>
</li>
<li id="section-22">
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Get file info and at most maxSize of command history</p>
@ -512,11 +531,11 @@ Unwrap that too.</p>
</li>
<li id="section-23">
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Read last <code>size</code> bytes from the file</p>
@ -530,11 +549,11 @@ Unwrap that too.</p>
</li>
<li id="section-24">
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Set the history on the interpreter</p>
@ -545,11 +564,11 @@ Unwrap that too.</p>
</li>
<li id="section-25">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<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 id="section-26">
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>Shift off the final blank newline</p>
@ -582,11 +601,11 @@ Unwrap that too.</p>
</li>
<li id="section-27">
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
<a class="pilcrow" href="#section-28">&#182;</a>
</div>
<p>Save the latest command in the file</p>
@ -598,11 +617,11 @@ Unwrap that too.</p>
</li>
<li id="section-28">
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</a>
<a class="pilcrow" href="#section-29">&#182;</a>
</div>
<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 id="section-29">
<li id="section-30">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-29">&#182;</a>
<a class="pilcrow" href="#section-30">&#182;</a>
</div>
<p>Add a command to show the history stack</p>
@ -635,11 +654,11 @@ Unwrap that too.</p>
</li>
<li id="section-30">
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-30">&#182;</a>
<a class="pilcrow" href="#section-31">&#182;</a>
</div>
<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()
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
repl = nodeREPL.start opts
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 id="section-31">
<li id="section-33">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-31">&#182;</a>
<a class="pilcrow" href="#section-33">&#182;</a>
</div>
<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>,
<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">'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">'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">'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">'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>
</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
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
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 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>}]
@comments = {}
@positions = {}
@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-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-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-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>
@ -645,7 +646,7 @@ div.CodeMirror-cursor {
<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>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>
npm install --save-dev coffeescript
@ -4634,25 +4635,25 @@ fn = (str ###: string ###, obj ###: Obj ###) ###: string ### ->
</div>
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="type_annotations-js">// @flow
var fn;
/*::
type Obj = {
num: number,
};
*/
var fn;
fn = function(str/*: string */, obj/*: Obj */)/*: string */ {
return str + obj.num;
};
</textarea>
<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">type Obj = {</span>
<span class="cm-comment"> num: number,</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-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 id="annotated-source">
<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>
<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>
@ -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>
<span class="comment"># Throws a TypeError at runtime</span>
</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 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>
@ -5177,6 +5174,59 @@ f = function*() {
@::[name] = <span class="function">-&gt;</span> <span class="comment"># This will work; assigns to `A.prototype.method`</span>
</code></pre>
</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 id="breaking-changes-super-extends">
<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 id="changelog">
<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>
<h2 class="header">
<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 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 type="text/x-coffeescript" class="test" id="cluster">
# Cluster Module
@ -4540,6 +4549,153 @@ test "Flow comment-based syntax support", ->
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 type="text/x-coffeescript" class="test" id="compilation">
# Compilation
@ -4711,6 +4867,10 @@ test "using transpile from the Node API requires an object", ->
catch exception
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 type="text/x-coffeescript" class="test" id="comprehensions">
# Comprehensions
@ -6597,7 +6757,7 @@ if require?
try
assertErrorFormat """
require '#{tempFile}'
require '#{tempFile.replace /\\/g, '\\\\'}'
""",
"""
#{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", ->
assertErrorFormat 'class extends A then constructor: (a = super()) ->', '''
[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()
class B
get: (x) -> x.value + 6
set: (x) -> x.value + 7
b = new B()
eq 12, obj.get 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 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 type="text/x-coffeescript" class="test" id="functions">
@ -11066,13 +11251,17 @@ test "heregex interpolation", ->
return unless require?
path = require 'path'
{spawnSync, execFileSync} = require 'child_process'
{ execFileSync, spawnSync } = require 'child_process'
# Get directory containing the compiled `coffee` executable and prepend it to
# the path so `#!/usr/bin/env coffee` resolves to our locally built file.
coffeeBinDir = path.dirname require.resolve('../bin/coffee')
patchedPath = "#{coffeeBinDir}:#{process.env.PATH}"
patchedEnv = Object.assign {}, process.env, {PATH: patchedPath}
# Get the folder containing the compiled `coffee` executable and make it the
# PATH so that `#!/usr/bin/env coffee` resolves to our locally built file.
coffeeBinFolder = path.dirname require.resolve '../bin/coffee'
spawnOptions =
cwd: coffeeBinFolder
encoding: 'utf8'
env:
PATH: coffeeBinFolder + (if isWindows() then ';' else ':') + process.env.PATH
shell: isWindows()
shebangScript = require.resolve './importing/shebang.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)", ->
return if isWindows()
stdout = execFileSync shebangScript, ['-abck'], {env: patchedEnv}
stdout = execFileSync shebangScript, ['-abck'], spawnOptions
expectedArgs = ['coffee', shebangScript, '-abck']
realArgs = JSON.parse stdout
arrayEq expectedArgs, realArgs
stdout = execFileSync initialSpaceScript, ['-abck'], {env: patchedEnv}
stdout = execFileSync initialSpaceScript, ['-abck'], spawnOptions
expectedArgs = ['coffee', initialSpaceScript, '-abck']
realArgs = JSON.parse stdout
arrayEq expectedArgs, realArgs
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()
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
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, '--']
ok result.status is 0
result = spawnSync 'coffee', ['-b', shebangScript, '--'], {env: patchedEnv}
result = spawnSync 'coffee', ['-b', shebangScript, '--'], spawnOptions
stderr = result.stderr.toString()
arrayEq JSON.parse(result.stdout), ['coffee', shebangScript]
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
result = spawnSync(
'coffee', ['-b', shebangScript, '--', 'ANOTHER ONE'], {env: patchedEnv})
'coffee', ['-b', shebangScript, '--', 'ANOTHER'], spawnOptions)
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
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
result = spawnSync(
'coffee', ['--', initialSpaceScript, 'arg'], {env: patchedEnv})
'coffee', ['--', initialSpaceScript, 'arg'], spawnOptions)
expectedArgs = ['coffee', initialSpaceScript, 'arg']
realArgs = JSON.parse result.stdout
arrayEq expectedArgs, realArgs
@ -11127,7 +11316,7 @@ test "warn and remove -- if it is the second positional argument", ->
ok result.status is 0
test "warn about non-portable shebang lines", ->
result = spawnSync 'coffee', [extraArgsScript, 'arg'], {env: patchedEnv}
result = spawnSync 'coffee', [extraArgsScript, 'arg'], spawnOptions
stderr = result.stderr.toString()
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
@ -11138,14 +11327,14 @@ test "warn about non-portable shebang lines", ->
arrayEq JSON.parse(args), ['coffee', '--']
ok result.status is 0
result = spawnSync 'coffee', [initialSpaceScript, 'arg'], {env: patchedEnv}
result = spawnSync 'coffee', [initialSpaceScript, 'arg'], spawnOptions
stderr = result.stderr.toString()
ok stderr is ''
arrayEq JSON.parse(result.stdout), ['coffee', initialSpaceScript, 'arg']
ok result.status is 0
result = spawnSync(
'coffee', [initialSpaceExtraArgsScript, 'arg'], {env: patchedEnv})
'coffee', [initialSpaceExtraArgsScript, 'arg'], spawnOptions)
stderr = result.stderr.toString()
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
@ -11158,7 +11347,7 @@ test "warn about non-portable shebang lines", ->
test "both warnings will be shown at once", ->
result = spawnSync(
'coffee', [initialSpaceExtraArgsScript, '--', 'arg'], {env: patchedEnv})
'coffee', [initialSpaceExtraArgsScript, '--', 'arg'], spawnOptions)
stderr = result.stderr.toString()
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
@ -12655,7 +12844,6 @@ test "export default named member, within an object", ->
bar
};"""
# Import and export in the same statement
test "export an entire module's contents", ->
@ -12679,18 +12867,21 @@ test "export as aliases members imported from another module", ->
} from 'lib';"""
test "export list can contain CoffeeScript keywords", ->
eqJS "export { unless } from 'lib'",
eqJS "export { unless, and } from 'lib'",
"""
export {
unless
unless,
and
} from 'lib';"""
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 {
when as bar,
baz as unless
baz as unless,
and as foo,
booze as not
} 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", ->
eqJS """
import { unless as bar } from 'lib'
import { unless as bar, and as computedAnd } from 'lib'
bar.barMethod()""",
"""
import {
unless as bar
unless as bar,
and as computedAnd
} from 'lib';
bar.barMethod();"""
@ -15020,6 +15212,10 @@ testRepl "#4604: wraps an async function", (input, output) ->
eq '33', output.lastWrite()
, 20
testRepl "transpile REPL", (input, output) ->
input.emitLine 'require("./test/importing/transpile_import").getSep()'
eq "'#{path.sep.replace '\\', '\\\\'}'", output.lastWrite()
process.on 'exit', ->
try
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
```
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:
```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
```
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')
```

View file

@ -187,6 +187,9 @@
<section id="breaking-changes-classes">
<%= htmlFor('breaking_changes_classes') %>
</section>
<section id="breaking-changes-super-this">
<%= htmlFor('breaking_changes_super_this') %>
</section>
<section id="breaking-changes-super-extends">
<%= htmlFor('breaking_changes_super_extends') %>
</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-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-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-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>

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.0.1
// Generated by CoffeeScript 2.0.2
(function() {
// This **Browser** compatibility layer extends core CoffeeScript functions
// 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() {
// `cake` is a simplified version of [Make](http://www.gnu.org/software/make/)
// ([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() {
// 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

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.0.1
// Generated by CoffeeScript 2.0.2
(function() {
// The `coffee` utility. Handles command-line compilation of CoffeeScript
// 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() {
// 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

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.0.1
// Generated by CoffeeScript 2.0.2
(function() {
// This file contains the common helper functions that we'd like to share among
// 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() {
// Node.js Implementation
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() {
// 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,

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.0.1
// Generated by CoffeeScript 2.0.2
(function() {
// `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),
@ -1266,6 +1266,8 @@
this[tag] = true;
}
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)) {
moveComments(this.base, this.properties[0].name);
}
@ -1568,6 +1570,10 @@
this.variable.error("literal is not a function");
}
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) {
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() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat,
slice = [].slice;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.0.1
// Generated by CoffeeScript 2.0.2
(function() {
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() {
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() {
// The CoffeeScript language has a good deal of optional syntax, implicit syntax,
// 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() {
// 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

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.0.1
// Generated by CoffeeScript 2.0.2
(function() {
// Source maps allow JavaScript runtimes to match running JavaScript back to
// the original source code that corresponds to it. This can be minified

View file

@ -8,7 +8,7 @@
"compiler"
],
"author": "Jeremy Ashkenas",
"version": "2.0.1",
"version": "2.0.2",
"license": "MIT",
"engines": {
"node": ">=6"