* 2.5.0 changelog

* Update dependencies

* Colors are expected to be globals by the new AST test helpers

* Disable testing of deepStrictIncludeExpectedProperties in browsers for now

* Update output of compiler only

* Update browser compiler output

* Update docs output

* Document ast option

* Update output

* Fix and reenable deepStrict test for browser test suite

* Update output
This commit is contained in:
Geoffrey Booth 2019-12-31 22:19:32 -08:00 committed by GitHub
parent ba41b4417d
commit 61d408f093
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 22537 additions and 4368 deletions

View File

@ -397,7 +397,41 @@ the same name.</p>
options.bare = <span class="hljs-literal">yes</span>
<span class="hljs-keyword">break</span>
fragments = parser.parse(tokens).compileToFragments options
nodes = parser.parse tokens</pre></div></div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>If all that was requested was a POJO representation of the nodes, e.g.
the abstract syntax tree (AST), we can stop now and just return that
(after fixing the location data for the root/<code>File</code>»<code>Program</code> node,
which mightve gotten misaligned from the original source due to the
<code>clean</code> function in the lexer).</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> options.ast
nodes.allCommentTokens = helpers.extractAllCommentTokens tokens
sourceCodeNumberOfLines = (code.match(<span class="hljs-regexp">/\r?\n/g</span>) <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>).length + <span class="hljs-number">1</span>
sourceCodeLastLine = <span class="hljs-regexp">/.*$/</span>.exec(code)[<span class="hljs-number">0</span>] <span class="hljs-comment"># `.*` matches all but line break characters.</span>
ast = nodes.ast options
range = [<span class="hljs-number">0</span>, code.length]
ast.start = ast.program.start = range[<span class="hljs-number">0</span>]
ast.end = ast.program.end = range[<span class="hljs-number">1</span>]
ast.range = ast.program.range = range
ast.loc.start = ast.program.loc.start = {line: <span class="hljs-number">1</span>, column: <span class="hljs-number">0</span>}
ast.loc.end.line = ast.program.loc.end.line = sourceCodeNumberOfLines
ast.loc.end.column = ast.program.loc.end.column = sourceCodeLastLine.length
ast.tokens = tokens
<span class="hljs-keyword">return</span> ast
fragments = nodes.compileToFragments options
currentLine = <span class="hljs-number">0</span>
currentLine += <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> options.header
@ -409,11 +443,11 @@ the same name.</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>Update the sourcemap with data from each fragment.</p>
@ -424,11 +458,11 @@ the same name.</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>Do not include empty, whitespace, or semicolon-only fragments.</p>
@ -449,11 +483,11 @@ the same name.</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>Copy the code from each fragment into the final JavaScript.</p>
@ -474,11 +508,11 @@ the same name.</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>This only happens if run via the Node API and <code>transpile</code> is set to
something other than an object.</p>
@ -490,11 +524,11 @@ something other than an object.</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>Get the reference to Babel that we have been passed if this compiler
is run via the CLI or Node API.</p>
@ -509,11 +543,11 @@ is run via the CLI or Node API.</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>See <a href="https://github.com/babel/babel/issues/827#issuecomment-77573107">https://github.com/babel/babel/issues/827#issuecomment-77573107</a>:
Babel can take a v3 source map object as input in <code>inputSourceMap</code>
@ -548,11 +582,11 @@ and it will return an <em>updated</em> v3 source map object in its output.</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>Tokenize a string of CoffeeScript code, and return the array of tokens.</p>
@ -564,11 +598,11 @@ and it will return an <em>updated</em> v3 source map object in its output.</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>Parse a string of CoffeeScript code or an array of lexed tokens, and
return the AST. You can then compile it by calling <code>.compile()</code> on the root,
@ -577,19 +611,17 @@ or traverse it by using <code>.traverseChildren()</code> with a callback.</p>
</div>
<div class="content"><div class='highlight'><pre>exports.nodes = withPrettyErrors (source, options) -&gt;
<span class="hljs-keyword">if</span> <span class="hljs-keyword">typeof</span> source <span class="hljs-keyword">is</span> <span class="hljs-string">'string'</span>
parser.parse lexer.tokenize source, options
<span class="hljs-keyword">else</span>
parser.parse source</pre></div></div>
source = lexer.tokenize source, options <span class="hljs-keyword">if</span> <span class="hljs-keyword">typeof</span> source <span class="hljs-keyword">is</span> <span class="hljs-string">'string'</span>
parser.parse source</pre></div></div>
</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>This file used to export these methods; leave stubs that throw warnings
instead. These methods have been moved into <code>index.coffee</code> to provide
@ -605,11 +637,11 @@ environment.</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>Instantiate a Lexer for our use here.</p>
@ -620,11 +652,11 @@ environment.</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>The real Lexer produces a generic stream of tokens. This object provides a
thin wrapper around it, compatible with the Jison API. We can then pass it
@ -633,6 +665,10 @@ directly as a “Jison lexer.”</p>
</div>
<div class="content"><div class='highlight'><pre>parser.lexer =
yylloc:
range: []
options:
ranges: <span class="hljs-literal">yes</span>
lex: <span class="hljs-function">-&gt;</span>
token = parser.tokens[@pos++]
<span class="hljs-keyword">if</span> token
@ -650,11 +686,11 @@ directly as a “Jison lexer.”</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>Make all the AST nodes visible to the parser.</p>
@ -665,11 +701,11 @@ directly as a “Jison lexer.”</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>Override Jisons default error handling function.</p>
@ -680,11 +716,11 @@ directly as a “Jison lexer.”</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>Disregard Jisons message, it contains redundant line number information.
Disregard the token, we take its value directly from the lexer in case
@ -708,11 +744,11 @@ the error is caused by a generated token which might refer to its origin.</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>The second argument has a <code>loc</code> property, which should have the location
data for this token. Unfortunately, Jison seems to send an outdated <code>loc</code>
@ -726,11 +762,11 @@ from the lexer.</p>
</li>
<li id="section-31">
<li id="section-32">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-31">&#182;</a>
<a class="pilcrow" href="#section-32">&#182;</a>
</div>
<p>Based on <a href="http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js">http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js</a>
Modified to handle sourceMap</p>
@ -758,11 +794,11 @@ Modified to handle sourceMap</p>
</li>
<li id="section-32">
<li id="section-33">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-32">&#182;</a>
<a class="pilcrow" href="#section-33">&#182;</a>
</div>
<p>Check for a sourceMap position</p>
@ -805,11 +841,11 @@ Modified to handle sourceMap</p>
</li>
<li id="section-33">
<li id="section-34">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-33">&#182;</a>
<a class="pilcrow" href="#section-34">&#182;</a>
</div>
<p>Skip files that we didnt compile, like Node system files that appear in
the stack trace, as they never have source maps.</p>
@ -824,11 +860,11 @@ the stack trace, as they never have source maps.</p>
</li>
<li id="section-34">
<li id="section-35">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-34">&#182;</a>
<a class="pilcrow" href="#section-35">&#182;</a>
</div>
<p>CoffeeScript compiled in a browser or via <code>CoffeeScript.compile</code> or <code>.run</code>
may get compiled with <code>options.filename</code> thats missing, which becomes
@ -843,11 +879,11 @@ filename of the script file. See if we have a source map cached under
</li>
<li id="section-35">
<li id="section-36">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-35">&#182;</a>
<a class="pilcrow" href="#section-36">&#182;</a>
</div>
<p>Work backwards from the most recent anonymous source maps, until we find
one that works. This isnt foolproof; there is a chance that multiple
@ -864,11 +900,11 @@ and its not foolproof either.</p>
</li>
<li id="section-36">
<li id="section-37">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-36">&#182;</a>
<a class="pilcrow" href="#section-37">&#182;</a>
</div>
<p>If all else fails, recompile this source to get a source map. We need the
previous section (for <code>&lt;anonymous&gt;</code>) despite this option, because after it
@ -891,11 +927,11 @@ time the source map we want is the last one.</p>
</li>
<li id="section-37">
<li id="section-38">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-37">&#182;</a>
<a class="pilcrow" href="#section-38">&#182;</a>
</div>
<p>Based on <a href="http://goo.gl/ZTx1p">michaelficarra/CoffeeScriptRedux</a>
NodeJS / V8 have no support for transforming positions in stack traces using

View File

