1
0
Fork 0
mirror of https://github.com/Reuh/candran.git synced 2025-10-27 09:59:29 +00:00

Discard warnings from external files in cancheck

This commit is contained in:
Étienne Fildadut 2020-04-06 23:11:17 +02:00
parent 1de0aafa5b
commit 33ac4c5d7f
3 changed files with 96 additions and 44 deletions

View file

@ -32,7 +32,7 @@ if arg[#arg] == "-" then
elseif #args >= 1 then elseif #args >= 1 then
local f, err = candran.loadfile(args[1], nil, args) local f, err = candran.loadfile(args[1], nil, args)
if not f then if not f then
print("can: "..err) io.stderr:write("can: "..err.."\n")
os.exit(1) os.exit(1)
else else
f() f()

View file

@ -46,7 +46,7 @@ for _, file in ipairs(args) do
local inputFile, err = io.open(file, "r") local inputFile, err = io.open(file, "r")
if not inputFile then if not inputFile then
io.stderr:write("canc: cannot open "..file..": "..err) io.stderr:write("canc: cannot open "..file..": "..err.."\n")
os.exit(1) os.exit(1)
end end
input = inputFile:read("*a") input = inputFile:read("*a")
@ -81,7 +81,7 @@ for _, file in ipairs(args) do
if args.preprocess then if args.preprocess then
local r, err = candran.preprocess(out, args) local r, err = candran.preprocess(out, args)
if not r then if not r then
print("canc: "..err) io.stderr:write("canc: "..err.."\n")
os.exit(1) os.exit(1)
end end
out = r out = r
@ -89,7 +89,7 @@ for _, file in ipairs(args) do
if args.compile then if args.compile then
local r, err = candran.compile(out, args) local r, err = candran.compile(out, args)
if not r then if not r then
print("canc: "..err) io.stderr:write("canc: "..err.."\n")
os.exit(1) os.exit(1)
end end
out = r out = r
@ -97,7 +97,7 @@ for _, file in ipairs(args) do
if args.compile == nil and args.preprocess == nil then if args.compile == nil and args.preprocess == nil then
local r, err = candran.make(input, args) local r, err = candran.make(input, args)
if not r then if not r then
print("canc: "..err) io.stderr:write("canc: "..err.."\n")
os.exit(1) os.exit(1)
end end
out = r out = r

View file

@ -2,9 +2,14 @@
-- Monkey patch Luacheck (tested against version 0.23.0) to support Candran files -- Monkey patch Luacheck (tested against version 0.23.0) to support Candran files
local candran = require("candran") local candran = require("candran")
local util = require("candran.util")
local function escape(str)
return str:gsub("[^%w]", "%%%0")
end
local function pattern(token) local function pattern(token)
return "()"..token:gsub("[^%w]", "%%%0").."()" return "()"..escape(token).."()"
end end
local tokenAlias = { local tokenAlias = {
@ -14,7 +19,8 @@ local tokenAlias = {
-- Patch checker -- Patch checker
local oldCheck = require("luacheck.check") local oldCheck = require("luacheck.check")
local function check(can) local function check(can)
local lua, err = candran.make(can) local lua, err = candran.make(can, {chunkname="_luacheck_source"})
-- Warnings
if lua then if lua then
local r = oldCheck(lua) local r = oldCheck(lua)
-- Calculate Candran file position. -- Calculate Candran file position.
@ -27,50 +33,72 @@ local function check(can)
for l in (can.."\n"):gmatch("([^\n]*)\n") do for l in (can.."\n"):gmatch("([^\n]*)\n") do
table.insert(can_lines, l) table.insert(can_lines, l)
end end
for _, warning in ipairs(r.warnings) do for i=#r.warnings, 1, -1 do
-- candran line local warning = r.warnings[i]
local lua_line = lua_lines[warning.line]
warning.can_line = tonumber(lua_line:match(".*%-%- .-%:(%d+)$"))
-- candran column -- calculating candran line
local can_line = can_lines[warning.can_line] local lua_line = lua_lines[warning.line]
local lua_token = lua_line:sub(warning.column, warning.end_column)
local token_pattern = pattern(lua_token) -- token finding pattern local source, line = lua_line:match(".*%-%- (.-)%:(%d+)$")
-- the warning happens on the n-th instance of lua_token on this line if source ~= "_luacheck_source" then -- line is from another file, discard
local lua_n = 1 table.remove(r.warnings, i)
for start in lua_line:gmatch(token_pattern) do
if start >= warning.column then elseif source then
break warning.can_line = tonumber(line)
end
lua_n = lua_n + 1 -- do the same for prev_line
end if warning.prev_line then
-- Find associated candran token. If lua_n > can_nmax, the last found lua_token is used. local s, l = lua_lines[warning.prev_line]:match(".*%-%- (.-)%:(%d+)$")
-- This approximation should work in like, 90% of cases. if s ~= "_luacheck_source" then
local can_n = 1 warning.prev_line = s..":"..l -- luacheck seems to do no validation on this, so we can redefine it to anything
local pos = 1 elseif l then
while can_n <= lua_n do warning.prev_line = l
-- 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
end end
-- found
if start then -- calculating candran column
pos = stop local can_line = can_lines[warning.can_line]
warning.can_column, warning.can_end_column = start, stop local lua_token = lua_line:sub(warning.column, warning.end_column)
can_n = can_n + 1 local token_pattern = pattern(lua_token) -- token finding pattern
else -- the warning happens on the n-th instance of lua_token on this line
break 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 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
-- AFAIK, prev_column and prev_column_end are not displayed in any warning so we don't need to recalculate them for Candran.
end end
end end
end end
return r return r
-- Syntax error
else else
local line, column, msg = err:match(":(%d+):(%d+):%s*(.*)$") local line, column, msg = err:match(":(%d+):(%d+):%s*(.*)$")
local syntax_error = { local syntax_error = {
@ -90,6 +118,14 @@ local function check(can)
end end
package.loaded["luacheck.check"] = check package.loaded["luacheck.check"] = check
local runner = require("luacheck.runner")
local oldRunner = runner.new
function runner.new(opts)
-- Disable max line length checking (it is compiled code...)
opts.max_line_length = false
return oldRunner(opts)
end
-- Patch formatter -- Patch formatter
local format = require("luacheck.format") local format = require("luacheck.format")
local function format_location(file, location, opts) local function format_location(file, location, opts)
@ -113,4 +149,20 @@ local function setupvalue(fn, val, name, ...)
end end
setupvalue(format.builtin_formatters.plain, format_location, "format_event", "format_location") setupvalue(format.builtin_formatters.plain, format_location, "format_event", "format_location")
require("luacheck.main") -- Fix some Luacheck messages and run
local path = util.search("luacheck.main", {"lua"})
if path then
local f = io.open(path, "r")
local code = f:read("*a")
f:close()
code = code:gsub(escape(" bug (please report at https://github.com/mpeterv/luacheck/issues)"), ", patched for Candran "..candran.VERSION.." bug. Please DO NOT report this bug to Luacheck") -- error text
:gsub(escape("\"luacheck\","), "\"cancheck\",") -- command name
:gsub("a linter and a static analyzer for Lua%.", "a linter and a static analyzer for Lua, patched for Candran "..candran.VERSION..".") -- help text
-- run
return load(code)()
else
io.stderr:write("can't find luacheck.main\n")
os.exit(1)
end