summaryrefslogtreecommitdiff
path: root/lib/repl.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/repl.js')
-rw-r--r--lib/repl.js74
1 files changed, 3 insertions, 71 deletions
diff --git a/lib/repl.js b/lib/repl.js
index 92c90de7bb..4a01595ce1 100644
--- a/lib/repl.js
+++ b/lib/repl.js
@@ -73,6 +73,7 @@ const {
} = require('internal/errors').codes;
const { sendInspectorCommand } = require('internal/util/inspector');
const { experimentalREPLAwait } = process.binding('config');
+const { isRecoverableError } = require('internal/repl/recoverable');
// Lazy-loaded.
let processTopLevelAwait;
@@ -227,7 +228,8 @@ function REPLServer(prompt,
// It's confusing for `{ a : 1 }` to be interpreted as a block
// statement rather than an object literal. So, we first try
// to wrap it in parentheses, so that it will be interpreted as
- // an expression.
+ // an expression. Note that if the above condition changes,
+ // lib/internal/repl/recoverable.js needs to be changed to match.
code = `(${code.trim()})\n`;
wrappedCmd = true;
}
@@ -1505,76 +1507,6 @@ function regexpEscape(s) {
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
-// 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, code) {
- if (e && e.name === 'SyntaxError') {
- var message = e.message;
- if (message === 'Unterminated template literal' ||
- message === 'Unexpected end of input') {
- return true;
- }
-
- if (message === 'missing ) after argument list') {
- const frames = e.stack.split(/\r?\n/);
- const pos = frames.findIndex((f) => f.match(/^\s*\^+$/));
- return pos > 0 && frames[pos - 1].length === frames[pos].length;
- }
-
- if (message === 'Invalid or unexpected token')
- return isCodeRecoverable(code);
- }
- return false;
-}
-
-// Check whether a code snippet should be forced to fail in the REPL.
-function isCodeRecoverable(code) {
- var current, previous, stringLiteral;
- var isBlockComment = false;
- var isSingleComment = false;
- var isRegExpLiteral = false;
- var lastChar = code.charAt(code.length - 2);
- var prevTokenChar = null;
-
- for (var i = 0; i < code.length; i++) {
- previous = current;
- current = code[i];
-
- if (previous === '\\' && (stringLiteral || isRegExpLiteral)) {
- current = null;
- } else if (stringLiteral) {
- if (stringLiteral === current) {
- stringLiteral = null;
- }
- } else if (isRegExpLiteral && current === '/') {
- isRegExpLiteral = false;
- } else if (isBlockComment && previous === '*' && current === '/') {
- isBlockComment = false;
- } else if (isSingleComment && current === '\n') {
- isSingleComment = false;
- } else if (!isBlockComment && !isRegExpLiteral && !isSingleComment) {
- if (current === '/' && previous === '/') {
- isSingleComment = true;
- } else if (previous === '/') {
- if (current === '*') {
- isBlockComment = true;
- // Distinguish between a division operator and the start of a regex
- // by examining the non-whitespace character that precedes the /
- } else if ([null, '(', '[', '{', '}', ';'].includes(prevTokenChar)) {
- isRegExpLiteral = true;
- }
- } else {
- if (current.trim()) prevTokenChar = current;
- if (current === '\'' || current === '"') {
- stringLiteral = current;
- }
- }
- }
- }
-
- return stringLiteral ? lastChar === '\\' : isBlockComment;
-}
-
function Recoverable(err) {
this.err = err;
}