repl: make REPL support multiline template literals
Let REPL enter multiline mode if user's input contains unterminated template literals. PR-URL: https://github.com/iojs/io.js/pull/333 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
Родитель
2253d30d9c
Коммит
b7365c1559
27
lib/repl.js
27
lib/repl.js
|
@ -87,6 +87,8 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
|
|||
self.useGlobal = !!useGlobal;
|
||||
self.ignoreUndefined = !!ignoreUndefined;
|
||||
|
||||
self._inTemplateLiteral = false;
|
||||
|
||||
// just for backwards compat, see github.com/joyent/node/pull/7127
|
||||
self.rli = this;
|
||||
|
||||
|
@ -102,7 +104,7 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
|
|||
});
|
||||
} catch (e) {
|
||||
debug('parse error %j', code, e);
|
||||
if (isRecoverableError(e))
|
||||
if (isRecoverableError(e, self))
|
||||
err = new Recoverable(e);
|
||||
else
|
||||
err = e;
|
||||
|
@ -226,7 +228,13 @@ function REPLServer(prompt, stream, eval_, useGlobal, ignoreUndefined) {
|
|||
debug('line %j', cmd);
|
||||
sawSIGINT = false;
|
||||
var skipCatchall = false;
|
||||
cmd = trimWhitespace(cmd);
|
||||
|
||||
// leading whitespaces in template literals should not be trimmed.
|
||||
if (self._inTemplateLiteral) {
|
||||
self._inTemplateLiteral = false;
|
||||
} else {
|
||||
cmd = trimWhitespace(cmd);
|
||||
}
|
||||
|
||||
// Check to see if a REPL keyword was used. If it returns true,
|
||||
// display next prompt and return.
|
||||
|
@ -928,10 +936,17 @@ REPLServer.prototype.convertToContext = function(cmd) {
|
|||
|
||||
// If the error is that we've unexpectedly ended the input,
|
||||
// then let the user try to recover by adding more input.
|
||||
function isRecoverableError(e) {
|
||||
return e &&
|
||||
e.name === 'SyntaxError' &&
|
||||
/^(Unexpected end of input|Unexpected token :)/.test(e.message);
|
||||
function isRecoverableError(e, self) {
|
||||
if (e && e.name === 'SyntaxError') {
|
||||
var message = e.message;
|
||||
if (message === 'Unterminated template literal' ||
|
||||
message === 'Missing } in template expression') {
|
||||
self._inTemplateLiteral = true;
|
||||
return true;
|
||||
}
|
||||
return /^(Unexpected end of input|Unexpected token :)/.test(message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function Recoverable(err) {
|
||||
|
|
|
@ -104,6 +104,17 @@ function error_test() {
|
|||
// But passing the same string to eval() should throw
|
||||
{ client: client_unix, send: 'eval("function test_func() {")',
|
||||
expect: /^SyntaxError: Unexpected end of input/ },
|
||||
// Can handle multiline template literals
|
||||
{ client: client_unix, send: '`io.js',
|
||||
expect: prompt_multiline },
|
||||
// Special REPL commands still available
|
||||
{ client: client_unix, send: '.break',
|
||||
expect: prompt_unix },
|
||||
// Template expressions can cross lines
|
||||
{ client: client_unix, send: '`io.js ${"1.0"',
|
||||
expect: prompt_multiline },
|
||||
{ client: client_unix, send: '+ ".2"}`',
|
||||
expect: `'io.js 1.0.2'\n${prompt_unix}` },
|
||||
// Floating point numbers are not interpreted as REPL commands.
|
||||
{ client: client_unix, send: '.1234',
|
||||
expect: '0.1234' },
|
||||
|
|
Загрузка…
Ссылка в новой задаче