mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 00:20:08 +01:00
debugger: fix behavior of plain object exec in debugger repl
Co-authored-by: Xuguang Mei <meixuguang@gmail.com> PR-URL: https://github.com/nodejs/node/pull/57498 Fixes: https://github.com/nodejs/node/issues/46808 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Xuguang Mei <meixuguang@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
parent
cad76cc1d5
commit
922ce9d236
|
|
@ -56,6 +56,7 @@ const { fileURLToPath } = require('internal/url');
|
|||
|
||||
const { customInspectSymbol, SideEffectFreeRegExpPrototypeSymbolReplace } = require('internal/util');
|
||||
const { inspect: utilInspect } = require('internal/util/inspect');
|
||||
const { isObjectLiteral } = require('internal/repl/utils');
|
||||
const debuglog = require('internal/util/debuglog').debuglog('inspect');
|
||||
|
||||
const SHORTCUTS = {
|
||||
|
|
@ -573,8 +574,15 @@ function createRepl(inspector) {
|
|||
if (input === '\n') return lastCommand;
|
||||
// Add parentheses: exec process.title => exec("process.title");
|
||||
const match = RegExpPrototypeExec(/^\s*(?:exec|p)\s+([^\n]*)/, input);
|
||||
input = match ? match[1] : input;
|
||||
|
||||
if (isObjectLiteral(input)) {
|
||||
// Add parentheses to make sure `input` is parsed as an expression
|
||||
input = `(${StringPrototypeTrim(input)})\n`;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
lastCommand = `exec(${JSONStringify(match[1])})`;
|
||||
lastCommand = `exec(${JSONStringify(input)})`;
|
||||
} else {
|
||||
lastCommand = input;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -739,6 +739,22 @@ function setupReverseSearch(repl) {
|
|||
return { reverseSearch };
|
||||
}
|
||||
|
||||
const startsWithBraceRegExp = /^\s*{/;
|
||||
const endsWithSemicolonRegExp = /;\s*$/;
|
||||
|
||||
/**
|
||||
* Checks if some provided code represents an object literal.
|
||||
* This is helpful to prevent confusing repl code evaluations where
|
||||
* strings such as `{ a : 1 }` would get interpreted as block statements
|
||||
* rather than object literals.
|
||||
* @param {string} code the code to check
|
||||
* @returns {boolean} true if the code represents an object literal, false otherwise
|
||||
*/
|
||||
function isObjectLiteral(code) {
|
||||
return RegExpPrototypeExec(startsWithBraceRegExp, code) !== null &&
|
||||
RegExpPrototypeExec(endsWithSemicolonRegExp, code) === null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
REPL_MODE_SLOPPY: Symbol('repl-sloppy'),
|
||||
REPL_MODE_STRICT,
|
||||
|
|
@ -746,4 +762,5 @@ module.exports = {
|
|||
kStandaloneREPL: Symbol('kStandaloneREPL'),
|
||||
setupPreview,
|
||||
setupReverseSearch,
|
||||
isObjectLiteral,
|
||||
};
|
||||
|
|
|
|||
10
lib/repl.js
10
lib/repl.js
|
|
@ -172,6 +172,7 @@ const {
|
|||
kStandaloneREPL,
|
||||
setupPreview,
|
||||
setupReverseSearch,
|
||||
isObjectLiteral,
|
||||
} = require('internal/repl/utils');
|
||||
const {
|
||||
constants: {
|
||||
|
|
@ -436,13 +437,8 @@ function REPLServer(prompt,
|
|||
let awaitPromise = false;
|
||||
const input = code;
|
||||
|
||||
// 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) {
|
||||
if (isObjectLiteral(code)) {
|
||||
// Add parentheses to make sure `code` is parsed as an expression
|
||||
code = `(${StringPrototypeTrim(code)})\n`;
|
||||
wrappedCmd = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,11 @@ async function waitInitialBreak() {
|
|||
/\[ 'undefined', 'function' \]/,
|
||||
'non-paused exec can see global but not module-scope values'
|
||||
);
|
||||
|
||||
// Ref: https://github.com/nodejs/node/issues/46808
|
||||
await cli.waitForPrompt();
|
||||
await cli.command('exec { a: 1 }');
|
||||
assert.match(cli.output, /\{ a: 1 \}/);
|
||||
} finally {
|
||||
await cli.quit();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user