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
|
local path = require 'pl.path'
local ok, moonscript, line_tables, util = pcall(function()
return require 'moonscript', require 'moonscript.line_tables', require 'moonscript.util'
end)
local _cache = {}
-- find the line number of `pos` chars into fname
local lookup_line = function(fname, pos)
if not _cache[fname] then
local f = io.open(fname)
_cache[fname] = f:read('*a')
f:close()
end
return util.pos_to_line(_cache[fname], pos)
end
local rewrite_linenumber = function(fname, lineno)
local tbl = line_tables['@' .. fname]
if fname and tbl then
for i = lineno, 0 ,-1 do
if tbl[i] then
return lookup_line(fname, tbl[i])
end
end
end
return lineno
end
local rewrite_filename = function(filename)
-- sometimes moonscript gives files like [string "./filename.moon"], so
-- we'll chop it up to only get the filename.
return filename:match('string "(.+)"') or filename
end
local rewrite_traceback = function(fname, trace)
local rewrite_one = function(line, pattern, sub)
if line == nil then return '' end
local fname, lineno = line:match(pattern)
if fname and lineno then
fname = rewrite_filename(fname)
local new_lineno = rewrite_linenumber(fname, tonumber(lineno))
if new_lineno then
line = line:gsub(sub:format(tonumber(lineno)), sub:format(tonumber(new_lineno)))
end
end
return line
end
local lines = {}
local j = 0
for line in trace:gmatch('[^\r\n]+') do
j = j + 1
line = rewrite_one(line, '%s*(.-):(%d+): ', ':%d:')
line = rewrite_one(line, '<(.*):(%d+)>', ':%d>')
lines[j] = line
end
return '\n' .. table.concat(lines, trace:match('[\r\n]+')) .. '\n'
end
local ret = {}
local getTrace = function(filename, info)
local index = info.traceback:find('\n%s*%[C]')
info.traceback = info.traceback:sub(1, index)
info.short_src = rewrite_filename(info.short_src)
info.traceback = rewrite_traceback(filename, info.traceback)
info.linedefined = rewrite_linenumber(filename, info.linedefined)
info.currentline = rewrite_linenumber(filename, info.currentline)
return info
end
local rewriteMessage = function(filename, message)
local fname, line, msg = message:match('^([^\n]-):(%d+): (.*)')
if not fname then
return message
end
fname = rewrite_filename(fname)
line = rewrite_linenumber(fname, tonumber(line))
return fname .. ':' .. tostring(line) .. ': ' .. msg
end
ret.match = function(busted, filename)
return ok and path.extension(filename) == '.moon'
end
ret.load = function(busted, filename)
local file, err = moonscript.loadfile(filename)
if not file then
busted.publish({ 'error', 'file' }, { descriptor = 'file', name = filename }, nil, err, {})
end
return file, getTrace, rewriteMessage
end
return ret
|