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

module,repl: remove repl require() hack #4026

Merged
merged 2 commits into from
Nov 30, 2015
Merged
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
2 changes: 1 addition & 1 deletion lib/_debugger.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const path = require('path');
const net = require('net');
const vm = require('vm');
const Module = require('module');
const repl = Module.requireRepl();
const repl = require('repl');
const inherits = util.inherits;
const assert = require('assert');
const spawn = require('child_process').spawn;
Expand Down
26 changes: 25 additions & 1 deletion lib/internal/module.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
'use strict';

module.exports.stripBOM = stripBOM;
module.exports = { makeRequireFunction, stripBOM };

// Invoke with makeRequireFunction.call(module) where |module| is the
// Module object to use as the context for the require() function.
function makeRequireFunction() {
const Module = this.constructor;
const self = this;

function require(path) {
return self.require(path);
}

require.resolve = function(request) {
return Module._resolveFilename(request, self);
};

require.main = process.mainModule;

// Enable support to add extra extension types.
require.extensions = Module._extensions;

require.cache = Module._cache;

return require;
}

/**
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
Expand Down
18 changes: 18 additions & 0 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,21 @@ exports._deprecate = function(fn, msg) {

return deprecated;
};

exports.decorateErrorStack = function decorateErrorStack(err) {
if (!(exports.isError(err) && err.stack))
return;

const arrow = exports.getHiddenValue(err, 'arrowMessage');

if (arrow)
err.stack = arrow + err.stack;
};

exports.isError = function isError(e) {
return exports.objectToString(e) === '[object Error]' || e instanceof Error;
};

exports.objectToString = function objectToString(o) {
return Object.prototype.toString.call(o);
};
43 changes: 8 additions & 35 deletions lib/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,17 +274,6 @@ Module._load = function(request, parent, isMain) {
debug('Module._load REQUEST %s parent: %s', request, parent.id);
}

// REPL is a special case, because it needs the real require.
if (request === 'internal/repl' || request === 'repl') {
if (Module._cache[request]) {
return Module._cache[request];
}
var replModule = new Module(request);
replModule._compile(NativeModule.getSource(request), `${request}.js`);
NativeModule._cache[request] = replModule;
return replModule.exports;
}

var filename = Module._resolveFilename(request, parent);

var cachedModule = Module._cache[filename];
Expand Down Expand Up @@ -376,27 +365,9 @@ var resolvedArgv;
// the file.
// Returns exception, if any.
Module.prototype._compile = function(content, filename) {
var self = this;
// remove shebang
content = content.replace(shebangRe, '');

function require(path) {
return self.require(path);
}

require.resolve = function(request) {
return Module._resolveFilename(request, self);
};

require.main = process.mainModule;

// Enable support to add extra extension types
require.extensions = Module._extensions;

require.cache = Module._cache;

var dirname = path.dirname(filename);

// create wrapper function
var wrapper = Module.wrap(content);

Expand All @@ -421,8 +392,10 @@ Module.prototype._compile = function(content, filename) {
global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0);
}
}
var args = [self.exports, require, self, filename, dirname];
return compiledWrapper.apply(self.exports, args);
const dirname = path.dirname(filename);
const require = internalModule.makeRequireFunction.call(this);
const args = [this.exports, require, this, filename, dirname];
return compiledWrapper.apply(this.exports, args);
};


Expand Down Expand Up @@ -488,10 +461,10 @@ Module._initPaths = function() {
Module.globalPaths = modulePaths.slice(0);
};

// bootstrap repl
Module.requireRepl = function() {
return Module._load('internal/repl', '.');
};
// TODO(bnoordhuis) Unused, remove in the future.
Module.requireRepl = internalUtil.deprecate(function() {
return NativeModule.require('internal/repl');
}, 'Module.requireRepl is deprecated.');

Module._preloadModules = function(requests) {
if (!Array.isArray(requests))
Expand Down
9 changes: 7 additions & 2 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

'use strict';

const internalModule = require('internal/module');
const internalUtil = require('internal/util');
const util = require('util');
const inherits = util.inherits;
const Stream = require('stream');
Expand All @@ -29,6 +31,7 @@ const path = require('path');
const fs = require('fs');
const Interface = require('readline').Interface;
const Console = require('console').Console;
const Module = require('module');
const domain = require('domain');
const debug = util.debuglog('repl');

Expand Down Expand Up @@ -274,7 +277,7 @@ function REPLServer(prompt,
self._domain.on('error', function(e) {
debug('domain error');
const top = replMap.get(self);
util.decorateErrorStack(e);
internalUtil.decorateErrorStack(e);
top.outputStream.write((e.stack || e) + '\n');
top.lineParser.reset();
top.bufferedCommand = '';
Expand Down Expand Up @@ -522,6 +525,8 @@ REPLServer.prototype.createContext = function() {
context.global.global = context;
}

const module = new Module('<repl>');
const require = internalModule.makeRequireFunction.call(module);
context.module = module;
context.require = require;

Expand Down Expand Up @@ -661,7 +666,7 @@ REPLServer.prototype.complete = function(line, callback) {
completionGroupsLoaded();
} else if (match = line.match(requireRE)) {
// require('...<Tab>')
var exts = Object.keys(require.extensions);
const exts = Object.keys(this.context.require.extensions);
var indexRe = new RegExp('^index(' + exts.map(regexpEscape).join('|') +
')$');

Expand Down
21 changes: 3 additions & 18 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const Buffer = require('buffer').Buffer;
const internalUtil = require('internal/util');
const binding = process.binding('util');

const isError = internalUtil.isError;
const objectToString = internalUtil.objectToString;

var Debug;

const formatRegExp = /%[sdj%]/g;
Expand Down Expand Up @@ -739,9 +742,6 @@ function isDate(d) {
}
exports.isDate = isDate;

function isError(e) {
return objectToString(e) === '[object Error]' || e instanceof Error;
}
exports.isError = isError;

function isFunction(arg) {
Expand All @@ -757,10 +757,6 @@ exports.isPrimitive = isPrimitive;

exports.isBuffer = Buffer.isBuffer;

function objectToString(o) {
return Object.prototype.toString.call(o);
}


function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
Expand Down Expand Up @@ -899,14 +895,3 @@ exports._exceptionWithHostPort = function(err,
}
return ex;
};


exports.decorateErrorStack = function(err) {
if (!(isError(err) && err.stack))
return;

const arrow = internalUtil.getHiddenValue(err, 'arrowMessage');

if (arrow)
err.stack = arrow + err.stack;
};
2 changes: 1 addition & 1 deletion src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
// If -i or --interactive were passed, or stdin is a TTY.
if (process._forceRepl || NativeModule.require('tty').isatty(0)) {
// REPL
var cliRepl = Module.requireRepl();
var cliRepl = NativeModule.require('internal/repl');
cliRepl.createInternalRepl(process.env, function(err, repl) {
if (err) {
throw err;
Expand Down
4 changes: 4 additions & 0 deletions test/parallel/test-repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ function error_test() {
expect: 'undefined\n' + prompt_unix },
{ client: client_unix, send: '/* \'\n"\n\'"\'\n*/',
expect: 'undefined\n' + prompt_unix },
// REPL should get a normal require() function, not one that allows
// access to internal modules without the --expose_internals flag.
{ client: client_unix, send: 'require("internal/repl")',
expect: /^Error: Cannot find module 'internal\/repl'/ },
]);
}

