@@ -159,7 +159,7 @@ <h1>coffeescript.coffee</h1>
159159
160160 < div class ="content "> < div class ='highlight '> < pre > exports.VERSION = packageJson.version
161161
162- exports.FILE_EXTENSIONS = [< span class ="hljs-string "> '.coffee'</ span > , < span class ="hljs-string "> '.litcoffee'</ span > , < span class ="hljs-string "> '.coffee.md'</ span > ]</ pre > </ div > </ div >
162+ exports.FILE_EXTENSIONS = FILE_EXTENSIONS = [< span class ="hljs-string "> '.coffee'</ span > , < span class ="hljs-string "> '.litcoffee'</ span > , < span class ="hljs-string "> '.coffee.md'</ span > ]</ pre > </ div > </ div >
163163
164164 </ li >
165165
@@ -252,7 +252,7 @@ <h1>coffeescript.coffee</h1>
252252a stack trace. Assuming that most of the time, code isn’t throwing
253253exceptions, it’s probably more efficient to compile twice only when we
254254need a stack trace, rather than always generating a source map even when
255- it’s not likely to be used. Save in form of < code > filename</ code > : < code > (source)</ code > </ p >
255+ it’s not likely to be used. Save in form of < code > filename</ code > : [ < code > (source)</ code > ] </ p >
256256
257257 </ div >
258258
@@ -267,7 +267,7 @@ <h1>coffeescript.coffee</h1>
267267 < div class ="pilwrap ">
268268 < a class ="pilcrow " href ="#section-9 "> ¶</ a >
269269 </ div >
270- < p > Also save source maps if generated, in form of < code > filename </ code > : < code > (source map)</ code > .</ p >
270+ < p > Also save source maps if generated, in form of < code > (source) </ code > : [ < code > (source map)</ code > ] .</ p >
271271
272272 </ div >
273273
@@ -317,7 +317,8 @@ <h1>coffeescript.coffee</h1>
317317
318318 checkShebangLine filename, code
319319
320- sources[filename] = code
320+ sources[filename] ?= []
321+ sources[filename].push code
321322 map = < span class ="hljs-keyword "> new</ span > SourceMap < span class ="hljs-keyword "> if</ span > generateSourceMap
322323
323324 tokens = lexer.tokenize code, options</ pre > </ div > </ div >
@@ -428,8 +429,9 @@ <h1>coffeescript.coffee</h1>
428429 js = < span class ="hljs-string "> "// < span class ="hljs-subst "> #{header}</ span > \n< span class ="hljs-subst "> #{js}</ span > "</ span >
429430
430431 < span class ="hljs-keyword "> if</ span > generateSourceMap
431- v3SourceMap = map.generate(options, code)
432- sourceMaps[filename] = map
432+ v3SourceMap = map.generate options, code
433+ sourceMaps[filename] ?= []
434+ sourceMaps[filename].push map
433435
434436 < span class ="hljs-keyword "> if</ span > options.inlineMap
435437 encoded = base64encode JSON.stringify v3SourceMap
@@ -701,9 +703,7 @@ <h1>coffeescript.coffee</h1>
701703 < span class ="hljs-keyword "> else</ span >
702704 fileLocation
703705< span class ="hljs-function ">
704- < span class ="hljs-title "> getSourceMap</ span > = < span class ="hljs-params "> (filename)</ span > -></ span >
705- < span class ="hljs-keyword "> if</ span > sourceMaps[filename]?
706- sourceMaps[filename]</ pre > </ div > </ div >
706+ < span class ="hljs-title "> getSourceMap</ span > = < span class ="hljs-params "> (filename, line, column)</ span > -></ span > </ pre > </ div > </ div >
707707
708708 </ li >
709709
@@ -714,16 +714,76 @@ <h1>coffeescript.coffee</h1>
714714 < div class ="pilwrap ">
715715 < a class ="pilcrow " href ="#section-28 "> ¶</ a >
716716 </ div >
717- < p > CoffeeScript compiled in a browser may get compiled with < code > options.filename</ code >
718- of < code > <anonymous></ code > , but the browser may request the stack trace with the
719- filename of the script file.</ p >
717+ < p > Skip files that we didn’t compile, like Node system files that appear in
718+ the stack trace, as they never have source maps.</ p >
720719
721720 </ div >
722721
723- < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> else</ span > < span class ="hljs-keyword "> if</ span > sourceMaps[< span class ="hljs-string "> '<anonymous>'</ span > ]?
724- sourceMaps[< span class ="hljs-string "> '<anonymous>'</ span > ]
725- < span class ="hljs-keyword "> else</ span > < span class ="hljs-keyword "> if</ span > sources[filename]?
726- answer = compile sources[filename],
722+ < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> return</ span > < span class ="hljs-literal "> null</ span > < span class ="hljs-keyword "> unless</ span > filename < span class ="hljs-keyword "> is</ span > < span class ="hljs-string "> '<anonymous>'</ span > < span class ="hljs-keyword "> or</ span > filename.slice(filename.lastIndexOf(< span class ="hljs-string "> '.'</ span > )) < span class ="hljs-keyword "> in</ span > FILE_EXTENSIONS
723+
724+ < span class ="hljs-keyword "> if</ span > filename < span class ="hljs-keyword "> isnt</ span > < span class ="hljs-string "> '<anonymous>'</ span > < span class ="hljs-keyword "> and</ span > sourceMaps[filename]?
725+ < span class ="hljs-keyword "> return</ span > sourceMaps[filename][sourceMaps[filename].length - < span class ="hljs-number "> 1</ span > ]</ pre > </ div > </ div >
726+
727+ </ li >
728+
729+
730+ < li id ="section-29 ">
731+ < div class ="annotation ">
732+
733+ < div class ="pilwrap ">
734+ < a class ="pilcrow " href ="#section-29 "> ¶</ a >
735+ </ div >
736+ < p > CoffeeScript compiled in a browser or via < code > CoffeeScript.compile</ code > or < code > .run</ code >
737+ may get compiled with < code > options.filename</ code > that’s missing, which becomes
738+ < code > <anonymous></ code > ; but the runtime might request the stack trace with the
739+ filename of the script file. See if we have a source map cached under
740+ < code > <anonymous></ code > that matches the error.</ p >
741+
742+ </ div >
743+
744+ < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> else</ span > < span class ="hljs-keyword "> if</ span > sourceMaps[< span class ="hljs-string "> '<anonymous>'</ span > ]?</ pre > </ div > </ div >
745+
746+ </ li >
747+
748+
749+ < li id ="section-30 ">
750+ < div class ="annotation ">
751+
752+ < div class ="pilwrap ">
753+ < a class ="pilcrow " href ="#section-30 "> ¶</ a >
754+ </ div >
755+ < p > Work backwards from the most recent anonymous source maps, until we find
756+ one that works. This isn’t foolproof; there is a chance that multiple
757+ source maps will have line/column pairs that match. But we have no other
758+ way to match them. < code > frame.getFunction().toString()</ code > doesn’t always work,
759+ and it’s not foolproof either.</ p >
760+
761+ </ div >
762+
763+ < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> for</ span > map < span class ="hljs-keyword "> in</ span > sourceMaps[< span class ="hljs-string "> '<anonymous>'</ span > ] < span class ="hljs-keyword "> by</ span > < span class ="hljs-number "> -1</ span >
764+ sourceLocation = map.sourceLocation [line - < span class ="hljs-number "> 1</ span > , column - < span class ="hljs-number "> 1</ span > ]
765+ < span class ="hljs-keyword "> return</ span > map < span class ="hljs-keyword "> if</ span > sourceLocation?[< span class ="hljs-number "> 0</ span > ]? < span class ="hljs-keyword "> and</ span > sourceLocation[< span class ="hljs-number "> 1</ span > ]?</ pre > </ div > </ div >
766+
767+ </ li >
768+
769+
770+ < li id ="section-31 ">
771+ < div class ="annotation ">
772+
773+ < div class ="pilwrap ">
774+ < a class ="pilcrow " href ="#section-31 "> ¶</ a >
775+ </ div >
776+ < p > If all else fails, recompile this source to get a source map. We need the
777+ previous section (for < code > <anonymous></ code > ) despite this option, because after it
778+ gets compiled we will still need to look it up from
779+ < code > sourceMaps['<anonymous>']</ code > in order to find and return it. That’s why we
780+ start searching from the end in the previous block, because most of the
781+ time the source map we want is the last one.</ p >
782+
783+ </ div >
784+
785+ < div class ="content "> < div class ='highlight '> < pre > < span class ="hljs-keyword "> if</ span > sources[filename]?
786+ answer = compile sources[filename][sources[filename].length - < span class ="hljs-number "> 1</ span > ],
727787 filename: filename
728788 sourceMap: < span class ="hljs-literal "> yes</ span >
729789 literate: helpers.isLiterate filename
@@ -734,11 +794,11 @@ <h1>coffeescript.coffee</h1>
734794 </ li >
735795
736796
737- < li id ="section-29 ">
797+ < li id ="section-32 ">
738798 < div class ="annotation ">
739799
740800 < div class ="pilwrap ">
741- < a class ="pilcrow " href ="#section-29 "> ¶</ a >
801+ < a class ="pilcrow " href ="#section-32 "> ¶</ a >
742802 </ div >
743803 < p > Based on < a href ="http://goo.gl/ZTx1p "> michaelficarra/CoffeeScriptRedux</ a >
744804NodeJS / V8 have no support for transforming positions in stack traces using
@@ -749,7 +809,7 @@ <h1>coffeescript.coffee</h1>
749809
750810 < div class ="content "> < div class ='highlight '> < pre > Error.prepareStackTrace = < span class ="hljs-function "> < span class ="hljs-params "> (err, stack)</ span > -></ span >
751811< span class ="hljs-function "> < span class ="hljs-title "> getSourceMapping</ span > = < span class ="hljs-params "> (filename, line, column)</ span > -></ span >
752- sourceMap = getSourceMap filename
812+ sourceMap = getSourceMap filename, line, column
753813 answer = sourceMap.sourceLocation [line - < span class ="hljs-number "> 1</ span > , column - < span class ="hljs-number "> 1</ span > ] < span class ="hljs-keyword "> if</ span > sourceMap?
754814 < span class ="hljs-keyword "> if</ span > answer? < span class ="hljs-keyword "> then</ span > [answer[< span class ="hljs-number "> 0</ span > ] + < span class ="hljs-number "> 1</ span > , answer[< span class ="hljs-number "> 1</ span > ] + < span class ="hljs-number "> 1</ span > ] < span class ="hljs-keyword "> else</ span > < span class ="hljs-literal "> null</ span >
755815
0 commit comments