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:
parent
1de0aafa5b
commit
33ac4c5d7f
3 changed files with 96 additions and 44 deletions
2
bin/can
2
bin/can
|
|
@ -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()
|
||||||
|
|
|
||||||
8
bin/canc
8
bin/canc
|
|
@ -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
|
||||||
|
|
|
||||||
130
bin/cancheck
130
bin/cancheck
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue