in shell/jrepl.js [71:283]
function REPLServer(prompt, stream, eval, useGlobal, ignoreUndefined) {
var self = this;
self.useGlobal = useGlobal;
self.eval = eval || function(code, context, file, cb) {
var err, result;
try {
if (useGlobal) {
result = vm.runInThisContext(code, file);
} else {
result = vm.runInContext(code, context, file);
}
} catch (e) {
err = e;
}
cb(err, result);
};
self.resetContext();
self.bufferedCommand = '';
if (stream) {
// We're given a duplex socket
if (stream.stdin || stream.stdout) {
self.outputStream = stream.stdout;
self.inputStream = stream.stdin;
} else {
self.outputStream = stream;
self.inputStream = stream;
}
} else {
self.outputStream = process.stdout;
self.inputStream = process.stdin;
process.stdin.resume();
}
self.prompt = (prompt != undefined ? prompt : '===> ');
function complete(text, callback) {
self.complete(text, callback);
}
var rli = rl.createInterface(self.inputStream, self.outputStream, complete);
self.rli = rli;
this.commands = {};
defineDefaultCommands(this);
if (rli.enabled && !exports.disableColors &&
exports.writer === util.inspect) {
// Turn on ANSI coloring.
exports.writer = function(obj, showHidden, depth) {
return util.inspect(obj, showHidden, depth, true);
};
}
rli.setPrompt(self.prompt);
var sawSIGINT = false;
rli.on('SIGINT', function() {
if (sawSIGINT) {
rli.close();
process.exit();
}
rli.line = '';
if (!(self.bufferedCommand && self.bufferedCommand.length > 0) &&
rli.line.length === 0) {
rli.output.write('\n(^C again if you really want to quit)\n');
sawSIGINT = true;
} else {
rli.output.write('\n');
}
self.bufferedCommand = '';
self.displayPrompt();
});
rli.addListener('line', function(cmd) {
function isPromise(ret) {
// console.log('isPromise', ret);
if (ret && ret.constructor && ret.constructor.name == 'Promise') {
ret.then(function(result) {
// console.log('=========================Promise.then with result:', result);
if (result && result.constructor && result.constructor.name == 'Session') {
// console.log('=========================Sesssion');
context.session = result;
context.sessionFactory = context.session.sessionFactory;
context.session.allowCreateUnmappedTable = true;
context.db = context.sessionFactory.db();
} else {
// console.log("----------------not a session--------");
// console.log(result);
}
// console.log('isPromise.then calling finish(null, result)');
finish(null, result);
}, function(e) {
// console.log('isPromise found', e);
finish(e);
});
return true;
}
return false;
}
sawSIGINT = false;
var skipCatchall = false;
cmd = trimWhitespace(cmd);
// Check to see if a REPL keyword was used. If it returns true,
// display next prompt and return.
if (cmd && cmd.charAt(0) === '.') {
var matches = cmd.match(/^(\.[^\s]+)\s*(.*)$/);
var keyword = matches && matches[1];
var rest = matches && matches[2];
if (self.parseREPLKeyword(keyword, rest) === true) {
return;
} else {
self.outputStream.write('Invalid REPL keyword\n');
skipCatchall = true;
}
}
if (!skipCatchall) {
var evalCmd = self.bufferedCommand + cmd + '\n';
// This try is for determining if the command is complete, or should
// continue onto the next line.
// We try to evaluate both expressions e.g.
// '{ a : 1 }'
// and statements e.g.
// 'for (var i = 0; i < 10; i++) console.log(i);'
// First we attempt to eval as expression with parens.
// This catches '{a : 1}' properly.
self.eval('(' + evalCmd + ')',
self.context,
'repl',
function(e, ret) {
// console.log('eval(self.context) complete', e);
if (isPromise(ret)) return;
if (e && !isSyntaxError(e)) return finish(e);
if (typeof ret === 'function' || e) {
// Now as statement without parens.
//console.log('==============now as a statement without parens.', e);
self.eval(evalCmd, self.context, 'repl', function(err, ret) {
console.log('eval self.context complete', e);
if (isPromise(ret)) return;
});
} else {
finish(null, ret);
}
});
} else {
finish(null);
}
function isSyntaxError(e) {
// Convert error to string
e = e && (e.stack || e.toString());
return e && e.match(/^SyntaxError/) &&
!(e.match(/^SyntaxError: Unexpected token .*\n/) &&
e.match(/\n at Object.parse \(native\)\n/));
}
function finish(e, ret) {
// console.log('finish e:', e, 'ret', ret&&ret.toString());
self.memory(cmd);
// If error was SyntaxError and not JSON.parse error
if (isSyntaxError(e)) {
// Start buffering data like that:
// {
// ... x: 1
// ... }
self.bufferedCommand += cmd + '\n';
self.displayPrompt();
return;
} else if (e) {
// console.log('finish not isSyntaxError e:', e, 'e.stack', e.stack, '(e.stack || e)', (e.stack || e), ret&&ret.toString());
self.outputStream.write(util.inspect(e.stack || e) + '\n');
}
// Clear buffer if no SyntaxErrors
self.bufferedCommand = '';
// If we got any output - print it (if no error)
if (!e && (!ignoreUndefined || ret !== undefined)) {
// console.log('finish write ret', e, ret&&ret.toString());
self.context._ = ret;
self.outputStream.write(exports.writer(ret) + '\n');
}
// Display prompt again
self.displayPrompt();
};
});
rli.addListener('close', function() {
self.inputStream.destroy();
});
self.displayPrompt();
}