@ -199,12 +199,14 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
</div>
<div class="content"><div class='highlight'><pre>SWITCHES = [
[ <span class="hljs-string">'--ast'</span>, <span class="hljs-string">'generate an abstract syntax tree of nodes'</span>]
[<span class="hljs-string">'-b'</span>, <span class="hljs-string">'--bare'</span>, <span class="hljs-string">'compile without a top-level function wrapper'</span>]
[<span class="hljs-string">'-c'</span>, <span class="hljs-string">'--compile'</span>, <span class="hljs-string">'compile to JavaScript and save as .js files'</span>]
[<span class="hljs-string">'-e'</span>, <span class="hljs-string">'--eval'</span>, <span class="hljs-string">'pass a string from the command line as input'</span>]
[<span class="hljs-string">'-h'</span>, <span class="hljs-string">'--help'</span>, <span class="hljs-string">'display this help message'</span>]
[<span class="hljs-string">'-i'</span>, <span class="hljs-string">'--interactive'</span>, <span class="hljs-string">'run an interactive CoffeeScript REPL'</span>]
[<span class="hljs-string">'-j'</span>, <span class="hljs-string">'--join [FILE]'</span>, <span class="hljs-string">'concatenate the source CoffeeScript before compiling'</span>]
[<span class="hljs-string">'-l'</span>, <span class="hljs-string">'--literate'</span>, <span class="hljs-string">'treat stdio as literate style coffeescript'</span>]
[<span class="hljs-string">'-m'</span>, <span class="hljs-string">'--map'</span>, <span class="hljs-string">'generate source map and save as .js.map files'</span>]
[<span class="hljs-string">'-M'</span>, <span class="hljs-string">'--inline-map'</span>, <span class="hljs-string">'generate source map and include it directly in output'</span>]
[<span class="hljs-string">'-n'</span>, <span class="hljs-string">'--nodes'</span>, <span class="hljs-string">'print out the parse tree that the parser produces'</span>]
@ -214,7 +216,6 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
[<span class="hljs-string">'-p'</span>, <span class="hljs-string">'--print'</span>, <span class="hljs-string">'print out the compiled JavaScript'</span>]
[<span class="hljs-string">'-r'</span>, <span class="hljs-string">'--require [MODULE*]'</span>, <span class="hljs-string">'require the given module before eval or REPL'</span>]
[<span class="hljs-string">'-s'</span>, <span class="hljs-string">'--stdio'</span>, <span class="hljs-string">'listen for and compile scripts over stdio'</span>]
[<span class="hljs-string">'-l'</span>, <span class="hljs-string">'--literate'</span>, <span class="hljs-string">'treat stdio as literate style coffeescript'</span>]
[<span class="hljs-string">'-t'</span>, <span class="hljs-string">'--transpile'</span>, <span class="hljs-string">'pipe generated JavaScript through Babel'</span>]
[ <span class="hljs-string">'--tokens'</span>, <span class="hljs-string">'print out the tokens that the lexer/rewriter produce'</span>]
[<span class="hljs-string">'-v'</span>, <span class="hljs-string">'--version'</span>, <span class="hljs-string">'display the version number'</span>]
@ -460,6 +461,9 @@ requested options. If evaluating the script directly, set <code>__filename</code
printTokens CoffeeScript.tokens task.input, task.options
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.nodes
printLine CoffeeScript.nodes(task.input, task.options).toString().trim()
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.ast
compiled = CoffeeScript.compile task.input, task.options
printLine JSON.stringify(compiled, <span class="hljs-literal">null</span>, <span class="hljs-number">2</span>)
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> opts.run
CoffeeScript.register()
CoffeeScript.eval opts.prelude, task.options <span class="hljs-keyword">if</span> opts.prelude
@ -960,6 +964,7 @@ along.</p>
transpile: opts.transpile
sourceMap: opts.map
inlineMap: opts[<span class="hljs-string">'inline-map'</span>]
ast: opts.ast
<span class="hljs-keyword">if</span> filename
<span class="hljs-keyword">if</span> base

File diff suppressed because it is too large Load Diff

View File

@ -383,9 +383,12 @@ If <code>last</code> is not provided, this will simply return <code>first</code>
first_column: first.first_column
last_line: last.last_line
last_column: last.last_column
<span class="hljs-function">
<span class="hljs-title">buildLocationHash</span> = <span class="hljs-params">(loc)</span> -&gt;</span>
<span class="hljs-string">"<span class="hljs-subst">#{loc.first_line}</span>x<span class="hljs-subst">#{loc.first_column}</span>-<span class="hljs-subst">#{loc.last_line}</span>x<span class="hljs-subst">#{loc.last_column}</span>"</span></pre></div></div>
last_line_exclusive: last.last_line_exclusive
last_column_exclusive: last.last_column_exclusive
range: [
first.range[<span class="hljs-number">0</span>]
last.range[<span class="hljs-number">1</span>]
]</pre></div></div>
</li>
@ -396,15 +399,19 @@ If <code>last</code> is not provided, this will simply return <code>first</code>
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Build a dictionary of extra token properties organized by tokens locations
used as lookup hashes.</p>
<p>Build a list of all comments attached to tokens.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildTokenDataDictionary</span> = <span class="hljs-params">(parserState)</span> -&gt;</span>
tokenData = {}
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> parserState.parser.tokens <span class="hljs-keyword">when</span> token.comments
tokenHash = buildLocationHash token[<span class="hljs-number">2</span>]</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.extractAllCommentTokens = <span class="hljs-function"><span class="hljs-params">(tokens)</span> -&gt;</span>
allCommentsObj = {}
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token.comments
<span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> token.comments
commentKey = comment.locationData.range[<span class="hljs-number">0</span>]
allCommentsObj[commentKey] = comment
sortedKeys = Object.keys(allCommentsObj).sort (a, b) -&gt; a - b
<span class="hljs-keyword">for</span> key <span class="hljs-keyword">in</span> sortedKeys
allCommentsObj[key]</pre></div></div>
</li>
@ -415,6 +422,44 @@ used as lookup hashes.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Get a lookup hash for a token based on its location data.
Multiple tokens might have the same location hash, but using exclusive
location data distinguishes e.g. zero-length generated tokens from
actual source tokens.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildLocationHash</span> = <span class="hljs-params">(loc)</span> -&gt;</span>
<span class="hljs-string">"<span class="hljs-subst">#{loc.range[<span class="hljs-number">0</span>]}</span>-<span class="hljs-subst">#{loc.range[<span class="hljs-number">1</span>]}</span>"</span></pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Build a dictionary of extra token properties organized by tokens locations
used as lookup hashes.</p>
</div>
<div class="content"><div class='highlight'><pre>exports.buildTokenDataDictionary = buildTokenDataDictionary = <span class="hljs-function"><span class="hljs-params">(tokens)</span> -&gt;</span>
tokenData = {}
<span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token.comments
tokenHash = buildLocationHash token[<span class="hljs-number">2</span>]</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Multiple tokens might have the same location hash, such as the generated
<code>JS</code> tokens added at the start or end of the token stream to hold
comments that start or end a file.</p>
@ -427,11 +472,11 @@ comments that start or end a file.</p>
</li>
<li id="section-17">
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>For “overlapping” tokens, that is tokens with the same location data
and therefore matching <code>tokenHash</code>es, merge the comments from both/all
@ -446,11 +491,11 @@ they will get sorted out later.</p>
</li>
<li id="section-18">
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>This returns a function which takes an object as a parameter, and if that
object is an AST node, updates that objects locationData.
@ -458,40 +503,43 @@ The object is returned either way.</p>
</div>
<div class="content"><div class='highlight'><pre>exports.addDataToNode = <span class="hljs-function"><span class="hljs-params">(parserState, first, last)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.addDataToNode = <span class="hljs-function"><span class="hljs-params">(parserState, firstLocationData, firstValue, lastLocationData, lastValue, forceUpdateLocation = <span class="hljs-literal">yes</span>)</span> -&gt;</span>
(obj) -&gt;</pre></div></div>
</li>
<li id="section-19">
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Add location data.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> obj?.updateLocationDataIfMissing? <span class="hljs-keyword">and</span> first?
obj.updateLocationDataIfMissing buildLocationData(first, last)</pre></div></div>
<div class="content"><div class='highlight'><pre> locationData = buildLocationData(firstValue?.locationData ? firstLocationData, lastValue?.locationData ? lastLocationData)
<span class="hljs-keyword">if</span> obj?.updateLocationDataIfMissing? <span class="hljs-keyword">and</span> firstLocationData?
obj.updateLocationDataIfMissing locationData, forceUpdateLocation
<span class="hljs-keyword">else</span>
obj.locationData = locationData</pre></div></div>
</li>
<li id="section-20">
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Add comments, building the dictionary of token data if it hasnt been
built yet.</p>
</div>
<div class="content"><div class='highlight'><pre> parserState.tokenData ?= buildTokenDataDictionary parserState
<div class="content"><div class='highlight'><pre> parserState.tokenData ?= buildTokenDataDictionary parserState.parser.tokens
<span class="hljs-keyword">if</span> obj.locationData?
objHash = buildLocationHash obj.locationData
<span class="hljs-keyword">if</span> parserState.tokenData[objHash]?.comments?
@ -506,11 +554,11 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
</li>
<li id="section-21">
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Convert jison location data to a string.
<code>obj</code> can be a token, or a locationData.</p>
@ -530,11 +578,11 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
</li>
<li id="section-22">
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>A <code>.coffee.md</code> compatible version of <code>basename</code>, that returns the file sans-extension.</p>
@ -553,11 +601,11 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
</li>
<li id="section-23">
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Determine if a filename represents a CoffeeScript file.</p>
@ -568,11 +616,11 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
</li>
<li id="section-24">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>Determine if a filename represents a Literate CoffeeScript file.</p>
@ -583,11 +631,11 @@ exports.attachCommentsToNode = attachCommentsToNode = <span class="hljs-function
</li>
<li id="section-25">
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>Throws a SyntaxError from a given location.
The errors <code>toString</code> will return an error message following the “standard”
@ -604,11 +652,11 @@ marker showing where the error is.</p>
</li>
<li id="section-26">
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
<a class="pilcrow" href="#section-28">&#182;</a>
</div>
<p>Instead of showing the compilers stacktrace, show our custom error message
(this is useful when the error bubbles up in Node.js applications that
@ -623,11 +671,11 @@ compile CoffeeScript for example).</p>
</li>
<li id="section-27">
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
<a class="pilcrow" href="#section-29">&#182;</a>
</div>
<p>Update a compiler SyntaxError with source code information if it didnt have
it already.</p>
@ -639,11 +687,11 @@ it already.</p>
</li>
<li id="section-28">
<li id="section-30">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</a>
<a class="pilcrow" href="#section-30">&#182;</a>
</div>
<p>Avoid screwing up the <code>stack</code> property of other errors (i.e. possible bugs).</p>
@ -669,11 +717,11 @@ it already.</p>
</li>
<li id="section-29">
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-29">&#182;</a>
<a class="pilcrow" href="#section-31">&#182;</a>
</div>
<p>Show only the first line on multi-line errors.</p>
@ -685,11 +733,11 @@ it already.</p>
</li>
<li id="section-30">
<li id="section-32">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-30">&#182;</a>
<a class="pilcrow" href="#section-32">&#182;</a>
</div>
<p>Check to see if were running on a color-enabled TTY.</p>
@ -715,7 +763,83 @@ exports.nameWhitespaceCharacter = <span class="hljs-function"><span class="hljs-
<span class="hljs-keyword">when</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'newline'</span>
<span class="hljs-keyword">when</span> <span class="hljs-string">'\r'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'carriage return'</span>
<span class="hljs-keyword">when</span> <span class="hljs-string">'\t'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'tab'</span>
<span class="hljs-keyword">else</span> string</pre></div></div>
<span class="hljs-keyword">else</span> string
exports.parseNumber = <span class="hljs-function"><span class="hljs-params">(string)</span> -&gt;</span>
<span class="hljs-keyword">return</span> NaN <span class="hljs-keyword">unless</span> string?
base = <span class="hljs-keyword">switch</span> string.charAt <span class="hljs-number">1</span>
<span class="hljs-keyword">when</span> <span class="hljs-string">'b'</span> <span class="hljs-keyword">then</span> <span class="hljs-number">2</span>
<span class="hljs-keyword">when</span> <span class="hljs-string">'o'</span> <span class="hljs-keyword">then</span> <span class="hljs-number">8</span>
<span class="hljs-keyword">when</span> <span class="hljs-string">'x'</span> <span class="hljs-keyword">then</span> <span class="hljs-number">16</span>
<span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>
<span class="hljs-keyword">if</span> base?
parseInt string[<span class="hljs-number">2.</span>.].replace(<span class="hljs-regexp">/_/g</span>, <span class="hljs-string">''</span>), base
<span class="hljs-keyword">else</span>
parseFloat string.replace(<span class="hljs-regexp">/_/g</span>, <span class="hljs-string">''</span>)
exports.isFunction = <span class="hljs-function"><span class="hljs-params">(obj)</span> -&gt;</span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Function]'</span>
exports.isNumber = isNumber = <span class="hljs-function"><span class="hljs-params">(obj)</span> -&gt;</span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Number]'</span>
exports.isString = isString = <span class="hljs-function"><span class="hljs-params">(obj)</span> -&gt;</span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object String]'</span>
exports.isBoolean = isBoolean = <span class="hljs-function"><span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">or</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">or</span> Object::toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Boolean]'</span>
exports.isPlainObject = <span class="hljs-function"><span class="hljs-params">(obj)</span> -&gt;</span> <span class="hljs-keyword">typeof</span> obj <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span> <span class="hljs-keyword">and</span> !!obj <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> Array.isArray(obj) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> isNumber(obj) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> isString(obj) <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> isBoolean(obj)
<span class="hljs-function">
<span class="hljs-title">unicodeCodePointToUnicodeEscapes</span> = <span class="hljs-params">(codePoint)</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-title">toUnicodeEscape</span> = <span class="hljs-params">(val)</span> -&gt;</span>
str = val.toString <span class="hljs-number">16</span>
<span class="hljs-string">"\\u<span class="hljs-subst">#{repeat <span class="hljs-string">'0'</span>, <span class="hljs-number">4</span> - str.length}</span><span class="hljs-subst">#{str}</span>"</span>
<span class="hljs-keyword">return</span> toUnicodeEscape(codePoint) <span class="hljs-keyword">if</span> codePoint &lt; <span class="hljs-number">0x10000</span></pre></div></div>
</li>
<li id="section-33">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-33">&#182;</a>
</div>
<p>surrogate pair</p>
</div>
<div class="content"><div class='highlight'><pre> high = Math.floor((codePoint - <span class="hljs-number">0x10000</span>) / <span class="hljs-number">0x400</span>) + <span class="hljs-number">0xD800</span>
low = (codePoint - <span class="hljs-number">0x10000</span>) % <span class="hljs-number">0x400</span> + <span class="hljs-number">0xDC00</span>
<span class="hljs-string">"<span class="hljs-subst">#{toUnicodeEscape(high)}</span><span class="hljs-subst">#{toUnicodeEscape(low)}</span>"</span></pre></div></div>
</li>
<li id="section-34">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-34">&#182;</a>
</div>
<p>Replace <code>\u{...}</code> with <code>\uxxxx[\uxxxx]</code> in regexes without <code>u</code> flag</p>
</div>
<div class="content"><div class='highlight'><pre>exports.replaceUnicodeCodePointEscapes = <span class="hljs-function"><span class="hljs-params">(str, {flags, error, delimiter = <span class="hljs-string">''</span>} = {})</span> -&gt;</span>
shouldReplace = flags? <span class="hljs-keyword">and</span> <span class="hljs-string">'u'</span> <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> flags
str.replace UNICODE_CODE_POINT_ESCAPE, <span class="hljs-function"><span class="hljs-params">(match, escapedBackslash, codePointHex, offset)</span> -&gt;</span>
<span class="hljs-keyword">return</span> escapedBackslash <span class="hljs-keyword">if</span> escapedBackslash
codePointDecimal = parseInt codePointHex, <span class="hljs-number">16</span>
<span class="hljs-keyword">if</span> codePointDecimal &gt; <span class="hljs-number">0x10ffff</span>
error <span class="hljs-string">"unicode code point escapes greater than \\u{10ffff} are not allowed"</span>,
offset: offset + delimiter.length
length: codePointHex.length + <span class="hljs-number">4</span>
<span class="hljs-keyword">return</span> match <span class="hljs-keyword">unless</span> shouldReplace
unicodeCodePointToUnicodeEscapes codePointDecimal
UNICODE_CODE_POINT_ESCAPE = <span class="hljs-regexp">///
( \\\\ ) <span class="hljs-comment"># Make sure the escape isnt escaped.</span>
|
\\u\{ ( [\da-fA-F]+ ) \}
///</span>g</pre></div></div>
</li>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -196,7 +196,7 @@ Unwrap that too.</p>
</div>
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal, Call, Code} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span>
<div class="content"><div class='highlight'><pre> {Block, Assign, Value, Literal, Call, Code, Root} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span>
<span class="hljs-keyword">try</span></pre></div></div>
@ -229,11 +229,11 @@ Unwrap that too.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tokens.length &gt;= <span class="hljs-number">2</span> <span class="hljs-keyword">and</span> tokens[<span class="hljs-number">0</span>].generated <span class="hljs-keyword">and</span>
tokens[<span class="hljs-number">0</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> tokens[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span> <span class="hljs-keyword">and</span>
tokens[<span class="hljs-number">0</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> <span class="hljs-string">"<span class="hljs-subst">#{tokens[<span class="hljs-number">0</span>][<span class="hljs-number">1</span>]}</span>"</span> <span class="hljs-keyword">is</span> <span class="hljs-string">''</span> <span class="hljs-keyword">and</span>
tokens[<span class="hljs-number">1</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'TERMINATOR'</span>
tokens = tokens[<span class="hljs-number">2.</span>..]
<span class="hljs-keyword">if</span> tokens.length &gt;= <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> tokens[tokens.length - <span class="hljs-number">1</span>].generated <span class="hljs-keyword">and</span>
tokens[tokens.length - <span class="hljs-number">1</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> tokens[tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
tokens[tokens.length - <span class="hljs-number">1</span>].comments?.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> <span class="hljs-string">"<span class="hljs-subst">#{tokens[tokens.length - <span class="hljs-number">1</span>][<span class="hljs-number">1</span>]}</span>"</span> <span class="hljs-keyword">is</span> <span class="hljs-string">''</span>
tokens.pop()</pre></div></div>
</li>
@ -264,7 +264,7 @@ Unwrap that too.</p>
</div>
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes tokens</pre></div></div>
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes(tokens).body</pre></div></div>
</li>
@ -310,7 +310,7 @@ Unwrap that too.</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]
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Root <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>}
<span class="hljs-keyword">if</span> transpile
js = transpile.transpile(js, transpile.options).code</pre></div></div>

View File

@ -125,7 +125,7 @@ parentheses, and generally clean things up.</p>
</div>
<div class="content"><div class='highlight'><pre>
{throwSyntaxError} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span></pre></div></div>
{throwSyntaxError, extractAllCommentTokens} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span></pre></div></div>
</li>
@ -234,11 +234,11 @@ output the token stream after it has been rewritten by this file.</p>
@normalizeLines()
@tagPostfixConditionals()
@addImplicitBracesAndParens()
@addParensToChainedDoIife()
@rescueStowawayComments()
@addLocationDataToGeneratedTokens()
@enforceValidCSXAttributes()
@fixOutdentLocationData()
@enforceValidJSXAttributes()
@fixIndentationLocationData()
@exposeTokenDataToGrammar()
<span class="hljs-keyword">if</span> process?.env?.DEBUG_REWRITTEN_TOKEN_STREAM
<span class="hljs-built_in">console</span>.log <span class="hljs-string">'Rewritten token stream:'</span> <span class="hljs-keyword">if</span> process.env.DEBUG_TOKEN_STREAM
<span class="hljs-built_in">console</span>.log (t[<span class="hljs-number">0</span>] + <span class="hljs-string">'/'</span> + t[<span class="hljs-number">1</span>] + (<span class="hljs-keyword">if</span> t.comments <span class="hljs-keyword">then</span> <span class="hljs-string">'*'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>) <span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> @tokens).join <span class="hljs-string">' '</span>
@ -386,14 +386,21 @@ Match it with its paired close.</p>
</div>
<div class="content"><div class='highlight'><pre> closeOpenIndexes: <span class="hljs-function">-&gt;</span>
startToken = <span class="hljs-literal">null</span>
<span class="hljs-function"> <span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> [<span class="hljs-string">']'</span>, <span class="hljs-string">'INDEX_END'</span>]
<span class="hljs-function">
<span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
token[<span class="hljs-number">0</span>] = <span class="hljs-string">'INDEX_END'</span>
<span class="hljs-keyword">if</span> @tokens.length &gt;= i <span class="hljs-keyword">and</span> @tokens[i + <span class="hljs-number">1</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">':'</span>
startToken[<span class="hljs-number">0</span>] = <span class="hljs-string">'['</span>
token[<span class="hljs-number">0</span>] = <span class="hljs-string">']'</span>
<span class="hljs-keyword">else</span>
token[<span class="hljs-number">0</span>] = <span class="hljs-string">'INDEX_END'</span>
@scanTokens (token, i) -&gt;
@detectEnd i + <span class="hljs-number">1</span>, condition, action <span class="hljs-keyword">if</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'INDEX_START'</span>
<span class="hljs-keyword">if</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'INDEX_START'</span>
startToken = token
@detectEnd i + <span class="hljs-number">1</span>, condition, action
<span class="hljs-number">1</span></pre></div></div>
</li>
@ -780,7 +787,12 @@ that creates grammatical ambiguities.</p>
</div>
<div class="content"><div class='highlight'><pre> s = <span class="hljs-keyword">switch</span>
<span class="hljs-keyword">when</span> @tag(i - <span class="hljs-number">1</span>) <span class="hljs-keyword">in</span> EXPRESSION_END <span class="hljs-keyword">then</span> start[<span class="hljs-number">1</span>]
<span class="hljs-keyword">when</span> @tag(i - <span class="hljs-number">1</span>) <span class="hljs-keyword">in</span> EXPRESSION_END
[startTag, startIndex] = start
<span class="hljs-keyword">if</span> startTag <span class="hljs-keyword">is</span> <span class="hljs-string">'['</span> <span class="hljs-keyword">and</span> startIndex &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> @tag(startIndex - <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'@'</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> tokens[startIndex - <span class="hljs-number">1</span>].spaced
startIndex - <span class="hljs-number">1</span>
<span class="hljs-keyword">else</span>
startIndex
<span class="hljs-keyword">when</span> @tag(i - <span class="hljs-number">2</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'@'</span> <span class="hljs-keyword">then</span> i - <span class="hljs-number">2</span>
<span class="hljs-keyword">else</span> i - <span class="hljs-number">1</span>
@ -969,13 +981,13 @@ array further up the stack, so give it a chance.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-38">&#182;</a>
</div>
<p>Make sure only strings and wrapped expressions are used in CSX attributes.</p>
<p>Make sure only strings and wrapped expressions are used in JSX attributes.</p>
</div>
<div class="content"><div class='highlight'><pre> enforceValidCSXAttributes: <span class="hljs-function">-&gt;</span>
<div class="content"><div class='highlight'><pre> enforceValidJSXAttributes: <span class="hljs-function">-&gt;</span>
@scanTokens (token, i, tokens) -&gt;
<span class="hljs-keyword">if</span> token.csxColon
<span class="hljs-keyword">if</span> token.jsxColon
next = tokens[i + <span class="hljs-number">1</span>]
<span class="hljs-keyword">if</span> next[<span class="hljs-number">0</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'STRING_START'</span>, <span class="hljs-string">'STRING'</span>, <span class="hljs-string">'('</span>]
throwSyntaxError <span class="hljs-string">'expected wrapped or quoted JSX attribute'</span>, next[<span class="hljs-number">2</span>]
@ -1000,6 +1012,13 @@ to a token that will make it to the other side.</p>
<span class="hljs-function"> <span class="hljs-title">insertPlaceholder</span> = <span class="hljs-params">(token, j, tokens, method)</span> -&gt;</span>
tokens[method] generate <span class="hljs-string">'TERMINATOR'</span>, <span class="hljs-string">'\n'</span>, tokens[j] <span class="hljs-keyword">unless</span> tokens[j][<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'TERMINATOR'</span>
tokens[method] generate <span class="hljs-string">'JS'</span>, <span class="hljs-string">''</span>, tokens[j], token
<span class="hljs-function">
<span class="hljs-title">dontShiftForward</span> = <span class="hljs-params">(i, tokens)</span> -&gt;</span>
j = i + <span class="hljs-number">1</span>
<span class="hljs-keyword">while</span> j <span class="hljs-keyword">isnt</span> tokens.length <span class="hljs-keyword">and</span> tokens[j][<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> DISCARDED
<span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> tokens[j][<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'INTERPOLATION_END'</span>
j++
<span class="hljs-literal">no</span>
<span class="hljs-function">
<span class="hljs-title">shiftCommentsForward</span> = <span class="hljs-params">(token, i, tokens)</span> -&gt;</span></pre></div></div>
@ -1114,7 +1133,7 @@ safe token, while other tokens should shift forward.</p>
ret = shiftCommentsBackward dummyToken, i - <span class="hljs-number">1</span>, tokens
<span class="hljs-keyword">if</span> token.comments.length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>
shiftCommentsForward token, i, tokens
<span class="hljs-keyword">else</span></pre></div></div>
<span class="hljs-keyword">else</span> <span class="hljs-keyword">unless</span> dontShiftForward i, tokens</pre></div></div>
</li>
@ -1169,17 +1188,26 @@ discarded tokens.</p>
@scanTokens (token, i, tokens) -&gt;
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> token[<span class="hljs-number">2</span>]
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> token.generated <span class="hljs-keyword">or</span> token.explicit
<span class="hljs-keyword">if</span> token.fromThen <span class="hljs-keyword">and</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'INDENT'</span>
token[<span class="hljs-number">2</span>] = token.origin[<span class="hljs-number">2</span>]
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
<span class="hljs-keyword">if</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'{'</span> <span class="hljs-keyword">and</span> nextLocation=tokens[i + <span class="hljs-number">1</span>]?[<span class="hljs-number">2</span>]
{first_line: line, first_column: column} = nextLocation
{first_line: line, first_column: column, range: [rangeIndex]} = nextLocation
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> prevLocation = tokens[i - <span class="hljs-number">1</span>]?[<span class="hljs-number">2</span>]
{last_line: line, last_column: column} = prevLocation
{last_line: line, last_column: column, range: [, rangeIndex]} = prevLocation
column += <span class="hljs-number">1</span>
<span class="hljs-keyword">else</span>
line = column = <span class="hljs-number">0</span>
token[<span class="hljs-number">2</span>] =
first_line: line
first_column: column
last_line: line
last_column: column
rangeIndex = <span class="hljs-number">0</span>
token[<span class="hljs-number">2</span>] = {
first_line: line
first_column: column
last_line: line
last_column: column
last_line_exclusive: line
last_column_exclusive: column
range: [rangeIndex, rangeIndex]
}
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span></pre></div></div>
</li>
@ -1197,18 +1225,36 @@ location corresponding to the last “real” token under the node.</p>
</div>
<div class="content"><div class='highlight'><pre> fixOutdentLocationData: <span class="hljs-function">-&gt;</span>
<div class="content"><div class='highlight'><pre> fixIndentationLocationData: <span class="hljs-function">-&gt;</span>
@allComments ?= extractAllCommentTokens @tokens
<span class="hljs-function"> <span class="hljs-title">findPrecedingComment</span> = <span class="hljs-params">(token, {afterPosition, indentSize, first, indented})</span> =&gt;</span>
tokenStart = token[<span class="hljs-number">2</span>].range[<span class="hljs-number">0</span>]
<span class="hljs-function"> <span class="hljs-title">matches</span> = <span class="hljs-params">(comment)</span> -&gt;</span>
<span class="hljs-keyword">if</span> comment.outdented
<span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> indentSize? <span class="hljs-keyword">and</span> comment.indentSize &gt; indentSize
<span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">if</span> indented <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> comment.indented
<span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> comment.locationData.range[<span class="hljs-number">0</span>] &lt; tokenStart
<span class="hljs-keyword">return</span> <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> comment.locationData.range[<span class="hljs-number">0</span>] &gt; afterPosition
<span class="hljs-literal">yes</span>
<span class="hljs-keyword">if</span> first
lastMatching = <span class="hljs-literal">null</span>
<span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> @allComments <span class="hljs-keyword">by</span> <span class="hljs-number">-1</span>
<span class="hljs-keyword">if</span> matches comment
lastMatching = comment
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> lastMatching
<span class="hljs-keyword">return</span> lastMatching
<span class="hljs-keyword">return</span> lastMatching
<span class="hljs-keyword">for</span> comment <span class="hljs-keyword">in</span> @allComments <span class="hljs-keyword">when</span> matches comment <span class="hljs-keyword">by</span> <span class="hljs-number">-1</span>
<span class="hljs-keyword">return</span> comment
<span class="hljs-literal">null</span>
@scanTokens (token, i, tokens) -&gt;
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'OUTDENT'</span> <span class="hljs-keyword">or</span>
(token.generated <span class="hljs-keyword">and</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'CALL_END'</span>) <span class="hljs-keyword">or</span>
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> [<span class="hljs-string">'INDENT'</span>, <span class="hljs-string">'OUTDENT'</span>] <span class="hljs-keyword">or</span>
(token.generated <span class="hljs-keyword">and</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'CALL_END'</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> token.data?.closingTagNameToken) <span class="hljs-keyword">or</span>
(token.generated <span class="hljs-keyword">and</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'}'</span>)
prevLocationData = tokens[i - <span class="hljs-number">1</span>][<span class="hljs-number">2</span>]
token[<span class="hljs-number">2</span>] =
first_line: prevLocationData.last_line
first_column: prevLocationData.last_column
last_line: prevLocationData.last_line
last_column: prevLocationData.last_column
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span></pre></div></div>
isIndent = token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'INDENT'</span>
prevToken = token.prevToken ? tokens[i - <span class="hljs-number">1</span>]
prevLocationData = prevToken[<span class="hljs-number">2</span>]</pre></div></div>
</li>
@ -1219,32 +1265,29 @@ location corresponding to the last “real” token under the node.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-48">&#182;</a>
</div>
<p>Add parens around a <code>do</code> IIFE followed by a chained <code>.</code> so that the
chaining applies to the executed function rather than the function
object (see #3736)</p>
<p>addLocationDataToGeneratedTokens() set the outdents location data
to the preceding tokens, but in order to detect comments inside an
empty “block” we want to look for comments preceding the next token.</p>
</div>
<div class="content"><div class='highlight'><pre> addParensToChainedDoIife: <span class="hljs-function">-&gt;</span>
<span class="hljs-function"> <span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
@tag(i - <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'OUTDENT'</span>
<span class="hljs-function"> <span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> CALL_CLOSERS
@tokens.splice doIndex, <span class="hljs-number">0</span>, generate <span class="hljs-string">'('</span>, <span class="hljs-string">'('</span>, @tokens[doIndex]
@tokens.splice i + <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, generate <span class="hljs-string">')'</span>, <span class="hljs-string">')'</span>, @tokens[i]
doIndex = <span class="hljs-literal">null</span>
@scanTokens (token, i, tokens) -&gt;
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> token[<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'do'</span>
doIndex = i
glyphIndex = i + <span class="hljs-number">1</span>
<span class="hljs-keyword">if</span> @tag(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'PARAM_START'</span>
glyphIndex = <span class="hljs-literal">null</span>
@detectEnd i + <span class="hljs-number">1</span>,
<span class="hljs-function"><span class="hljs-params">(token, i)</span> -&gt;</span> @tag(i - <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'PARAM_END'</span>
(token, i) -&gt; glyphIndex = i
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> glyphIndex? <span class="hljs-keyword">and</span> @tag(glyphIndex) <span class="hljs-keyword">in</span> [<span class="hljs-string">'-&gt;'</span>, <span class="hljs-string">'=&gt;'</span>] <span class="hljs-keyword">and</span> @tag(glyphIndex + <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'INDENT'</span>
@detectEnd glyphIndex + <span class="hljs-number">1</span>, condition, action
<span class="hljs-keyword">return</span> <span class="hljs-number">2</span></pre></div></div>
<div class="content"><div class='highlight'><pre> useNextToken = token.explicit <span class="hljs-keyword">or</span> token.generated
<span class="hljs-keyword">if</span> useNextToken
nextToken = token
nextTokenIndex = i
nextToken = tokens[nextTokenIndex++] <span class="hljs-keyword">while</span> (nextToken.explicit <span class="hljs-keyword">or</span> nextToken.generated) <span class="hljs-keyword">and</span> nextTokenIndex <span class="hljs-keyword">isnt</span> tokens.length - <span class="hljs-number">1</span>
precedingComment = findPrecedingComment(
<span class="hljs-keyword">if</span> useNextToken
nextToken
<span class="hljs-keyword">else</span>
token
afterPosition: prevLocationData.range[<span class="hljs-number">0</span>]
indentSize: token.indentSize
first: isIndent
indented: useNextToken
)
<span class="hljs-keyword">if</span> isIndent
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">unless</span> precedingComment?.newLine</pre></div></div>
</li>
@ -1255,6 +1298,50 @@ object (see #3736)</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-49">&#182;</a>
</div>
<p>We dont want e.g. an implicit call at the end of an <code>if</code> condition to
include a following indented comment.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> token.generated <span class="hljs-keyword">and</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'CALL_END'</span> <span class="hljs-keyword">and</span> precedingComment?.indented
prevLocationData = precedingComment.locationData <span class="hljs-keyword">if</span> precedingComment?
token[<span class="hljs-number">2</span>] =
first_line:
<span class="hljs-keyword">if</span> precedingComment?
prevLocationData.first_line
<span class="hljs-keyword">else</span>
prevLocationData.last_line
first_column:
<span class="hljs-keyword">if</span> precedingComment?
<span class="hljs-keyword">if</span> isIndent
<span class="hljs-number">0</span>
<span class="hljs-keyword">else</span>
prevLocationData.first_column
<span class="hljs-keyword">else</span>
prevLocationData.last_column
last_line: prevLocationData.last_line
last_column: prevLocationData.last_column
last_line_exclusive: prevLocationData.last_line_exclusive
last_column_exclusive: prevLocationData.last_column_exclusive
range:
<span class="hljs-keyword">if</span> isIndent <span class="hljs-keyword">and</span> precedingComment?
[
prevLocationData.range[<span class="hljs-number">0</span>] - precedingComment.indentSize
prevLocationData.range[<span class="hljs-number">1</span>]
]
<span class="hljs-keyword">else</span>
prevLocationData.range
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span></pre></div></div>
</li>
<li id="section-50">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-50">&#182;</a>
</div>
<p>Because our grammar is LALR(1), it cant handle some single-line
expressions that lack ending delimiters. The <strong>Rewriter</strong> adds the implicit
blocks, so it doesnt need to. To keep the grammar clean and tidy, trailing
@ -1271,11 +1358,11 @@ blocks are added.</p>
</li>
<li id="section-50">
<li id="section-51">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-50">&#182;</a>
<a class="pilcrow" href="#section-51">&#182;</a>
</div>
<p>Count <code>THEN</code> tags</p>
@ -1305,11 +1392,11 @@ blocks are added.</p>
</li>
<li id="section-51">
<li id="section-52">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-51">&#182;</a>
<a class="pilcrow" href="#section-52">&#182;</a>
</div>
<p>Insert <code>OUTDENT</code> to close inner <code>IF</code>.</p>
@ -1321,11 +1408,11 @@ blocks are added.</p>
</li>
<li id="section-52">
<li id="section-53">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-52">&#182;</a>
<a class="pilcrow" href="#section-53">&#182;</a>
</div>
<p>Insert <code>OUTDENT</code> to close outer <code>IF</code>.</p>
@ -1337,11 +1424,11 @@ blocks are added.</p>
</li>
<li id="section-53">
<li id="section-54">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-53">&#182;</a>
<a class="pilcrow" href="#section-54">&#182;</a>
</div>
<p>Remove outdents from the end.</p>
@ -1365,13 +1452,16 @@ blocks are added.</p>
tokens.splice i, <span class="hljs-number">1</span>, @indentation()...
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
<span class="hljs-keyword">if</span> @tag(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">in</span> EXPRESSION_CLOSE
<span class="hljs-keyword">if</span> token[<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">';'</span> <span class="hljs-keyword">and</span> @tag(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'OUTDENT'</span>
tokens[i + <span class="hljs-number">1</span>].prevToken = token
moveComments token, tokens[i + <span class="hljs-number">1</span>]
tokens.splice i, <span class="hljs-number">1</span>
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>
<span class="hljs-keyword">if</span> tag <span class="hljs-keyword">is</span> <span class="hljs-string">'CATCH'</span>
<span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> [<span class="hljs-number">1.</span><span class="hljs-number">.2</span>] <span class="hljs-keyword">when</span> @tag(i + j) <span class="hljs-keyword">in</span> [<span class="hljs-string">'OUTDENT'</span>, <span class="hljs-string">'TERMINATOR'</span>, <span class="hljs-string">'FINALLY'</span>]
tokens.splice i + j, <span class="hljs-number">0</span>, @indentation()...
<span class="hljs-keyword">return</span> <span class="hljs-number">2</span> + j
<span class="hljs-keyword">if</span> tag <span class="hljs-keyword">in</span> [<span class="hljs-string">'-&gt;'</span>, <span class="hljs-string">'=&gt;'</span>] <span class="hljs-keyword">and</span> (@tag(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">','</span> <span class="hljs-keyword">or</span> @tag(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'.'</span> <span class="hljs-keyword">and</span> token.newLine)
<span class="hljs-keyword">if</span> tag <span class="hljs-keyword">in</span> [<span class="hljs-string">'-&gt;'</span>, <span class="hljs-string">'=&gt;'</span>] <span class="hljs-keyword">and</span> (@tag(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">in</span> [<span class="hljs-string">','</span>, <span class="hljs-string">']'</span>] <span class="hljs-keyword">or</span> @tag(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'.'</span> <span class="hljs-keyword">and</span> token.newLine)
[indent, outdent] = @indentation tokens[i]
tokens.splice i + <span class="hljs-number">1</span>, <span class="hljs-number">0</span>, indent, outdent
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>
@ -1389,11 +1479,11 @@ blocks are added.</p>
</li>
<li id="section-54">
<li id="section-55">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-54">&#182;</a>
<a class="pilcrow" href="#section-55">&#182;</a>
</div>
<p><code>ELSE</code> tag is not closed.</p>
@ -1410,11 +1500,11 @@ blocks are added.</p>
</li>
<li id="section-55">
<li id="section-56">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-55">&#182;</a>
<a class="pilcrow" href="#section-56">&#182;</a>
</div>
<p>Tag postfix conditionals as such, so that we can parse them with a
different precedence.</p>
@ -1442,11 +1532,36 @@ different precedence.</p>
</li>
<li id="section-56">
<li id="section-57">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-56">&#182;</a>
<a class="pilcrow" href="#section-57">&#182;</a>
</div>
<p>For tokens with extra data, we want to make that data visible to the grammar
by wrapping the token value as a String() object and setting the data as
properties of that object. The grammar should then be responsible for
cleaning this up for the node constructor: unwrapping the token value to a
primitive string and separately passing any expected token data properties</p>
</div>
<div class="content"><div class='highlight'><pre> exposeTokenDataToGrammar: <span class="hljs-function">-&gt;</span>
@scanTokens (token, i) -&gt;
<span class="hljs-keyword">if</span> token.generated <span class="hljs-keyword">or</span> (token.data <span class="hljs-keyword">and</span> Object.keys(token.data).length <span class="hljs-keyword">isnt</span> <span class="hljs-number">0</span>)
token[<span class="hljs-number">1</span>] = <span class="hljs-keyword">new</span> String token[<span class="hljs-number">1</span>]
token[<span class="hljs-number">1</span>][key] = val <span class="hljs-keyword">for</span> own key, val <span class="hljs-keyword">of</span> (token.data ? {})
token[<span class="hljs-number">1</span>].generated = <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> token.generated
<span class="hljs-number">1</span></pre></div></div>
</li>
<li id="section-58">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-58">&#182;</a>
</div>
<p>Generate the indentation tokens, based on another token on the same line.</p>
@ -1467,11 +1582,11 @@ different precedence.</p>
</li>
<li id="section-57">
<li id="section-59">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-57">&#182;</a>
<a class="pilcrow" href="#section-59">&#182;</a>
</div>
<p>Look up a tag by token index.</p>
@ -1482,11 +1597,11 @@ different precedence.</p>
</li>
<li id="section-58">
<li id="section-60">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-58">&#182;</a>
<a class="pilcrow" href="#section-60">&#182;</a>
</div>
<h2 id="constants">Constants</h2>
@ -1495,11 +1610,11 @@ different precedence.</p>
</li>
<li id="section-59">
<li id="section-61">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-59">&#182;</a>
<a class="pilcrow" href="#section-61">&#182;</a>
</div>
</div>
@ -1507,11 +1622,11 @@ different precedence.</p>
</li>
<li id="section-60">
<li id="section-62">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-60">&#182;</a>
<a class="pilcrow" href="#section-62">&#182;</a>
</div>
<p>List of the token pairs that must be balanced.</p>
@ -1526,17 +1641,18 @@ different precedence.</p>
[<span class="hljs-string">'PARAM_START'</span>, <span class="hljs-string">'PARAM_END'</span>]
[<span class="hljs-string">'INDEX_START'</span>, <span class="hljs-string">'INDEX_END'</span>]
[<span class="hljs-string">'STRING_START'</span>, <span class="hljs-string">'STRING_END'</span>]
[<span class="hljs-string">'INTERPOLATION_START'</span>, <span class="hljs-string">'INTERPOLATION_END'</span>]
[<span class="hljs-string">'REGEX_START'</span>, <span class="hljs-string">'REGEX_END'</span>]
]</pre></div></div>
</li>
<li id="section-61">
<li id="section-63">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-61">&#182;</a>
<a class="pilcrow" href="#section-63">&#182;</a>
</div>
<p>The inverse mappings of <code>BALANCED_PAIRS</code> were trying to fix up, so we can
look things up from either end.</p>
@ -1548,11 +1664,11 @@ look things up from either end.</p>
</li>
<li id="section-62">
<li id="section-64">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-62">&#182;</a>
<a class="pilcrow" href="#section-64">&#182;</a>
</div>
<p>The tokens that signal the start/end of a balanced pair.</p>
@ -1568,11 +1684,11 @@ EXPRESSION_END = []
</li>
<li id="section-63">
<li id="section-65">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-63">&#182;</a>
<a class="pilcrow" href="#section-65">&#182;</a>
</div>
<p>Tokens that indicate the close of a clause of an expression.</p>
@ -1583,11 +1699,11 @@ EXPRESSION_END = []
</li>
<li id="section-64">
<li id="section-66">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-64">&#182;</a>
<a class="pilcrow" href="#section-66">&#182;</a>
</div>
<p>Tokens that, if followed by an <code>IMPLICIT_CALL</code>, indicate a function invocation.</p>
@ -1598,22 +1714,22 @@ EXPRESSION_END = []
</li>
<li id="section-65">
<li id="section-67">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-65">&#182;</a>
<a class="pilcrow" href="#section-67">&#182;</a>
</div>
<p>If preceded by an <code>IMPLICIT_FUNC</code>, indicates a function invocation.</p>
</div>
<div class="content"><div class='highlight'><pre>IMPLICIT_CALL = [
<span class="hljs-string">'IDENTIFIER'</span>, <span class="hljs-string">'CSX_TAG'</span>, <span class="hljs-string">'PROPERTY'</span>, <span class="hljs-string">'NUMBER'</span>, <span class="hljs-string">'INFINITY'</span>, <span class="hljs-string">'NAN'</span>
<span class="hljs-string">'IDENTIFIER'</span>, <span class="hljs-string">'JSX_TAG'</span>, <span class="hljs-string">'PROPERTY'</span>, <span class="hljs-string">'NUMBER'</span>, <span class="hljs-string">'INFINITY'</span>, <span class="hljs-string">'NAN'</span>
<span class="hljs-string">'STRING'</span>, <span class="hljs-string">'STRING_START'</span>, <span class="hljs-string">'REGEX'</span>, <span class="hljs-string">'REGEX_START'</span>, <span class="hljs-string">'JS'</span>
<span class="hljs-string">'NEW'</span>, <span class="hljs-string">'PARAM_START'</span>, <span class="hljs-string">'CLASS'</span>, <span class="hljs-string">'IF'</span>, <span class="hljs-string">'TRY'</span>, <span class="hljs-string">'SWITCH'</span>, <span class="hljs-string">'THIS'</span>
<span class="hljs-string">'UNDEFINED'</span>, <span class="hljs-string">'NULL'</span>, <span class="hljs-string">'BOOL'</span>
<span class="hljs-string">'UNARY'</span>, <span class="hljs-string">'YIELD'</span>, <span class="hljs-string">'AWAIT'</span>, <span class="hljs-string">'UNARY_MATH'</span>, <span class="hljs-string">'SUPER'</span>, <span class="hljs-string">'THROW'</span>
<span class="hljs-string">'UNARY'</span>, <span class="hljs-string">'DO'</span>, <span class="hljs-string">'DO_IIFE'</span>, <span class="hljs-string">'YIELD'</span>, <span class="hljs-string">'AWAIT'</span>, <span class="hljs-string">'UNARY_MATH'</span>, <span class="hljs-string">'SUPER'</span>, <span class="hljs-string">'THROW'</span>
<span class="hljs-string">'@'</span>, <span class="hljs-string">'-&gt;'</span>, <span class="hljs-string">'=&gt;'</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>
]
@ -1622,11 +1738,11 @@ IMPLICIT_UNSPACED_CALL = [<span class="hljs-string">'+'</span>, <span class="hlj
</li>
<li id="section-66">
<li id="section-68">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-66">&#182;</a>
<a class="pilcrow" href="#section-68">&#182;</a>
</div>
<p>Tokens that always mark the end of an implicit call for single-liners.</p>
@ -1638,11 +1754,11 @@ IMPLICIT_UNSPACED_CALL = [<span class="hljs-string">'+'</span>, <span class="hlj
</li>
<li id="section-67">
<li id="section-69">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-67">&#182;</a>
<a class="pilcrow" href="#section-69">&#182;</a>
</div>
<p>Single-line flavors of block expressions that have unclosed endings.
The grammar cant disambiguate them, so we insert the implicit indentation.</p>
@ -1655,11 +1771,11 @@ SINGLE_CLOSERS = [<span class="hljs-string">'TERMINATOR'</span>, <span class="
</li>
<li id="section-68">
<li id="section-70">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-68">&#182;</a>
<a class="pilcrow" href="#section-70">&#182;</a>
</div>
<p>Tokens that end a line.</p>
@ -1670,11 +1786,11 @@ SINGLE_CLOSERS = [<span class="hljs-string">'TERMINATOR'</span>, <span class="
</li>
<li id="section-69">
<li id="section-71">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-69">&#182;</a>
<a class="pilcrow" href="#section-71">&#182;</a>
</div>
<p>Tokens that close open calls when they follow a newline.</p>
@ -1685,11 +1801,11 @@ SINGLE_CLOSERS = [<span class="hljs-string">'TERMINATOR'</span>, <span class="
</li>
<li id="section-70">
<li id="section-72">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-70">&#182;</a>
<a class="pilcrow" href="#section-72">&#182;</a>
</div>
<p>Tokens that prevent a subsequent indent from ending implicit calls/objects</p>
@ -1700,11 +1816,11 @@ SINGLE_CLOSERS = [<span class="hljs-string">'TERMINATOR'</span>, <span class="
</li>
<li id="section-71">
<li id="section-73">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-71">&#182;</a>
<a class="pilcrow" href="#section-73">&#182;</a>
</div>
<p>Tokens that are swallowed up by the parser, never leading to code generation.
You can spot these in <code>grammar.coffee</code> because the <code>o</code> function second
@ -1715,11 +1831,11 @@ the node that becomes <code>StringWithInterpolations</code>, and therefore
</div>
<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_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>
<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">'?'</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">'DO'</span>, <span class="hljs-string">'DO_IIFE'</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">'INTERPOLATION_START'</span>, <span class="hljs-string">'INTERPOLATION_END'</span>, <span class="hljs-string">'LEADING_WHEN'</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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -693,7 +693,7 @@ textarea {
<section id="introduction">
<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.4.1">2.4.1</a></p>
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.5.0">2.5.0</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
@ -994,6 +994,10 @@ cubes = (function() {
<td>The <code>node</code> executable has some useful options you can set, such as <code>--debug</code>, <code>--debug-brk</code>, <code>--max-stack-size</code>, and <code>--expose-gc</code>. Use this flag to forward options directly to Node.js. To pass multiple flags, use <code>--nodejs</code> multiple times.</td>
</tr>
<tr>
<td><code>--ast</code></td>
<td>Generate an abstract syntax tree of nodes of the CoffeeScript. Used for integrating with JavaScript build tools.</td>
</tr>
<tr>
<td><code>--tokens</code></td>
<td>Instead of parsing the CoffeeScript, just lex it, and print out the token stream. Used for debugging the compiler.</td>
</tr>
@ -1041,6 +1045,7 @@ eval CoffeeScript.compile <span class="string">'console.log "Mmmmm, I could real
<li><code>options.bare</code>, boolean: if true, output without the <a href="#lexical-scope">top-level function safety wrapper</a>.</li>
<li><code>options.header</code>, boolean: if true, output the <code>Generated by CoffeeScript</code> header.</li>
<li><code>options.transpile</code>, <strong>object</strong>: if set, this must be an object with the <a href="http://babeljs.io/docs/usage/api/#options">options to pass to Babel</a>. See <a href="#transpilation">Transpilation</a>.</li>
<li><code>options.ast</code>, boolean: if true, return an abstract syntax tree of the input CoffeeScript source code.</li>
</ul>
</section>
@ -1276,11 +1281,15 @@ mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely --
<div class="col-md-6 javascript-output-column">
<textarea class="javascript-output" id="heredocs-js">var html;
html = "<strong>\n cup of coffeescript\n</strong>";
html = `<strong>
cup of coffeescript
</strong>`;
</textarea>
<pre class="placeholder-code"><span class="cm-keyword">var</span> <span class="cm-def">html</span>;
<span class="cm-variable">html</span> <span class="cm-operator">=</span> <span class="cm-string">"&lt;strong>\n cup of coffeescript\n&lt;/strong>"</span>;
<span class="cm-variable">html</span> <span class="cm-operator">=</span> <span class="cm-string-2">`&lt;strong></span>
<span class="cm-string-2">cup of coffeescript</span>
<span class="cm-string-2">&lt;/strong>`</span>;
</pre>
</div>
</div>
@ -1705,7 +1714,9 @@ contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn
awardMedals(...contenders);
alert(`Gold: ${gold}\nSilver: ${silver}\nThe Field: ${rest.join(', ')}`);
alert(`Gold: ${gold}
Silver: ${silver}
The Field: ${rest.join(', ')}`);
</textarea>
<pre class="placeholder-code"><span class="cm-keyword">var</span> <span class="cm-def">awardMedals</span>, <span class="cm-def">contenders</span>, <span class="cm-def">gold</span>, <span class="cm-def">rest</span>, <span class="cm-def">silver</span>;
@ -1721,7 +1732,9 @@ alert(`Gold: ${gold}\nSilver: ${silver}\nThe Field: ${rest.join(', ')}`);
<span class="cm-variable">awardMedals</span>(<span class="cm-meta">...</span><span class="cm-variable">contenders</span>);
<span class="cm-variable">alert</span>(<span class="cm-string-2">`Gold: ${</span><span class="cm-variable">gold</span><span class="cm-string-2">}\nSilver: ${</span><span class="cm-variable">silver</span><span class="cm-string-2">}\nThe Field: ${</span><span class="cm-variable">rest</span>.<span class="cm-property">join</span>(<span class="cm-string">', '</span>)<span class="cm-string-2">}`</span>);
<span class="cm-variable">alert</span>(<span class="cm-string-2">`Gold: ${</span><span class="cm-variable">gold</span><span class="cm-string-2">}</span>
<span class="cm-string-2">Silver: ${</span><span class="cm-variable">silver</span><span class="cm-string-2">}</span>
<span class="cm-string-2">The Field: ${</span><span class="cm-variable">rest</span>.<span class="cm-property">join</span>(<span class="cm-string">', '</span>)<span class="cm-string-2">}`</span>);
</pre>
</div>
</div>
@ -4441,14 +4454,20 @@ do ->
(async function() {
var run;
({run} = (await import('./browser-compiler-modern/coffeescript.js')));
return run('if 5 < new Date().getHours() < 9\n alert \'Time to make the coffee!\'\nelse\n alert \'Time to get some work done.\'');
return run(`if 5 < new Date().getHours() < 9
alert 'Time to make the coffee!'
else
alert 'Time to get some work done.'`);
})();
</textarea>
<pre class="placeholder-code"><span class="cm-comment">// Your browser must support dynamic import to run this example.</span>
(<span class="cm-keyword">async</span> <span class="cm-keyword">function</span>() {
<span class="cm-keyword">var</span> <span class="cm-def">run</span>;
({<span class="cm-property">run</span>} <span class="cm-operator">=</span> (<span class="cm-keyword">await</span> <span class="cm-keyword">import</span>(<span class="cm-string">'./browser-compiler-modern/coffeescript.js'</span>)));
<span class="cm-keyword">return</span> <span class="cm-variable-2">run</span>(<span class="cm-string">'if 5 &lt; new Date().getHours() &lt; 9\n alert \'Time to make the coffee!\'\nelse\n alert \'Time to get some work done.\''</span>);
<span class="cm-keyword">return</span> <span class="cm-variable-2">run</span>(<span class="cm-string-2">`if 5 &lt; new Date().getHours() &lt; 9</span>
<span class="cm-string-2">alert 'Time to make the coffee!'</span>
<span class="cm-string-2">else</span>
<span class="cm-string-2">alert 'Time to get some work done.'`</span>);
})();
</pre>
</div>
@ -4510,8 +4529,8 @@ hi = function() {
</div>
</aside>
<p>Escape backticks with backslashes: <code>\`</code> becomes <code>`</code>.</p>
<p>Escape backslashes before backticks with more backslashes: <code>\\\`</code> becomes <code>\`</code>.</p>
<p>Escape backticks with backslashes: <code> \`</code> becomes <code> `</code>.</p>
<p>Escape backslashes before backticks with more backslashes: <code> \\\`</code> becomes <code> \`</code>.</p>
<aside class="code-example container-fluid bg-ribbed-dark" data-example="embedded_escaped">
<div class="row">
<div class="col-md-6 coffeescript-input-column">
@ -4640,7 +4659,7 @@ renderStarRating = function({rating, maxStars}) {
}
return results;
})()}
{(rating % 1 !== 0 ? <Star className="halfStar" /> : void 0)}
{rating % 1 !== 0 ? <Star className="halfStar" /> : void 0}
{(function() {
var i, ref, ref1, results;
results = [];
@ -4665,7 +4684,7 @@ renderStarRating = function({rating, maxStars}) {
<span class="cm-string-2">}</span>
<span class="cm-string-2">return results;</span>
<span class="cm-string-2">})()}</span>
<span class="cm-string-2">{(rating % 1 !== 0 ? &lt;Star className="halfStar" /> : void 0)}</span>
<span class="cm-string-2">{rating % 1 !== 0 ? &lt;Star className="halfStar" /> : void 0}</span>
<span class="cm-string-2">{(function() {</span>
<span class="cm-string-2">var i, ref, ref1, results;</span>
<span class="cm-string-2">results = [];</span>
@ -4901,7 +4920,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.4.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.5.0 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>
@ -5450,7 +5469,7 @@ extend = function(child, parent) {
}
}
ctor.prototype = parent.prototype;
child.prototype = new ctor;
child.prototype = new ctor();
return child;
};
@ -5480,7 +5499,7 @@ B.prototype.foo = function() {
}
}
<span class="cm-variable-2">ctor</span>.<span class="cm-property">prototype</span> <span class="cm-operator">=</span> <span class="cm-variable-2">parent</span>.<span class="cm-property">prototype</span>;
<span class="cm-variable-2">child</span>.<span class="cm-property">prototype</span> <span class="cm-operator">=</span> <span class="cm-keyword">new</span> <span class="cm-variable-2">ctor</span>;
<span class="cm-variable-2">child</span>.<span class="cm-property">prototype</span> <span class="cm-operator">=</span> <span class="cm-keyword">new</span> <span class="cm-variable-2">ctor</span>();
<span class="cm-keyword">return</span> <span class="cm-variable-2">child</span>;
};
@ -5579,6 +5598,20 @@ x = <span class="number">2</span> + <span class="number">2</span>
<section id="changelog">
<h2>Changelog</h2>
<section id="2.5.0">
<h3><a href="https://github.com/jashkenas/coffeescript/compare/2.4.1...2.5.0">2.5.0</a>
<span class="timestamp"> &mdash; <time datetime="2019-12-31">2019-12-31</time></span>
</h3><ul>
<li>The compiler now supports a new <code>ast</code> option, available via <code>--ast</code> on the command line or <code>ast</code> via the Node API. This option outputs an “abstract syntax tree,” or a JSON-like representation of the input CoffeeScript source code. This AST follows <a href="https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md">Babels spec</a> as closely as possible, for compatibility with tools that work with JavaScript source code. Two tools that use this new AST output are <a href="https://github.com/helixbass/eslint-plugin-coffee"><code>eslint-plugin-coffee</code></a>, a plugin to lint CoffeeScript via <a href="https://eslint.org/">ESLint</a>; and <a href="https://github.com/helixbass/prettier-plugin-coffeescript"><code>prettier-plugin-coffeescript</code></a>, a plugin to reformat CoffeeScript source code via <a href="https://prettier.io/">Prettier</a>. <em>The structure and properties of CoffeeScripts AST are not final and may undergo breaking changes between CoffeeScript versions; please <a href="https://github.com/jashkenas/coffeescript/issues">open an issue</a> if you are interested in creating new integrations.</em></li>
<li><a href="https://github.com/tc39/proposal-numeric-separator">Numeric separators</a> are now supported in CoffeeScript, following the same syntax as JavaScript: <code>1_234_567</code>.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt"><code>BigInt</code> numbers</a> are now supported in CoffeeScript, following the same syntax as JavaScript: <code>42n</code>.</li>
<li><code>'''</code> and <code>&quot;&quot;&quot;</code> strings are now output as more readable JavaScript template literals, or backtick (<code>`</code>) strings, with actual newlines rather than <code>\n</code> escape sequences.</li>
<li>Classes can now contain computed properties, e.g. <code>[someVar]: -&gt;</code> or <code>@[anotherVar]: -&gt;</code>.</li>
<li>JSX tags can now contain XML-style namespaces, e.g. <code>&lt;image xlink:href=&quot;data:image/png&quot; /&gt;</code> or <code>&lt;Something:Tag&gt;&lt;/Something:Tag&gt;</code>.</li>
<li>Bugfixes for comments after colons not appearing the output; reserved words mistakenly being disallowed as JSX attributes; indented leading elisions in multiline arrays; and invalid location data in source maps.</li>
</ul>
</section>
<section id="2.4.1">
<h3><a href="https://github.com/jashkenas/coffeescript/compare/2.4.0...2.4.1">2.4.1</a>
<span class="timestamp"> &mdash; <time datetime="2019-04-08">2019-04-08</time></span>
@ -5939,8 +5972,8 @@ x = <span class="number">2</span> + <span class="number">2</span>
</h3><ul>
<li>CoffeeScript now supports ES2015 <a href="#tagged-template-literals">tagged template literals</a>. Note that using tagged template literals in your code makes you responsible for ensuring that either your runtime supports tagged template literals or that you transpile the output JavaScript further to a version your target runtime(s) support.</li>
<li>CoffeeScript now provides a <a href="#generator-iteration"><code>for…from</code></a> syntax for outputting ES2015 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of"><code>for…of</code></a>. (Sorry they couldnt match, but we came up with <code>for…of</code> first for something else.) This allows iterating over generators or any other iterable object. Note that using <code>for…from</code> in your code makes you responsible for ensuring that either your runtime supports <code>for…of</code> or that you transpile the output JavaScript further to a version your target runtime(s) support.</li>
<li>Triple backticks (<code>```</code>) allow the creation of embedded JavaScript blocks where escaping single backticks is not required, which should improve interoperability with ES2015 template literals and with Markdown.</li>
<li>Within single-backtick embedded JavaScript, backticks can now be escaped via <code>\`</code>.</li>
<li>Triple backticks (<code> ```</code>) allow the creation of embedded JavaScript blocks where escaping single backticks is not required, which should improve interoperability with ES2015 template literals and with Markdown.</li>
<li>Within single-backtick embedded JavaScript, backticks can now be escaped via <code> \`</code>.</li>
<li>The browser tests now run in the browser again, and are accessible <a href="/v2/test.html">here</a> if you would like to test your browser.</li>
<li>CoffeeScript-only keywords in ES2015 <code>import</code>s and <code>export</code>s are now ignored.</li>
<li>The compiler now throws an error on trying to export an anonymous class.</li>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
```
releaseHeader('2019-12-31', '2.5.0', '2.4.1')
```
* The compiler now supports a new `ast` option, available via `--ast` on the command line or `ast` via the Node API. This option outputs an “abstract syntax tree,” or a JSON-like representation of the input CoffeeScript source code. This AST follows [Babels spec](https://github.com/babel/babel/blob/master/packages/babel-parser/ast/spec.md) as closely as possible, for compatibility with tools that work with JavaScript source code. Two tools that use this new AST output are [`eslint-plugin-coffee`](https://github.com/helixbass/eslint-plugin-coffee), a plugin to lint CoffeeScript via [ESLint](https://eslint.org/); and [`prettier-plugin-coffeescript`](https://github.com/helixbass/prettier-plugin-coffeescript), a plugin to reformat CoffeeScript source code via [Prettier](https://prettier.io/). _The structure and properties of CoffeeScripts AST are not final and may undergo breaking changes between CoffeeScript versions; please [open an issue](https://github.com/jashkenas/coffeescript/issues) if you are interested in creating new integrations._
* [Numeric separators](https://github.com/tc39/proposal-numeric-separator) are now supported in CoffeeScript, following the same syntax as JavaScript: `1_234_567`.
* [`BigInt` numbers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) are now supported in CoffeeScript, following the same syntax as JavaScript: `42n`.
* `'''` and `"""` strings are now output as more readable JavaScript template literals, or backtick (`` ` ``) strings, with actual newlines rather than `\n` escape sequences.
* Classes can now contain computed properties, e.g. `[someVar]: ->` or `@[anotherVar]: ->`.
* JSX tags can now contain XML-style namespaces, e.g. `<image xlink:href="data:image/png" />` or `<Something:Tag></Something:Tag>`.
* Bugfixes for comments after colons not appearing the output; reserved words mistakenly being disallowed as JSX attributes; indented leading elisions in multiline arrays; and invalid location data in source maps.

View File

@ -19,6 +19,7 @@ Once installed, you should have access to the `coffee` command, which can execut
| `-b, --bare` | Compile the JavaScript without the [top-level function safety wrapper](#lexical-scope). |
| `--no-header` | Suppress the “Generated by CoffeeScript” header. |
| `--nodejs` | The `node` executable has some useful options you can set, such as `--debug`, `--debug-brk`, `--max-stack-size`, and `--expose-gc`. Use this flag to forward options directly to Node.js. To pass multiple flags, use `--nodejs` multiple times. |
| `--ast` | Generate an abstract syntax tree of nodes of the CoffeeScript. Used for integrating with JavaScript build tools. |
| `--tokens` | Instead of parsing the CoffeeScript, just lex it, and print out the token stream. Used for debugging the compiler. |
| `-n, --nodes` | Instead of compiling the CoffeeScript, just lex and parse it, and print out the parse tree. Used for debugging the compiler. |

View File

@ -23,4 +23,5 @@ The `compile` method has the signature `compile(code, options)` where `code` is
* `options.filename`, string: the filename to use for the source map. It can include a path (relative or absolute).
* `options.bare`, boolean: if true, output without the [top-level function safety wrapper](#lexical-scope).
* `options.header`, boolean: if true, output the `Generated by CoffeeScript` header.
* `options.transpile`, **object**: if set, this must be an object with the [options to pass to Babel](http://babeljs.io/docs/usage/api/#options). See [Transpilation](#transpilation).
* `options.transpile`, **object**: if set, this must be an object with the [options to pass to Babel](http://babeljs.io/docs/usage/api/#options). See [Transpilation](#transpilation).
* `options.ast`, boolean: if true, return an abstract syntax tree of the input CoffeeScript source code.

View File

@ -207,6 +207,9 @@
</section>
<section id="changelog">
<%= htmlFor('changelog') %>
<section id="2.5.0">
<%= htmlFor('changelog/2.5.0') %>
</section>
<section id="2.4.1">
<%= htmlFor('changelog/2.4.1') %>
</section>

View File

@ -44,7 +44,7 @@
<script type="text/coffeescript">
@testingBrowser = yes
@global = window
bold = red = green = reset = ''
@bold = @red = @green = @reset = ''
stdout = document.getElementById 'stdout'
start = new Date
@currentFile = ''

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(function() {
// Node.js Implementation
var CoffeeScript, ext, fs, helpers, i, len, path, ref, universalCompile, vm,

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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),

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.4.1
// Generated by CoffeeScript 2.5.0
(function() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat,
splice = [].splice;

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(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.4.1
// Generated by CoffeeScript 2.5.0
(function() {
// Source maps allow JavaScript runtimes to match running JavaScript back to
// the original source code that corresponds to it. This can be minified

1834
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
"compiler"
],
"author": "Jeremy Ashkenas",
"version": "2.4.1",
"version": "2.5.0",
"license": "MIT",
"engines": {
"node": ">=6"
@ -40,16 +40,16 @@
"url": "git://github.com/jashkenas/coffeescript.git"
},
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/preset-env": "^7.4.2",
"babel-preset-minify": "^0.5.0",
"codemirror": "^5.45.0",
"@babel/core": "^7.7.7",
"@babel/preset-env": "^7.7.7",
"babel-preset-minify": "^0.5.1",
"codemirror": "^5.50.0",
"docco": "~0.8.0",
"highlight.js": "~9.15.6",
"highlight.js": "~9.17.1",
"jison": "^0.4.18",
"markdown-it": "~8.4.2",
"markdown-it": "~10.0.0",
"underscore": "~1.9.1",
"webpack": "~4.29.6"
"webpack": "~4.41.5"
},
"dependencies": {}
}

View File

@ -57,7 +57,7 @@ test 'Confirm functionality of `deepStrictIncludeExpectedProperties`', ->
x: [1, 2, 3]
check = (message, test, expected) ->
test (-> deepStrictIncludeExpectedProperties actual, expected), message
test (-> deepStrictIncludeExpectedProperties actual, expected), null, message
check 'Expected property does not match', throws,
name: '"Name"'