Skip to content

Commit 6087e36

Browse files
princejwesleyFishrock123
authored andcommitted
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 <anna@addaleax.net>
1 parent 0c745e3 commit 6087e36

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

lib/repl.js

+27-24
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

@@ -506,8 +532,7 @@ function REPLServer(prompt,
506532
}
507533
}
508534

509-
var evalCmd = self.bufferedCommand + cmd;
510-
evalCmd = preprocess(evalCmd);
535+
const evalCmd = self.bufferedCommand + cmd + '\n';
511536

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

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

test/parallel/test-repl-eval.js

+8-2
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)