-
Notifications
You must be signed in to change notification settings - Fork 0
/
reporter.lua
108 lines (87 loc) · 2.63 KB
/
reporter.lua
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 reporter = {
errors = 0,
warnings = 0,
}
local function writeFmt(format, ...) io.write(string.format(format, ...)) end
---@param source string
function reporter:setSource(source)
self.source = source
end
---@param msg string
---@param startPos Position
---@param endPos Position
function reporter:error(msg, startPos, endPos)
io.write("error ")
writeFmt("[%i, %i]", startPos.line, startPos.col)
if startPos.line ~= endPos.line
or startPos.col ~= endPos.col then
writeFmt("-[%i, %i]", endPos.line, endPos.col)
end
writeFmt(": %s\n", msg)
reporter:printLocText(startPos, endPos)
self.errors = self.errors + 1
end
---@param msg string
---@param startPos Position
---@param endPos Position
function reporter:warn(msg, startPos, endPos)
io.write("warn ")
writeFmt("[%i, %i]", startPos.line, startPos.col)
if startPos.line ~= endPos.line
or startPos.col ~= endPos.col then
writeFmt("-[%i, %i]", endPos.line, endPos.col)
end
writeFmt(": %s\n", msg)
reporter:printLocText(startPos, endPos)
self.warnings = self.warnings + 1
end
---@return boolean
---@nodiscard
function reporter:didError() return self.errors > 0 end
local PREFIX = "..."
local MULTI_PREFIX = "..."
local LINE_NUM_LEN = 4
local SPACES_PER_TAB = 8
---@private
function reporter:printLocText(startPos, endPos)
writeFmt("%s\n", PREFIX)
local lines = {}
for m in self.source:gmatch "[^\n]*" do
table.insert(lines, m)
end
if startPos.line == endPos.line then
local line = lines[startPos.line]
writeFmt("%."..LINE_NUM_LEN.."i\t%s\n", startPos.line, line)
local tabCount = 0
for _ in line:gmatch "\t" do tabCount = tabCount + 1 end
local s = ""
s = s .. string.rep(" ", tabCount * SPACES_PER_TAB - tabCount)
s = s .. string.rep(" ", startPos.col-1)
if startPos.col == endPos.col then
s = s .. "^"
else
s = s .. "|" .. string.rep("-", math.max(1, endPos.col - startPos.col-2)) .. "|"
end
writeFmt("%s\t%s\n", PREFIX, s)
else
local chosenLines = { table.unpack(lines, startPos.line, endPos.line) }
chosenLines[1] = chosenLines[1]:sub(startPos.col)
chosenLines[#chosenLines] = chosenLines[#chosenLines]:sub(1, endPos.col)
for i, t in ipairs(chosenLines) do
writeFmt("%."..LINE_NUM_LEN.."i\t%s\n", startPos.line + i-1, t)
---@type string
local s
if i == 1 then
s = string.rep(" ", startPos.col-1)
s = s .. "|" .. string.rep("-", #t - startPos.col-1) .. ">"
elseif i == #chosenLines then
s = "<" .. string.rep("-", endPos.col-1) .. "|"
else
s = "<" .. string.rep("-", #t-2) .. ">"
end
writeFmt("%s\t%s\n", MULTI_PREFIX, s)
end
end -- startPos.line == endPos.line
writeFmt("%s\n", PREFIX)
end
return reporter