Skip to content

Commit

Permalink
Refactor core check modules
Browse files Browse the repository at this point in the history
* Move chstate methods for creating warnings into modules doing detection,
  to make them more isolated and easier to test.
* Minor refactoring and renaming.
* Fix a bug when reporting unused mutually recursive functions as
  unused values.
  • Loading branch information
mpeterv committed Feb 2, 2018
1 parent 43cebe7 commit ce3ac84
Show file tree
Hide file tree
Showing 19 changed files with 448 additions and 419 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,11 @@
functions with complexity higher than a configurable limit; disabled
by default (#141).

### Fixes

* Fixed errors or incorrect reporting when unused mutually recursive functions
have other values assigned to their local variables.

## 0.21.2 (2017-11-13)

### Fixes
Expand Down
54 changes: 27 additions & 27 deletions install.lua
Expand Up @@ -94,42 +94,42 @@ end
print(" Installing luacheck modules into " .. luacheck_src_dir)
mkdir(luacheck_lib_dir)

for _, filename in ipairs {
"main.lua",
for _, filename in ipairs({
"init.lua",
"argparse.lua",
"builtin_standards.lua",
"cache.lua",
"check.lua",
"config.lua",
"linearize.lua",
"analyze.lua",
"core_utils.lua",
"check.lua",
"parser.lua",
"lexer.lua",
"filter.lua",
"options.lua",
"inline_options.lua",
"builtin_standards.lua",
"love_standard.lua",
"ngx_standard.lua",
"detect_bad_whitespace.lua",
"detect_cyclomatic_complexity.lua",
"detect_globals.lua",
"detect_uninit_access.lua",
"detect_unreachable_code.lua",
"detect_unused_locals.lua",
"detect_unused_rec_funcs.lua",
"expand_rockspec.lua",
"multithreading.lua",
"cache.lua",
"filter.lua",
"format.lua",
"version.lua",
"fs.lua",
"globbing.lua",
"utils.lua",
"argparse.lua",
"whitespace.lua",
"detect_cyclomatic_complexity.lua",
"detect_globals.lua",
"standards.lua",
"lua_fs.lua",
"inline_options.lua",
"lexer.lua",
"lfs_fs.lua",
"detect_unused_rec_funcs.lua",
"detect_unreachable_code.lua",
"detect_uninit_access.lua",
"linearize.lua",
"love_standard.lua",
"lua_fs.lua",
"main.lua",
"name_functions.lua",
"detect_unused_locals.lua"} do
"multithreading.lua",
"ngx_standard.lua",
"options.lua",
"parser.lua",
"resolve_locals.lua",
"standards.lua",
"utils.lua",
"version.lua"}) do
copy("src" .. dirsep .. "luacheck" .. dirsep .. filename, luacheck_lib_dir)
end

Expand Down
6 changes: 3 additions & 3 deletions luacheck-dev-1.rockspec
Expand Up @@ -19,13 +19,13 @@ build = {
type = "builtin",
modules = {
luacheck = "src/luacheck/init.lua",
["luacheck.analyze"] = "src/luacheck/analyze.lua",
["luacheck.argparse"] = "src/luacheck/argparse.lua",
["luacheck.builtin_standards"] = "src/luacheck/builtin_standards.lua",
["luacheck.cache"] = "src/luacheck/cache.lua",
["luacheck.check"] = "src/luacheck/check.lua",
["luacheck.config"] = "src/luacheck/config.lua",
["luacheck.core_utils"] = "src/luacheck/core_utils.lua",
["luacheck.detect_bad_whitespace"] = "src/luacheck/detect_bad_whitespace.lua",
["luacheck.detect_cyclomatic_complexity"] = "src/luacheck/detect_cyclomatic_complexity.lua",
["luacheck.detect_globals"] = "src/luacheck/detect_globals.lua",
["luacheck.detect_uninit_access"] = "src/luacheck/detect_uninit_access.lua",
Expand All @@ -49,10 +49,10 @@ build = {
["luacheck.ngx_standard"] = "src/luacheck/ngx_standard.lua",
["luacheck.options"] = "src/luacheck/options.lua",
["luacheck.parser"] = "src/luacheck/parser.lua",
["luacheck.resolve_locals"] = "src/luacheck/resolve_locals.lua",
["luacheck.standards"] = "src/luacheck/standards.lua",
["luacheck.utils"] = "src/luacheck/utils.lua",
["luacheck.version"] = "src/luacheck/version.lua",
["luacheck.whitespace"] = "src/luacheck/whitespace.lua"
["luacheck.version"] = "src/luacheck/version.lua"
},
install = {
bin = {
Expand Down
19 changes: 19 additions & 0 deletions spec/check_spec.lua
Expand Up @@ -250,6 +250,25 @@ end
]])
end)

it("detects unused mutually recursive functions as values", function()
assert.same({
{code = "311", name = "odd", line = 5, column = 10, end_column = 12},
{code = "311", name = "even", line = 9, column = 10, end_column = 13}
}, check[[
local even = 2
local odd = 3
(...)(even, odd)
function odd(x)
return x == 1 or even(x - 1)
end
function even(x)
return x == 0 or odd(x - 1) or even(x)
end
]])
end)

it("does not incorrectly detect unused recursive functions inside unused functions", function()
assert.same({
{code = "211", name = "unused", func = true, line = 1, column = 16, end_column = 21}
Expand Down
6 changes: 3 additions & 3 deletions spec/cli_spec.lua
Expand Up @@ -915,7 +915,7 @@ spec/samples/bad_code.lua
local A,B,C,D,E,F="package","711","helper","function","embrace","hepler";return {{{"112",A,1,1,7,[23]={A,"loaded",true}},{B,[3]=1,[4]=1,[5]=1,[27]=1,[29]="main_chunk"},{B,[3]=3,[4]=7,[5]=14,[27]=1,[28]=C,[29]=D},{"211",C,3,16,21,[10]=true},{"212","...",3,23,25},{B,[3]=7,[4]=1,[5]=8,[27]=2,[28]=E,[29]=D},{"111",E,7,10,16,[11]=true,[23]={E}},{"412","opt",8,10,12,7,18},{"113",F,9,11,16,[23]={F}}},{},{24,0,26,9,3,0,21,31,26,3,0},{[4]="comment"}}
spec/samples/python_code.lua
(%d+)
return {{{"011",[3]=1,[4]=6,[5]=15,[12]="expected '=' near '__future__'"}},{},{}}
return {{{"011",[3]=1,[4]=6,[5]=15,[12]="expected '=' near '__future__'"}},{},{},{}}
]]):gsub("[%[%]]", "%%%0")))
-- luacheck: pop

