Compare commits

..

8 Commits
2.3.1 ... 2.3.2

Author SHA1 Message Date
Geoffrey Booth
6e86b67818 Release 2.3.2 (#5110)
* Bump version to 2.3.2

* 2.3.2 changelog

* Update output for 2.3.2
2018-09-19 23:53:49 -07:00
Geoffrey Booth
b4dceaea67 Fix #5086: Don't generate unnecessary interpolations in JSX tags when the tags contain only here (/* ... */) comments (#5108) 2018-09-18 08:02:41 -07:00
Julian Rosse
6225627579 Fix #4609: support new.target (#5106)
* support new.target

* check token type
2018-09-16 13:52:47 -07:00
Geoffrey Booth
c4245e50c2 Babel 7 (#5105)
* Port to Babel 7

Use the Babel 7 @babel/core transpiler, falling back to the older babel-core version if possible.

* Use Babel 7 and preset-env 7 to build the browser compiler and test Babel transpilation

* Update docs for Babel 7
2018-09-09 13:41:49 -07:00
Geoffrey Booth
98b2a69416 Update dependencies; disable some babel-minify transforms to work around https://github.com/babel/minify/issues/893 (#5095) 2018-08-14 08:47:38 -07:00
Geoffrey Booth
7f8b36a8bd Revert "fix momentum scrolling on iOS (#5083)" (#5084)
This reverts commit 812571843c.
2018-06-16 15:35:34 -07:00
Paul Nta
812571843c fix momentum scrolling on iOS (#5083) 2018-06-16 15:32:16 -07:00
Julian Rosse
70f6cb70e2 Allow yield indented object (#5072)
* allow yield indented object

* allow await indented object

* fixes from code review
2018-06-10 21:45:45 -07:00
46 changed files with 3003 additions and 2452 deletions

View File

@@ -1,3 +1,3 @@
{
"presets": ["env"]
"presets": ["@babel/env"]
}

View File

@@ -67,12 +67,12 @@ build = (callback) ->
buildExceptParser callback
transpile = (code) ->
babel = require 'babel-core'
babel = require '@babel/core'
presets = []
# Exclude the `modules` plugin in order to not break the `}(this));`
# at the end of the `build:browser` code block.
presets.push ['env', {modules: no}] unless process.env.TRANSFORM is 'false'
presets.push ['minify', {mangle: no}] unless process.env.MINIFY is 'false'
presets.push ['@babel/env', {modules: no}] unless process.env.TRANSFORM is 'false'
presets.push ['minify', {mangle: no, evaluate: no, removeUndefined: no}] unless process.env.MINIFY is 'false'
babelOptions =
compact: process.env.MINIFY isnt 'false'
presets: presets

View File

@@ -875,8 +875,11 @@ browsers) or use a proper build chain like Gulp or Webpack.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">try</span>
<span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
<span class="hljs-keyword">catch</span></pre></div></div>
<span class="hljs-built_in">require</span> <span class="hljs-string">'@babel/core'</span>
<span class="hljs-keyword">catch</span>
<span class="hljs-keyword">try</span>
<span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
<span class="hljs-keyword">catch</span></pre></div></div>
</li>
@@ -892,21 +895,21 @@ locally or globally.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'.'</span>).indexOf(process.cwd()) <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
To use --transpile, you must have babel-core installed:
npm install --save-dev babel-core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''</span>
<span class="hljs-keyword">else</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
To use --transpile with globally-installed CoffeeScript, you must have babel-core installed globally:
npm install --global babel-core
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
See https://coffeescript.org/#transpilation
'''</span>
process.exit <span class="hljs-number">1</span>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'.'</span>).indexOf(process.cwd()) <span class="hljs-keyword">is</span> <span class="hljs-number">0</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
To use --transpile, you must have @babel/core installed:
npm install --save-dev @babel/core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''</span>
<span class="hljs-keyword">else</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:
npm install --global @babel/core
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
See https://coffeescript.org/#transpilation
'''</span>
process.exit <span class="hljs-number">1</span>
opts.transpile = {} <span class="hljs-keyword">unless</span> <span class="hljs-keyword">typeof</span> opts.transpile <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span></pre></div></div>

View File

@@ -442,6 +442,7 @@ wrapped in braces: E.g <code>a = b if do -&gt; f a is 1</code>, <code>if f (a) -
Yield: [
o <span class="hljs-string">'YIELD'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span>, <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">''</span>
o <span class="hljs-string">'YIELD Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'YIELD INDENT Object OUTDENT'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
o <span class="hljs-string">'YIELD FROM Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1.</span>concat($<span class="hljs-number">2</span>), $<span class="hljs-number">3</span>
]</pre></div></div>
@@ -1733,7 +1734,8 @@ rules are necessary.</p>
o <span class="hljs-string">'- Expression'</span>, (<span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'-'</span>, $<span class="hljs-number">2</span>), prec: <span class="hljs-string">'UNARY_MATH'</span>
o <span class="hljs-string">'+ Expression'</span>, (<span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'+'</span>, $<span class="hljs-number">2</span>), prec: <span class="hljs-string">'UNARY_MATH'</span>
o <span class="hljs-string">'AWAIT Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span> , $<span class="hljs-number">2</span>
o <span class="hljs-string">'AWAIT Expression'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'AWAIT INDENT Object OUTDENT'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span>, $<span class="hljs-number">3</span>
o <span class="hljs-string">'-- SimpleAssignable'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'--'</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'++ SimpleAssignable'</span>, <span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'++'</span>, $<span class="hljs-number">2</span>

View File

@@ -128,8 +128,11 @@ helpers = CoffeeScript.helpers
CoffeeScript.transpile = <span class="hljs-function"><span class="hljs-params">(js, options)</span> -&gt;</span>
<span class="hljs-keyword">try</span>
babel = <span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
<span class="hljs-keyword">catch</span></pre></div></div>
babel = <span class="hljs-built_in">require</span> <span class="hljs-string">'@babel/core'</span>
<span class="hljs-keyword">catch</span>
<span class="hljs-keyword">try</span>
babel = <span class="hljs-built_in">require</span> <span class="hljs-string">'babel-core'</span>
<span class="hljs-keyword">catch</span></pre></div></div>
</li>
@@ -145,7 +148,7 @@ earlier if they dont have Babel installed.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">'To use the transpile option, you must have the \'babel-core\' module installed'</span>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Error <span class="hljs-string">'To use the transpile option, you must have the \'@babel/core\' module installed'</span>
babel.transform js, options</pre></div></div>
</li>

View File

@@ -465,6 +465,8 @@ what CoffeeScript would normally interpret as calls to functions named
@tokens.length &gt; <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> @tokens[@tokens.length - <span class="hljs-number">2</span>][<span class="hljs-number">0</span>] <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'.'</span>, <span class="hljs-string">'?.'</span>, <span class="hljs-string">'@'</span>]
@error <span class="hljs-string">"'<span class="hljs-subst">#{prev[<span class="hljs-number">1</span>]}</span>' cannot be used as a keyword, or as a function call
without parentheses"</span>, prev[<span class="hljs-number">2</span>]
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> prev[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'.'</span> <span class="hljs-keyword">and</span> @tokens.length &gt; <span class="hljs-number">1</span> <span class="hljs-keyword">and</span> (prevprev = @tokens[@tokens.length - <span class="hljs-number">2</span>])[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'UNARY'</span> <span class="hljs-keyword">and</span> prevprev[<span class="hljs-number">1</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'new'</span>
prevprev[<span class="hljs-number">0</span>] = <span class="hljs-string">'IDENTIFIER'</span>
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> @tokens.length &gt; <span class="hljs-number">2</span>
prevprev = @tokens[@tokens.length - <span class="hljs-number">2</span>]
<span class="hljs-keyword">if</span> prev[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> [<span class="hljs-string">'@'</span>, <span class="hljs-string">'THIS'</span>] <span class="hljs-keyword">and</span> prevprev <span class="hljs-keyword">and</span> prevprev.spaced <span class="hljs-keyword">and</span>

View File

@@ -2117,6 +2117,7 @@ evaluate anything twice when building the soak chain.</p>
</div>
<div class="content"><div class='highlight'><pre> compileNode: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
@checkNewTarget o
@base.front = @front
props = @properties
<span class="hljs-keyword">if</span> props.length <span class="hljs-keyword">and</span> @base.cached?</pre></div></div>
@@ -2147,7 +2148,15 @@ Example:
<span class="hljs-keyword">for</span> prop <span class="hljs-keyword">in</span> props
fragments.push (prop.compileToFragments o)...
fragments</pre></div></div>
fragments
checkNewTarget: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> @base <span class="hljs-keyword">instanceof</span> IdentifierLiteral <span class="hljs-keyword">and</span> @base.value <span class="hljs-keyword">is</span> <span class="hljs-string">'new'</span> <span class="hljs-keyword">and</span> @properties.length
<span class="hljs-keyword">if</span> @properties[<span class="hljs-number">0</span>] <span class="hljs-keyword">instanceof</span> Access <span class="hljs-keyword">and</span> @properties[<span class="hljs-number">0</span>].name.value <span class="hljs-keyword">is</span> <span class="hljs-string">'target'</span>
<span class="hljs-keyword">unless</span> o.scope.parent?
@error <span class="hljs-string">"new.target can only occur inside functions"</span>
<span class="hljs-keyword">else</span>
@error <span class="hljs-string">"the only valid meta property for new is new.target"</span></pre></div></div>
</li>
@@ -7071,7 +7080,8 @@ and using @body.compileNode. <code>StringWithInterpolations.compileNode</code> i
<span class="hljs-keyword">else</span>
fragments.push @makeCode <span class="hljs-string">'$'</span> <span class="hljs-keyword">unless</span> @csx
code = element.compileToFragments(o, LEVEL_PAREN)
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> @isNestedTag(element) <span class="hljs-keyword">or</span> code.some(<span class="hljs-function"><span class="hljs-params">(fragment)</span> -&gt;</span> fragment.comments?)
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> @isNestedTag(element) <span class="hljs-keyword">or</span>
code.some(<span class="hljs-function"><span class="hljs-params">(fragment)</span> -&gt;</span> fragment.comments?.some(<span class="hljs-function"><span class="hljs-params">(comment)</span> -&gt;</span> comment.here <span class="hljs-keyword">is</span> <span class="hljs-literal">no</span>))
code = @wrapInBraces code</pre></div></div>
</li>
@@ -7085,8 +7095,10 @@ and using @body.compileNode. <code>StringWithInterpolations.compileNode</code> i
</div>
<p>Flag the <code>{</code> and <code>}</code> fragments as having been generated by this
<code>StringWithInterpolations</code> node, so that <code>compileComments</code> knows
to treat them as bounds. Dont trust <code>fragment.type</code>, which can
report minified variable names when this compiler is minified.</p>
to treat them as bounds. But the braces are unnecessary if all of
the enclosed comments are <code>/* */</code> comments. Dont trust
<code>fragment.type</code>, which can report minified variable names when
this compiler is minified.</p>
</div>

View File

@@ -699,19 +699,22 @@ undeclared variable <code>__</code>.</p>
CoffeeScript.register()
process.argv = [<span class="hljs-string">'coffee'</span>].concat process.argv[<span class="hljs-number">2.</span>.]
<span class="hljs-keyword">if</span> opts.transpile
transpile = {}
<span class="hljs-keyword">try</span>
transpile = {}
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'babel-core'</span>).transform
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@babel/core'</span>).transform
<span class="hljs-keyword">catch</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
To use --transpile with an interactive REPL, babel-core must be installed either in the current folder or globally:
npm install --save-dev babel-core
or
npm install --global babel-core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''</span>
process.exit <span class="hljs-number">1</span>
<span class="hljs-keyword">try</span>
transpile.transpile = <span class="hljs-built_in">require</span>(<span class="hljs-string">'babel-core'</span>).transform
<span class="hljs-keyword">catch</span>
<span class="hljs-built_in">console</span>.error <span class="hljs-string">'''
To use --transpile with an interactive REPL, @babel/core must be installed either in the current folder or globally:
npm install --save-dev @babel/core
or
npm install --global @babel/core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''</span>
process.exit <span class="hljs-number">1</span>
transpile.options =
filename: path.resolve process.cwd(), <span class="hljs-string">'&lt;repl&gt;'</span></pre></div></div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1552,6 +1552,14 @@ test "async methods in classes", ->
eq await Child.static(), 1
eq await new Child().method(), 2
test "#3199: await multiline implicit object", ->
do ->
y =
if no then await
type: 'a'
msg: 'b'
eq undefined, y
</script>
<script type="text/x-coffeescript" class="test" id="async_iterators">
# This is always fulfilled.
@@ -3515,6 +3523,29 @@ test "#4868: Incorrect Cant call super with @params error", ->
d = new (new D).c
eq 3, d.a
test "#4609: Support new.target", ->
class A
constructor: ->
@calledAs = new.target.name
class B extends A
b = new B
eq b.calledAs, 'B'
newTarget = null
Foo = ->
newTarget = !!new.target
Foo()
eq newTarget, no
newTarget = null
new Foo()
eq newTarget, yes
</script>
<script type="text/x-coffeescript" class="test" id="cluster">
# Cluster Module
@@ -4673,7 +4704,7 @@ transpile = (method, code, options = {}) ->
options.bare = yes
options.transpile =
# Target Internet Explorer 6, which supports no ES2015+ features.
presets: [['env', {targets: browsers: ['ie 6']}]]
presets: [['@babel/env', {targets: browsers: ['ie 6']}]]
CoffeeScript[method] code, options
@@ -4839,6 +4870,7 @@ test "#3306: trailing comma in a function call in the last line", ->
''', '''
foo(bar);
'''
</script>
<script type="text/x-coffeescript" class="test" id="comprehensions">
# Comprehensions
@@ -7480,6 +7512,47 @@ test '#4686: comments inside interpolations that also contain CSX attributes', -
</div>;
'''
test '#5086: comments inside CSX tags but outside interpolations', ->
eqJS '''
<div>
<div ###comment### attribute={value} />
</div>
''', '''
<div>
<div /*comment*/attribute={value} />
</div>;
'''
test '#5086: comments inside CSX attributes but outside interpolations', ->
eqJS '''
<div>
<div attribute={###attr comment### value} />
</div>
''', '''
<div>
<div attribute={/*attr comment*/value} />
</div>;
'''
test '#5086: comments inside nested CSX tags and attributes but outside interpolations', ->
eqJS '''
<div>
<div>
<div>
<div ###comment### attribute={###attr comment### value} />
</div>
</div>
</div>
''', '''
<div>
<div>
<div>
<div /*comment*/attribute={/*attr comment*/value} />
</div>
</div>
</div>;
'''
# https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
test 'JSX fragments: empty fragment', ->
eqJS '''
@@ -9377,6 +9450,50 @@ test "#3199: error message for throw indented comprehension", ->
^
'''
test "#3199: error message for yield indented non-object", ->
assertErrorFormat '''
->
yield
1
''', '''
[stdin]:3:5: error: unexpected number
1
^
'''
test "#3199: error message for yield indented comprehension", ->
assertErrorFormat '''
->
yield
x for x in [1, 2, 3]
''', '''
[stdin]:3:5: error: unexpected identifier
x for x in [1, 2, 3]
^
'''
test "#3199: error message for await indented non-object", ->
assertErrorFormat '''
->
await
1
''', '''
[stdin]:3:5: error: unexpected number
1
^
'''
test "#3199: error message for await indented comprehension", ->
assertErrorFormat '''
->
await
x for x in [1, 2, 3]
''', '''
[stdin]:3:5: error: unexpected identifier
x for x in [1, 2, 3]
^
'''
test "#3098: suppressed newline should be unsuppressed by semicolon", ->
assertErrorFormat '''
a = ; 5
@@ -9445,6 +9562,24 @@ test "#3933: prevent implicit calls when cotrol flow is missing `THEN`", ->
^^
'''
test "`new.target` outside of a function", ->
assertErrorFormat '''
new.target
''', '''
[stdin]:1:1: error: new.target can only occur inside functions
new.target
^^^^^^^^^^
'''
test "`new.target` is only allowed meta property", ->
assertErrorFormat '''
-> new.something
''', '''
[stdin]:1:4: error: the only valid meta property for new is new.target
-> new.something
^^^^^^^^^^^^^
'''
</script>
<script type="text/x-coffeescript" class="test" id="eval">
if vm = require? 'vm'
@@ -10108,6 +10243,22 @@ test "#3199: throw multiline implicit object", ->
msg: 'b'
eq undefined, y
y = do ->
yield
type: 'a'
msg: 'b'
if no then yield
type: 'c'
msg: 'd'
1
{value, done} = y.next()
ok value.type is 'a' and done is no
{value, done} = y.next()
ok value is 1 and done is yes
test "#4576: multiple row function chaining", ->
->
eq @a, 3

View File

@@ -0,0 +1,8 @@
```
releaseHeader('2018-09-19', '2.3.2', '2.3.1')
```
* Babel 7 is now supported. With version 7, the Babel team moved from `babel-core` on NPM to `@babel/core`. Now the CoffeeScript `--transpile` option will first search for `@babel/core` (Babel versions 7 and above) and then search for `babel-core` (versions 6 and below) to try to find an installed version of Babel to use for transpilation.
* The syntax [`new.target`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target) is now supported.
* You can now follow the keyword `yield` with an indented object, like has already been allowed for `return` and other keywords.
* Previously, any comments inside a JSX tag or attribute would cause interpolation braces (`{` and `}`) to be output. This is only necessary for line (`#`, or `//` in JavaScript) comments, not here (`###`, or `/* */`) comments; so now the compiler checks if all the comments that would trigger the braces are here comments, and if so it doesnt generate the unnecessary interpolation braces.

View File

@@ -5,7 +5,7 @@ Once installed, you should have access to the `coffee` command, which can execut
| Option | Description |
| --- | --- |
| `-c, --compile` | Compile a `.coffee` script into a `.js` JavaScript file of the same name. |
| `-t, --transpile` | Pipe the CoffeeScript compilers output through Babel before saving or running the generated JavaScript. Requires `babel-core` to be installed, and options to pass to Babel in a `.babelrc` file or a `package.json` with a `babel` key in the path of the file or folder to be compiled. See [Transpilation](#transpilation).
| `-t, --transpile` | Pipe the CoffeeScript compilers output through Babel before saving or running the generated JavaScript. Requires `@babel/core` to be installed, and options to pass to Babel in a `.babelrc` file or a `package.json` with a `babel` key in the path of the file or folder to be compiled. See [Transpilation](#transpilation).
| `-m, --map` | Generate source maps alongside the compiled JavaScript files. Adds `sourceMappingURL` directives to the JavaScript as well. |
| `-M, --inline-map` | Just like `--map`, but include the source map directly in the compiled JavaScript files, rather than in a separate file. |
| `-i, --interactive` | Launch an interactive CoffeeScript session to try short snippets. Identical to calling `coffee` with no arguments. |
@@ -37,4 +37,4 @@ Once installed, you should have access to the `coffee` command, which can execut
* Start the CoffeeScript REPL (`Ctrl-D` to exit, `Ctrl-V`for multi-line):<br>
`coffee`
To use `--transpile`, see [Transpilation](#transpilation).
To use `--transpile`, see [Transpilation](#transpilation).

View File

@@ -18,4 +18,4 @@ npm install --save-dev coffeescript
The `coffee` and `cake` commands will first look in the current folder to see if CoffeeScript is installed locally, and use that version if so. This allows different versions of CoffeeScript to be installed globally and locally.
If you plan to use the `--transpile` option (see [Transpilation](#transpilation)) you will need to also install `babel-core` either globally or locally, depending on whether you are running a globally or locally installed version of CoffeeScript.
If you plan to use the `--transpile` option (see [Transpilation](#transpilation)) you will need to also install `@babel/core` either globally or locally, depending on whether you are running a globally or locally installed version of CoffeeScript.

View File

@@ -7,43 +7,43 @@ CoffeeScript 2 generates JavaScript that uses the latest, modern syntax. The run
From the root of your project:
```bash
npm install --save-dev babel-core babel-preset-env
echo '{ "presets": ["env"] }' > .babelrc
npm install --save-dev @babel/core @babel/preset-env
echo '{ "presets": ["@babel/env"] }' > .babelrc
coffee --compile --transpile --inline-map some-file.coffee
```
#### Transpiling with the CoffeeScript compiler
To make things easy, CoffeeScript has built-in support for the popular [Babel](http://babeljs.io/) transpiler. You can use it via the `--transpile` command-line option or the `transpile` Node API option. To use either, `babel-core` must be installed in your project:
To make things easy, CoffeeScript has built-in support for the popular [Babel](http://babeljs.io/) transpiler. You can use it via the `--transpile` command-line option or the `transpile` Node API option. To use either, `@babel/core` must be installed in your project:
```bash
npm install --save-dev babel-core
npm install --save-dev @babel/core
```
Or if youre running the `coffee` command outside of a project folder, using a globally-installed `coffeescript` module, `babel-core` needs to be installed globally:
Or if youre running the `coffee` command outside of a project folder, using a globally-installed `coffeescript` module, `@babel/core` needs to be installed globally:
```bash
npm install --global babel-core
npm install --global @babel/core
```
By default, Babel doesnt do anything—it doesnt make assumptions about what you want to transpile to. You need to provide it with a configuration so that it knows what to do. One way to do this is by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files youre compiling, or in any parent folder up the path above those files. (Babel supports [other ways](https://babeljs.io/docs/usage/babelrc/), too.) A minimal `.babelrc` file would be just `{ "presets": ["env"] }`. This implies that you have installed [`babel-preset-env`](https://babeljs.io/docs/plugins/preset-env/):
By default, Babel doesnt do anything—it doesnt make assumptions about what you want to transpile to. You need to provide it with a configuration so that it knows what to do. One way to do this is by creating a [`.babelrc` file](https://babeljs.io/docs/usage/babelrc/) in the folder containing the files youre compiling, or in any parent folder up the path above those files. (Babel supports [other ways](https://babeljs.io/docs/usage/babelrc/), too.) A minimal `.babelrc` file would be just `{ "presets": ["@babel/env"] }`. This implies that you have installed [`@babel/preset-env`](https://babeljs.io/docs/plugins/preset-env/):
```bash
npm install --save-dev babel-preset-env # Or --global for non-project-based usage
npm install --save-dev @babel/preset-env # Or --global for non-project-based usage
```
See [Babels website to learn about presets and plugins](https://babeljs.io/docs/plugins/) and the multitude of options you have. Another preset you might need is [`transform-react-jsx`](https://babeljs.io/docs/plugins/transform-react-jsx/) if youre using JSX with React (JSX can also be used with other frameworks).
See [Babels website to learn about presets and plugins](https://babeljs.io/docs/plugins/) and the multitude of options you have. Another preset you might need is [`@babel/plugin-transform-react-jsx`](https://babeljs.io/docs/en/babel-plugin-transform-react-jsx/) if youre using JSX with React (JSX can also be used with other frameworks).
Once you have `babel-core` and `babel-preset-env` (or other presets or plugins) installed, and a `.babelrc` file (or other equivalent) in place, you can use `coffee --transpile` to pipe CoffeeScripts output through Babel using the options youve saved.
Once you have `@babel/core` and `@babel/preset-env` (or other presets or plugins) installed, and a `.babelrc` file (or other equivalent) in place, you can use `coffee --transpile` to pipe CoffeeScripts output through Babel using the options youve saved.
If youre using CoffeeScript via the [Node API](nodejs_usage), where you call `CoffeeScript.compile` with a string to be compiled and an `options` object, the `transpile` key of the `options` object should be the Babel options:
```js
CoffeeScript.compile(code, {transpile: {presets: ['env']}})
CoffeeScript.compile(code, {transpile: {presets: ['@babel/env']}})
```
You can also transpile CoffeeScripts output without using the `transpile` option, for example as part of a build chain. This lets you use transpilers other than Babel, and it gives you greater control over the process. There are many great task runners for setting up JavaScript build chains, such as [Gulp](http://gulpjs.com/), [Webpack](https://webpack.github.io/), [Grunt](https://gruntjs.com/) and [Broccoli](http://broccolijs.com/).
#### Polyfills
Note that transpiling doesnt automatically supply [polyfills](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill) for your code. CoffeeScript itself will output [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) if you use the `in` operator, or destructuring or spread/rest syntax; and [`Function.bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) if you use a bound (`=>`) method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. Youll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is [`babel-polyfill`](https://babeljs.io/docs/usage/polyfill/), though there are many [other](https://hackernoon.com/polyfills-everything-you-ever-wanted-to-know-or-maybe-a-bit-less-7c8de164e423) [strategies](https://philipwalton.com/articles/loading-polyfills-only-when-needed/).
Note that transpiling doesnt automatically supply [polyfills](https://developer.mozilla.org/en-US/docs/Glossary/Polyfill) for your code. CoffeeScript itself will output [`Array.indexOf`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) if you use the `in` operator, or destructuring or spread/rest syntax; and [`Function.bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) if you use a bound (`=>`) method in a class. Both are supported in Internet Explorer 9+ and all more recent browsers, but you will need to supply polyfills if you need to support Internet Explorer 8 or below and are using features that would cause these methods to be output. Youll also need to supply polyfills if your own code uses these methods or another method added in recent versions of JavaScript. One polyfill option is [`@babel/polyfill`](https://babeljs.io/docs/en/babel-polyfill/), though there are many [other](https://hackernoon.com/polyfills-everything-you-ever-wanted-to-know-or-maybe-a-bit-less-7c8de164e423) [strategies](https://philipwalton.com/articles/loading-polyfills-only-when-needed/).

View File

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

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// This **Browser** compatibility layer extends core CoffeeScript functions
// to make things work smoothly when compiling code directly in the browser.

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// `cake` is a simplified version of [Make](http://www.gnu.org/software/make/)
// ([Rake](http://rake.rubyforge.org/), [Jake](https://github.com/280north/jake))

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// CoffeeScript can be used both on the server, as a command-line compiler based
// on Node.js/V8, or to run CoffeeScript directly in the browser. This module

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// The `coffee` utility. Handles command-line compilation of CoffeeScript
// into various forms: saved into `.js` files or printed to stdout
@@ -619,16 +619,20 @@
// on us to transpile for them; we assume most users will probably either
// run CoffeeScripts output without transpilation (modern Node or evergreen
// browsers) or use a proper build chain like Gulp or Webpack.
require('babel-core');
require('@babel/core');
} catch (error) {
// Give appropriate instructions depending on whether `coffee` was run
// locally or globally.
if (require.resolve('.').indexOf(process.cwd()) === 0) {
console.error('To use --transpile, you must have babel-core installed:\n npm install --save-dev babel-core\nAnd you must save options to configure Babel in one of the places it looks to find its options.\nSee https://coffeescript.org/#transpilation');
} else {
console.error('To use --transpile with globally-installed CoffeeScript, you must have babel-core installed globally:\n npm install --global babel-core\nAnd you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.\nSee https://coffeescript.org/#transpilation');
try {
require('babel-core');
} catch (error) {
// Give appropriate instructions depending on whether `coffee` was run
// locally or globally.
if (require.resolve('.').indexOf(process.cwd()) === 0) {
console.error('To use --transpile, you must have @babel/core installed:\n npm install --save-dev @babel/core\nAnd you must save options to configure Babel in one of the places it looks to find its options.\nSee https://coffeescript.org/#transpilation');
} else {
console.error('To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:\n npm install --global @babel/core\nAnd you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.\nSee https://coffeescript.org/#transpilation');
}
process.exit(1);
}
process.exit(1);
}
if (typeof opts.transpile !== 'object') {
opts.transpile = {};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// The CoffeeScript parser is generated by [Jison](https://github.com/zaach/jison)
// from this grammar file. Jison is a bottom-up parser generator, similar in
@@ -129,6 +129,11 @@
return new Op($1,
$2);
}),
o('YIELD INDENT Object OUTDENT',
function() {
return new Op($1,
$3);
}),
o('YIELD FROM Expression',
function() {
return new Op($1.concat($2),
@@ -1958,6 +1963,11 @@
return new Op($1,
$2);
}),
o('AWAIT INDENT Object OUTDENT',
function() {
return new Op($1,
$3);
}),
o('-- SimpleAssignable',
function() {
return new Op('--',

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// This file contains the common helper functions that we'd like to share among
// the **Lexer**, **Rewriter**, and the **Nodes**. Merge objects, flatten

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// Node.js Implementation
var CoffeeScript, ext, fs, helpers, i, len, path, ref, universalCompile, vm,
@@ -17,11 +17,15 @@
CoffeeScript.transpile = function(js, options) {
var babel;
try {
babel = require('babel-core');
babel = require('@babel/core');
} catch (error) {
// This error is only for Node, as CLI users will see a different error
// earlier if they dont have Babel installed.
throw new Error('To use the transpile option, you must have the \'babel-core\' module installed');
try {
babel = require('babel-core');
} catch (error) {
// This error is only for Node, as CLI users will see a different error
// earlier if they dont have Babel installed.
throw new Error('To use the transpile option, you must have the \'@babel/core\' module installed');
}
}
return babel.transform(js, options);
};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
// matches against the beginning of the source code. When a match is found,
@@ -202,6 +202,8 @@
} else if (tag === 'PROPERTY' && prev) {
if (prev.spaced && (ref7 = prev[0], indexOf.call(CALLABLE, ref7) >= 0) && /^[gs]et$/.test(prev[1]) && this.tokens.length > 1 && ((ref8 = this.tokens[this.tokens.length - 2][0]) !== '.' && ref8 !== '?.' && ref8 !== '@')) {
this.error(`'${prev[1]}' cannot be used as a keyword, or as a function call without parentheses`, prev[2]);
} else if (prev[0] === '.' && this.tokens.length > 1 && (prevprev = this.tokens[this.tokens.length - 2])[0] === 'UNARY' && prevprev[1] === 'new') {
prevprev[0] = 'IDENTIFIER';
} else if (this.tokens.length > 2) {
prevprev = this.tokens[this.tokens.length - 2];
if (((ref9 = prev[0]) === '@' || ref9 === 'THIS') && prevprev && prevprev.spaced && /^[gs]et$/.test(prevprev[1]) && ((ref10 = this.tokens[this.tokens.length - 3][0]) !== '.' && ref10 !== '?.' && ref10 !== '@')) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// `nodes.coffee` contains all of the node classes for the syntax tree. Most
// nodes are created as the result of actions in the [grammar](grammar.html),
@@ -1445,6 +1445,7 @@
// evaluate anything twice when building the soak chain.
compileNode(o) {
var fragments, j, len1, prop, props;
this.checkNewTarget(o);
this.base.front = this.front;
props = this.properties;
if (props.length && (this.base.cached != null)) {
@@ -1468,6 +1469,19 @@
return fragments;
}
checkNewTarget(o) {
if (!(this.base instanceof IdentifierLiteral && this.base.value === 'new' && this.properties.length)) {
return;
}
if (this.properties[0] instanceof Access && this.properties[0].name.value === 'target') {
if (o.scope.parent == null) {
return this.error("new.target can only occur inside functions");
}
} else {
return this.error("the only valid meta property for new is new.target");
}
}
// Unfold a soak into an `If`: `a?.b` -> `a.b if a?`
unfoldSoak(o) {
return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (() => {
@@ -5201,13 +5215,18 @@
}
code = element.compileToFragments(o, LEVEL_PAREN);
if (!this.isNestedTag(element) || code.some(function(fragment) {
return fragment.comments != null;
var ref1;
return (ref1 = fragment.comments) != null ? ref1.some(function(comment) {
return comment.here === false;
}) : void 0;
})) {
code = this.wrapInBraces(code);
// Flag the `{` and `}` fragments as having been generated by this
// `StringWithInterpolations` node, so that `compileComments` knows
// to treat them as bounds. Dont trust `fragment.type`, which can
// report minified variable names when this compiler is minified.
// to treat them as bounds. But the braces are unnecessary if all of
// the enclosed comments are `/* */` comments. Dont trust
// `fragment.type`, which can report minified variable names when
// this compiler is minified.
code[0].isStringWithInterpolations = true;
code[code.length - 1].isStringWithInterpolations = true;
}

View File

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

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, getRootModule, helpers, i, len, loadFile, path, ref;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, runInContext, sawSIGINT, transpile, updateSyntaxError, vm;
@@ -250,12 +250,16 @@
CoffeeScript.register();
process.argv = ['coffee'].concat(process.argv.slice(2));
if (opts.transpile) {
transpile = {};
try {
transpile = {};
transpile.transpile = require('babel-core').transform;
transpile.transpile = require('@babel/core').transform;
} catch (error) {
console.error('To use --transpile with an interactive REPL, babel-core must be installed either in the current folder or globally:\n npm install --save-dev babel-core\nor\n npm install --global babel-core\nAnd you must save options to configure Babel in one of the places it looks to find its options.\nSee https://coffeescript.org/#transpilation');
process.exit(1);
try {
transpile.transpile = require('babel-core').transform;
} catch (error) {
console.error('To use --transpile with an interactive REPL, @babel/core must be installed either in the current folder or globally:\n npm install --save-dev @babel/core\nor\n npm install --global @babel/core\nAnd you must save options to configure Babel in one of the places it looks to find its options.\nSee https://coffeescript.org/#transpilation');
process.exit(1);
}
}
transpile.options = {
filename: path.resolve(process.cwd(), '<repl>')

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// The CoffeeScript language has a good deal of optional syntax, implicit syntax,
// and shorthand syntax. This can greatly complicate a grammar and bloat

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 2.3.1
// Generated by CoffeeScript 2.3.2
(function() {
// The **Scope** class regulates lexical scoping within CoffeeScript. As you
// generate code, you create a tree of scopes in the same shape as the nested

View File

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

4286
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.3.1",
"version": "2.3.2",
"license": "MIT",
"engines": {
"node": ">=6"
@@ -39,16 +39,16 @@
"url": "git://github.com/jashkenas/coffeescript.git"
},
"devDependencies": {
"babel-core": "6.26.3",
"babel-preset-env": "1.6.1",
"babel-preset-minify": "0.4.0",
"codemirror": "^5.37.0",
"@babel/core": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"babel-preset-minify": "^0.4.3",
"codemirror": "^5.39.2",
"docco": "~0.8.0",
"highlight.js": "~9.12.0",
"jison": ">=0.4.18",
"markdown-it": "~8.4.1",
"underscore": "~1.9.0",
"webpack": "~4.6.0"
"markdown-it": "~8.4.2",
"underscore": "~1.9.1",
"webpack": "~4.17.2"
},
"dependencies": {}
}

View File

@@ -454,25 +454,28 @@ compileOptions = (filename, base) ->
# run CoffeeScripts output without transpilation (modern Node or evergreen
# browsers) or use a proper build chain like Gulp or Webpack.
try
require 'babel-core'
require '@babel/core'
catch
# Give appropriate instructions depending on whether `coffee` was run
# locally or globally.
if require.resolve('.').indexOf(process.cwd()) is 0
console.error '''
To use --transpile, you must have babel-core installed:
npm install --save-dev babel-core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''
else
console.error '''
To use --transpile with globally-installed CoffeeScript, you must have babel-core installed globally:
npm install --global babel-core
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
See https://coffeescript.org/#transpilation
'''
process.exit 1
try
require 'babel-core'
catch
# Give appropriate instructions depending on whether `coffee` was run
# locally or globally.
if require.resolve('.').indexOf(process.cwd()) is 0
console.error '''
To use --transpile, you must have @babel/core installed:
npm install --save-dev @babel/core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''
else
console.error '''
To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:
npm install --global @babel/core
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
See https://coffeescript.org/#transpilation
'''
process.exit 1
opts.transpile = {} unless typeof opts.transpile is 'object'

View File

@@ -138,6 +138,7 @@ grammar =
Yield: [
o 'YIELD', -> new Op $1, new Value new Literal ''
o 'YIELD Expression', -> new Op $1, $2
o 'YIELD INDENT Object OUTDENT', -> new Op $1, $3
o 'YIELD FROM Expression', -> new Op $1.concat($2), $3
]
@@ -817,7 +818,8 @@ grammar =
o '- Expression', (-> new Op '-', $2), prec: 'UNARY_MATH'
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY_MATH'
o 'AWAIT Expression', -> new Op $1 , $2
o 'AWAIT Expression', -> new Op $1, $2
o 'AWAIT INDENT Object OUTDENT', -> new Op $1, $3
o '-- SimpleAssignable', -> new Op '--', $2
o '++ SimpleAssignable', -> new Op '++', $2

View File

@@ -8,11 +8,14 @@ helpers = CoffeeScript.helpers
CoffeeScript.transpile = (js, options) ->
try
babel = require 'babel-core'
babel = require '@babel/core'
catch
# This error is only for Node, as CLI users will see a different error
# earlier if they dont have Babel installed.
throw new Error 'To use the transpile option, you must have the \'babel-core\' module installed'
try
babel = require 'babel-core'
catch
# This error is only for Node, as CLI users will see a different error
# earlier if they dont have Babel installed.
throw new Error 'To use the transpile option, you must have the \'@babel/core\' module installed'
babel.transform js, options
# The `compile` method shared by the CLI, Node and browser APIs.

View File

@@ -196,6 +196,8 @@ exports.Lexer = class Lexer
@tokens.length > 1 and @tokens[@tokens.length - 2][0] not in ['.', '?.', '@']
@error "'#{prev[1]}' cannot be used as a keyword, or as a function call
without parentheses", prev[2]
else if prev[0] is '.' and @tokens.length > 1 and (prevprev = @tokens[@tokens.length - 2])[0] is 'UNARY' and prevprev[1] is 'new'
prevprev[0] = 'IDENTIFIER'
else if @tokens.length > 2
prevprev = @tokens[@tokens.length - 2]
if prev[0] in ['@', 'THIS'] and prevprev and prevprev.spaced and

View File

@@ -965,6 +965,7 @@ exports.Value = class Value extends Base
# operators `?.` interspersed. Then we have to take care not to accidentally
# evaluate anything twice when building the soak chain.
compileNode: (o) ->
@checkNewTarget o
@base.front = @front
props = @properties
if props.length and @base.cached?
@@ -984,6 +985,14 @@ exports.Value = class Value extends Base
fragments
checkNewTarget: (o) ->
return unless @base instanceof IdentifierLiteral and @base.value is 'new' and @properties.length
if @properties[0] instanceof Access and @properties[0].name.value is 'target'
unless o.scope.parent?
@error "new.target can only occur inside functions"
else
@error "the only valid meta property for new is new.target"
# Unfold a soak into an `If`: `a?.b` -> `a.b if a?`
unfoldSoak: (o) ->
@unfoldedSoak ?= do =>
@@ -3501,12 +3510,15 @@ exports.StringWithInterpolations = class StringWithInterpolations extends Base
else
fragments.push @makeCode '$' unless @csx
code = element.compileToFragments(o, LEVEL_PAREN)
if not @isNestedTag(element) or code.some((fragment) -> fragment.comments?)
if not @isNestedTag(element) or
code.some((fragment) -> fragment.comments?.some((comment) -> comment.here is no))
code = @wrapInBraces code
# Flag the `{` and `}` fragments as having been generated by this
# `StringWithInterpolations` node, so that `compileComments` knows
# to treat them as bounds. Dont trust `fragment.type`, which can
# report minified variable names when this compiler is minified.
# to treat them as bounds. But the braces are unnecessary if all of
# the enclosed comments are `/* */` comments. Dont trust
# `fragment.type`, which can report minified variable names when
# this compiler is minified.
code[0].isStringWithInterpolations = yes
code[code.length - 1].isStringWithInterpolations = yes
fragments.push code...

View File

@@ -182,19 +182,22 @@ module.exports =
CoffeeScript.register()
process.argv = ['coffee'].concat process.argv[2..]
if opts.transpile
transpile = {}
try
transpile = {}
transpile.transpile = require('babel-core').transform
transpile.transpile = require('@babel/core').transform
catch
console.error '''
To use --transpile with an interactive REPL, babel-core must be installed either in the current folder or globally:
npm install --save-dev babel-core
or
npm install --global babel-core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''
process.exit 1
try
transpile.transpile = require('babel-core').transform
catch
console.error '''
To use --transpile with an interactive REPL, @babel/core must be installed either in the current folder or globally:
npm install --save-dev @babel/core
or
npm install --global @babel/core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
'''
process.exit 1
transpile.options =
filename: path.resolve process.cwd(), '<repl>'
# Since the REPL compilation path is unique (in `eval` above), we need

View File

@@ -196,3 +196,11 @@ test "async methods in classes", ->
eq await Child.static(), 1
eq await new Child().method(), 2
test "#3199: await multiline implicit object", ->
do ->
y =
if no then await
type: 'a'
msg: 'b'
eq undefined, y

View File

@@ -1899,4 +1899,26 @@ test "#4868: Incorrect Cant call super with @params error", ->
super class then constructor: (@a) -> @a = 3
d = new (new D).c
eq 3, d.a
eq 3, d.a
test "#4609: Support new.target", ->
class A
constructor: ->
@calledAs = new.target.name
class B extends A
b = new B
eq b.calledAs, 'B'
newTarget = null
Foo = ->
newTarget = !!new.target
Foo()
eq newTarget, no
newTarget = null
new Foo()
eq newTarget, yes

View File

@@ -11,7 +11,7 @@ transpile = (method, code, options = {}) ->
options.bare = yes
options.transpile =
# Target Internet Explorer 6, which supports no ES2015+ features.
presets: [['env', {targets: browsers: ['ie 6']}]]
presets: [['@babel/env', {targets: browsers: ['ie 6']}]]
CoffeeScript[method] code, options
@@ -176,4 +176,4 @@ test "#3306: trailing comma in a function call in the last line", ->
foo bar,
''', '''
foo(bar);
'''
'''

View File

@@ -742,6 +742,47 @@ test '#4686: comments inside interpolations that also contain CSX attributes', -
</div>;
'''
test '#5086: comments inside CSX tags but outside interpolations', ->
eqJS '''
<div>
<div ###comment### attribute={value} />
</div>
''', '''
<div>
<div /*comment*/attribute={value} />
</div>;
'''
test '#5086: comments inside CSX attributes but outside interpolations', ->
eqJS '''
<div>
<div attribute={###attr comment### value} />
</div>
''', '''
<div>
<div attribute={/*attr comment*/value} />
</div>;
'''
test '#5086: comments inside nested CSX tags and attributes but outside interpolations', ->
eqJS '''
<div>
<div>
<div>
<div ###comment### attribute={###attr comment### value} />
</div>
</div>
</div>
''', '''
<div>
<div>
<div>
<div /*comment*/attribute={/*attr comment*/value} />
</div>
</div>
</div>;
'''
# https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
test 'JSX fragments: empty fragment', ->
eqJS '''

View File

@@ -1796,6 +1796,50 @@ test "#3199: error message for throw indented comprehension", ->
^
'''
test "#3199: error message for yield indented non-object", ->
assertErrorFormat '''
->
yield
1
''', '''
[stdin]:3:5: error: unexpected number
1
^
'''
test "#3199: error message for yield indented comprehension", ->
assertErrorFormat '''
->
yield
x for x in [1, 2, 3]
''', '''
[stdin]:3:5: error: unexpected identifier
x for x in [1, 2, 3]
^
'''
test "#3199: error message for await indented non-object", ->
assertErrorFormat '''
->
await
1
''', '''
[stdin]:3:5: error: unexpected number
1
^
'''
test "#3199: error message for await indented comprehension", ->
assertErrorFormat '''
->
await
x for x in [1, 2, 3]
''', '''
[stdin]:3:5: error: unexpected identifier
x for x in [1, 2, 3]
^
'''
test "#3098: suppressed newline should be unsuppressed by semicolon", ->
assertErrorFormat '''
a = ; 5
@@ -1863,3 +1907,21 @@ test "#3933: prevent implicit calls when cotrol flow is missing `THEN`", ->
when a ->
^^
'''
test "`new.target` outside of a function", ->
assertErrorFormat '''
new.target
''', '''
[stdin]:1:1: error: new.target can only occur inside functions
new.target
^^^^^^^^^^
'''
test "`new.target` is only allowed meta property", ->
assertErrorFormat '''
-> new.something
''', '''
[stdin]:1:4: error: the only valid meta property for new is new.target
-> new.something
^^^^^^^^^^^^^
'''

View File

@@ -417,6 +417,22 @@ test "#3199: throw multiline implicit object", ->
msg: 'b'
eq undefined, y
y = do ->
yield
type: 'a'
msg: 'b'
if no then yield
type: 'c'
msg: 'd'
1
{value, done} = y.next()
ok value.type is 'a' and done is no
{value, done} = y.next()
ok value is 1 and done is yes
test "#4576: multiple row function chaining", ->
->
eq @a, 3