mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Removed unnecessary source map generation during require()
and made stack line number patching on by default.
This commit is contained in:
parent
cc3b4e8080
commit
3d761e73e3
2 changed files with 48 additions and 49 deletions
|
@ -15,6 +15,8 @@ SourceMap = require './sourcemap'
|
|||
# The current CoffeeScript version number.
|
||||
exports.VERSION = '1.6.3'
|
||||
|
||||
extensions = ['.coffee', '.litcoffee', '.coffee.md']
|
||||
|
||||
# Expose helpers for testing.
|
||||
exports.helpers = helpers
|
||||
|
||||
|
@ -84,7 +86,7 @@ exports.nodes = (source, options) ->
|
|||
# setting `__filename`, `__dirname`, and relative `require()`.
|
||||
exports.run = (code, options = {}) ->
|
||||
mainModule = require.main
|
||||
options.sourceMap ?= true
|
||||
|
||||
# Set the filename.
|
||||
mainModule.filename = process.argv[1] =
|
||||
if options.filename then fs.realpathSync(options.filename) else '.'
|
||||
|
@ -97,14 +99,10 @@ exports.run = (code, options = {}) ->
|
|||
|
||||
# Compile.
|
||||
if not helpers.isCoffee(mainModule.filename) or require.extensions
|
||||
answer = compile(code, options)
|
||||
# Attach sourceMap object to sourceMaps[options.filename] so that
|
||||
# it is accessible by Error.prepareStackTrace.
|
||||
do patchStackTrace
|
||||
sourceMaps[mainModule.filename] = answer.sourceMap
|
||||
mainModule._compile answer.js, mainModule.filename
|
||||
else
|
||||
mainModule._compile code, mainModule.filename
|
||||
answer = compile code, options
|
||||
code = answer.js? and answer.js or answer
|
||||
|
||||
mainModule._compile code, mainModule.filename
|
||||
|
||||
# Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
|
||||
# The CoffeeScript REPL uses this to run the input.
|
||||
|
@ -142,12 +140,12 @@ exports.eval = (code, options = {}) ->
|
|||
else
|
||||
vm.runInContext js, sandbox
|
||||
|
||||
# Load and run a CoffeeScript file for Node, stripping any `BOM`s.
|
||||
loadFile = (module, filename) ->
|
||||
compileFile = (filename, sourceMap) ->
|
||||
raw = fs.readFileSync filename, 'utf8'
|
||||
stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
|
||||
|
||||
try
|
||||
answer = compile(stripped, {filename, sourceMap: true, literate: helpers.isLiterate filename})
|
||||
answer = compile(stripped, {filename, sourceMap, literate: helpers.isLiterate filename})
|
||||
catch err
|
||||
# As the filename and code of a dynamically loaded file will be different
|
||||
# from the original file compiled with CoffeeScript.run, add that
|
||||
|
@ -155,13 +153,18 @@ loadFile = (module, filename) ->
|
|||
err.filename = filename
|
||||
err.code = stripped
|
||||
throw err
|
||||
sourceMaps[filename] = answer.sourceMap
|
||||
module._compile answer.js, filename
|
||||
|
||||
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 ['.coffee', '.litcoffee', '.coffee.md']
|
||||
for ext in extensions
|
||||
require.extensions[ext] = loadFile
|
||||
|
||||
# Patch Node's module loader to be able to handle mult-dot extensions.
|
||||
|
@ -219,7 +222,6 @@ parser.lexer =
|
|||
@pos = 0
|
||||
upcomingInput: ->
|
||||
""
|
||||
|
||||
# Make all the AST nodes visible to the parser.
|
||||
parser.yy = require './nodes'
|
||||
|
||||
|
@ -233,38 +235,6 @@ parser.yy.parseError = (message, {token}) ->
|
|||
# from the lexer.
|
||||
helpers.throwSyntaxError message, parser.lexer.yylloc
|
||||
|
||||
# Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p)
|
||||
# NodeJS / V8 have no support for transforming positions in stack traces using
|
||||
# sourceMap, so we must monkey-patch Error to display CoffeeScript source
|
||||
# positions.
|
||||
|
||||
patched = false
|
||||
|
||||
# Map of filenames -> sourceMap object.
|
||||
sourceMaps = {}
|
||||
|
||||
patchStackTrace = ->
|
||||
return if patched
|
||||
patched = true
|
||||
|
||||
# (Assigning to a property of the Module object in the normal module cache is
|
||||
# unsuitable, because node deletes those objects from the cache if an
|
||||
# exception is thrown in the module body.)
|
||||
|
||||
Error.prepareStackTrace = (err, stack) ->
|
||||
sourceFiles = {}
|
||||
|
||||
getSourceMapping = (filename, line, column) ->
|
||||
sourceMap = sourceMaps[filename]
|
||||
answer = sourceMap.sourceLocation [line - 1, column - 1] if sourceMap
|
||||
if answer then [answer[0] + 1, answer[1] + 1] else null
|
||||
|
||||
frames = for frame in stack
|
||||
break if frame.getFunction() is exports.run
|
||||
" at #{formatSourcePosition frame, getSourceMapping}"
|
||||
|
||||
"#{err.name}: #{err.message ? ''}\n#{frames.join '\n'}\n"
|
||||
|
||||
# Based on http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js
|
||||
# Modified to handle sourceMap
|
||||
formatSourcePosition = (frame, getSourceMapping) ->
|
||||
|
@ -293,7 +263,6 @@ formatSourcePosition = (frame, getSourceMapping) ->
|
|||
else
|
||||
"#{fileName}:#{line}:#{column}"
|
||||
|
||||
|
||||
functionName = frame.getFunctionName()
|
||||
isConstructor = frame.isConstructor()
|
||||
isMethodCall = not (frame.isToplevel() or isConstructor)
|
||||
|
@ -319,3 +288,29 @@ formatSourcePosition = (frame, getSourceMapping) ->
|
|||
else
|
||||
fileLocation
|
||||
|
||||
# Map of filenames -> sourceMap object.
|
||||
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 extensions
|
||||
answer = compileFile filename, true
|
||||
sourceMaps[filename] = answer.sourceMap
|
||||
|
||||
# Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p)
|
||||
# NodeJS / V8 have no support for transforming positions in stack traces using
|
||||
# sourceMap, so we must monkey-patch Error to display CoffeeScript source
|
||||
# positions.
|
||||
Error.prepareStackTrace = (err, stack) ->
|
||||
getSourceMapping = (filename, line, column) ->
|
||||
sourceMap = getSourceMap filename
|
||||
answer = sourceMap.sourceLocation [line - 1, column - 1] if sourceMap
|
||||
if answer then [answer[0] + 1, answer[1] + 1] else null
|
||||
|
||||
frames = for frame in stack
|
||||
break if frame.getFunction() is exports.run
|
||||
" at #{formatSourcePosition frame, getSourceMapping}"
|
||||
|
||||
"#{err.name}: #{err.message ? ''}\n#{frames.join '\n'}\n"
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ test "compiler error formatting", ->
|
|||
^^^^
|
||||
'''
|
||||
|
||||
test "patchStackTrace line patching", ->
|
||||
err = new Error 'error'
|
||||
ok err.stack.indexOf('test/error_messages.coffee:47:4') >= 0 # should be fixed to the correct line if more lines added to this file
|
||||
|
||||
fs = require 'fs'
|
||||
|
||||
test "#2849: compilation error in a require()d file", ->
|
||||
|
|
Loading…
Reference in a new issue