Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

repl: preprocess only for defaultEval #9752

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 27 additions & 24 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,33 @@ function REPLServer(prompt,

eval_ = eval_ || defaultEval;

function preprocess(code) {
let cmd = code;
if (/^\s*\{/.test(cmd) && /\}\s*$/.test(cmd)) {
// 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.
cmd = `(${cmd})`;
self.wrappedCmd = true;
} else {
// Mitigate https://github.com/nodejs/node/issues/548
cmd = cmd.replace(
/^\s*function(?:\s*(\*)\s*|\s+)([^(]+)/,
(_, genStar, name) => `var ${name} = function ${genStar || ''}${name}`
);
}
// Append a \n so that it will be either
// terminated, or continued onto the next expression if it's an
// unexpected end of input.
return `${cmd}\n`;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appending of the \n isn't needed for custom eval functions?
Because it was being appended before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nunocastromartins Good point. \n was appended for most of the cases and it was done in same preprocess. I'll add \n for all cases as if eval function receives what user entered including the final enter.

CC: @Fishrock123

}

function defaultEval(code, context, file, cb) {
// Remove trailing new line
code = code.replace(/\n$/, '');
code = preprocess(code);

var err, result, retry = false, input = code, wrappedErr;
// first, create the Script object to check the syntax

Expand Down Expand Up @@ -499,8 +525,7 @@ function REPLServer(prompt,
}
}

var evalCmd = self.bufferedCommand + cmd;
evalCmd = preprocess(evalCmd);
const evalCmd = self.bufferedCommand + cmd + '\n';

debug('eval %j', evalCmd);
self.eval(evalCmd, self.context, 'repl', finish);
Expand Down Expand Up @@ -557,28 +582,6 @@ function REPLServer(prompt,
// Display prompt again
self.displayPrompt();
}

function preprocess(code) {
let cmd = code;
if (/^\s*\{/.test(cmd) && /\}\s*$/.test(cmd)) {
// 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.
cmd = `(${cmd})`;
self.wrappedCmd = true;
} else {
// Mitigate https://github.com/nodejs/node/issues/548
cmd = cmd.replace(
/^\s*function(?:\s*(\*)\s*|\s+)([^(]+)/,
(_, genStar, name) => `var ${name} = function ${genStar || ''}${name}`
);
}
// Append a \n so that it will be either
// terminated, or continued onto the next expression if it's an
// unexpected end of input.
return `${cmd}\n`;
}
});

self.on('SIGCONT', function onSigCont() {
Expand Down
10 changes: 8 additions & 2 deletions test/parallel/test-repl-eval.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,21 @@ const repl = require('repl');
eval: common.mustCall((cmd, context) => {
// Assertions here will not cause the test to exit with an error code
// so set a boolean that is checked in process.on('exit',...) instead.
evalCalledWithExpectedArgs = (cmd === 'foo\n' && context.foo === 'bar');
evalCalledWithExpectedArgs = (cmd === 'function f() {}\n' &&
context.foo === 'bar');
})
};

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

try {
r.write('foo\n');
// Default preprocessor transforms
// function f() {} to
// var f = function f() {}
// Test to ensure that original input is preserved.
// Reference: https://github.com/nodejs/node/issues/9743
r.write('function f() {}\n');
} finally {
r.write('.exit\n');
}
Expand Down