mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-01-13 08:47:55 -05:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5aa758dda | ||
|
|
001f97ac39 | ||
|
|
ce66a499de | ||
|
|
0268505119 | ||
|
|
5a43b2d7c5 | ||
|
|
820942c3d0 | ||
|
|
1869f3121d | ||
|
|
4c0363fb7c | ||
|
|
746b0c7cc6 | ||
|
|
b2fe7772c5 | ||
|
|
23479eb486 | ||
|
|
63b8543d73 | ||
|
|
7542a75ff8 | ||
|
|
0875039d52 | ||
|
|
e0833c29ce | ||
|
|
72ab6feb2f | ||
|
|
eb7009268d | ||
|
|
571e9df335 |
@@ -3,6 +3,7 @@ language: node_js
|
||||
node_js:
|
||||
- 6
|
||||
- 8
|
||||
- 9
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -14,5 +15,6 @@ script:
|
||||
- node ./bin/cake build:full
|
||||
- node ./bin/cake build:browser
|
||||
- node ./bin/cake test
|
||||
- node --harmony ./bin/cake test
|
||||
- node ./bin/cake test:browser
|
||||
- node ./bin/cake test:integrations
|
||||
|
||||
46
CODE_OF_CONDUCT.md
Normal file
46
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at maintainers@coffeescript.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
22
Cakefile
22
Cakefile
@@ -425,12 +425,6 @@ runTests = (CoffeeScript) ->
|
||||
catch err
|
||||
onFail description, fn, err
|
||||
|
||||
global.supportsAsync = try
|
||||
new Function('async () => {}')()
|
||||
yes
|
||||
catch
|
||||
no
|
||||
|
||||
helpers.extend global, require './test/support/helpers'
|
||||
|
||||
# When all the tests have run, collect and print errors.
|
||||
@@ -448,10 +442,18 @@ runTests = (CoffeeScript) ->
|
||||
console.log " #{source}" if source
|
||||
return
|
||||
|
||||
# Run every test in the `test` folder, recording failures.
|
||||
files = fs.readdirSync 'test'
|
||||
unless global.supportsAsync # Except for async tests, if async isn’t supported.
|
||||
files = files.filter (filename) -> filename isnt 'async.coffee'
|
||||
# Run every test in the `test` folder, recording failures, except for files
|
||||
# we’re skipping because the features to be tested are unsupported in the
|
||||
# current Node runtime.
|
||||
testFilesToSkip = []
|
||||
skipUnless = (featureDetect, filenames) ->
|
||||
unless (try new Function featureDetect)
|
||||
testFilesToSkip = testFilesToSkip.concat filenames
|
||||
skipUnless 'async () => {}', ['async.coffee', 'async_iterators.coffee']
|
||||
skipUnless 'async function* generator() { yield 42; }', ['async_iterators.coffee']
|
||||
skipUnless 'var a = 2 ** 2; a **= 3', ['exponentiation.coffee']
|
||||
files = fs.readdirSync('test').filter (filename) ->
|
||||
filename not in testFilesToSkip
|
||||
|
||||
startTime = Date.now()
|
||||
for file in files when helpers.isCoffee file
|
||||
|
||||
62
ISSUE_TEMPLATE.md
Normal file
62
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,62 @@
|
||||
<!---
|
||||
Thanks for filing an issue 😄! Before you submit, please read the following:
|
||||
|
||||
Search open/closed issues before submitting since someone might have asked the same thing before!
|
||||
Our issues history stretches back to 2009, so the odds are good that your topic has come up.
|
||||
|
||||
If you have a support request or question please use Stack Overflow:
|
||||
https://stackoverflow.com/questions/tagged/coffeescript
|
||||
|
||||
Issues on GitHub are only related to problems of the CoffeeScript compiler itself and we cannot answer
|
||||
support questions here.
|
||||
-->
|
||||
|
||||
Choose one: is this a bug report or feature request?
|
||||
|
||||
<!---
|
||||
Provide a general summary of the issue in the title above.
|
||||
|
||||
For bugs, please also preface your title with “Bug:”. For feature requests, please preface your title
|
||||
with “Proposal:”. Once your issue is reviewed, a maintainer will edit the title to refer to the part
|
||||
of the codebase most relevant to the issue (if applicable).
|
||||
|
||||
If your request is that CoffeeScript support a new feature recently arrived to JavaScript, please note
|
||||
that we generally only add features that have reached Stage 4 in the specification (in other words,
|
||||
the syntax is finalized and the feature is approved to be part of the next ES release). You can still
|
||||
open an issue, but it will likely be tagged with “[Awaiting Stage 4]” until the relevant ES feature is
|
||||
approved for release. See http://coffeescript.org/#contributing
|
||||
|
||||
There are also a handful of JavaScript features that CoffeeScript intentionally does not support.
|
||||
Please do not open issues regarding these. They’re listed in http://coffeescript.org/#unsupported
|
||||
-->
|
||||
|
||||
### Input Code
|
||||
<!--- If you're describing a bug, please let us know which sample code reproduces your problem. -->
|
||||
<!--- If you have link from http://coffeescript.org/#try or a standalone repo please include that! -->
|
||||
|
||||
```coffee
|
||||
your (code) => here
|
||||
```
|
||||
|
||||
### Expected Behavior
|
||||
<!--- If you’re describing a bug, tell us what should happen. -->
|
||||
<!--- If you’re suggesting a change/improvement, tell us how it should work. -->
|
||||
|
||||
### Current Behavior
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior. -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior. -->
|
||||
|
||||
### Possible Solution
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change. -->
|
||||
|
||||
### Context
|
||||
<!--- How has this issue affected you? What are you trying to accomplish? -->
|
||||
<!--- Providing context helps us come up with a solution that is most useful in the real world. -->
|
||||
|
||||
### Environment
|
||||
<!--- For bugs, please let us know what version of CoffeeScript you’re running: `coffee -v`. -->
|
||||
<!--- If you think it might be relevant, please also let us know your version of Node. -->
|
||||
|
||||
* CoffeeScript version:
|
||||
* Node.js version:
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2017 Jeremy Ashkenas
|
||||
Copyright (c) 2009-2018 Jeremy Ashkenas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
||||
22
PULL_REQUEST_TEMPLATE.md
Normal file
22
PULL_REQUEST_TEMPLATE.md
Normal file
@@ -0,0 +1,22 @@
|
||||
<!--
|
||||
Before making a PR please make sure to read our contributing guidelines:
|
||||
http://coffeescript.org/#contributing
|
||||
|
||||
For issue references: Add a comma-separated list of a
|
||||
[closing word](https://help.github.com/articles/closing-issues-via-commit-messages/) followed by
|
||||
the ticket number fixed by the PR. It should be underlined in the preview if done correctly.
|
||||
|
||||
All new features require tests. All but the most trivial bug fixes should also have new or updated tests.
|
||||
|
||||
Ensure that all new code you add to the compiler can be run in the minimum version of Node listed in
|
||||
`package.json`. New tests can require newer Node runtimes, but you may need to ensure that such tests
|
||||
only run in supported runtimes; see `Cakefile` for examples of how to filter out certain tests in
|
||||
runtimes that don’t support them.
|
||||
|
||||
Please follow the code style of the rest of the CoffeeScript codebase. Write comments in complete
|
||||
sentences using Markdown, as the comments become the [annotated source](http://coffeescript.org/#annotated-source).
|
||||
For tests proving a bug is fixed, please mention the issue number in the test description (see examples
|
||||
in the codebase).
|
||||
|
||||
Describe your changes below in as much detail as possible.
|
||||
-->
|
||||
@@ -2,6 +2,7 @@ environment:
|
||||
matrix:
|
||||
- nodejs_version: '6'
|
||||
- nodejs_version: '8'
|
||||
- nodejs_version: '9'
|
||||
- nodejs_version: '' # Installs latest.
|
||||
|
||||
install:
|
||||
@@ -19,6 +20,7 @@ test_script:
|
||||
- node ./bin/cake build:full
|
||||
- node ./bin/cake build:browser
|
||||
- node ./bin/cake test
|
||||
- node --harmony ./bin/cake test
|
||||
- node ./bin/cake test:browser
|
||||
- node ./bin/cake test:integrations
|
||||
|
||||
|
||||
@@ -920,10 +920,10 @@ can close multiple indents, so we need to know how far in we happen to be.</p>
|
||||
indent = match[<span class="hljs-number">0</span>]
|
||||
|
||||
prev = @prev()
|
||||
backslash = prev? <span class="hljs-keyword">and</span> prev[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'\\'</span>
|
||||
backslash = prev?[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'\\'</span>
|
||||
@seenFor = <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> backslash <span class="hljs-keyword">and</span> @seenFor
|
||||
@seenImport = <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> @importSpecifierList
|
||||
@seenExport = <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> @exportSpecifierList
|
||||
@seenImport = <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> (backslash <span class="hljs-keyword">and</span> @seenImport) <span class="hljs-keyword">or</span> @importSpecifierList
|
||||
@seenExport = <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> (backslash <span class="hljs-keyword">and</span> @seenExport) <span class="hljs-keyword">or</span> @exportSpecifierList
|
||||
|
||||
size = indent.length - <span class="hljs-number">1</span> - indent.lastIndexOf <span class="hljs-string">'\n'</span>
|
||||
noNewlines = @unfinished()
|
||||
@@ -944,7 +944,7 @@ can close multiple indents, so we need to know how far in we happen to be.</p>
|
||||
|
||||
<span class="hljs-keyword">if</span> size > @indent
|
||||
<span class="hljs-keyword">if</span> noNewlines
|
||||
@indebt = size - @indent
|
||||
@indebt = size - @indent <span class="hljs-keyword">unless</span> backslash
|
||||
@suppressNewlines()
|
||||
<span class="hljs-keyword">return</span> indent.length
|
||||
<span class="hljs-keyword">unless</span> @tokens.length
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -646,7 +646,7 @@ div.CodeMirror-cursor {
|
||||
<section id="overview">
|
||||
<p><strong>CoffeeScript is a little language that compiles into JavaScript.</strong> Underneath that awkward Java-esque patina, JavaScript has always had a gorgeous heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way.</p>
|
||||
<p>The golden rule of CoffeeScript is: <em>“It’s just JavaScript.”</em> The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable, pretty-printed, and tends to run as fast or faster than the equivalent handwritten JavaScript.</p>
|
||||
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.2.1">2.2.1</a></p>
|
||||
<p><strong>Latest Version:</strong> <a href="https://github.com/jashkenas/coffeescript/tarball/2.2.4">2.2.4</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
|
||||
|
||||
@@ -3504,7 +3504,7 @@ say = function(text) {
|
||||
|
||||
countdown = async function(seconds) {
|
||||
var i, j, ref;
|
||||
for (i = j = ref = seconds; undefined !== 0 && (ref <= 1 ? ref <= j && j <= 1 : ref >= j && j >= 1); i = ref <= 1 ? ++j : --j) {
|
||||
for (i = j = ref = seconds; (ref <= 1 ? j <= 1 : j >= 1); i = ref <= 1 ? ++j : --j) {
|
||||
say(i);
|
||||
await sleep(1000); // wait one second
|
||||
}
|
||||
@@ -3530,7 +3530,7 @@ countdown(3);
|
||||
|
||||
<span class="cm-variable">countdown</span> <span class="cm-operator">=</span> <span class="cm-keyword">async</span> <span class="cm-keyword">function</span>(<span class="cm-def">seconds</span>) {
|
||||
<span class="cm-keyword">var</span> <span class="cm-def">i</span>, <span class="cm-def">j</span>, <span class="cm-def">ref</span>;
|
||||
<span class="cm-keyword">for</span> (<span class="cm-variable-2">i</span> <span class="cm-operator">=</span> <span class="cm-variable-2">j</span> <span class="cm-operator">=</span> <span class="cm-variable-2">ref</span> <span class="cm-operator">=</span> <span class="cm-variable-2">seconds</span>; <span class="cm-atom">undefined</span> <span class="cm-operator">!==</span> <span class="cm-number">0</span> <span class="cm-operator">&&</span> (<span class="cm-variable-2">ref</span> <span class="cm-operator"><=</span> <span class="cm-number">1</span> <span class="cm-operator">?</span> <span class="cm-variable-2">ref</span> <span class="cm-operator"><=</span> <span class="cm-variable-2">j</span> <span class="cm-operator">&&</span> <span class="cm-variable-2">j</span> <span class="cm-operator"><=</span> <span class="cm-number">1</span> : <span class="cm-variable-2">ref</span> <span class="cm-operator">>=</span> <span class="cm-variable-2">j</span> <span class="cm-operator">&&</span> <span class="cm-variable-2">j</span> <span class="cm-operator">>=</span> <span class="cm-number">1</span>); <span class="cm-variable-2">i</span> <span class="cm-operator">=</span> <span class="cm-variable-2">ref</span> <span class="cm-operator"><=</span> <span class="cm-number">1</span> <span class="cm-operator">?</span> <span class="cm-operator">++</span><span class="cm-variable-2">j</span> : <span class="cm-operator">--</span><span class="cm-variable-2">j</span>) {
|
||||
<span class="cm-keyword">for</span> (<span class="cm-variable-2">i</span> <span class="cm-operator">=</span> <span class="cm-variable-2">j</span> <span class="cm-operator">=</span> <span class="cm-variable-2">ref</span> <span class="cm-operator">=</span> <span class="cm-variable-2">seconds</span>; (<span class="cm-variable-2">ref</span> <span class="cm-operator"><=</span> <span class="cm-number">1</span> <span class="cm-operator">?</span> <span class="cm-variable-2">j</span> <span class="cm-operator"><=</span> <span class="cm-number">1</span> : <span class="cm-variable-2">j</span> <span class="cm-operator">>=</span> <span class="cm-number">1</span>); <span class="cm-variable-2">i</span> <span class="cm-operator">=</span> <span class="cm-variable-2">ref</span> <span class="cm-operator"><=</span> <span class="cm-number">1</span> <span class="cm-operator">?</span> <span class="cm-operator">++</span><span class="cm-variable-2">j</span> : <span class="cm-operator">--</span><span class="cm-variable-2">j</span>) {
|
||||
<span class="cm-variable">say</span>(<span class="cm-variable-2">i</span>);
|
||||
<span class="cm-keyword">await</span> <span class="cm-variable">sleep</span>(<span class="cm-number">1000</span>); <span class="cm-comment">// wait one second</span>
|
||||
}
|
||||
@@ -4524,7 +4524,7 @@ renderStarRating = function({rating, maxStars}) {
|
||||
{(function() {
|
||||
var i, ref, results;
|
||||
results = [];
|
||||
for (wholeStar = i = 0, ref = Math.floor(rating); undefined !== 0 && (0 <= ref ? 0 <= i && i < ref : 0 >= i && i > ref); wholeStar = 0 <= ref ? ++i : --i) {
|
||||
for (wholeStar = i = 0, ref = Math.floor(rating); (0 <= ref ? i < ref : i > ref); wholeStar = 0 <= ref ? ++i : --i) {
|
||||
results.push(<Star className="wholeStar" key={wholeStar} />);
|
||||
}
|
||||
return results;
|
||||
@@ -4533,7 +4533,7 @@ renderStarRating = function({rating, maxStars}) {
|
||||
{(function() {
|
||||
var i, ref, ref1, results;
|
||||
results = [];
|
||||
for (emptyStar = i = ref = Math.ceil(rating), ref1 = maxStars; undefined !== 0 && (ref <= ref1 ? ref <= i && i < ref1 : ref >= i && i > ref1); emptyStar = ref <= ref1 ? ++i : --i) {
|
||||
for (emptyStar = i = ref = Math.ceil(rating), ref1 = maxStars; (ref <= ref1 ? i < ref1 : i > ref1); emptyStar = ref <= ref1 ? ++i : --i) {
|
||||
results.push(<Star className="emptyStar" key={emptyStar} />);
|
||||
}
|
||||
return results;
|
||||
@@ -4549,7 +4549,7 @@ renderStarRating = function({rating, maxStars}) {
|
||||
<span class="cm-string-2">{(function() {</span>
|
||||
<span class="cm-string-2">var i, ref, results;</span>
|
||||
<span class="cm-string-2">results = [];</span>
|
||||
<span class="cm-string-2">for (wholeStar = i = 0, ref = Math.floor(rating); undefined !== 0 && (0 <= ref ? 0 <= i && i < ref : 0 >= i && i > ref); wholeStar = 0 <= ref ? ++i : --i) {</span>
|
||||
<span class="cm-string-2">for (wholeStar = i = 0, ref = Math.floor(rating); (0 <= ref ? i < ref : i > ref); wholeStar = 0 <= ref ? ++i : --i) {</span>
|
||||
<span class="cm-string-2">results.push(<Star className="wholeStar" key={wholeStar} />);</span>
|
||||
<span class="cm-string-2">}</span>
|
||||
<span class="cm-string-2">return results;</span>
|
||||
@@ -4558,7 +4558,7 @@ renderStarRating = function({rating, maxStars}) {
|
||||
<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>
|
||||
<span class="cm-string-2">for (emptyStar = i = ref = Math.ceil(rating), ref1 = maxStars; undefined !== 0 && (ref <= ref1 ? ref <= i && i < ref1 : ref >= i && i > ref1); emptyStar = ref <= ref1 ? ++i : --i) {</span>
|
||||
<span class="cm-string-2">for (emptyStar = i = ref = Math.ceil(rating), ref1 = maxStars; (ref <= ref1 ? i < ref1 : i > ref1); emptyStar = ref <= ref1 ? ++i : --i) {</span>
|
||||
<span class="cm-string-2">results.push(<Star className="emptyStar" key={emptyStar} />);</span>
|
||||
<span class="cm-string-2">}</span>
|
||||
<span class="cm-string-2">return results;</span>
|
||||
@@ -4790,7 +4790,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.2.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.2.4 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>
|
||||
@@ -4859,7 +4859,7 @@ Object.defineProperty screen, 'height',
|
||||
get: ->
|
||||
this.width / this.ratio
|
||||
set: (val) ->
|
||||
this.width = val / this.ratio
|
||||
this.width = val * this.ratio
|
||||
</textarea>
|
||||
<pre class="placeholder-code"><span class="cm-variable">screen</span> <span class="cm-punctuation">=</span>
|
||||
<span class="cm-indent"> </span><span class="cm-variable">width</span><span class="cm-punctuation">:</span> <span class="cm-number">1200</span>
|
||||
@@ -4869,7 +4869,7 @@ Object.defineProperty screen, 'height',
|
||||
<span class="cm-indent"> </span><span class="cm-variable">get</span><span class="cm-punctuation">:</span> <span class="cm-operator">-></span>
|
||||
<span class="cm-keyword">this</span><span class="cm-punctuation">.</span><span class="cm-property">width</span> <span class="cm-operator">/</span> <span class="cm-keyword">this</span><span class="cm-punctuation">.</span><span class="cm-property">ratio</span>
|
||||
<span class="cm-dedent"> </span><span class="cm-variable">set</span><span class="cm-punctuation">:</span> <span class="cm-punctuation">(</span><span class="cm-variable">val</span><span class="cm-punctuation">)</span> <span class="cm-operator">-></span>
|
||||
<span class="cm-keyword">this</span><span class="cm-punctuation">.</span><span class="cm-property">width</span> <span class="cm-punctuation">=</span> <span class="cm-variable">val</span> <span class="cm-operator">/</span> <span class="cm-keyword">this</span><span class="cm-punctuation">.</span><span class="cm-property">ratio</span>
|
||||
<span class="cm-keyword">this</span><span class="cm-punctuation">.</span><span class="cm-property">width</span> <span class="cm-punctuation">=</span> <span class="cm-variable">val</span> <span class="cm-operator">*</span> <span class="cm-keyword">this</span><span class="cm-punctuation">.</span><span class="cm-property">ratio</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="col-md-6 javascript-output-column">
|
||||
@@ -4885,7 +4885,7 @@ Object.defineProperty(screen, 'height', {
|
||||
return this.width / this.ratio;
|
||||
},
|
||||
set: function(val) {
|
||||
return this.width = val / this.ratio;
|
||||
return this.width = val * this.ratio;
|
||||
}
|
||||
});
|
||||
</textarea>
|
||||
@@ -4901,7 +4901,7 @@ Object.defineProperty(screen, 'height', {
|
||||
<span class="cm-keyword">return</span> <span class="cm-keyword">this</span>.<span class="cm-property">width</span> <span class="cm-operator">/</span> <span class="cm-keyword">this</span>.<span class="cm-property">ratio</span>;
|
||||
},
|
||||
<span class="cm-property">set</span>: <span class="cm-keyword">function</span>(<span class="cm-def">val</span>) {
|
||||
<span class="cm-keyword">return</span> <span class="cm-keyword">this</span>.<span class="cm-property">width</span> <span class="cm-operator">=</span> <span class="cm-variable-2">val</span> <span class="cm-operator">/</span> <span class="cm-keyword">this</span>.<span class="cm-property">ratio</span>;
|
||||
<span class="cm-keyword">return</span> <span class="cm-keyword">this</span>.<span class="cm-property">width</span> <span class="cm-operator">=</span> <span class="cm-variable-2">val</span> <span class="cm-operator">*</span> <span class="cm-keyword">this</span>.<span class="cm-property">ratio</span>;
|
||||
}
|
||||
});
|
||||
</pre>
|
||||
@@ -5467,9 +5467,33 @@ x = <span class="number">2</span> + <span class="number">2</span>
|
||||
</section>
|
||||
<section id="changelog">
|
||||
<h2>Changelog</h2>
|
||||
<div class="anchor" id="2.2.4"></div>
|
||||
<h2 class="header">
|
||||
<a href="https://github.com/jashkenas/coffeescript/compare/2.2.3...2.2.4">2.2.4</a>
|
||||
<span class="timestamp"> — <time datetime="2018-03-29">March 29, 2018</time></span>
|
||||
</h2><ul>
|
||||
<li>When the <code>by</code> value in a <code>for</code> loop is a literal number, e.g. <code>for x in [2..1] by -1</code>, fewer checks are necessary to determine if the loop is in range.</li>
|
||||
<li>Bugfix for regression in 2.2.0 where a statement inside parentheses, e.g. <code>(fn(); break) while condition</code>, was compiling. Pure statements like <code>break</code> or <code>return</code> cannot turn a parenthesized block into an expression, and should throw an error.</li>
|
||||
</ul>
|
||||
<div class="anchor" id="2.2.3"></div>
|
||||
<h2 class="header">
|
||||
<a href="https://github.com/jashkenas/coffeescript/compare/2.2.2...2.2.3">2.2.3</a>
|
||||
<span class="timestamp"> — <time datetime="2018-03-11">March 11, 2018</time></span>
|
||||
</h2><ul>
|
||||
<li>Bugfix for object destructuring with an empty array as a key’s value: <code>{ key: [] } = obj</code>.</li>
|
||||
<li>Bugfix for array destructuring onto targets attached to <code>this</code>: <code>[ @most... , @penultimate, @last ] = arr</code>.</li>
|
||||
</ul>
|
||||
<div class="anchor" id="2.2.2"></div>
|
||||
<h2 class="header">
|
||||
<a href="https://github.com/jashkenas/coffeescript/compare/2.2.1...2.2.2">2.2.2</a>
|
||||
<span class="timestamp"> — <time datetime="2018-02-21">February 21, 2018</time></span>
|
||||
</h2><ul>
|
||||
<li>Bugfix for regression in 2.2.0 where a range with a <code>by</code> (step) value that increments or decrements in the opposite direction as the range was returning an array containing the first value of the range, whereas it should be returning an empty array. In other words, <code>x for x in [2..1] by 1</code> should equal <code>[]</code>, not <code>[2]</code> (because the step value is positive 1, counting up, whereas the range goes from 2 to 1, counting down).</li>
|
||||
<li>Bugfixes for allowing backslashes in <code>import</code> and <code>export</code> statements and lines that trigger the start of an indented block, like an <code>if</code> statement.</li>
|
||||
</ul>
|
||||
<div class="anchor" id="2.2.1"></div>
|
||||
<h2 class="header">
|
||||
<a href="https://github.com/jashkenas/coffeescript/compare/2.1.0...2.2.1">2.2.1</a>
|
||||
<a href="https://github.com/jashkenas/coffeescript/compare/2.2.0...2.2.1">2.2.1</a>
|
||||
<span class="timestamp"> — <time datetime="2018-02-06">February 6, 2018</time></span>
|
||||
</h2><ul>
|
||||
<li>Bugfix for regression in 2.2.0 involving an error thrown by the compiler in certain cases when using destructuring with a splat or expansion in an array.</li>
|
||||
|
||||
@@ -1586,7 +1586,7 @@ test "#4878: Compile error when using destructuring with a splat or expansion in
|
||||
([first, ...] = list); first
|
||||
|
||||
f4 = (list) ->
|
||||
([first, ...rest] = list); rest
|
||||
([first, rest...] = list); rest
|
||||
|
||||
arrayEq f1(arr), arr
|
||||
arrayEq f2(arr), arr
|
||||
@@ -1606,20 +1606,68 @@ test "#4878: Compile error when using destructuring with a splat or expansion in
|
||||
bar = (list) ->
|
||||
ret =
|
||||
if list?.length > 0
|
||||
[first, ...rest] = list
|
||||
[first, rest...] = list
|
||||
[first, rest]
|
||||
else
|
||||
[]
|
||||
|
||||
arrayEq bar(arr), ['a', ['b', 'c', 'd']]
|
||||
|
||||
test "destructuring assignment with an empty array in object", ->
|
||||
obj =
|
||||
a1: [1, 2]
|
||||
b1: 3
|
||||
|
||||
{a1:[], b1} = obj
|
||||
eq 'undefined', typeof a1
|
||||
eq b1, 3
|
||||
|
||||
obj =
|
||||
a2:
|
||||
b2: [1, 2]
|
||||
c2: 3
|
||||
|
||||
{a2: {b2:[]}, c2} = obj
|
||||
eq 'undefined', typeof b2
|
||||
eq c2, 3
|
||||
|
||||
test "#5004: array destructuring with accessors", ->
|
||||
obj =
|
||||
arr: ['a', 'b', 'c', 'd']
|
||||
list: {}
|
||||
f1: ->
|
||||
[@first, @rest...] = @arr
|
||||
f2: ->
|
||||
[@second, @third..., @last] = @rest
|
||||
f3: ->
|
||||
[@list.a, @list.middle..., @list.d] = @arr
|
||||
|
||||
obj.f1()
|
||||
eq obj.first, 'a'
|
||||
arrayEq obj.rest, ['b', 'c', 'd']
|
||||
|
||||
obj.f2()
|
||||
eq obj.second, 'b'
|
||||
arrayEq obj.third, ['c']
|
||||
eq obj.last, 'd'
|
||||
|
||||
obj.f3()
|
||||
eq obj.list.a, 'a'
|
||||
arrayEq obj.list.middle, ['b', 'c']
|
||||
eq obj.list.d, 'd'
|
||||
|
||||
[obj.list.middle..., d] = obj.arr
|
||||
eq d, 'd'
|
||||
arrayEq obj.list.middle, ['a', 'b', 'c']
|
||||
|
||||
</script>
|
||||
<script type="text/x-coffeescript" class="test" id="async">
|
||||
# Functions that contain the `await` keyword will compile into async functions,
|
||||
# supported by Node 7.6+, Chrome 55+, Firefox 52+, Safari 10.1+ and Edge.
|
||||
# But runtimes that don’t support the `await` keyword will throw an error,
|
||||
# even if we put `return unless global.supportsAsync` at the top of this file.
|
||||
# Therefore we need to prevent runtimes which will choke on such code from even
|
||||
# But runtimes that don’t support the `await` keyword will throw an error just
|
||||
# from parsing this file, even without executing it, even if we put
|
||||
# `return unless try new Function 'async () => {}'` at the top of this file.
|
||||
# Therefore we need to prevent runtimes which will choke on such code from
|
||||
# parsing it, which is handled in `Cakefile`.
|
||||
|
||||
|
||||
@@ -2107,6 +2155,7 @@ test "classes with value'd constructors", ->
|
||||
inner = ++counter
|
||||
->
|
||||
@value = inner
|
||||
@
|
||||
|
||||
class One
|
||||
constructor: classMaker()
|
||||
@@ -6761,37 +6810,6 @@ test "#3921: `switch`", ->
|
||||
else "none"
|
||||
eq "five", c
|
||||
|
||||
# Issue #3441: Parentheses wrapping expression throw invalid error in `then` clause
|
||||
test "#3441: `StatementLiteral` in parentheses", ->
|
||||
i = 0
|
||||
r1 = ((i++; break) while i < 10)
|
||||
arrayEq r1, []
|
||||
|
||||
i = 0
|
||||
r2 = ((i++; continue) while i < 10)
|
||||
arrayEq r2, []
|
||||
|
||||
i = 0
|
||||
r4 = while i < 10 then (i++; break)
|
||||
arrayEq r4, []
|
||||
|
||||
i = 0
|
||||
r5 = while i < 10 then (i++; continue)
|
||||
arrayEq r5, []
|
||||
|
||||
arr = [0..9]
|
||||
r6 = ((a; break) for a in arr)
|
||||
arrayEq r6, []
|
||||
|
||||
r7 = ((a; continue) for a in arr)
|
||||
arrayEq r7, []
|
||||
|
||||
r8 = for a in arr then (a; break)
|
||||
arrayEq r8, []
|
||||
|
||||
r9 = for a in arr then (a; continue)
|
||||
arrayEq r9, []
|
||||
|
||||
# Issue #3909: backslash to break line in `for` loops throw syntax error
|
||||
test "#3909: backslash `for own ... of`", ->
|
||||
|
||||
@@ -6937,6 +6955,59 @@ test "#4871: `else if` no longer output together ", ->
|
||||
}
|
||||
'''
|
||||
|
||||
test "#4898: Lexer: backslash line continuation is inconsistent", ->
|
||||
if ( \
|
||||
false \
|
||||
or \
|
||||
true \
|
||||
)
|
||||
a = 42
|
||||
|
||||
eq a, 42
|
||||
|
||||
if ( \
|
||||
false \
|
||||
or \
|
||||
true \
|
||||
)
|
||||
b = 42
|
||||
|
||||
eq b, 42
|
||||
|
||||
if ( \
|
||||
false \
|
||||
or \
|
||||
true \
|
||||
)
|
||||
c = 42
|
||||
|
||||
eq c, 42
|
||||
|
||||
if \
|
||||
false \
|
||||
or \
|
||||
true
|
||||
d = 42
|
||||
|
||||
eq d, 42
|
||||
|
||||
if \
|
||||
false or \
|
||||
true
|
||||
e = 42
|
||||
|
||||
eq e, 42
|
||||
|
||||
if \
|
||||
false or \
|
||||
true \
|
||||
then \
|
||||
f = 42 \
|
||||
else
|
||||
f = 24
|
||||
|
||||
eq f, 42
|
||||
|
||||
</script>
|
||||
<script type="text/x-coffeescript" class="test" id="csx">
|
||||
# We usually do not check the actual JS output from the compiler, but since
|
||||
@@ -8694,6 +8765,42 @@ test "#4097: `yield return` as an expression", ->
|
||||
^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `await return` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
-> (await return)
|
||||
''', '''
|
||||
[stdin]:1:5: error: cannot use a pure statement in an expression
|
||||
-> (await return)
|
||||
^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `return` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
-> (return)
|
||||
''', '''
|
||||
[stdin]:1:5: error: cannot use a pure statement in an expression
|
||||
-> (return)
|
||||
^^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `break` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
(b = 1; break) for b in a
|
||||
''', '''
|
||||
[stdin]:1:9: error: cannot use a pure statement in an expression
|
||||
(b = 1; break) for b in a
|
||||
^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `continue` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
(b = 1; continue) for b in a
|
||||
''', '''
|
||||
[stdin]:1:9: error: cannot use a pure statement in an expression
|
||||
(b = 1; continue) for b in a
|
||||
^^^^^^^^
|
||||
'''
|
||||
|
||||
test "`&&=` and `||=` with a space in-between", ->
|
||||
assertErrorFormat '''
|
||||
a = 0
|
||||
@@ -14369,6 +14476,73 @@ test "#4491: import- and export-specific lexing should stop after import/export
|
||||
from('foo');
|
||||
"""
|
||||
|
||||
# Issue #4874: Backslash not supported in import or export statements
|
||||
test "#4874: backslash `import`", ->
|
||||
|
||||
eqJS """
|
||||
import foo \
|
||||
from 'lib'
|
||||
|
||||
foo a
|
||||
""",
|
||||
"""
|
||||
import foo from 'lib';
|
||||
|
||||
foo(a);
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import \
|
||||
foo \
|
||||
from \
|
||||
'lib'
|
||||
|
||||
foo a
|
||||
""",
|
||||
"""
|
||||
import foo from 'lib';
|
||||
|
||||
foo(a);
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import \
|
||||
utilityBelt \
|
||||
, {
|
||||
each
|
||||
} from \
|
||||
'underscore'
|
||||
""",
|
||||
"""
|
||||
import utilityBelt, {
|
||||
each
|
||||
} from 'underscore';
|
||||
"""
|
||||
|
||||
test "#4874: backslash `export`", ->
|
||||
eqJS """
|
||||
export \
|
||||
* \
|
||||
from \
|
||||
'underscore'
|
||||
""",
|
||||
"""
|
||||
export * from 'underscore';
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
export \
|
||||
{ max, min } \
|
||||
from \
|
||||
'underscore'
|
||||
""",
|
||||
"""
|
||||
export {
|
||||
max,
|
||||
min
|
||||
} from 'underscore';
|
||||
"""
|
||||
|
||||
</script>
|
||||
<script type="text/x-coffeescript" class="test" id="numbers">
|
||||
# Number Literals
|
||||
@@ -16147,43 +16321,43 @@ test "#2047: Infinite loop possible when `for` loop with `range` uses variables"
|
||||
|
||||
testData = [
|
||||
[1, 5, 1, [1..5]]
|
||||
[1, 5, -1, [1]]
|
||||
[1, 5, -1, []]
|
||||
[1, 5, up, [1..5]]
|
||||
[1, 5, down, [1]]
|
||||
[1, 5, down, []]
|
||||
|
||||
[a, 5, 1, [1..5]]
|
||||
[a, 5, -1, [1]]
|
||||
[a, 5, -1, []]
|
||||
[a, 5, up, [1..5]]
|
||||
[a, 5, down, [1]]
|
||||
[a, 5, down, []]
|
||||
|
||||
[1, b, 1, [1..5]]
|
||||
[1, b, -1, [1]]
|
||||
[1, b, -1, []]
|
||||
[1, b, up, [1..5]]
|
||||
[1, b, down, [1]]
|
||||
[1, b, down, []]
|
||||
|
||||
[a, b, 1, [1..5]]
|
||||
[a, b, -1, [1]]
|
||||
[a, b, -1, []]
|
||||
[a, b, up, [1..5]]
|
||||
[a, b, down, [1]]
|
||||
[a, b, down, []]
|
||||
|
||||
[5, 1, 1, [5]]
|
||||
[5, 1, 1, []]
|
||||
[5, 1, -1, [5..1]]
|
||||
[5, 1, up, [5]]
|
||||
[5, 1, up, []]
|
||||
[5, 1, down, [5..1]]
|
||||
|
||||
[5, a, 1, [5]]
|
||||
[5, a, 1, []]
|
||||
[5, a, -1, [5..1]]
|
||||
[5, a, up, [5]]
|
||||
[5, a, up, []]
|
||||
[5, a, down, [5..1]]
|
||||
|
||||
[b, 1, 1, [5]]
|
||||
[b, 1, 1, []]
|
||||
[b, 1, -1, [5..1]]
|
||||
[b, 1, up, [5]]
|
||||
[b, 1, up, []]
|
||||
[b, 1, down, [5..1]]
|
||||
|
||||
[b, a, 1, [5]]
|
||||
[b, a, 1, []]
|
||||
[b, a, -1, [5..1]]
|
||||
[b, a, up, [5]]
|
||||
[b, a, up, []]
|
||||
[b, a, down, [5..1]]
|
||||
]
|
||||
|
||||
@@ -16199,10 +16373,10 @@ test "#2047: from, to and step as variables", ->
|
||||
arrayEq r, [1..5]
|
||||
|
||||
r = (x for x in [a..b] by down)
|
||||
arrayEq r, [1]
|
||||
arrayEq r, []
|
||||
|
||||
r = (x for x in [b..a] by up)
|
||||
arrayEq r, [5]
|
||||
arrayEq r, []
|
||||
|
||||
r = (x for x in [b..a] by down)
|
||||
arrayEq r, [5..1]
|
||||
@@ -16220,6 +16394,46 @@ test "#4884: Range not declaring var for the 'i'", ->
|
||||
|
||||
eq global.i, undefined
|
||||
|
||||
test "#4889: `for` loop unexpected behavior", ->
|
||||
n = 1
|
||||
result = []
|
||||
for i in [0..n]
|
||||
result.push i
|
||||
for j in [(i+1)..n]
|
||||
result.push j
|
||||
|
||||
arrayEq result, [0,1,1,2,1]
|
||||
|
||||
test "#4889: `for` loop unexpected behavior with `by 1` on second loop", ->
|
||||
n = 1
|
||||
result = []
|
||||
for i in [0..n]
|
||||
result.push i
|
||||
for j in [(i+1)..n] by 1
|
||||
result.push j
|
||||
|
||||
arrayEq result, [0,1,1]
|
||||
|
||||
test "countdown example from docs", ->
|
||||
countdown = (num for num in [10..1])
|
||||
arrayEq countdown, [10,9,8,7,6,5,4,3,2,1]
|
||||
|
||||
test "counting up when the range goes down returns an empty array", ->
|
||||
countdown = (num for num in [10..1] by 1)
|
||||
arrayEq countdown, []
|
||||
|
||||
test "counting down when the range goes up returns an empty array", ->
|
||||
countup = (num for num in [1..10] by -1)
|
||||
arrayEq countup, []
|
||||
|
||||
test "counting down by too much returns just the first value", ->
|
||||
countdown = (num for num in [10..1] by -100)
|
||||
arrayEq countdown, [10]
|
||||
|
||||
test "counting up by too much returns just the first value", ->
|
||||
countup = (num for num in [1..10] by 100)
|
||||
arrayEq countup, [1]
|
||||
|
||||
</script>
|
||||
<script type="text/x-coffeescript" class="test" id="regexps">
|
||||
# Regular Expression Literals
|
||||
@@ -16679,7 +16893,7 @@ testRepl "keeps running after runtime error", (input, output) ->
|
||||
eq 'undefined', output.lastWrite()
|
||||
|
||||
testRepl "#4604: wraps an async function", (input, output) ->
|
||||
return unless global.supportsAsync
|
||||
return unless try new Function 'async () => {}' # Feature detect support for async functions.
|
||||
input.emitLine 'await new Promise (resolve) -> setTimeout (-> resolve 33), 10'
|
||||
setTimeout ->
|
||||
eq '33', output.lastWrite()
|
||||
|
||||
@@ -6,4 +6,4 @@ Object.defineProperty screen, 'height',
|
||||
get: ->
|
||||
this.width / this.ratio
|
||||
set: (val) ->
|
||||
this.width = val / this.ratio
|
||||
this.width = val * this.ratio
|
||||
|
||||
@@ -1,7 +1,25 @@
|
||||
## Changelog
|
||||
|
||||
```
|
||||
releaseHeader('2018-02-06', '2.2.1', '2.1.0')
|
||||
releaseHeader('2018-03-29', '2.2.4', '2.2.3')
|
||||
```
|
||||
* When the `by` value in a `for` loop is a literal number, e.g. `for x in [2..1] by -1`, fewer checks are necessary to determine if the loop is in range.
|
||||
* Bugfix for regression in 2.2.0 where a statement inside parentheses, e.g. `(fn(); break) while condition`, was compiling. Pure statements like `break` or `return` cannot turn a parenthesized block into an expression, and should throw an error.
|
||||
|
||||
```
|
||||
releaseHeader('2018-03-11', '2.2.3', '2.2.2')
|
||||
```
|
||||
* Bugfix for object destructuring with an empty array as a key’s value: `{ key: [] } = obj`.
|
||||
* Bugfix for array destructuring onto targets attached to `this`: `[ @most... , @penultimate, @last ] = arr`.
|
||||
|
||||
```
|
||||
releaseHeader('2018-02-21', '2.2.2', '2.2.1')
|
||||
```
|
||||
* Bugfix for regression in 2.2.0 where a range with a `by` (step) value that increments or decrements in the opposite direction as the range was returning an array containing the first value of the range, whereas it should be returning an empty array. In other words, `x for x in [2..1] by 1` should equal `[]`, not `[2]` (because the step value is positive 1, counting up, whereas the range goes from 2 to 1, counting down).
|
||||
* Bugfixes for allowing backslashes in `import` and `export` statements and lines that trigger the start of an indented block, like an `if` statement.
|
||||
|
||||
```
|
||||
releaseHeader('2018-02-06', '2.2.1', '2.2.0')
|
||||
```
|
||||
* Bugfix for regression in 2.2.0 involving an error thrown by the compiler in certain cases when using destructuring with a splat or expansion in an array.
|
||||
* Bugfix for regression in 2.2.0 where in certain cases a range iterator variable was declared in the global scope.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
// This **Browser** compatibility layer extends core CoffeeScript functions
|
||||
// to make things work smoothly when compiling code directly in the browser.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(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))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
// The `coffee` utility. Handles command-line compilation of CoffeeScript
|
||||
// into various forms: saved into `.js` files or printed to stdout
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
// This file contains the common helper functions that we'd like to share among
|
||||
// the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
// Node.js Implementation
|
||||
var CoffeeScript, ext, fs, helpers, i, len, path, ref, universalCompile, vm,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(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,
|
||||
@@ -593,14 +593,14 @@
|
||||
}
|
||||
indent = match[0];
|
||||
prev = this.prev();
|
||||
backslash = (prev != null) && prev[0] === '\\';
|
||||
backslash = (prev != null ? prev[0] : void 0) === '\\';
|
||||
if (!(backslash && this.seenFor)) {
|
||||
this.seenFor = false;
|
||||
}
|
||||
if (!this.importSpecifierList) {
|
||||
if (!((backslash && this.seenImport) || this.importSpecifierList)) {
|
||||
this.seenImport = false;
|
||||
}
|
||||
if (!this.exportSpecifierList) {
|
||||
if (!((backslash && this.seenExport) || this.exportSpecifierList)) {
|
||||
this.seenExport = false;
|
||||
}
|
||||
size = indent.length - 1 - indent.lastIndexOf('\n');
|
||||
@@ -629,7 +629,9 @@
|
||||
}
|
||||
if (size > this.indent) {
|
||||
if (noNewlines) {
|
||||
this.indebt = size - this.indent;
|
||||
if (!backslash) {
|
||||
this.indebt = size - this.indent;
|
||||
}
|
||||
this.suppressNewlines();
|
||||
return indent.length;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(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),
|
||||
@@ -1267,15 +1267,6 @@
|
||||
if (!props && base instanceof Value) {
|
||||
return base;
|
||||
}
|
||||
if (base instanceof Parens && base.contains(function(n) {
|
||||
return n instanceof StatementLiteral;
|
||||
})) {
|
||||
// When `Parens` block includes a `StatementLiteral` (e.g. `(b; break) for a in arr`),
|
||||
// it won't compile since `Parens` (`(b; break)`) is compiled as `Value` and
|
||||
// pure statement (`break`) can't be used in an expression.
|
||||
// For this reasons, we return `Block` instead of `Parens`.
|
||||
return base.unwrap();
|
||||
}
|
||||
this.base = base;
|
||||
this.properties = props || [];
|
||||
if (tag) {
|
||||
@@ -2031,7 +2022,7 @@
|
||||
// When compiled normally, the range returns the contents of the *for loop*
|
||||
// needed to iterate over the values in the range. Used by comprehensions.
|
||||
compileNode(o) {
|
||||
var cond, condPart, from, gt, idx, idxName, known, lowerBound, lt, namedIndex, stepCond, stepPart, to, upperBound, varPart;
|
||||
var cond, condPart, from, gt, idx, idxName, known, lowerBound, lt, namedIndex, ref1, ref2, stepCond, stepNotZero, stepPart, to, upperBound, varPart;
|
||||
if (!this.fromVar) {
|
||||
this.compileVariables(o);
|
||||
}
|
||||
@@ -2054,12 +2045,11 @@
|
||||
// Generate the condition.
|
||||
[from, to] = [this.fromNum, this.toNum];
|
||||
// Always check if the `step` isn't zero to avoid the infinite loop.
|
||||
stepCond = this.stepNum ? `${this.stepNum} !== 0` : `${this.stepVar} !== 0`;
|
||||
condPart = known ? this.step == null ? from <= to ? `${lt} ${to}` : `${gt} ${ // from < to
|
||||
to}` : (lowerBound = `${from} <= ${idx} && ${lt} ${// from > to
|
||||
to}`, upperBound = `${from} >= ${idx} && ${gt} ${to}`, from <= to ? `${stepCond} && ${lowerBound}` : `${stepCond} && ${// from < to
|
||||
upperBound}`) : (lowerBound = `${this.fromVar} <= ${idx} && ${lt} ${// from > to
|
||||
this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `${stepCond} && (${this.fromVar} <= ${this.toVar} ? ${lowerBound} : ${upperBound})`);
|
||||
stepNotZero = `${(ref1 = this.stepNum) != null ? ref1 : this.stepVar} !== 0`;
|
||||
stepCond = `${(ref2 = this.stepNum) != null ? ref2 : this.stepVar} > 0`;
|
||||
lowerBound = `${lt} ${(known ? to : this.toVar)}`;
|
||||
upperBound = `${gt} ${(known ? to : this.toVar)}`;
|
||||
condPart = this.step != null ? (this.stepNum != null) && this.stepNum !== 0 ? this.stepNum > 0 ? `${lowerBound}` : `${upperBound}` : `${stepNotZero} && (${stepCond} ? ${lowerBound} : ${upperBound})` : known ? `${(from <= to ? lt : gt)} ${to}` : `(${this.fromVar} <= ${this.toVar} ? ${lowerBound} : ${upperBound})`;
|
||||
cond = this.stepVar ? `${this.stepVar} > 0` : `${this.fromVar} <= ${this.toVar}`;
|
||||
// Generate the step.
|
||||
stepPart = this.stepVar ? `${idx} += ${this.stepVar}` : known ? namedIndex ? from <= to ? `++${idx}` : `--${idx}` : from <= to ? `${idx}++` : `${idx}--` : namedIndex ? `${cond} ? ++${idx} : --${idx}` : `${cond} ? ${idx}++ : ${idx}--`;
|
||||
@@ -2180,7 +2170,7 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
||||
}
|
||||
|
||||
isAssignable() {
|
||||
var j, len1, message, prop, ref1;
|
||||
var j, len1, message, prop, ref1, ref2;
|
||||
ref1 = this.properties;
|
||||
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||
prop = ref1[j];
|
||||
@@ -2189,7 +2179,7 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
||||
if (message) {
|
||||
prop.error(message);
|
||||
}
|
||||
if (prop instanceof Assign && prop.context === 'object') {
|
||||
if (prop instanceof Assign && prop.context === 'object' && !(((ref2 = prop.value) != null ? ref2.base : void 0) instanceof Arr)) {
|
||||
prop = prop.value;
|
||||
}
|
||||
if (!prop.isAssignable()) {
|
||||
@@ -3594,7 +3584,10 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
||||
slicer = function(type) {
|
||||
return function(vvar, start, end = false) {
|
||||
var args, slice;
|
||||
args = [new IdentifierLiteral(vvar), new NumberLiteral(start)];
|
||||
if (!(vvar instanceof Value)) {
|
||||
vvar = new IdentifierLiteral(vvar);
|
||||
}
|
||||
args = [vvar, new NumberLiteral(start)];
|
||||
if (end) {
|
||||
args.push(new NumberLiteral(end));
|
||||
}
|
||||
@@ -3746,7 +3739,7 @@ this.toVar}`, upperBound = `${this.fromVar} >= ${idx} && ${gt} ${this.toVar}`, `
|
||||
refExp = (function() {
|
||||
switch (false) {
|
||||
case !isSplat:
|
||||
return compSplice(objects[expIdx].unwrapAll().value, rightObjs.length * -1);
|
||||
return compSplice(new Value(objects[expIdx].name), rightObjs.length * -1);
|
||||
case !isExpans:
|
||||
return compSlice(vvarText, rightObjs.length * -1);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat,
|
||||
splice = [].splice;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, getRootModule, helpers, i, len, loadFile, path, ref;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, runInContext, sawSIGINT, transpile, updateSyntaxError, vm;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
// The CoffeeScript language has a good deal of optional syntax, implicit syntax,
|
||||
// and shorthand syntax. This can greatly complicate a grammar and bloat
|
||||
@@ -218,7 +218,7 @@
|
||||
indexOfTag(i, ...pattern) {
|
||||
var fuzz, j, k, ref, ref1;
|
||||
fuzz = 0;
|
||||
for (j = k = 0, ref = pattern.length; undefined !== 0 && (0 <= ref ? 0 <= k && k < ref : 0 >= k && k > ref); j = 0 <= ref ? ++k : --k) {
|
||||
for (j = k = 0, ref = pattern.length; (0 <= ref ? k < ref : k > ref); j = 0 <= ref ? ++k : --k) {
|
||||
if (pattern[j] == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Generated by CoffeeScript 2.2.1
|
||||
// Generated by CoffeeScript 2.2.4
|
||||
(function() {
|
||||
// Source maps allow JavaScript runtimes to match running JavaScript back to
|
||||
// the original source code that corresponds to it. This can be minified
|
||||
|
||||
2766
package-lock.json
generated
2766
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
"compiler"
|
||||
],
|
||||
"author": "Jeremy Ashkenas",
|
||||
"version": "2.2.1",
|
||||
"version": "2.2.4",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@@ -43,13 +43,13 @@
|
||||
"babel-preset-babili": "~0.1.4",
|
||||
"babel-preset-env": "~1.6.1",
|
||||
"babel-preset-minify": "^0.3.0",
|
||||
"codemirror": "^5.32.0",
|
||||
"codemirror": "^5.35.0",
|
||||
"docco": "~0.8.0",
|
||||
"highlight.js": "~9.12.0",
|
||||
"jison": ">=0.4.18",
|
||||
"markdown-it": "~8.4.0",
|
||||
"markdown-it": "~8.4.1",
|
||||
"underscore": "~1.8.3",
|
||||
"webpack": "~3.10.0"
|
||||
"webpack": "~4.1.1"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
@@ -454,10 +454,10 @@ exports.Lexer = class Lexer
|
||||
indent = match[0]
|
||||
|
||||
prev = @prev()
|
||||
backslash = prev? and prev[0] is '\\'
|
||||
backslash = prev?[0] is '\\'
|
||||
@seenFor = no unless backslash and @seenFor
|
||||
@seenImport = no unless @importSpecifierList
|
||||
@seenExport = no unless @exportSpecifierList
|
||||
@seenImport = no unless (backslash and @seenImport) or @importSpecifierList
|
||||
@seenExport = no unless (backslash and @seenExport) or @exportSpecifierList
|
||||
|
||||
size = indent.length - 1 - indent.lastIndexOf '\n'
|
||||
noNewlines = @unfinished()
|
||||
@@ -478,7 +478,7 @@ exports.Lexer = class Lexer
|
||||
|
||||
if size > @indent
|
||||
if noNewlines
|
||||
@indebt = size - @indent
|
||||
@indebt = size - @indent unless backslash
|
||||
@suppressNewlines()
|
||||
return indent.length
|
||||
unless @tokens.length
|
||||
|
||||
@@ -863,11 +863,6 @@ exports.Value = class Value extends Base
|
||||
constructor: (base, props, tag, isDefaultValue = no) ->
|
||||
super()
|
||||
return base if not props and base instanceof Value
|
||||
# When `Parens` block includes a `StatementLiteral` (e.g. `(b; break) for a in arr`),
|
||||
# it won't compile since `Parens` (`(b; break)`) is compiled as `Value` and
|
||||
# pure statement (`break`) can't be used in an expression.
|
||||
# For this reasons, we return `Block` instead of `Parens`.
|
||||
return base.unwrap() if base instanceof Parens and base.contains (n) -> n instanceof StatementLiteral
|
||||
@base = base
|
||||
@properties = props or []
|
||||
@[tag] = yes if tag
|
||||
@@ -1365,23 +1360,21 @@ exports.Range = class Range extends Base
|
||||
# Generate the condition.
|
||||
[from, to] = [@fromNum, @toNum]
|
||||
# Always check if the `step` isn't zero to avoid the infinite loop.
|
||||
stepCond = if @stepNum then "#{@stepNum} !== 0" else "#{@stepVar} !== 0"
|
||||
stepNotZero = "#{ @stepNum ? @stepVar } !== 0"
|
||||
stepCond = "#{ @stepNum ? @stepVar } > 0"
|
||||
lowerBound = "#{lt} #{ if known then to else @toVar }"
|
||||
upperBound = "#{gt} #{ if known then to else @toVar }"
|
||||
condPart =
|
||||
if known
|
||||
unless @step?
|
||||
if from <= to then "#{lt} #{to}" else "#{gt} #{to}"
|
||||
if @step?
|
||||
if @stepNum? and @stepNum isnt 0
|
||||
if @stepNum > 0 then "#{lowerBound}" else "#{upperBound}"
|
||||
else
|
||||
# from < to
|
||||
lowerBound = "#{from} <= #{idx} && #{lt} #{to}"
|
||||
# from > to
|
||||
upperBound = "#{from} >= #{idx} && #{gt} #{to}"
|
||||
if from <= to then "#{stepCond} && #{lowerBound}" else "#{stepCond} && #{upperBound}"
|
||||
"#{stepNotZero} && (#{stepCond} ? #{lowerBound} : #{upperBound})"
|
||||
else
|
||||
# from < to
|
||||
lowerBound = "#{@fromVar} <= #{idx} && #{lt} #{@toVar}"
|
||||
# from > to
|
||||
upperBound = "#{@fromVar} >= #{idx} && #{gt} #{@toVar}"
|
||||
"#{stepCond} && (#{@fromVar} <= #{@toVar} ? #{lowerBound} : #{upperBound})"
|
||||
if known
|
||||
"#{ if from <= to then lt else gt } #{to}"
|
||||
else
|
||||
"(#{@fromVar} <= #{@toVar} ? #{lowerBound} : #{upperBound})"
|
||||
|
||||
cond = if @stepVar then "#{@stepVar} > 0" else "#{@fromVar} <= #{@toVar}"
|
||||
|
||||
@@ -1482,7 +1475,9 @@ exports.Obj = class Obj extends Base
|
||||
message = isUnassignable prop.unwrapAll().value
|
||||
prop.error message if message
|
||||
|
||||
prop = prop.value if prop instanceof Assign and prop.context is 'object'
|
||||
prop = prop.value if prop instanceof Assign and
|
||||
prop.context is 'object' and
|
||||
prop.value?.base not instanceof Arr
|
||||
return no unless prop.isAssignable()
|
||||
yes
|
||||
|
||||
@@ -2431,7 +2426,8 @@ exports.Assign = class Assign extends Base
|
||||
vvarText = ref
|
||||
|
||||
slicer = (type) -> (vvar, start, end = no) ->
|
||||
args = [new IdentifierLiteral(vvar), new NumberLiteral(start)]
|
||||
vvar = new IdentifierLiteral vvar unless vvar instanceof Value
|
||||
args = [vvar, new NumberLiteral(start)]
|
||||
args.push new NumberLiteral end if end
|
||||
slice = new Value (new IdentifierLiteral utility type, o), [new Access new PropertyName 'call']
|
||||
new Value new Call slice, args
|
||||
@@ -2522,7 +2518,7 @@ exports.Assign = class Assign extends Base
|
||||
if rightObjs.length isnt 0
|
||||
# Slice or splice `objects`.
|
||||
refExp = switch
|
||||
when isSplat then compSplice objects[expIdx].unwrapAll().value, rightObjs.length * -1
|
||||
when isSplat then compSplice new Value(objects[expIdx].name), rightObjs.length * -1
|
||||
when isExpans then compSlice vvarText, rightObjs.length * -1
|
||||
if complexObjects rightObjs
|
||||
restVar = refExp
|
||||
|
||||
@@ -959,7 +959,7 @@ test "#4878: Compile error when using destructuring with a splat or expansion in
|
||||
([first, ...] = list); first
|
||||
|
||||
f4 = (list) ->
|
||||
([first, ...rest] = list); rest
|
||||
([first, rest...] = list); rest
|
||||
|
||||
arrayEq f1(arr), arr
|
||||
arrayEq f2(arr), arr
|
||||
@@ -979,9 +979,56 @@ test "#4878: Compile error when using destructuring with a splat or expansion in
|
||||
bar = (list) ->
|
||||
ret =
|
||||
if list?.length > 0
|
||||
[first, ...rest] = list
|
||||
[first, rest...] = list
|
||||
[first, rest]
|
||||
else
|
||||
[]
|
||||
|
||||
arrayEq bar(arr), ['a', ['b', 'c', 'd']]
|
||||
|
||||
test "destructuring assignment with an empty array in object", ->
|
||||
obj =
|
||||
a1: [1, 2]
|
||||
b1: 3
|
||||
|
||||
{a1:[], b1} = obj
|
||||
eq 'undefined', typeof a1
|
||||
eq b1, 3
|
||||
|
||||
obj =
|
||||
a2:
|
||||
b2: [1, 2]
|
||||
c2: 3
|
||||
|
||||
{a2: {b2:[]}, c2} = obj
|
||||
eq 'undefined', typeof b2
|
||||
eq c2, 3
|
||||
|
||||
test "#5004: array destructuring with accessors", ->
|
||||
obj =
|
||||
arr: ['a', 'b', 'c', 'd']
|
||||
list: {}
|
||||
f1: ->
|
||||
[@first, @rest...] = @arr
|
||||
f2: ->
|
||||
[@second, @third..., @last] = @rest
|
||||
f3: ->
|
||||
[@list.a, @list.middle..., @list.d] = @arr
|
||||
|
||||
obj.f1()
|
||||
eq obj.first, 'a'
|
||||
arrayEq obj.rest, ['b', 'c', 'd']
|
||||
|
||||
obj.f2()
|
||||
eq obj.second, 'b'
|
||||
arrayEq obj.third, ['c']
|
||||
eq obj.last, 'd'
|
||||
|
||||
obj.f3()
|
||||
eq obj.list.a, 'a'
|
||||
arrayEq obj.list.middle, ['b', 'c']
|
||||
eq obj.list.d, 'd'
|
||||
|
||||
[obj.list.middle..., d] = obj.arr
|
||||
eq d, 'd'
|
||||
arrayEq obj.list.middle, ['a', 'b', 'c']
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Functions that contain the `await` keyword will compile into async functions,
|
||||
# supported by Node 7.6+, Chrome 55+, Firefox 52+, Safari 10.1+ and Edge.
|
||||
# But runtimes that don’t support the `await` keyword will throw an error,
|
||||
# even if we put `return unless global.supportsAsync` at the top of this file.
|
||||
# Therefore we need to prevent runtimes which will choke on such code from even
|
||||
# But runtimes that don’t support the `await` keyword will throw an error just
|
||||
# from parsing this file, even without executing it, even if we put
|
||||
# `return unless try new Function 'async () => {}'` at the top of this file.
|
||||
# Therefore we need to prevent runtimes which will choke on such code from
|
||||
# parsing it, which is handled in `Cakefile`.
|
||||
|
||||
|
||||
|
||||
@@ -266,6 +266,7 @@ test "classes with value'd constructors", ->
|
||||
inner = ++counter
|
||||
->
|
||||
@value = inner
|
||||
@
|
||||
|
||||
class One
|
||||
constructor: classMaker()
|
||||
|
||||
@@ -1112,37 +1112,6 @@ test "#3921: `switch`", ->
|
||||
else "none"
|
||||
eq "five", c
|
||||
|
||||
# Issue #3441: Parentheses wrapping expression throw invalid error in `then` clause
|
||||
test "#3441: `StatementLiteral` in parentheses", ->
|
||||
i = 0
|
||||
r1 = ((i++; break) while i < 10)
|
||||
arrayEq r1, []
|
||||
|
||||
i = 0
|
||||
r2 = ((i++; continue) while i < 10)
|
||||
arrayEq r2, []
|
||||
|
||||
i = 0
|
||||
r4 = while i < 10 then (i++; break)
|
||||
arrayEq r4, []
|
||||
|
||||
i = 0
|
||||
r5 = while i < 10 then (i++; continue)
|
||||
arrayEq r5, []
|
||||
|
||||
arr = [0..9]
|
||||
r6 = ((a; break) for a in arr)
|
||||
arrayEq r6, []
|
||||
|
||||
r7 = ((a; continue) for a in arr)
|
||||
arrayEq r7, []
|
||||
|
||||
r8 = for a in arr then (a; break)
|
||||
arrayEq r8, []
|
||||
|
||||
r9 = for a in arr then (a; continue)
|
||||
arrayEq r9, []
|
||||
|
||||
# Issue #3909: backslash to break line in `for` loops throw syntax error
|
||||
test "#3909: backslash `for own ... of`", ->
|
||||
|
||||
@@ -1287,3 +1256,56 @@ test "#4871: `else if` no longer output together ", ->
|
||||
2;
|
||||
}
|
||||
'''
|
||||
|
||||
test "#4898: Lexer: backslash line continuation is inconsistent", ->
|
||||
if ( \
|
||||
false \
|
||||
or \
|
||||
true \
|
||||
)
|
||||
a = 42
|
||||
|
||||
eq a, 42
|
||||
|
||||
if ( \
|
||||
false \
|
||||
or \
|
||||
true \
|
||||
)
|
||||
b = 42
|
||||
|
||||
eq b, 42
|
||||
|
||||
if ( \
|
||||
false \
|
||||
or \
|
||||
true \
|
||||
)
|
||||
c = 42
|
||||
|
||||
eq c, 42
|
||||
|
||||
if \
|
||||
false \
|
||||
or \
|
||||
true
|
||||
d = 42
|
||||
|
||||
eq d, 42
|
||||
|
||||
if \
|
||||
false or \
|
||||
true
|
||||
e = 42
|
||||
|
||||
eq e, 42
|
||||
|
||||
if \
|
||||
false or \
|
||||
true \
|
||||
then \
|
||||
f = 42 \
|
||||
else
|
||||
f = 24
|
||||
|
||||
eq f, 42
|
||||
|
||||
@@ -962,6 +962,42 @@ test "#4097: `yield return` as an expression", ->
|
||||
^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `await return` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
-> (await return)
|
||||
''', '''
|
||||
[stdin]:1:5: error: cannot use a pure statement in an expression
|
||||
-> (await return)
|
||||
^^^^^^^^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `return` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
-> (return)
|
||||
''', '''
|
||||
[stdin]:1:5: error: cannot use a pure statement in an expression
|
||||
-> (return)
|
||||
^^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `break` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
(b = 1; break) for b in a
|
||||
''', '''
|
||||
[stdin]:1:9: error: cannot use a pure statement in an expression
|
||||
(b = 1; break) for b in a
|
||||
^^^^^
|
||||
'''
|
||||
|
||||
test "#5013: `continue` as an expression", ->
|
||||
assertErrorFormat '''
|
||||
(b = 1; continue) for b in a
|
||||
''', '''
|
||||
[stdin]:1:9: error: cannot use a pure statement in an expression
|
||||
(b = 1; continue) for b in a
|
||||
^^^^^^^^
|
||||
'''
|
||||
|
||||
test "`&&=` and `||=` with a space in-between", ->
|
||||
assertErrorFormat '''
|
||||
a = 0
|
||||
|
||||
@@ -853,3 +853,70 @@ test "#4491: import- and export-specific lexing should stop after import/export
|
||||
|
||||
from('foo');
|
||||
"""
|
||||
|
||||
# Issue #4874: Backslash not supported in import or export statements
|
||||
test "#4874: backslash `import`", ->
|
||||
|
||||
eqJS """
|
||||
import foo \
|
||||
from 'lib'
|
||||
|
||||
foo a
|
||||
""",
|
||||
"""
|
||||
import foo from 'lib';
|
||||
|
||||
foo(a);
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import \
|
||||
foo \
|
||||
from \
|
||||
'lib'
|
||||
|
||||
foo a
|
||||
""",
|
||||
"""
|
||||
import foo from 'lib';
|
||||
|
||||
foo(a);
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
import \
|
||||
utilityBelt \
|
||||
, {
|
||||
each
|
||||
} from \
|
||||
'underscore'
|
||||
""",
|
||||
"""
|
||||
import utilityBelt, {
|
||||
each
|
||||
} from 'underscore';
|
||||
"""
|
||||
|
||||
test "#4874: backslash `export`", ->
|
||||
eqJS """
|
||||
export \
|
||||
* \
|
||||
from \
|
||||
'underscore'
|
||||
""",
|
||||
"""
|
||||
export * from 'underscore';
|
||||
"""
|
||||
|
||||
eqJS """
|
||||
export \
|
||||
{ max, min } \
|
||||
from \
|
||||
'underscore'
|
||||
""",
|
||||
"""
|
||||
export {
|
||||
max,
|
||||
min
|
||||
} from 'underscore';
|
||||
"""
|
||||
|
||||
@@ -130,43 +130,43 @@ test "#2047: Infinite loop possible when `for` loop with `range` uses variables"
|
||||
|
||||
testData = [
|
||||
[1, 5, 1, [1..5]]
|
||||
[1, 5, -1, [1]]
|
||||
[1, 5, -1, []]
|
||||
[1, 5, up, [1..5]]
|
||||
[1, 5, down, [1]]
|
||||
[1, 5, down, []]
|
||||
|
||||
[a, 5, 1, [1..5]]
|
||||
[a, 5, -1, [1]]
|
||||
[a, 5, -1, []]
|
||||
[a, 5, up, [1..5]]
|
||||
[a, 5, down, [1]]
|
||||
[a, 5, down, []]
|
||||
|
||||
[1, b, 1, [1..5]]
|
||||
[1, b, -1, [1]]
|
||||
[1, b, -1, []]
|
||||
[1, b, up, [1..5]]
|
||||
[1, b, down, [1]]
|
||||
[1, b, down, []]
|
||||
|
||||
[a, b, 1, [1..5]]
|
||||
[a, b, -1, [1]]
|
||||
[a, b, -1, []]
|
||||
[a, b, up, [1..5]]
|
||||
[a, b, down, [1]]
|
||||
[a, b, down, []]
|
||||
|
||||
[5, 1, 1, [5]]
|
||||
[5, 1, 1, []]
|
||||
[5, 1, -1, [5..1]]
|
||||
[5, 1, up, [5]]
|
||||
[5, 1, up, []]
|
||||
[5, 1, down, [5..1]]
|
||||
|
||||
[5, a, 1, [5]]
|
||||
[5, a, 1, []]
|
||||
[5, a, -1, [5..1]]
|
||||
[5, a, up, [5]]
|
||||
[5, a, up, []]
|
||||
[5, a, down, [5..1]]
|
||||
|
||||
[b, 1, 1, [5]]
|
||||
[b, 1, 1, []]
|
||||
[b, 1, -1, [5..1]]
|
||||
[b, 1, up, [5]]
|
||||
[b, 1, up, []]
|
||||
[b, 1, down, [5..1]]
|
||||
|
||||
[b, a, 1, [5]]
|
||||
[b, a, 1, []]
|
||||
[b, a, -1, [5..1]]
|
||||
[b, a, up, [5]]
|
||||
[b, a, up, []]
|
||||
[b, a, down, [5..1]]
|
||||
]
|
||||
|
||||
@@ -182,10 +182,10 @@ test "#2047: from, to and step as variables", ->
|
||||
arrayEq r, [1..5]
|
||||
|
||||
r = (x for x in [a..b] by down)
|
||||
arrayEq r, [1]
|
||||
arrayEq r, []
|
||||
|
||||
r = (x for x in [b..a] by up)
|
||||
arrayEq r, [5]
|
||||
arrayEq r, []
|
||||
|
||||
r = (x for x in [b..a] by down)
|
||||
arrayEq r, [5..1]
|
||||
@@ -202,3 +202,43 @@ test "#4884: Range not declaring var for the 'i'", ->
|
||||
idx + 1
|
||||
|
||||
eq global.i, undefined
|
||||
|
||||
test "#4889: `for` loop unexpected behavior", ->
|
||||
n = 1
|
||||
result = []
|
||||
for i in [0..n]
|
||||
result.push i
|
||||
for j in [(i+1)..n]
|
||||
result.push j
|
||||
|
||||
arrayEq result, [0,1,1,2,1]
|
||||
|
||||
test "#4889: `for` loop unexpected behavior with `by 1` on second loop", ->
|
||||
n = 1
|
||||
result = []
|
||||
for i in [0..n]
|
||||
result.push i
|
||||
for j in [(i+1)..n] by 1
|
||||
result.push j
|
||||
|
||||
arrayEq result, [0,1,1]
|
||||
|
||||
test "countdown example from docs", ->
|
||||
countdown = (num for num in [10..1])
|
||||
arrayEq countdown, [10,9,8,7,6,5,4,3,2,1]
|
||||
|
||||
test "counting up when the range goes down returns an empty array", ->
|
||||
countdown = (num for num in [10..1] by 1)
|
||||
arrayEq countdown, []
|
||||
|
||||
test "counting down when the range goes up returns an empty array", ->
|
||||
countup = (num for num in [1..10] by -1)
|
||||
arrayEq countup, []
|
||||
|
||||
test "counting down by too much returns just the first value", ->
|
||||
countdown = (num for num in [10..1] by -100)
|
||||
arrayEq countdown, [10]
|
||||
|
||||
test "counting up by too much returns just the first value", ->
|
||||
countup = (num for num in [1..10] by 100)
|
||||
arrayEq countup, [1]
|
||||
|
||||
@@ -124,7 +124,7 @@ testRepl "keeps running after runtime error", (input, output) ->
|
||||
eq 'undefined', output.lastWrite()
|
||||
|
||||
testRepl "#4604: wraps an async function", (input, output) ->
|
||||
return unless global.supportsAsync
|
||||
return unless try new Function 'async () => {}' # Feature detect support for async functions.
|
||||
input.emitLine 'await new Promise (resolve) -> setTimeout (-> resolve 33), 10'
|
||||
setTimeout ->
|
||||
eq '33', output.lastWrite()
|
||||
|
||||
Reference in New Issue
Block a user