Expand All @@ -934,10 +934,10 @@ return {{{"011",[3]=1,[4]=6,[5]=15,[12]="expected '=' near '__future__'"}},{},{}
%s
spec/samples/python_code.lua
%s
return {{{"111", "global", 1, 1, [23]={"global"}}, {"321", "uninit", 6, 8}},{},{}}
return {{{"111", "global", 1, 1, [23]={"global"}}, {"321", "uninit", 6, 8}},{},{},{}}
spec/samples/good_code.lua
%s
return {{{"011",[3]=5,[4]=7,[12]="this code is actually bad"}},{},{}}
return {{{"011",[3]=5,[4]=7,[12]="this code is actually bad"}},{},{},{}}
spec/samples/bad_code.lua
%s
return {{},{},{}}]]):format(version, python_mtime, good_mtime, tostring(tonumber(bad_mtime) - 1)))
Expand Down
15 changes: 3 additions & 12 deletions spec/linearize_spec.lua
@@ -1,20 +1,11 @@
local linearize = require "luacheck.linearize"
local parser = require "luacheck.parser"
local utils = require "luacheck.utils"

local ChState = utils.class()

function ChState.__init() end
function ChState.warn_redefined() end
function ChState.warn_global() end
function ChState.warn_unused_label() end
function ChState.warn_unbalanced() end
function ChState.warn_empty_block() end

local function get_line_(src)
local ast = parser.parse(src)
local chstate = ChState()
return linearize(chstate, ast)
local chstate = {ast = ast, warnings = {}}
linearize(chstate)
return chstate.main_line
end

local function get_line(src)
Expand Down
41 changes: 7 additions & 34 deletions spec/analyze_spec.lua → spec/resolve_locals_spec.lua
@@ -1,35 +1,6 @@
local analyze = require "luacheck.analyze"
local linearize = require "luacheck.linearize"
local parser = require "luacheck.parser"
local utils = require "luacheck.utils"

local ChState = utils.class()

function ChState.__init() end
function ChState.warn_redefined() end
function ChState.warn_global() end
function ChState.warn_unused_label() end
function ChState.warn_unused_variable() end
function ChState.warn_unused_value() end
function ChState.warn_unset() end

local function get_line_(src)
local ast = parser.parse(src)
local chstate = ChState()
return linearize(chstate, ast)
end

local function get_line(src)
local ok, res = pcall(get_line_, src)

if ok then
return res
elseif type(res) == "table" then
return nil
else
error(res, 0)
end
end
local resolve_locals = require "luacheck.resolve_locals"

local function used_variables_to_string(item)
local buf = {}
Expand All @@ -49,12 +20,14 @@ local function used_variables_to_string(item)
end

local function get_used_variables_as_string(src)
local line = get_line(src)
analyze(line)
local ast = parser.parse(src)
local chstate = {ast = ast, warnings = {}}
linearize(chstate)
resolve_locals(chstate)

local buf = {}

for _, item in ipairs(line.items) do
for _, item in ipairs(chstate.main_line.items) do
if item.accesses and next(item.accesses) then
assert.is_table(item.used_values)
table.insert(buf, used_variables_to_string(item))
Expand All @@ -64,7 +37,7 @@ local function get_used_variables_as_string(src)
return table.concat(buf, "\n")
end

describe("analyze", function()
describe("resolve_locals", function()
describe("when resolving values", function()
it("resolves values in linear cases", function()
assert.equal([[
Expand Down

0 comments on commit ce3ac84

Please sign in to comment.