From b173a377a64fcedd654658cdd8958b3cc76325d3 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Sun, 20 Oct 2013 11:08:13 -0300 Subject: [PATCH] Fixes #3208. You now have to require 'coffee-script/extensions' in order to be able to auto-require CoffeeScript files. --- Cakefile | 1 + lib/coffee-script/coffee-script.js | 78 +++++------------------------- lib/coffee-script/extensions.js | 71 +++++++++++++++++++++++++++ src/coffee-script.coffee | 56 ++------------------- src/extensions.coffee | 51 +++++++++++++++++++ 5 files changed, 138 insertions(+), 119 deletions(-) create mode 100644 lib/coffee-script/extensions.js create mode 100644 src/extensions.coffee diff --git a/Cakefile b/Cakefile index 5973c51d..b62a1be1 100644 --- a/Cakefile +++ b/Cakefile @@ -161,6 +161,7 @@ task 'bench', 'quick benchmark of compilation time', -> # Run the CoffeeScript test suite. runTests = (CoffeeScript) -> + require './lib/coffee-script/extensions' startTime = Date.now() currentFile = null passedTests = 0 diff --git a/lib/coffee-script/coffee-script.js b/lib/coffee-script/coffee-script.js index 7d21c3a8..ff408286 100644 --- a/lib/coffee-script/coffee-script.js +++ b/lib/coffee-script/coffee-script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 1.6.3 (function() { - var Lexer, Module, SourceMap, binary, child_process, compile, compileFile, ext, fileExtensions, findExtension, fork, formatSourcePosition, fs, getSourceMap, helpers, lexer, loadFile, parser, path, sourceMaps, vm, withPrettyErrors, _i, _len, + var Lexer, SourceMap, compile, formatSourcePosition, fs, getSourceMap, helpers, lexer, parser, path, sourceMaps, vm, withPrettyErrors, __hasProp = {}.hasOwnProperty, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; @@ -10,8 +10,6 @@ path = require('path'); - child_process = require('child_process'); - Lexer = require('./lexer').Lexer; parser = require('./parser').parser; @@ -22,7 +20,7 @@ exports.VERSION = '1.6.3'; - fileExtensions = ['.coffee', '.litcoffee', '.coffee.md']; + exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md']; exports.helpers = helpers; @@ -182,8 +180,11 @@ } }; - compileFile = function(filename, sourceMap) { + exports._compileFile = function(filename, sourceMap) { var answer, err, raw, stripped; + if (sourceMap == null) { + sourceMap = false; + } raw = fs.readFileSync(filename, 'utf8'); stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw; try { @@ -199,63 +200,6 @@ return answer; }; - loadFile = function(module, filename) { - var answer; - answer = compileFile(filename, false); - return module._compile(answer, filename); - }; - - if (require.extensions) { - for (_i = 0, _len = fileExtensions.length; _i < _len; _i++) { - ext = fileExtensions[_i]; - require.extensions[ext] = loadFile; - } - Module = require('module'); - findExtension = function(filename) { - var curExtension, extensions; - extensions = path.basename(filename).split('.'); - if (extensions[0] === '') { - extensions.shift(); - } - while (extensions.shift()) { - curExtension = '.' + extensions.join('.'); - if (Module._extensions[curExtension]) { - return curExtension; - } - } - return '.js'; - }; - Module.prototype.load = function(filename) { - var extension; - this.filename = filename; - this.paths = Module._nodeModulePaths(path.dirname(filename)); - extension = findExtension(filename); - Module._extensions[extension](this, filename); - return this.loaded = true; - }; - } - - if (child_process) { - fork = child_process.fork; - binary = require.resolve('../../bin/coffee'); - child_process.fork = function(path, args, options) { - var execPath; - if (args == null) { - args = []; - } - if (options == null) { - options = {}; - } - execPath = helpers.isCoffee(path) ? binary : null; - if (!Array.isArray(args)) { - args = []; - options = args || {}; - } - options.execPath || (options.execPath = execPath); - return fork(path, args, options); - }; - } - lexer = new Lexer; parser.lexer = { @@ -343,10 +287,10 @@ if (sourceMaps[filename]) { return sourceMaps[filename]; } - if (_ref = path != null ? path.extname(filename) : void 0, __indexOf.call(fileExtensions, _ref) < 0) { + if (_ref = path != null ? path.extname(filename) : void 0, __indexOf.call(exports.FILE_EXTENSIONS, _ref) < 0) { return; } - answer = compileFile(filename, true); + answer = exports._compileFile(filename, true); return sourceMaps[filename] = answer.sourceMap; }; @@ -365,10 +309,10 @@ } }; frames = (function() { - var _j, _len1, _results; + var _i, _len, _results; _results = []; - for (_j = 0, _len1 = stack.length; _j < _len1; _j++) { - frame = stack[_j]; + for (_i = 0, _len = stack.length; _i < _len; _i++) { + frame = stack[_i]; if (frame.getFunction() === exports.run) { break; } diff --git a/lib/coffee-script/extensions.js b/lib/coffee-script/extensions.js new file mode 100644 index 00000000..35a18854 --- /dev/null +++ b/lib/coffee-script/extensions.js @@ -0,0 +1,71 @@ +// Generated by CoffeeScript 1.6.3 +(function() { + var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, helpers, loadFile, path, _i, _len, _ref; + + CoffeeScript = require('./coffee-script'); + + child_process = require('child_process'); + + helpers = require('./helpers'); + + path = require('path'); + + loadFile = function(module, filename) { + var answer; + answer = CoffeeScript._compileFile(filename, false); + return module._compile(answer, filename); + }; + + if (require.extensions) { + _ref = CoffeeScript.FILE_EXTENSIONS; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + ext = _ref[_i]; + require.extensions[ext] = loadFile; + } + Module = require('module'); + findExtension = function(filename) { + var curExtension, extensions; + extensions = path.basename(filename).split('.'); + if (extensions[0] === '') { + extensions.shift(); + } + while (extensions.shift()) { + curExtension = '.' + extensions.join('.'); + if (Module._extensions[curExtension]) { + return curExtension; + } + } + return '.js'; + }; + Module.prototype.load = function(filename) { + var extension; + this.filename = filename; + this.paths = Module._nodeModulePaths(path.dirname(filename)); + extension = findExtension(filename); + Module._extensions[extension](this, filename); + return this.loaded = true; + }; + } + + if (child_process) { + fork = child_process.fork; + binary = require.resolve('../../bin/coffee'); + child_process.fork = function(path, args, options) { + var execPath; + if (args == null) { + args = []; + } + if (options == null) { + options = {}; + } + execPath = helpers.isCoffee(path) ? binary : null; + if (!Array.isArray(args)) { + args = []; + options = args || {}; + } + options.execPath || (options.execPath = execPath); + return fork(path, args, options); + }; + } + +}).call(this); diff --git a/src/coffee-script.coffee b/src/coffee-script.coffee index c0867afc..5a5833ea 100644 --- a/src/coffee-script.coffee +++ b/src/coffee-script.coffee @@ -6,7 +6,6 @@ fs = require 'fs' vm = require 'vm' path = require 'path' -child_process = require 'child_process' {Lexer} = require './lexer' {parser} = require './parser' helpers = require './helpers' @@ -15,7 +14,7 @@ SourceMap = require './sourcemap' # The current CoffeeScript version number. exports.VERSION = '1.6.3' -fileExtensions = ['.coffee', '.litcoffee', '.coffee.md'] +exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md'] # Expose helpers for testing. exports.helpers = helpers @@ -152,7 +151,7 @@ exports.eval = (code, options = {}) -> else vm.runInContext js, sandbox -compileFile = (filename, sourceMap) -> +exports._compileFile = (filename, sourceMap = no) -> raw = fs.readFileSync filename, 'utf8' stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw @@ -166,53 +165,6 @@ compileFile = (filename, sourceMap) -> answer -# Load and run a CoffeeScript file for Node, stripping any `BOM`s. -loadFile = (module, filename) -> - answer = compileFile filename, false - module._compile answer, filename - -# If the installed version of Node supports `require.extensions`, register -# CoffeeScript as an extension. -if require.extensions - for ext in fileExtensions - require.extensions[ext] = loadFile - - # Patch Node's module loader to be able to handle mult-dot extensions. - # This is a horrible thing that should not be required. Perhaps, one day, - # when a truly benevolent dictator comes to rule over the Republik of Node, - # it won't be. - Module = require 'module' - - findExtension = (filename) -> - extensions = path.basename(filename).split '.' - # Remove the initial dot from dotfiles. - extensions.shift() if extensions[0] is '' - # Start with the longest possible extension and work our way shortwards. - while extensions.shift() - curExtension = '.' + extensions.join '.' - return curExtension if Module._extensions[curExtension] - '.js' - - Module::load = (filename) -> - @filename = filename - @paths = Module._nodeModulePaths path.dirname filename - extension = findExtension filename - Module._extensions[extension](this, filename) - @loaded = true - -# If we're on Node, patch `child_process.fork` so that Coffee scripts are able -# to fork both CoffeeScript files, and JavaScript files, directly. -if child_process - {fork} = child_process - binary = require.resolve '../../bin/coffee' - child_process.fork = (path, args = [], options = {}) -> - execPath = if helpers.isCoffee(path) then binary else null - if not Array.isArray args - args = [] - options = args or {} - options.execPath or= execPath - fork path, args, options - # Instantiate a Lexer for our use here. lexer = new Lexer @@ -305,8 +257,8 @@ sourceMaps = {} # Generates the source map for a coffee file and stores it in the local cache variable. getSourceMap = (filename) -> return sourceMaps[filename] if sourceMaps[filename] - return unless path?.extname(filename) in fileExtensions - answer = compileFile filename, true + return unless path?.extname(filename) in exports.FILE_EXTENSIONS + answer = exports._compileFile filename, true sourceMaps[filename] = answer.sourceMap # Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p) diff --git a/src/extensions.coffee b/src/extensions.coffee new file mode 100644 index 00000000..1eee64e7 --- /dev/null +++ b/src/extensions.coffee @@ -0,0 +1,51 @@ +CoffeeScript = require './coffee-script' +child_process = require 'child_process' +helpers = require './helpers' +path = require 'path' + +# Load and run a CoffeeScript file for Node, stripping any `BOM`s. +loadFile = (module, filename) -> + answer = CoffeeScript._compileFile filename, false + module._compile answer, filename + +# If the installed version of Node supports `require.extensions`, register +# CoffeeScript as an extension. +if require.extensions + for ext in CoffeeScript.FILE_EXTENSIONS + require.extensions[ext] = loadFile + + # Patch Node's module loader to be able to handle mult-dot extensions. + # This is a horrible thing that should not be required. Perhaps, one day, + # when a truly benevolent dictator comes to rule over the Republik of Node, + # it won't be. + Module = require 'module' + + findExtension = (filename) -> + extensions = path.basename(filename).split '.' + # Remove the initial dot from dotfiles. + extensions.shift() if extensions[0] is '' + # Start with the longest possible extension and work our way shortwards. + while extensions.shift() + curExtension = '.' + extensions.join '.' + return curExtension if Module._extensions[curExtension] + '.js' + + Module::load = (filename) -> + @filename = filename + @paths = Module._nodeModulePaths path.dirname filename + extension = findExtension filename + Module._extensions[extension](this, filename) + @loaded = true + +# If we're on Node, patch `child_process.fork` so that Coffee scripts are able +# to fork both CoffeeScript files, and JavaScript files, directly. +if child_process + {fork} = child_process + binary = require.resolve '../../bin/coffee' + child_process.fork = (path, args = [], options = {}) -> + execPath = if helpers.isCoffee(path) then binary else null + if not Array.isArray args + args = [] + options = args or {} + options.execPath or= execPath + fork path, args, options \ No newline at end of file