Expand Down
17 changes: 9 additions & 8 deletions test/parallel/test-util-decorate-error-stack.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// Flags: --expose_internals
'use strict';
const common = require('../common');
const assert = require('assert');
const util = require('util');
const internalUtil = require('internal/util');

assert.doesNotThrow(function() {
util.decorateErrorStack();
util.decorateErrorStack(null);
util.decorateErrorStack(1);
util.decorateErrorStack(true);
internalUtil.decorateErrorStack();
internalUtil.decorateErrorStack(null);
internalUtil.decorateErrorStack(1);
internalUtil.decorateErrorStack(true);
});

// Verify that a stack property is not added to non-Errors
const obj = {};
util.decorateErrorStack(obj);
internalUtil.decorateErrorStack(obj);
assert.strictEqual(obj.stack, undefined);

// Verify that the stack is decorated when possible
Expand All @@ -23,13 +24,13 @@ try {
} catch (e) {
err = e;
assert(!/var foo bar;/.test(err.stack));
util.decorateErrorStack(err);
internalUtil.decorateErrorStack(err);
}

assert(/var foo bar;/.test(err.stack));

// Verify that the stack is unchanged when there is no arrow message
err = new Error('foo');
const originalStack = err.stack;
util.decorateErrorStack(err);
internalUtil.decorateErrorStack(err);
assert.strictEqual(originalStack, err.stack);