Skip to content
This repository was archived by the owner on Feb 1, 2022. It is now read-only.

Commit 9e97d73

Browse files
author
Jan Krems
committed
feat: repl to enter exec mode
1 parent df6b89d commit 9e97d73

File tree

3 files changed

+71
-26
lines changed

3 files changed

+71
-26
lines changed

lib/internal/inspect-repl.js

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ function createRepl(inspector) {
199199
let repl; // eslint-disable-line prefer-const
200200
let lastCommand;
201201

202+
const history = { control: [], debug: [] };
202203
const knownScripts = {};
203204
const watchedExpressions = [];
204205
const knownBreakpoints = [];
@@ -282,6 +283,27 @@ function createRepl(inspector) {
282283
return lastCommand;
283284
}
284285

286+
function evalInCurrentContext(code) {
287+
// Repl asked for scope variables
288+
if (code === '.scope') {
289+
return Promise.reject('client.reqScopes not implemented');
290+
}
291+
292+
if (selectedFrame) {
293+
return Debugger.evaluateOnCallFrame({
294+
callFrameId: selectedFrame.callFrameId,
295+
expression: code,
296+
objectGroup: 'node-inspect',
297+
generatePreview: true,
298+
}).then(convertResultToRemoteObject);
299+
}
300+
return Runtime.evaluate({
301+
expression: code,
302+
objectGroup: 'node-inspect',
303+
generatePreview: true,
304+
}).then(convertResultToRemoteObject);
305+
}
306+
285307
function controlEval(input, context, filename, callback) {
286308
debuglog('eval:', input);
287309
function returnToCallback(error, result) {
@@ -303,25 +325,24 @@ function createRepl(inspector) {
303325
}
304326
}
305327

306-
function debugEval(code) {
307-
// Repl asked for scope variables
308-
if (code === '.scope') {
309-
return Promise.reject('client.reqScopes not implemented');
328+
function debugEval(input, context, filename, callback) {
329+
debuglog('eval:', input);
330+
function returnToCallback(error, result) {
331+
debuglog('end-eval:', input, error);
332+
callback(error, result);
310333
}
311334

312-
if (selectedFrame) {
313-
return Debugger.evaluateOnCallFrame({
314-
callFrameId: selectedFrame.callFrameId,
315-
expression: code,
316-
objectGroup: 'node-inspect',
317-
generatePreview: true,
318-
}).then(convertResultToRemoteObject);
335+
try {
336+
const result = evalInCurrentContext(input);
337+
338+
if (result && typeof result.then === 'function') {
339+
toCallback(result, returnToCallback);
340+
return;
341+
}
342+
returnToCallback(null, result);
343+
} catch (e) {
344+
returnToCallback(e);
319345
}
320-
return Runtime.evaluate({
321-
expression: code,
322-
objectGroup: 'node-inspect',
323-
generatePreview: true,
324-
}).then(convertResultToRemoteObject);
325346
}
326347

327348
function formatWatchers(verbose = false) {
@@ -330,7 +351,7 @@ function createRepl(inspector) {
330351
}
331352

332353
const inspectValue = expr =>
333-
debugEval(expr)
354+
evalInCurrentContext(expr)
334355
// .then(formatValue)
335356
.catch(error => `<${error.message}>`);
336357

@@ -606,7 +627,7 @@ function createRepl(inspector) {
606627
},
607628

608629
exec(expr) {
609-
return debugEval(expr);
630+
return evalInCurrentContext(expr);
610631
},
611632

612633
get watchers() {
@@ -627,13 +648,12 @@ function createRepl(inspector) {
627648
},
628649

629650
get repl() {
630-
// if (!this.requireConnection()) return;
631-
print('Press Ctrl + C to leave debug repl');
632-
633651
// Don't display any default messages
634652
const listeners = repl.rli.listeners('SIGINT').slice(0);
635653
repl.rli.removeAllListeners('SIGINT');
636654

655+
const oldContext = repl.context;
656+
637657
function exitDebugRepl() {
638658
// Restore all listeners
639659
process.nextTick(() => {
@@ -649,7 +669,7 @@ function createRepl(inspector) {
649669
history.debug = repl.rli.history;
650670
repl.rli.history = history.control;
651671

652-
repl.context = inspector.context;
672+
repl.context = oldContext;
653673
repl.rli.setPrompt('debug> ');
654674
repl.displayPrompt();
655675

@@ -664,16 +684,16 @@ function createRepl(inspector) {
664684
repl.on('exit', exitDebugRepl);
665685

666686
// Set new
667-
repl.eval = (code, evalCtx, file, cb) => {
668-
toCallback(debugEval(code), cb);
669-
};
687+
repl.eval = debugEval;
670688
repl.context = {};
671689

672690
// Swap history
673691
history.control = repl.rli.history;
674692
repl.rli.history = history.debug;
675693

676694
repl.rli.setPrompt('> ');
695+
696+
print('Press Ctrl + C to leave debug repl');
677697
repl.displayPrompt();
678698
},
679699

@@ -707,6 +727,12 @@ function createRepl(inspector) {
707727
repl = Repl.start(replOptions); // eslint-disable-line prefer-const
708728
initializeContext(repl.context);
709729
repl.on('reset', initializeContext);
730+
731+
repl.defineCommand('interrupt', () => {
732+
// We want this for testing purposes where sending CTRL-C can be tricky.
733+
repl.rli.emit('SIGINT');
734+
});
735+
710736
return repl;
711737
};
712738
}

test/cli/exec.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@ test('examples/alive.js', (t) => {
1717
.then(() => {
1818
t.match(cli.output, '[ \'function\', \'function\' ]', 'works w/o paren');
1919
})
20+
.then(() => cli.command('repl'))
21+
.then(() => {
22+
t.match(cli.output, 'Press Ctrl + C to leave debug repl\n> ',
23+
'shows hint for how to leave repl');
24+
t.notMatch(cli.output, 'debug>', 'changes the repl style');
25+
})
26+
.then(() => cli.command('[typeof heartbeat, typeof process.exit]'))
27+
.then(() => cli.waitFor(/function/))
28+
.then(() => cli.waitForPrompt())
29+
.then(() => {
30+
t.match(cli.output, '[ \'function\', \'function\' ]', 'can evaluate in the repl');
31+
t.match(cli.output, /> $/);
32+
})
33+
.then(() => cli.ctrlC())
34+
.then(() => cli.waitFor(/debug> $/))
2035
.then(() => cli.command('exec("[typeof heartbeat, typeof process.exit]")'))
2136
.then(() => {
2237
t.match(cli.output, '[ \'function\', \'function\' ]', 'works w/ paren');

test/cli/start-cli.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,11 @@ function startCLI(args) {
7373
},
7474

7575
waitForPrompt(timeout = 2000) {
76-
return this.waitFor(/debug>\s*$/, timeout);
76+
return this.waitFor(/>\s+$/, timeout);
77+
},
78+
79+
ctrlC() {
80+
return this.command('.interrupt');
7781
},
7882

7983
get output() {

0 commit comments

Comments
 (0)