1 |
|
2 |
|
3 | fs = require 'fs'
|
4 | path = require 'path'
|
5 | Module = require 'module'
|
6 | CoffeeScript = require './module'
|
7 | {SourceMapConsumer} = require 'source-map'
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | patched = false
|
20 | patchStackTrace = ->
|
21 | return if patched
|
22 | patched = true
|
23 |
|
24 |
|
25 | Module._sourceMaps = {}
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | Error.prepareStackTrace = (err, stack) ->
|
32 | sourceFiles = {}
|
33 |
|
34 | getSourceMapping = (filename, line, column) ->
|
35 | mapString = Module._sourceMaps[filename]?()
|
36 | if mapString
|
37 | sourceMap = sourceFiles[filename] ?= new SourceMapConsumer mapString
|
38 | sourceMap.originalPositionFor {line, column}
|
39 |
|
40 | frames = for frame in stack
|
41 | break if frame.getFunction() is exports.runMain
|
42 | " at #{formatSourcePosition frame, getSourceMapping}"
|
43 |
|
44 | "#{err.name}: #{err.message ? ''}\n#{frames.join '\n'}\n"
|
45 |
|
46 |
|
47 |
|
48 | formatSourcePosition = (frame, getSourceMapping) ->
|
49 | fileName = undefined
|
50 | fileLocation = ''
|
51 |
|
52 | if frame.isNative()
|
53 | fileLocation = "native"
|
54 | else
|
55 | if frame.isEval()
|
56 | fileName = frame.getScriptNameOrSourceURL()
|
57 | fileLocation = "#{frame.getEvalOrigin()}, " unless fileName
|
58 | else
|
59 | fileName = frame.getFileName()
|
60 |
|
61 | fileName or= "<anonymous>"
|
62 |
|
63 | line = frame.getLineNumber()
|
64 | column = frame.getColumnNumber()
|
65 |
|
66 |
|
67 | source = getSourceMapping fileName, line, column
|
68 | fileLocation =
|
69 | if source
|
70 | "#{fileName}:#{source.line}:#{source.column}, <js>:#{line}:#{column}"
|
71 | else
|
72 | "#{fileName}:#{line}:#{column}"
|
73 |
|
74 | functionName = frame.getFunctionName()
|
75 | isConstructor = frame.isConstructor()
|
76 | isMethodCall = not (frame.isToplevel() or isConstructor)
|
77 |
|
78 | if isMethodCall
|
79 | methodName = frame.getMethodName()
|
80 | typeName = frame.getTypeName()
|
81 |
|
82 | if functionName
|
83 | tp = as = ''
|
84 | if typeName and functionName.indexOf typeName
|
85 | tp = "#{typeName}."
|
86 | if methodName and functionName.indexOf(".#{methodName}") isnt functionName.length - methodName.length - 1
|
87 | as = " [as #{methodName}]"
|
88 |
|
89 | "#{tp}#{functionName}#{as} (#{fileLocation})"
|
90 | else
|
91 | "#{typeName}.#{methodName or '<anonymous>'} (#{fileLocation})"
|
92 | else if isConstructor
|
93 | "new #{functionName or '<anonymous>'} (#{fileLocation})"
|
94 | else if functionName
|
95 | "#{functionName} (#{fileLocation})"
|
96 | else
|
97 | fileLocation
|
98 |
|
99 |
|
100 | exports.runMain = (csSource, jsSource, jsAst, filename) ->
|
101 | mainModule = new Module '.'
|
102 | mainModule.filename = process.argv[1] = filename
|
103 |
|
104 |
|
105 | process.mainModule = mainModule
|
106 |
|
107 |
|
108 | Module._cache[mainModule.filename] = mainModule
|
109 |
|
110 |
|
111 | mainModule.paths = Module._nodeModulePaths path.dirname filename
|
112 |
|
113 | runModule mainModule, jsSource, jsAst, filename
|
114 |
|
115 | runModule = (module, jsSource, jsAst, filename) ->
|
116 | do patchStackTrace
|
117 |
|
118 | Module._sourceMaps[filename] = -> "#{CoffeeScript.sourceMap jsAst, filename}"
|
119 |
|
120 | module._compile jsSource, filename
|
121 |
|
122 | require.extensions['.coffee'] = (module, filename) ->
|
123 | input = fs.readFileSync filename, 'utf8'
|
124 | csAst = CoffeeScript.parse input, raw: yes
|
125 | jsAst = CoffeeScript.compile csAst
|
126 | js = CoffeeScript.js jsAst
|
127 |
|
128 | runModule module, js, jsAst, filename
|