Skip to content

Commit 83f5bb6

Browse files
repl: fix dot command handling in multiline mode
Update conditional logic to correctly handle dot commands in multiline REPL input Fixes: #63864 Refs: #63889 Signed-off-by: SudhansuBandha bandhasudhansu@gmail.com
1 parent 4383f67 commit 83f5bb6

2 files changed

Lines changed: 51 additions & 4 deletions

File tree

lib/repl.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ const {
7676
StringPrototypeCharAt,
7777
StringPrototypeEndsWith,
7878
StringPrototypeIncludes,
79+
StringPrototypeIndexOf,
7980
StringPrototypeRepeat,
8081
StringPrototypeSlice,
8182
StringPrototypeStartsWith,
@@ -807,10 +808,17 @@ class REPLServer extends Interface {
807808
// Check to see if a REPL keyword was used. If it returns true,
808809
// display next prompt and return.
809810
if (trimmedCmd) {
810-
if (StringPrototypeCharAt(trimmedCmd, 0) === '.' &&
811-
StringPrototypeCharAt(trimmedCmd, 1) !== '.' &&
812-
NumberIsNaN(NumberParseFloat(trimmedCmd))) {
813-
const matches = RegExpPrototypeExec(/^\.([^\s]+)\s*(.*)$/, trimmedCmd);
811+
// If condition validates for dot commands at the beginning of the line,
812+
// or dot commands after some whitespace.
813+
const isDotCommandAtStart = StringPrototypeCharAt(trimmedCmd, 0) === '.' &&
814+
StringPrototypeCharAt(trimmedCmd, 1) !== '.';
815+
const dotIndex = StringPrototypeIndexOf(trimmedCmd, '.');
816+
const isDotCommandAfterWhitespace = dotIndex > 0 &&
817+
StringPrototypeCharAt(trimmedCmd, dotIndex + 1) !== '.';
818+
819+
if ((isDotCommandAtStart || isDotCommandAfterWhitespace) &&
820+
NumberIsNaN(NumberParseFloat(trimmedCmd))) {
821+
const matches = RegExpPrototypeExec(/(?:^|\s)\.([^\s]+)\s*(.*)$/, trimmedCmd);
814822
const keyword = matches?.[1];
815823
const rest = matches?.[2];
816824
if (FunctionPrototypeCall(_parseREPLKeyword, self, keyword, rest) === true) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const { startNewREPLServer } = require('../common/repl');
5+
6+
const dotCommandSyntaxError =
7+
/Uncaught SyntaxError: Unexpected token '\.'/;
8+
9+
10+
function runDotCommand(command, validate) {
11+
const { replServer, output } = startNewREPLServer();
12+
13+
replServer.on('exit', common.mustCall());
14+
replServer.write('function a() {\n');
15+
replServer.write(`${command}\n`);
16+
validate(replServer, output);
17+
replServer.write('arr = [1,\n');
18+
replServer.write(`${command}\n`);
19+
validate(replServer, output);
20+
replServer.close();
21+
}
22+
23+
runDotCommand('.break', ((replServer, output) => {
24+
replServer.write('1 + 1\n');
25+
assert.doesNotMatch(output.accumulator, dotCommandSyntaxError);
26+
assert.match(output.accumulator, /2\n/);
27+
}));
28+
29+
runDotCommand('.clear', ((replServer, output) => {
30+
replServer.write('1 + 1\n');
31+
assert.doesNotMatch(output.accumulator, dotCommandSyntaxError);
32+
assert.match(output.accumulator, /2\n/);
33+
}));
34+
35+
runDotCommand('.help', ((replServer, output) => {
36+
replServer.write('1 + 1\n');
37+
assert.doesNotMatch(output.accumulator, dotCommandSyntaxError);
38+
assert.match(output.accumulator, /2\n/);
39+
}));

0 commit comments

Comments
 (0)