forked from gjtorikian/function-extractor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsample.coffee
129 lines (100 loc) · 4.12 KB
/
sample.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# Node.js-specific support: module loading, sourceMapping errors
fs = require 'fs'
path = require 'path'
Module = require 'module'
CoffeeScript = require './module'
{SourceMapConsumer} = require 'source-map'
# NodeJS / V8 have no support for transforming positions in stack traces using
# sourceMap, so we must monkey-patch Error to display CoffeeScript source
# positions.
# Ideally, this would happen in a way that is scalable to multiple compile-to-
# JS languages trying to do the same thing in the same NodeJS process. We can
# implement it as if there were an API, and then patch in support for that
# API. The following maybe should be in its own npm module that multiple
# compilers can include.
patched = false
patchStackTrace = ->
return if patched
patched = true
# Map of filenames -> functions that return a sourceMap string.
Module._sourceMaps = {}
# (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) ->
mapString = Module._sourceMaps[filename]?()
if mapString
sourceMap = sourceFiles[filename] ?= new SourceMapConsumer mapString
sourceMap.originalPositionFor {line, column}
frames = for frame in stack
break if frame.getFunction() is exports.runMain
" 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) ->
fileName = undefined
fileLocation = ''
if frame.isNative()
fileLocation = "native"
else
if frame.isEval()
fileName = frame.getScriptNameOrSourceURL()
fileLocation = "#{frame.getEvalOrigin()}, " unless fileName
else
fileName = frame.getFileName()
fileName or= "<anonymous>"
line = frame.getLineNumber()
column = frame.getColumnNumber()
# Check for a sourceMap position
source = getSourceMapping fileName, line, column
fileLocation =
if source
"#{fileName}:#{source.line}:#{source.column}, <js>:#{line}:#{column}"
else
"#{fileName}:#{line}:#{column}"
functionName = frame.getFunctionName()
isConstructor = frame.isConstructor()
isMethodCall = not (frame.isToplevel() or isConstructor)
if isMethodCall
methodName = frame.getMethodName()
typeName = frame.getTypeName()
if functionName
tp = as = ''
if typeName and functionName.indexOf typeName
tp = "#{typeName}."
if methodName and functionName.indexOf(".#{methodName}") isnt functionName.length - methodName.length - 1
as = " [as #{methodName}]"
"#{tp}#{functionName}#{as} (#{fileLocation})"
else
"#{typeName}.#{methodName or '<anonymous>'} (#{fileLocation})"
else if isConstructor
"new #{functionName or '<anonymous>'} (#{fileLocation})"
else if functionName
"#{functionName} (#{fileLocation})"
else
fileLocation
# Run JavaScript as a main program - resetting process.argv and module lookup paths
exports.runMain = (csSource, jsSource, jsAst, filename) ->
mainModule = new Module '.'
mainModule.filename = process.argv[1] = filename
# Set it as the main module -- this is used for require.main
process.mainModule = mainModule
# Add the module to the cache
Module._cache[mainModule.filename] = mainModule
# Assign paths for node_modules loading
mainModule.paths = Module._nodeModulePaths path.dirname filename
runModule mainModule, jsSource, jsAst, filename
runModule = (module, jsSource, jsAst, filename) ->
do patchStackTrace
Module._sourceMaps[filename] = ->
CoffeeScript.sourceMap jsAst, filename
module._compile jsSource, filename
require.extensions['.coffee'] = (module, filename) ->
input = fs.readFileSync filename, 'utf8'
csAst = CoffeeScript.parse input, raw: yes
jsAst = CoffeeScript.compile csAst
js = CoffeeScript.js jsAst
runModule module, js, jsAst, filename