Update how REPLServer uses contexts
* Always use `this.context` or `self.context`. * Move `resetContext` to `REPLServer.createContext`. * Add `REPLServer.resetContext`, memoize `context` here. * Memoize `exports.repl` in `start`. Closes GH-851.
This commit is contained in:
parent
bfa9db9dd6
commit
d63a551f86
50
lib/repl.js
50
lib/repl.js
@ -60,27 +60,14 @@ module.filename = process.cwd() + '/repl';
|
||||
// hack for repl require to work properly with node_modules folders
|
||||
module.paths = require('module')._nodeModulePaths(module.filename);
|
||||
|
||||
|
||||
function resetContext() {
|
||||
context = vm.createContext();
|
||||
for (var i in global) context[i] = global[i];
|
||||
context.module = module;
|
||||
context.require = require;
|
||||
context.global = context;
|
||||
context.global.global = context;
|
||||
for (var i in require.cache) delete require.cache[i];
|
||||
}
|
||||
|
||||
|
||||
// Can overridden with custom print functions, such as `probe` or `eyes.js`
|
||||
exports.writer = util.inspect;
|
||||
|
||||
|
||||
function REPLServer(prompt, stream) {
|
||||
var self = this;
|
||||
if (!context) resetContext();
|
||||
if (!exports.repl) exports.repl = this;
|
||||
self.context = context;
|
||||
|
||||
self.resetContext();
|
||||
self.bufferedCommand = '';
|
||||
|
||||
if (stream) {
|
||||
@ -159,7 +146,7 @@ function REPLServer(prompt, stream) {
|
||||
// First we attempt to eval as expression with parens.
|
||||
// This catches '{a : 1}' properly.
|
||||
ret = vm.runInContext('(' + self.bufferedCommand + ')',
|
||||
context,
|
||||
self.context,
|
||||
'repl');
|
||||
if (typeof ret !== 'function') success = true;
|
||||
} catch (e) {
|
||||
@ -168,11 +155,11 @@ function REPLServer(prompt, stream) {
|
||||
|
||||
if (!success) {
|
||||
// Now as statement without parens.
|
||||
ret = vm.runInContext(self.bufferedCommand, context, 'repl');
|
||||
ret = vm.runInContext(self.bufferedCommand, self.context, 'repl');
|
||||
}
|
||||
|
||||
if (ret !== undefined) {
|
||||
context._ = ret;
|
||||
self.context._ = ret;
|
||||
self.outputStream.write(exports.writer(ret) + '\n');
|
||||
}
|
||||
|
||||
@ -215,10 +202,33 @@ exports.REPLServer = REPLServer;
|
||||
// prompt is a string to print on each line for the prompt,
|
||||
// source is a stream to use for I/O, defaulting to stdin/stdout.
|
||||
exports.start = function(prompt, source) {
|
||||
return new REPLServer(prompt, source);
|
||||
var repl = new REPLServer(prompt, source);
|
||||
if (!exports.repl) exports.repl = repl;
|
||||
return repl;
|
||||
};
|
||||
|
||||
|
||||
REPLServer.prototype.createContext = function() {
|
||||
var context = vm.createContext();
|
||||
|
||||
for (var i in global) context[i] = global[i];
|
||||
context.module = module;
|
||||
context.require = require;
|
||||
context.global = context;
|
||||
context.global.global = context;
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
REPLServer.prototype.resetContext = function(force) {
|
||||
if (!context || force) {
|
||||
context = this.createContext();
|
||||
for (var i in require.cache) delete require.cache[i];
|
||||
}
|
||||
|
||||
this.context = context;
|
||||
};
|
||||
|
||||
REPLServer.prototype.displayPrompt = function() {
|
||||
this.rli.setPrompt(this.bufferedCommand.length ? '... ' : this.prompt);
|
||||
this.rli.prompt();
|
||||
@ -503,7 +513,7 @@ function defineDefaultCommands(repl) {
|
||||
action: function() {
|
||||
this.outputStream.write('Clearing context...\n');
|
||||
this.bufferedCommand = '';
|
||||
resetContext();
|
||||
this.resetContext(true);
|
||||
this.displayPrompt();
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user