Merge pull request #2856 from epidemian/issue2849

Fixes #2849: use correct filename and code in require()d sources
This commit is contained in:
Jeremy Ashkenas 2013-06-09 00:40:18 -07:00
commit 13187b0199
6 changed files with 59 additions and 19 deletions

View File

@ -170,14 +170,21 @@
};
loadFile = function(module, filename) {
var answer, raw, stripped;
var answer, err, raw, stripped;
raw = fs.readFileSync(filename, 'utf8');
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
answer = compile(stripped, {
filename: filename,
sourceMap: true,
literate: helpers.isLiterate(filename)
});
try {
answer = compile(stripped, {
filename: filename,
sourceMap: true,
literate: helpers.isLiterate(filename)
});
} catch (_error) {
err = _error;
err.filename = filename;
err.code = stripped;
throw err;
}
sourceMaps[filename] = answer.sourceMap;
return module._compile(answer.js, filename);
};

View File

@ -389,7 +389,7 @@
}
basename = helpers.baseFileName(source, true, useWinPathSep);
srcDir = path.dirname(source);
baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
baseDir = base === '.' || base === './' ? srcDir : srcDir.substring(base.length);
dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
return path.join(dir, basename + extension);
};

View File

@ -199,11 +199,13 @@
throw error;
};
exports.prettyErrorMessage = function(error, fileName, code, useColors) {
exports.prettyErrorMessage = function(error, filename, code, useColors) {
var codeLine, colorize, end, first_column, first_line, last_column, last_line, marker, message, start, _ref1;
if (!error.location) {
return error.stack || ("" + error);
}
filename = error.filename || filename;
code = error.code || code;
_ref1 = error.location, first_line = _ref1.first_line, first_column = _ref1.first_column, last_line = _ref1.last_line, last_column = _ref1.last_column;
codeLine = code.split('\n')[first_line];
start = first_column;
@ -216,7 +218,7 @@
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
marker = colorize(marker);
}
message = "" + fileName + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + error.message + "\n" + codeLine + "\n" + marker;
message = "" + filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + error.message + "\n" + codeLine + "\n" + marker;
return message;
};

View File

@ -146,7 +146,15 @@ exports.eval = (code, options = {}) ->
loadFile = (module, filename) ->
raw = fs.readFileSync filename, 'utf8'
stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
answer = compile(stripped, {filename, sourceMap: true, literate: helpers.isLiterate filename})
try
answer = compile(stripped, {filename, sourceMap: true, 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
# information to error so it can be pretty-printed later.
err.filename = filename
err.code = stripped
throw err
sourceMaps[filename] = answer.sourceMap
module._compile answer.js, filename

View File

@ -146,9 +146,13 @@ exports.throwSyntaxError = (message, location) ->
# Creates a nice error message like, following the "standard" format
# <filename>:<line>:<col>: <message> plus the line with the error and a marker
# showing where the error is.
exports.prettyErrorMessage = (error, fileName, code, useColors) ->
exports.prettyErrorMessage = (error, filename, code, useColors) ->
return error.stack or "#{error}" unless error.location
# Prefer original source file information stored in the error if present.
filename = error.filename or filename
code = error.code or code
{first_line, first_column, last_line, last_column} = error.location
codeLine = code.split('\n')[first_line]
start = first_column
@ -157,15 +161,15 @@ exports.prettyErrorMessage = (error, fileName, code, useColors) ->
marker = repeat(' ', start) + repeat('^', end - start)
if useColors
colorize = (str) -> "\x1B[1;31m#{str}\x1B[0m"
colorize = (str) -> "\x1B[1;31m#{str}\x1B[0m"
codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
marker = colorize marker
marker = colorize marker
message = """
#{fileName}:#{first_line + 1}:#{first_column + 1}: error: #{error.message}
#{codeLine}
#{marker}
"""
#{filename}:#{first_line + 1}:#{first_column + 1}: error: #{error.message}
#{codeLine}
#{marker}
"""
# Uncomment to add stacktrace.
#message += "\n#{error.stack}"

View File

@ -7,7 +7,7 @@
{prettyErrorMessage} = CoffeeScript.helpers
assertErrorFormat = (code, expectedErrorFormat) ->
throws (-> CoffeeScript.compile code), (err) ->
throws (-> CoffeeScript.run code), (err) ->
message = prettyErrorMessage err, 'test.coffee', code
eq expectedErrorFormat, message
yes
@ -41,4 +41,23 @@ test "compiler error formatting", ->
test.coffee:1:14: error: parameter name "eval" is not allowed
evil = (foo, eval, bar) ->
^^^^
'''
'''
fs = require 'fs'
test "#2849: compilation error in a require()d file", ->
# Create a temporary file to require().
ok not fs.existsSync 'test/syntax-error.coffee'
fs.writeFileSync 'test/syntax-error.coffee', 'foo in bar or in baz'
try
assertErrorFormat '''
require './test/syntax-error'
''',
"""
#{__dirname}/syntax-error.coffee:1:15: error: unexpected RELATION
foo in bar or in baz
^^
"""
finally
fs.unlink 'test/syntax-error.coffee'