Add REPL support.
Reviewed-by: asquare
This commit is contained in:
parent
b0f3c1ca3f
commit
7241ec81bf
@ -274,6 +274,7 @@
|
||||
<apply-diff src="lib" mod="src/main/js/lib" name="querystring.js"/>
|
||||
<apply-diff src="lib" mod="src/main/js/lib" name="module.js"/>
|
||||
<apply-diff src="lib" mod="src/main/js/lib" name="net.js"/>
|
||||
<apply-diff src="lib" mod="src/main/js/lib" name="repl.js"/>
|
||||
<apply-diff src="lib" mod="src/main/js/lib" name="string_decoder.js"/>
|
||||
<apply-diff src="lib" mod="src/main/js/lib" name="tls.js"/>
|
||||
<!-- tests -->
|
||||
@ -350,6 +351,7 @@
|
||||
<apply-patch-file target="src/main/js/lib" dir="lib" name="querystring.js"/>
|
||||
<apply-patch-file target="src/main/js/lib" dir="lib" name="module.js"/>
|
||||
<apply-patch-file target="src/main/js/lib" dir="lib" name="net.js"/>
|
||||
<apply-patch-file target="src/main/js/lib" dir="lib" name="repl.js"/>
|
||||
<apply-patch-file target="src/main/js/lib" dir="lib" name="string_decoder.js"/>
|
||||
<apply-patch-file target="src/main/js/lib" dir="lib" name="tls.js"/>
|
||||
<!-- tests -->
|
||||
|
@ -1,5 +1,5 @@
|
||||
--- ../node/lib/module.js 2013-08-22 13:55:28.000000000 +0200
|
||||
+++ src/main/js/lib/module.js 2013-10-07 14:01:12.000000000 +0200
|
||||
--- ../nodejs/lib/module.js 2013-12-02 16:45:51.723090200 -0800
|
||||
+++ src/main/js/lib/module.js 2013-12-05 16:49:59.264917800 -0800
|
||||
@@ -271,13 +271,19 @@
|
||||
return [id, [path.dirname(parent.filename)]];
|
||||
};
|
||||
@ -21,6 +21,15 @@
|
||||
|
||||
var cachedModule = Module._cache[filename];
|
||||
if (cachedModule) {
|
||||
@@ -288,7 +294,7 @@
|
||||
// REPL is a special case, because it needs the real require.
|
||||
if (filename == 'repl') {
|
||||
var replModule = new Module('repl');
|
||||
- replModule._compile(NativeModule.getSource('repl'), 'repl.js');
|
||||
+ replModule._compile(NativeModule.getSource('/lib/repl.js'), 'repl.js');
|
||||
NativeModule._cache.repl = replModule;
|
||||
return replModule.exports;
|
||||
}
|
||||
@@ -309,7 +315,11 @@
|
||||
var hadException = true;
|
||||
|
||||
@ -49,7 +58,7 @@
|
||||
// Returns exception if any
|
||||
Module.prototype._compile = function(content, filename) {
|
||||
var self = this;
|
||||
+
|
||||
+
|
||||
// remove shebang
|
||||
+ if(content != null) {
|
||||
content = content.replace(/^\#\!.*/, '');
|
||||
|
24
patches/lib/repl.js.patch
Normal file
24
patches/lib/repl.js.patch
Normal file
@ -0,0 +1,24 @@
|
||||
--- ../nodejs/lib/repl.js 2013-12-05 16:43:37.738090700 -0800
|
||||
+++ src/main/js/lib/repl.js 2013-12-05 16:44:53.691533100 -0800
|
||||
@@ -535,7 +535,7 @@
|
||||
// Get global vars synchronously
|
||||
if (this.useGlobal ||
|
||||
this.context.constructor &&
|
||||
- this.context.constructor.name === 'Context') {
|
||||
+ this.context.constructor.name === 'Object') {
|
||||
var contextProto = this.context;
|
||||
while (contextProto = Object.getPrototypeOf(contextProto)) {
|
||||
completionGroups.push(Object.getOwnPropertyNames(contextProto));
|
||||
@@ -918,10 +918,10 @@
|
||||
e = e && (e.stack || e.toString());
|
||||
return e && e.match(/^SyntaxError/) &&
|
||||
// RegExp syntax error
|
||||
- !e.match(/^SyntaxError: Invalid regular expression/) &&
|
||||
+ !e.match(/^SyntaxError: repl/) &&
|
||||
!e.match(/^SyntaxError: Invalid flags supplied to RegExp constructor/) &&
|
||||
// "strict mode" syntax errors
|
||||
!e.match(/^SyntaxError: .*strict mode.*/i) &&
|
||||
// JSON.parse() error
|
||||
- !e.match(/\n {4}at Object.parse \(native\)\n/);
|
||||
+ !e.match(/^SyntaxError: Invalid /);
|
||||
}
|
@ -28,6 +28,7 @@ source.lib.modules = \
|
||||
path.js \
|
||||
querystring.js \
|
||||
readline.js \
|
||||
repl.js \
|
||||
stream.js \
|
||||
string_decoder.js \
|
||||
timers.js \
|
||||
@ -436,6 +437,12 @@ source.test.simple.list = \
|
||||
test-regress-GH-877.js \
|
||||
test-regress-GH-897.js \
|
||||
test-regression-object-prototype.js \
|
||||
test-repl-autolibs.js \
|
||||
test-repl-console.js \
|
||||
test-repl-end-emits-exit.js \
|
||||
test-repl-options.js \
|
||||
test-repl-require-cache.js \
|
||||
test-repl-tab-complete.js \
|
||||
test-require-cache.js \
|
||||
test-require-cache-without-stat.js \
|
||||
test-require-exceptions.js \
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package net.java.avatar.js;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -125,6 +126,8 @@ public abstract class Loader {
|
||||
*/
|
||||
public abstract boolean exists(final String id);
|
||||
|
||||
public abstract String load(final String id);
|
||||
|
||||
/**
|
||||
* Returns the value of a compiled-in property.
|
||||
* @param key the key whose value is desired
|
||||
@ -192,6 +195,27 @@ public abstract class Loader {
|
||||
return BUILD_PROPERTIES.getProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String load(final String id) {
|
||||
final int BUFFERSIZE = 64 * 1024;
|
||||
final byte[] data = new byte[BUFFERSIZE];
|
||||
final ByteArrayOutputStream buffer = new ByteArrayOutputStream(BUFFERSIZE);
|
||||
final InputStream is = this.getClass().getResourceAsStream(id);
|
||||
assert is != null;
|
||||
|
||||
try {
|
||||
int bytesRead = is.read(data, 0, data.length);
|
||||
while (bytesRead != -1) {
|
||||
buffer.write(data, 0, bytesRead);
|
||||
bytesRead = is.read(data, 0, data.length);
|
||||
}
|
||||
buffer.flush();
|
||||
} catch (final IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return new String(buffer.toByteArray());
|
||||
}
|
||||
|
||||
protected String pathFor(final String id) {
|
||||
return MODULES_DIR + id + SCRIPT_EXTENSION;
|
||||
}
|
||||
|
@ -100,9 +100,7 @@ public final class Server {
|
||||
}
|
||||
|
||||
public static void main(final String... args) throws Exception {
|
||||
if (args != null && args.length > 0) {
|
||||
new Server().run(args);
|
||||
}
|
||||
new Server().run(args);
|
||||
}
|
||||
|
||||
public Server() throws Exception {
|
||||
@ -147,7 +145,11 @@ public final class Server {
|
||||
checkPermission();
|
||||
bindings.put(SECURE_HOLDER, holder);
|
||||
try {
|
||||
runUserScripts(args);
|
||||
if (args.length == 0) {
|
||||
runREPL();
|
||||
} else {
|
||||
runUserScripts(args);
|
||||
}
|
||||
} catch (final ScriptException ex) {
|
||||
if (!eventLoop.handleCallbackException(ex)) {
|
||||
throw ex;
|
||||
@ -206,11 +208,21 @@ public final class Server {
|
||||
}
|
||||
|
||||
final String[] userFiles = {userFile};
|
||||
holder.setArgs(avatarArgs.toArray(new String[avatarArgs.size()]),
|
||||
userArgs.toArray(new String[userArgs.size()]),
|
||||
userFiles);
|
||||
|
||||
runEventLoop(avatarArgs.toArray(new String[avatarArgs.size()]),
|
||||
userArgs.toArray(new String[userArgs.size()]),
|
||||
userFiles);
|
||||
}
|
||||
|
||||
private void runREPL() throws Exception {
|
||||
holder.setForceRepl(true);
|
||||
runEventLoop(null, null, null);
|
||||
}
|
||||
|
||||
private void runEventLoop(final String[] avatarArgs, final String[] userArgs, final String[] userFiles) throws Exception {
|
||||
Exception rootCause = null;
|
||||
// First run the main script...
|
||||
holder.setArgs(avatarArgs, userArgs, userFiles);
|
||||
|
||||
try {
|
||||
runSystemScript(SYSTEM_INIT_SCRIPTS);
|
||||
} catch(Exception ex) {
|
||||
@ -234,17 +246,15 @@ public final class Server {
|
||||
throw ex;
|
||||
}
|
||||
} finally {
|
||||
if (args != null && args.length > 0) {
|
||||
try {
|
||||
// emit the process.exit event
|
||||
runSystemScript(SYSTEM_FINALIZATION_SCRIPTS);
|
||||
} catch (Exception ex) {
|
||||
if (rootCause != null) {
|
||||
rootCause.addSuppressed(ex);
|
||||
throw rootCause;
|
||||
}
|
||||
throw ex;
|
||||
try {
|
||||
// emit the process.exit event
|
||||
runSystemScript(SYSTEM_FINALIZATION_SCRIPTS);
|
||||
} catch (Exception ex) {
|
||||
if (rootCause != null) {
|
||||
rootCause.addSuppressed(ex);
|
||||
throw rootCause;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -266,6 +276,8 @@ public final class Server {
|
||||
} else if ("--trace-deprecation".equals(arg)) {
|
||||
holder.setTraceDeprecation(true);
|
||||
holder.setThrowDeprecation(false);
|
||||
} else if ("-i".equals(arg) || "--interactive".equals(arg)) {
|
||||
holder.setForceRepl(true);
|
||||
} else {
|
||||
System.out.println(HELP);
|
||||
throw new IllegalArgumentException(arg);
|
||||
@ -339,6 +351,7 @@ public final class Server {
|
||||
private String[] userFiles;
|
||||
private boolean throwDeprecation = true;
|
||||
private boolean traceDeprecation;
|
||||
private boolean forceRepl = false;
|
||||
private int exitCode = 0;
|
||||
private final Invocable invocable;
|
||||
private Object nativeModule;
|
||||
@ -368,9 +381,9 @@ public final class Server {
|
||||
}
|
||||
|
||||
private void setArgs(final String[] avatarArgs, final String[] userArgs, final String[] userFiles) {
|
||||
this.avatarArgs = avatarArgs.clone();
|
||||
this.userArgs = userArgs.clone();
|
||||
this.userFiles = userFiles.clone();
|
||||
this.avatarArgs = avatarArgs != null ? avatarArgs.clone() : null;
|
||||
this.userArgs = userArgs != null ? userArgs.clone() : null;
|
||||
this.userFiles = userFiles != null ? userFiles.clone() : null;
|
||||
}
|
||||
|
||||
public String[] getAvatarArgs() {
|
||||
@ -393,6 +406,10 @@ public final class Server {
|
||||
this.traceDeprecation = traceDeprecation;
|
||||
}
|
||||
|
||||
private void setForceRepl(boolean forceRepl) {
|
||||
this.forceRepl = forceRepl;
|
||||
}
|
||||
|
||||
public boolean getThrowDeprecation() {
|
||||
return throwDeprecation;
|
||||
}
|
||||
@ -401,6 +418,10 @@ public final class Server {
|
||||
return traceDeprecation;
|
||||
}
|
||||
|
||||
public boolean getForceRepl() {
|
||||
return forceRepl;
|
||||
}
|
||||
|
||||
private void setExitCode(int exitCode) {
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
|
@ -77,6 +77,11 @@ Object.defineProperty(exports, 'traceDeprecation', {
|
||||
value: __avatar.traceDeprecation
|
||||
});
|
||||
|
||||
Object.defineProperty(exports, '_forceRepl', {
|
||||
enumerable: true,
|
||||
value: __avatar.forceRepl
|
||||
});
|
||||
|
||||
var stdin;
|
||||
Object.defineProperty(exports, 'stdin', {
|
||||
enumerable: true,
|
||||
@ -278,12 +283,12 @@ Object.defineProperty(exports, 'argv', {
|
||||
_argv = [];
|
||||
_argv.push(exports.execPath);
|
||||
var uf = __avatar.userFiles;
|
||||
var flen = uf.length;
|
||||
var flen = uf ? uf.length : 0;
|
||||
for (var i=0; i < flen; i++) {
|
||||
_argv.push(uf[i]);
|
||||
}
|
||||
var ua = __avatar.userArgs;
|
||||
var alen = ua.length;
|
||||
var alen = ua ? ua.length : 0;
|
||||
for (var j=0; j < alen; j++) {
|
||||
_argv.push(ua[j]);
|
||||
}
|
||||
@ -302,7 +307,7 @@ Object.defineProperty(exports, 'execArgv', {
|
||||
if (!_execArgv) {
|
||||
_execArgv = [];
|
||||
var aa = __avatar.avatarArgs;
|
||||
var alen = aa.length;
|
||||
var alen = aa ? aa.length : 0;
|
||||
for (var j=0; j < alen; j++) {
|
||||
_execArgv.push(aa[j]);
|
||||
}
|
||||
|
@ -300,6 +300,55 @@ var gc = global.gc;
|
||||
return current.apply(this, args);
|
||||
}
|
||||
|
||||
NativeModule.require('module').runMain();
|
||||
if (process.argv[1]) {
|
||||
// make process.argv[1] into a full path
|
||||
var path = NativeModule.require('path');
|
||||
process.argv[1] = path.resolve(process.argv[1]);
|
||||
|
||||
// If this is a worker in cluster mode, start up the communiction
|
||||
// channel.
|
||||
if (process.env.NODE_UNIQUE_ID) {
|
||||
var cluster = NativeModule.require('cluster');
|
||||
cluster._setupWorker();
|
||||
|
||||
// Make sure it's not accidentally inherited by child processes.
|
||||
delete process.env.NODE_UNIQUE_ID;
|
||||
}
|
||||
|
||||
NativeModule.require('module').runMain();
|
||||
} else {
|
||||
var Module = NativeModule.require('module');
|
||||
|
||||
// If -i or --interactive were passed, or stdin is a TTY.
|
||||
if (process._forceRepl || NativeModule.require('tty').isatty(0)) {
|
||||
// REPL
|
||||
var opts = {
|
||||
useGlobal: true,
|
||||
ignoreUndefined: false
|
||||
};
|
||||
if (parseInt(process.env['NODE_NO_READLINE'], 10)) {
|
||||
opts.terminal = false;
|
||||
}
|
||||
if (parseInt(process.env['NODE_DISABLE_COLORS'], 10)) {
|
||||
opts.useColors = false;
|
||||
}
|
||||
var repl = Module.requireRepl().start(opts);
|
||||
repl.on('exit', function() {
|
||||
process.exit();
|
||||
});
|
||||
} else {
|
||||
// Read all of stdin - execute it.
|
||||
process.stdin.setEncoding('utf8');
|
||||
|
||||
var code = '';
|
||||
process.stdin.on('data', function(d) {
|
||||
code += d;
|
||||
});
|
||||
|
||||
process.stdin.on('end', function() {
|
||||
process._eval = code;
|
||||
evalScript('[stdin]');
|
||||
});
|
||||
}
|
||||
}
|
||||
} )();
|
||||
|
Loading…
Reference in New Issue
Block a user