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
|
// hack for repl require to work properly with node_modules folders
|
||||||
module.paths = require('module')._nodeModulePaths(module.filename);
|
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`
|
// Can overridden with custom print functions, such as `probe` or `eyes.js`
|
||||||
exports.writer = util.inspect;
|
exports.writer = util.inspect;
|
||||||
|
|
||||||
|
|
||||||
function REPLServer(prompt, stream) {
|
function REPLServer(prompt, stream) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (!context) resetContext();
|
|
||||||
if (!exports.repl) exports.repl = this;
|
self.resetContext();
|
||||||
self.context = context;
|
|
||||||
self.bufferedCommand = '';
|
self.bufferedCommand = '';
|
||||||
|
|
||||||
if (stream) {
|
if (stream) {
|
||||||
@ -159,7 +146,7 @@ function REPLServer(prompt, stream) {
|
|||||||
// First we attempt to eval as expression with parens.
|
// First we attempt to eval as expression with parens.
|
||||||
// This catches '{a : 1}' properly.
|
// This catches '{a : 1}' properly.
|
||||||
ret = vm.runInContext('(' + self.bufferedCommand + ')',
|
ret = vm.runInContext('(' + self.bufferedCommand + ')',
|
||||||
context,
|
self.context,
|
||||||
'repl');
|
'repl');
|
||||||
if (typeof ret !== 'function') success = true;
|
if (typeof ret !== 'function') success = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -168,11 +155,11 @@ function REPLServer(prompt, stream) {
|
|||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
// Now as statement without parens.
|
// Now as statement without parens.
|
||||||
ret = vm.runInContext(self.bufferedCommand, context, 'repl');
|
ret = vm.runInContext(self.bufferedCommand, self.context, 'repl');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret !== undefined) {
|
if (ret !== undefined) {
|
||||||
context._ = ret;
|
self.context._ = ret;
|
||||||
self.outputStream.write(exports.writer(ret) + '\n');
|
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,
|
// 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.
|
// source is a stream to use for I/O, defaulting to stdin/stdout.
|
||||||
exports.start = function(prompt, source) {
|
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() {
|
REPLServer.prototype.displayPrompt = function() {
|
||||||
this.rli.setPrompt(this.bufferedCommand.length ? '... ' : this.prompt);
|
this.rli.setPrompt(this.bufferedCommand.length ? '... ' : this.prompt);
|
||||||
this.rli.prompt();
|
this.rli.prompt();
|
||||||
@ -503,7 +513,7 @@ function defineDefaultCommands(repl) {
|
|||||||
action: function() {
|
action: function() {
|
||||||
this.outputStream.write('Clearing context...\n');
|
this.outputStream.write('Clearing context...\n');
|
||||||
this.bufferedCommand = '';
|
this.bufferedCommand = '';
|
||||||
resetContext();
|
this.resetContext(true);
|
||||||
this.displayPrompt();
|
this.displayPrompt();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user