mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 17:59:30 +00:00
Added cancheck; candran.compile, .make and .preprocess returns nil, err instead of throwing an error; can and canc error output should now be similar to Lua
This commit is contained in:
parent
dc19ac56a9
commit
1de0aafa5b
9 changed files with 412 additions and 226 deletions
116
bin/cancheck
Normal file
116
bin/cancheck
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
-- Monkey patch Luacheck (tested against version 0.23.0) to support Candran files
|
||||
local candran = require("candran")
|
||||
|
||||
local function pattern(token)
|
||||
return "()"..token:gsub("[^%w]", "%%%0").."()"
|
||||
end
|
||||
|
||||
local tokenAlias = {
|
||||
["self"] = { "@", ":" }
|
||||
}
|
||||
|
||||
-- Patch checker
|
||||
local oldCheck = require("luacheck.check")
|
||||
local function check(can)
|
||||
local lua, err = candran.make(can)
|
||||
if lua then
|
||||
local r = oldCheck(lua)
|
||||
-- Calculate Candran file position.
|
||||
if #r.warnings > 0 then
|
||||
local lua_lines = {}
|
||||
for l in (lua.."\n"):gmatch("([^\n]*)\n") do
|
||||
table.insert(lua_lines, l)
|
||||
end
|
||||
local can_lines = {}
|
||||
for l in (can.."\n"):gmatch("([^\n]*)\n") do
|
||||
table.insert(can_lines, l)
|
||||
end
|
||||
for _, warning in ipairs(r.warnings) do
|
||||
-- candran line
|
||||
local lua_line = lua_lines[warning.line]
|
||||
warning.can_line = tonumber(lua_line:match(".*%-%- .-%:(%d+)$"))
|
||||
|
||||
-- candran column
|
||||
local can_line = can_lines[warning.can_line]
|
||||
local lua_token = lua_line:sub(warning.column, warning.end_column)
|
||||
local token_pattern = pattern(lua_token) -- token finding pattern
|
||||
-- the warning happens on the n-th instance of lua_token on this line
|
||||
local lua_n = 1
|
||||
for start in lua_line:gmatch(token_pattern) do
|
||||
if start >= warning.column then
|
||||
break
|
||||
end
|
||||
lua_n = lua_n + 1
|
||||
end
|
||||
-- Find associated candran token. If lua_n > can_nmax, the last found lua_token is used.
|
||||
-- This approximation should work in like, 90% of cases.
|
||||
local can_n = 1
|
||||
local pos = 1
|
||||
while can_n <= lua_n do
|
||||
-- find first token or alias of this token
|
||||
local start, stop = can_line:match(token_pattern, pos)
|
||||
if tokenAlias[lua_token] then
|
||||
for _, token in ipairs(tokenAlias[lua_token]) do
|
||||
local nstart, nstop = can_line:match(pattern(token), pos)
|
||||
if nstart and (not start or nstart < start) then
|
||||
start, stop = nstart, nstop
|
||||
end
|
||||
end
|
||||
end
|
||||
-- found
|
||||
if start then
|
||||
pos = stop
|
||||
warning.can_column, warning.can_end_column = start, stop
|
||||
can_n = can_n + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return r
|
||||
else
|
||||
local line, column, msg = err:match(":(%d+):(%d+):%s*(.*)$")
|
||||
local syntax_error = {
|
||||
code = "011",
|
||||
line = line,
|
||||
column = column,
|
||||
end_column = column,
|
||||
msg = msg
|
||||
}
|
||||
return {
|
||||
warnings = {syntax_error},
|
||||
inline_options = {},
|
||||
line_lengths = {},
|
||||
line_endings = {}
|
||||
}
|
||||
end
|
||||
end
|
||||
package.loaded["luacheck.check"] = check
|
||||
|
||||
-- Patch formatter
|
||||
local format = require("luacheck.format")
|
||||
local function format_location(file, location, opts)
|
||||
local res = ("%s:%d:%d"):format(file, location.can_line or location.line, location.can_column or location.column)
|
||||
if opts.ranges then
|
||||
res = ("%s-%d"):format(res, location.can_end_column or location.end_column)
|
||||
end
|
||||
return res
|
||||
end
|
||||
local function setupvalue(fn, val, name, ...)
|
||||
for i=1, debug.getinfo(fn, "u").nups do
|
||||
local n, v = debug.getupvalue(fn, i)
|
||||
if n == name then
|
||||
if not ... then
|
||||
debug.setupvalue(fn, i, val)
|
||||
else
|
||||
setupvalue(v, val, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
setupvalue(format.builtin_formatters.plain, format_location, "format_event", "format_location")
|
||||
|
||||
require("luacheck.main")
|
||||
Loading…
Add table
Add a link
Reference in a new issue