From 30b4dbc19bea6b5415f4826250483af38381fb94 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Thu, 27 Feb 2020 14:34:50 -0800 Subject: [PATCH] repl: allow recovery for wrapped eval --- lib/repl.js | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 00820953b553cf..0b172a748169e1 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -69,8 +69,17 @@ const { } = require('internal/modules/cjs/helpers'); const { isIdentifierStart, - isIdentifierChar + isIdentifierChar, + Parser } = require('internal/deps/acorn/acorn/dist/acorn'); +const privateMethods = + require('internal/deps/acorn-plugins/acorn-private-methods/index'); +const classFields = + require('internal/deps/acorn-plugins/acorn-class-fields/index'); +const numericSeparator = + require('internal/deps/acorn-plugins/acorn-numeric-separator/index'); +const staticClassFeatures = + require('internal/deps/acorn-plugins/acorn-static-class-features/index'); const { decorateErrorStack, isError, @@ -332,8 +341,23 @@ function REPLServer(prompt, // an expression. Note that if the above condition changes, // lib/internal/repl/utils.js needs to be changed to match. if (/^\s*{/.test(code) && !/;\s*$/.test(code)) { - code = `(${code.trim()})\n`; - wrappedCmd = true; + const parser = Parser.extend( + privateMethods, + classFields, + numericSeparator, + staticClassFeatures + ); + + // Ensure that the wrapped expression is valid, + // otherwise proceed unwrapped. + try { + parser.parse(`(${code.trim()})\n`, { + ecmaVersion: 11, + allowAwaitOutsideFunction: true + }); + code = `(${code.trim()})\n`; + wrappedCmd = true; + } catch {} } if (experimentalREPLAwait && code.includes('await')) {