Skip to content

Commit b345fab

Browse files
committed
repl: preprocess only for defaultEval
Code preprocessing is applicable only for default eval function. Therefore, Moved `preprocess` function invocation inside `defaultEval` function. Fixes: #9743 PR-URL: #9752 Reviewed-By: Anna Henningsen <[email protected]>
1 parent e21e129 commit b345fab

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

lib/repl.js

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,33 @@ function REPLServer(prompt,
238238

239239
eval_ = eval_ || defaultEval;
240240

241+
function preprocess(code) {
242+
let cmd = code;
243+
if (/^\s*\{/.test(cmd) && /\}\s*$/.test(cmd)) {
244+
// It's confusing for `{ a : 1 }` to be interpreted as a block
245+
// statement rather than an object literal. So, we first try
246+
// to wrap it in parentheses, so that it will be interpreted as
247+
// an expression.
248+
cmd = `(${cmd})`;
249+
self.wrappedCmd = true;
250+
} else {
251+
// Mitigate https://github.com/nodejs/node/issues/548
252+
cmd = cmd.replace(
253+
/^\s*function(?:\s*(\*)\s*|\s+)([^(]+)/,
254+
(_, genStar, name) => `var ${name} = function ${genStar || ''}${name}`
255+
);
256+
}
257+
// Append a \n so that it will be either
258+
// terminated, or continued onto the next expression if it's an
259+
// unexpected end of input.
260+
return `${cmd}\n`;
261+
}
262+
241263
function defaultEval(code, context, file, cb) {
264+
// Remove trailing new line
265+
code = code.replace(/\n$/, '');
266+
code = preprocess(code);
267+
242268
var err, result, retry = false, input = code, wrappedErr;
243269
// first, create the Script object to check the syntax
244270

@@ -499,8 +525,7 @@ function REPLServer(prompt,
499525
}
500526
}
501527

502-
var evalCmd = self.bufferedCommand + cmd;
503-
evalCmd = preprocess(evalCmd);
528+
const evalCmd = self.bufferedCommand + cmd + '\n';
504529

505530
debug('eval %j', evalCmd);
506531
self.eval(evalCmd, self.context, 'repl', finish);
@@ -557,28 +582,6 @@ function REPLServer(prompt,
557582
// Display prompt again
558583
self.displayPrompt();
559584
}
560-
561-
function preprocess(code) {
562-
let cmd = code;
563-
if (/^\s*\{/.test(cmd) && /\}\s*$/.test(cmd)) {
564-
// It's confusing for `{ a : 1 }` to be interpreted as a block
565-
// statement rather than an object literal. So, we first try
566-
// to wrap it in parentheses, so that it will be interpreted as
567-
// an expression.
568-
cmd = `(${cmd})`;
569-
self.wrappedCmd = true;
570-
} else {
571-
// Mitigate https://github.com/nodejs/node/issues/548
572-
cmd = cmd.replace(
573-
/^\s*function(?:\s*(\*)\s*|\s+)([^(]+)/,
574-
(_, genStar, name) => `var ${name} = function ${genStar || ''}${name}`
575-
);
576-
}
577-
// Append a \n so that it will be either
578-
// terminated, or continued onto the next expression if it's an
579-
// unexpected end of input.
580-
return `${cmd}\n`;
581-
}
582585
});
583586

584587
self.on('SIGCONT', function onSigCont() {

test/parallel/test-repl-eval.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,21 @@ const repl = require('repl');
1010
eval: common.mustCall((cmd, context) => {
1111
// Assertions here will not cause the test to exit with an error code
1212
// so set a boolean that is checked in process.on('exit',...) instead.
13-
evalCalledWithExpectedArgs = (cmd === 'foo\n' && context.foo === 'bar');
13+
evalCalledWithExpectedArgs = (cmd === 'function f() {}\n' &&
14+
context.foo === 'bar');
1415
})
1516
};
1617

1718
const r = repl.start(options);
1819
r.context = {foo: 'bar'};
1920

2021
try {
21-
r.write('foo\n');
22+
// Default preprocessor transforms
23+
// function f() {} to
24+
// var f = function f() {}
25+
// Test to ensure that original input is preserved.
26+
// Reference: https://github.com/nodejs/node/issues/9743
27+
r.write('function f() {}\n');
2228
} finally {
2329
r.write('.exit\n');
2430
}

0 commit comments

Comments
 (0)