Skip to content

Commit 22fb31e

Browse files
Transpile REPL (#4729)
* Fix #4725: apply transpile option to require’d .coffee files * Use the current module’s options if it has any, before going searching up the tree * Don’t mutate passed-in options object * If the REPL is run with `--transpile`, turn transpilation on for both the current REPL input and any files imported by that input * Use the command.coffee machinery for parsing arguments * Fix test for Windows
1 parent a2037e7 commit 22fb31e

File tree

5 files changed

+77
-8
lines changed

5 files changed

+77
-8
lines changed

lib/coffeescript/command.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/coffeescript/repl.js

Lines changed: 37 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/command.coffee

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ exports.run = ->
9292
replCliOpts = useGlobal: yes
9393
opts.prelude = makePrelude opts.require if opts.require
9494
replCliOpts.prelude = opts.prelude
95+
replCliOpts.transpile = opts.transpile
9596
return forkNode() if opts.nodejs
9697
return usage() if opts.help
9798
return version() if opts.version

src/repl.coffee

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CoffeeScript = require './'
66
{merge, updateSyntaxError} = require './helpers'
77

88
sawSIGINT = no
9+
transpile = no
910

1011
replDefaults =
1112
prompt: 'coffee> ',
@@ -35,14 +36,19 @@ replDefaults =
3536
ast = CoffeeScript.nodes tokens
3637
# Add assignment to `__` variable to force the input to be an expression.
3738
ast = new Block [new Assign (new Value new Literal '__'), ast, '=']
38-
# Wrap the expression in a closure to support top-level `await`
39+
# Wrap the expression in a closure to support top-level `await`.
3940
ast = new Code [], ast
4041
isAsync = ast.isAsync
41-
# Invoke the wrapping closure
42+
# Invoke the wrapping closure.
4243
ast = new Block [new Call ast]
4344
js = ast.compile {bare: yes, locals: Object.keys(context), referencedVars, sharedScope: yes}
45+
if transpile
46+
js = transpile.transpile(js, transpile.options).code
47+
# Strip `"use strict"`, to avoid an exception on assigning to
48+
# undeclared variable `__`.
49+
js = js.replace /^"use strict"|^'use strict'/, ''
4450
result = runInContext js, context, filename
45-
# Await an async result, if necessary
51+
# Await an async result, if necessary.
4652
if isAsync
4753
result.then (resolvedResult) ->
4854
cb null, resolvedResult unless sawSIGINT
@@ -167,6 +173,31 @@ module.exports =
167173

168174
CoffeeScript.register()
169175
process.argv = ['coffee'].concat process.argv[2..]
176+
if opts.transpile
177+
try
178+
transpile = {}
179+
transpile.transpile = require('babel-core').transform
180+
catch
181+
console.error '''
182+
To use --transpile with an interactive REPL, babel-core must be installed either in the current folder or globally:
183+
npm install --save-dev babel-core
184+
or
185+
npm install --global babel-core
186+
And you must save options to configure Babel in one of the places it looks to find its options.
187+
See http://coffeescript.org/#transpilation
188+
'''
189+
process.exit 1
190+
transpile.options =
191+
filename: path.resolve process.cwd(), '<repl>'
192+
# Since the REPL compilation path is unique (in `eval` above), we need
193+
# another way to get the `options` object attached to a module so that
194+
# it knows later on whether it needs to be transpiled. In the case of
195+
# the REPL, the only applicable option is `transpile`.
196+
Module = require 'module'
197+
originalModuleLoad = Module::load
198+
Module::load = (filename) ->
199+
@options = transpile: transpile.options
200+
originalModuleLoad.call @, filename
170201
opts = merge replDefaults, opts
171202
repl = nodeREPL.start opts
172203
runInContext opts.prelude, repl.context, 'prelude' if opts.prelude

test/repl.coffee

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ testRepl "#4604: wraps an async function", (input, output) ->
122122
eq '33', output.lastWrite()
123123
, 20
124124

125+
testRepl "transpile REPL", (input, output) ->
126+
input.emitLine 'require("./test/importing/transpile_import").getSep()'
127+
eq "'#{path.sep.replace '\\', '\\\\'}'", output.lastWrite()
128+
125129
process.on 'exit', ->
126130
try
127131
fs.unlinkSync historyFile

0 commit comments

Comments
 (0)