1
0
Fork 0
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:
Alex Gorbatchev 2013-06-13 12:54:20 -07:00
parent cc3b4e8080
commit 3d761e73e3
2 changed files with 48 additions and 49 deletions

View file

@ -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"

View file

@ -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", ->