Skip to content

Commit 3108244

Browse files
Fix stack trace (#4428)
* Revert aee27fb * Patch Jison’s output so that it requires `fs` only if we’re truly in a CommonJS/Node environment, not a browser environment that may happen to have globals named `require` and `exports` (as would be the case if require.js is being used). Fixes #4391. * Temporary fix for exceptions getting thrown when trying to generate a stack trace for a file that has been deleted since compilation; fixes #3890, but not well. A better solution would not try to recompile the file when trying to retrieve its stack trace. * Save the test REPL history in the system temp folder, not in the CoffeeScript project folder * Rewrite `getSourceMap` to never read a file from disk, and therefore not throw IO-related exceptions; source maps are either retrieved from memory, or the related source code is retrieved from memory to generate a new source map. Fixes #3890 the proper way. * Add test to verify that stack traces reference the correct line number. Closes #4418. * Get the parser working in the browser compiler again; rather than detecting a CommonJS environment generally, just check for `fs` before trying to use it * Follow Node’s standard of 4-space indentation of stack trace data * Better .gitignore * Fix caching of compiled code and source maps; add more tests to verify correct line numbers in stack traces * Better fallback value for the parser source * Fix the stack traces and tests when running in a browser * Update the browser compiler so that @murrayju doesn’t have any extra work to do to test this branch
1 parent d0ed2de commit 3108244

File tree

9 files changed

+733
-369
lines changed

9 files changed

+733
-369
lines changed

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
raw
22
presentation
33
test.coffee
4+
test*.coffee
45
test.litcoffee
5-
parser.output
6+
test*.litcoffee
67
test/*.js
8+
parser.output
79
/node_modules
8-
npm-debug.log
10+
npm-debug.log*

Cakefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,15 @@ task 'build:full', 'rebuild the source twice, and run the tests', ->
8585
task 'build:parser', 'rebuild the Jison parser (run build first)', ->
8686
helpers.extend global, require 'util'
8787
require 'jison'
88-
parser = require('./lib/coffee-script/grammar').parser
89-
fs.writeFileSync 'lib/coffee-script/parser.js', parser.generate()
88+
parser = require('./lib/coffee-script/grammar').parser.generate()
89+
# Patch Jison’s output, until https://github.com/zaach/jison/pull/339 is accepted,
90+
# to ensure that require('fs') is only called where it exists.
91+
parser = parser.replace "var source = require('fs')", """
92+
var source = '';
93+
var fs = require('fs');
94+
if (typeof fs !== 'undefined' && fs !== null)
95+
source = fs"""
96+
fs.writeFileSync 'lib/coffee-script/parser.js', parser
9097

9198

9299
task 'build:browser', 'rebuild the merged script for inclusion in the browser', ->

docs/v1/browser-compiler/coffee-script.js

Lines changed: 346 additions & 344 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/v1/test.html

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,6 +2882,16 @@ <h1>CoffeeScript Test Suite</h1>
28822882
obj.method()
28832883
eq obj.item, 3
28842884

2885+
test "#4411: Allow @values as loop indices", ->
2886+
obj =
2887+
index: null
2888+
get: -> @index
2889+
method: ->
2890+
@get() for _, @index in [1, 2, 3]
2891+
eq obj.index, null
2892+
arrayEq obj.method(), [0, 1, 2]
2893+
eq obj.index, 3
2894+
28852895
test "#2525, #1187, #1208, #1758, looping over an array forwards", ->
28862896
list = [0, 1, 2, 3, 4]
28872897

@@ -3470,9 +3480,21 @@ <h1>CoffeeScript Test Suite</h1>
34703480

34713481

34723482
if require?
3483+
os = require 'os'
34733484
fs = require 'fs'
34743485
path = require 'path'
34753486

3487+
test "patchStackTrace line patching", ->
3488+
err = new Error 'error'
3489+
ok err.stack.match /test[\/\\]error_messages\.coffee:\d+:\d+\b/
3490+
3491+
test "patchStackTrace stack prelude consistent with V8", ->
3492+
err = new Error
3493+
ok err.stack.match /^Error\n/ # Notice no colon when no message.
3494+
3495+
err = new Error 'error'
3496+
ok err.stack.match /^Error: error\n/
3497+
34763498
test "#2849: compilation error in a require()d file", ->
34773499
# Create a temporary file to require().
34783500
ok not fs.existsSync 'test/syntax-error.coffee'
@@ -3490,6 +3512,57 @@ <h1>CoffeeScript Test Suite</h1>
34903512
finally
34913513
fs.unlinkSync 'test/syntax-error.coffee'
34923514

3515+
test "#3890 Error.prepareStackTrace doesn't throw an error if a compiled file is deleted", ->
3516+
# Adapted from https://github.com/atom/coffee-cash/blob/master/spec/coffee-cash-spec.coffee
3517+
filePath = path.join os.tmpdir(), 'PrepareStackTraceTestFile.coffee'
3518+
fs.writeFileSync filePath, "module.exports = -> throw new Error('hello world')"
3519+
throwsAnError = require filePath
3520+
fs.unlinkSync filePath
3521+
3522+
try
3523+
throwsAnError()
3524+
catch error
3525+
3526+
eq error.message, 'hello world'
3527+
doesNotThrow(-> error.stack)
3528+
notEqual error.stack.toString().indexOf(filePath), -1
3529+
3530+
test "#4418 stack traces for compiled files reference the correct line number", ->
3531+
filePath = path.join os.tmpdir(), 'StackTraceLineNumberTestFile.coffee'
3532+
fileContents = """
3533+
testCompiledFileStackTraceLineNumber = ->
3534+
# `a` on the next line is undefined and should throw a ReferenceError
3535+
console.log a if true
3536+
3537+
do testCompiledFileStackTraceLineNumber
3538+
"""
3539+
fs.writeFileSync filePath, fileContents
3540+
3541+
try
3542+
require filePath
3543+
catch error
3544+
fs.unlinkSync filePath
3545+
3546+
# Make sure the line number reported is line 3 (the original Coffee source)
3547+
# and not line 6 (the generated JavaScript).
3548+
eq /StackTraceLineNumberTestFile.coffee:(\d)/.exec(error.stack.toString())[1], '3'
3549+
3550+
3551+
test "#4418 stack traces for compiled strings reference the correct line number", ->
3552+
try
3553+
CoffeeScript.run """
3554+
testCompiledStringStackTraceLineNumber = ->
3555+
# `a` on the next line is undefined and should throw a ReferenceError
3556+
console.log a if true
3557+
3558+
do testCompiledStringStackTraceLineNumber
3559+
"""
3560+
catch error
3561+
3562+
# Make sure the line number reported is line 3 (the original Coffee source)
3563+
# and not line 6 (the generated JavaScript).
3564+
eq /at testCompiledStringStackTraceLineNumber.*:(\d):/.exec(error.stack.toString())[1], '3'
3565+
34933566

34943567
test "#1096: unexpected generated tokens", ->
34953568
# Implicit ends
@@ -3844,7 +3917,7 @@ <h1>CoffeeScript Test Suite</h1>
38443917
assertErrorFormat '''
38453918
///a \\u002 0 space///
38463919
''', '''
3847-
[stdin]:1:6: error: invalid escape sequence \\u002
3920+
[stdin]:1:6: error: invalid escape sequence \\u002 \n\
38483921
///a \\u002 0 space///
38493922
^\^^^^^
38503923
'''
@@ -4596,6 +4669,13 @@ <h1>CoffeeScript Test Suite</h1>
45964669
^
45974670
'''
45984671

4672+
test "can't use pattern matches for loop indices", ->
4673+
assertErrorFormat 'a for b, {c} in d', '''
4674+
[stdin]:1:10: error: index cannot be a pattern matching expression
4675+
a for b, {c} in d
4676+
^^^
4677+
'''
4678+
45994679
</script>
46004680
<script type="text/x-coffeescript" class="test" id="eval">
46014681
if vm = require? 'vm'
@@ -9227,7 +9307,7 @@ <h1>CoffeeScript Test Suite</h1>
92279307
92289308
test "floor division operator compound assignment", ->
92299309
a = 7
9230-
a //= 2
9310+
a //= 1 + 1
92319311
eq 3, a
92329312
92339313
test "modulo operator", ->
@@ -9823,7 +9903,9 @@ <h1>CoffeeScript Test Suite</h1>
98239903
<script type="text/x-coffeescript" class="test" id="repl">
98249904
return if global.testingBrowser
98259905

9906+
os = require 'os'
98269907
fs = require 'fs'
9908+
path = require 'path'
98279909

98289910
# REPL
98299911
# ----
@@ -9851,7 +9933,7 @@ <h1>CoffeeScript Test Suite</h1>
98519933
@written[@written.length - 1 + fromEnd].replace /\r?\n$/, ''
98529934

98539935
# Create a dummy history file
9854-
historyFile = '.coffee_history_test'
9936+
historyFile = path.join os.tmpdir(), '.coffee_history_test'
98559937
fs.writeFileSync historyFile, '1 + 2\n'
98569938

98579939
testRepl = (desc, fn) ->

lib/coffee-script/coffee-script.js

Lines changed: 106 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/coffee-script/parser.js

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)