1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

Fixes #1035, #1425, and #1444: (another) overhaul of REPL and

CoffeeScript.eval. Instead of writing about all the changes and why I
made those decisions, I'll just answer any questions in the commit
comments, so add a commit comment if you want to question anything.
Thanks to @TrevorBurnham and @satyr for their help/contributions. Also,
closes #1487. And still no REPL tests...
This commit is contained in:
Michael Ficarra 2011-07-06 03:54:36 -04:00
parent 18ab569b2d
commit fff4c9c672
4 changed files with 77 additions and 55 deletions

View file

@ -1,8 +1,10 @@
(function() {
var Lexer, RESERVED, compile, fs, lexer, parser, path, vm, _ref;
var Lexer, Module, RESERVED, Script, compile, fs, lexer, parser, path, _ref;
var __hasProp = Object.prototype.hasOwnProperty;
fs = require('fs');
path = require('path');
vm = require('vm');
Script = require('vm').Script;
Module = require('module');
_ref = require('./lexer'), Lexer = _ref.Lexer, RESERVED = _ref.RESERVED;
parser = require('./parser').parser;
if (require.extensions) {
@ -45,7 +47,7 @@
}
};
exports.run = function(code, options) {
var Module, mainModule;
var mainModule;
mainModule = require.main;
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
mainModule.moduleCache && (mainModule.moduleCache = {});
@ -60,39 +62,59 @@
}
};
exports.eval = function(code, options) {
var g, js, k, o, sandbox, v, _i, _len, _ref2;
var js, k, o, r, sandbox, v, _, _i, _len, _module, _ref2, _ref3, _require;
if (options == null) {
options = {};
}
if (!(code = code.trim())) {
return;
}
sandbox = options.sandbox;
if (!sandbox) {
sandbox = {
require: require,
module: {
exports: {}
sandbox = Script.createContext();
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
if (options.sandbox != null) {
if (options.sandbox instanceof sandbox.constructor) {
sandbox = options.sandbox;
} else {
_ref2 = options.sandbox;
for (k in _ref2) {
if (!__hasProp.call(_ref2, k)) continue;
v = _ref2[k];
sandbox[k] = v;
}
};
_ref2 = Object.getOwnPropertyNames(global);
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
g = _ref2[_i];
sandbox[g] = global[g];
}
sandbox.global = sandbox;
sandbox.global.global = sandbox.global.root = sandbox.global.GLOBAL = sandbox;
}
sandbox.__filename = options.filename || 'eval';
sandbox.__dirname = path.dirname(sandbox.__filename);
if (!(sandbox.module || sandbox.require)) {
Module = require('module');
sandbox.module = _module = new Module(options.modulename || 'eval');
sandbox.require = _require = function(path) {
return Module._load(path, _module);
};
_module.filename = sandbox.__filename;
_ref3 = Object.getOwnPropertyNames(require);
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
r = _ref3[_i];
_require[r] = require[r];
}
_require.paths = _module.paths = Module._nodeModulePaths(process.cwd());
_require.resolve = function(request) {
return Module._resolveFilename(request, _module);
};
}
o = {};
for (k in options) {
if (!__hasProp.call(options, k)) continue;
v = options[k];
o[k] = v;
}
o.bare = true;
js = compile("_=(" + code + "\n)", o);
return vm.runInNewContext(js, sandbox, sandbox.__filename);
js = compile("(" + code + "\n)", o);
_ = Script.runInContext(js, sandbox);
if (_ != null) {
sandbox._ = _;
}
return _;
};
lexer = new Lexer;
parser.lexer = {

View file

@ -1,10 +1,11 @@
(function() {
var ACCESSOR, CoffeeScript, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, getCompletions, getPropertyNames, inspect, readline, repl, run, stdin, stdout;
var ACCESSOR, CoffeeScript, Module, SIMPLEVAR, Script, autocomplete, backlog, completeAttribute, completeVariable, enableColours, error, getCompletions, getPropertyNames, inspect, readline, repl, run, stdin, stdout;
var __hasProp = Object.prototype.hasOwnProperty;
CoffeeScript = require('./coffee-script');
readline = require('readline');
inspect = require('util').inspect;
Script = require('vm').Script;
Module = require('module');
enableColours = false;
if (process.platform !== 'win32') {
enableColours = !process.env.NODE_DISABLE_COLORS;
@ -16,20 +17,9 @@
};
backlog = '';
run = (function() {
var g, sandbox, _i, _len, _ref;
sandbox = {
require: require,
module: {
exports: {}
}
};
_ref = Object.getOwnPropertyNames(global);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
g = _ref[_i];
sandbox[g] = global[g];
}
sandbox.global = sandbox;
sandbox.global.global = sandbox.global.root = sandbox.global.GLOBAL = sandbox;
var sandbox;
sandbox = Script.createContext();
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox;
return function(buffer) {
var code, val;
code = backlog += '\n' + buffer.toString();
@ -40,8 +30,8 @@
try {
val = CoffeeScript.eval(code, {
sandbox: sandbox,
bare: true,
filename: 'repl'
filename: 'repl',
modulename: 'repl'
});
if (val !== void 0) {
process.stdout.write(inspect(val, false, 2, enableColours) + '\n');

View file

@ -8,7 +8,8 @@
fs = require 'fs'
path = require 'path'
vm = require 'vm'
{Script} = require 'vm'
Module = require 'module'
{Lexer,RESERVED} = require './lexer'
{parser} = require './parser'
@ -78,20 +79,32 @@ exports.run = (code, options) ->
# The CoffeeScript REPL uses this to run the input.
exports.eval = (code, options = {}) ->
return unless code = code.trim()
sandbox = options.sandbox
unless sandbox
sandbox =
require: require
module : { exports: {} }
sandbox[g] = global[g] for g in Object.getOwnPropertyNames global
sandbox.global = sandbox
sandbox.global.global = sandbox.global.root = sandbox.global.GLOBAL = sandbox
sandbox = Script.createContext()
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
if options.sandbox?
if options.sandbox instanceof sandbox.constructor
sandbox = options.sandbox
else
sandbox[k] = v for own k, v of options.sandbox
sandbox.__filename = options.filename || 'eval'
sandbox.__dirname = path.dirname sandbox.__filename
o = {}; o[k] = v for k, v of options
# define module/require only if they chose not to specify their own
unless sandbox.module or sandbox.require
Module = require 'module'
sandbox.module = _module = new Module(options.modulename || 'eval')
sandbox.require = _require = (path) -> Module._load path, _module
_module.filename = sandbox.__filename
_require[r] = require[r] for r in Object.getOwnPropertyNames require
# use the same hack node currently uses for their own REPL
_require.paths = _module.paths = Module._nodeModulePaths process.cwd()
_require.resolve = (request) -> Module._resolveFilename request, _module
o = {}
o[k] = v for own k, v of options
o.bare = on # ensure return value
js = compile "_=(#{code}\n)", o
vm.runInNewContext js, sandbox, sandbox.__filename
js = compile "(#{code}\n)", o
_ = Script.runInContext js, sandbox
sandbox._ = _ if _?
_
# Instantiate a Lexer for our use here.
lexer = new Lexer

View file

@ -9,6 +9,7 @@ CoffeeScript = require './coffee-script'
readline = require 'readline'
{inspect} = require 'util'
{Script} = require 'vm'
Module = require 'module'
# REPL Setup
@ -32,12 +33,8 @@ backlog = ''
# Attempt to evaluate the command. If there's an exception, print it out instead
# of exiting.
run = do ->
sandbox =
require: require
module : { exports: {} }
sandbox[g] = global[g] for g in Object.getOwnPropertyNames global
sandbox.global = sandbox
sandbox.global.global = sandbox.global.root = sandbox.global.GLOBAL = sandbox
sandbox = Script.createContext()
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
(buffer) ->
code = backlog += '\n' + buffer.toString()
if code[code.length - 1] is '\\'
@ -46,8 +43,8 @@ run = do ->
try
val = CoffeeScript.eval code, {
sandbox,
bare: on,
filename: 'repl'
modulename: 'repl'
}
unless val is undefined
process.stdout.write inspect(val, no, 2, enableColours) + '\n'