X Tutup
Skip to content
Prev Previous commit
Next Next commit
repl: check valid syntax by using acorn
  • Loading branch information
jenthone authored and meixg committed Aug 24, 2025
commit c20260e799507ea763ccc4dbc86c6a499972dec4
36 changes: 21 additions & 15 deletions lib/internal/repl/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
// curly brace with parenthesis.
if (StringPrototypeStartsWith(input, '{') &&
!StringPrototypeEndsWith(input, ';') &&
isValidParentheses(input) &&
isValidSyntax(input) &&
!wrapped) {
input = `(${input})`;
wrapped = true;
Expand Down Expand Up @@ -789,18 +789,24 @@ function isValidParentheses(input) {
return false;
}
}
}

return stack.length === 0;
}
function isValidSyntax(input) {
const Parser = require('internal/deps/acorn/acorn/dist/acorn').Parser;
try {
let result = Parser.parse(input, { ecmaVersion: 'latest' });
return true;
} catch (e) {
return false;
}
}

module.exports = {
REPL_MODE_SLOPPY: Symbol('repl-sloppy'),
REPL_MODE_STRICT,
isRecoverableError,
kStandaloneREPL: Symbol('kStandaloneREPL'),
setupPreview,
setupReverseSearch,
isObjectLiteral,
isValidParentheses,
};
module.exports = {
REPL_MODE_SLOPPY: Symbol('repl-sloppy'),
REPL_MODE_STRICT,
isRecoverableError,
kStandaloneREPL: Symbol('kStandaloneREPL'),
setupPreview,
setupReverseSearch,
isObjectLiteral,
isValidParentheses,
isValidSyntax,
};
12 changes: 10 additions & 2 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ const {
setupReverseSearch,
isObjectLiteral,
isValidParentheses,
isValidSyntax,
} = require('internal/repl/utils');
const {
constants: {
Expand Down Expand Up @@ -446,8 +447,14 @@ function REPLServer(prompt,
let awaitPromise = false;
const input = code;

if (isObjectLiteral(code)) {
// Add parentheses to make sure `code` is parsed as an expression
// 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. Note that if the above condition changes,
// lib/internal/repl/utils.js needs to be changed to match.
if (RegExpPrototypeExec(/^\s*{/, code) !== null &&
RegExpPrototypeExec(/;\s*$/, code) === null &&
isValidSyntax(code)) {
code = `(${StringPrototypeTrim(code)})\n`;
wrappedCmd = true;
}
Expand Down Expand Up @@ -2157,6 +2164,7 @@ module.exports = {
REPL_MODE_SLOPPY,
REPL_MODE_STRICT,
Recoverable,
isValidSyntax,
};

ObjectDefineProperty(module.exports, 'builtinModules', {
Expand Down
X Tutup