-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds table field checks #65
base: master
Are you sure you want to change the base?
Conversation
The branched luacheck remains very fast on a ~100K line code base, with no false positives. No true positives either, and it looks like this initial level of caution is pretty limiting. For example, it's not allowed to catch problems here because local x = {}
print(x.oops) So it'd be interesting to see if other projects hit these cautious warnings, and (if the implementation is well received) how some bits which extend the tracking boundaries look. |
I’ve run it across 12 largeish lua GitHub projects; it found issues in 3. This version catches the typo’d field name, but not the duplicate assignment. It also finds non-functionality-affecting minor issues in two other codebases: In Kong/Kong, there are four places where env.plugins is checked on an empty env tables, eg line 20 here: https://github.com/Kong/kong/blob/911385466571e4f72999fa43419daafae08159d0/spec/02-integration/03-db/11-db_transformations_spec.lua In LunarVim, some of the colors (red2, orange, gray3) are unused here: https://github.com/LunarVim/onedarker.nvim/blob/master/lua/lualine/themes/onedarker.lua Making analysis continue through function calls involves a lot of code and cases, but is conceptually straightforward- we need to track which variables are externally accessible; which are passed to the function directly; and add special cases for builtins we care about like table.insert. Adding support for continuing analysis through control flow is too complicated to be feasible without a different setup- this is currently looping over the linearized code from linearize.lua, which adapts poorly to non-linear control flow. |
I don't usually use Github, so I'm not familiar with the standard workflow- would it be standard for me to add the (conceptually separate/additional) support for continued execution through function calls to this PR, open a separate PR (on top of this branch or something? not sure how) or something else? |
If it is conceptually a different feature but dependent on this one my suggestion is to start a new branch based on this one and open a new PR in draft mode. It will show all the commits in this branch too until this PR is merged, then after this is merged it will show just the new commits in that branch and can be taken out of draft mode for review. There are different workflows to handle this but that's the one I usually reach for. If early review of the unique commits is important you can open a PR merging into this branch, then change the target later, but I don't feel that is necessary for this case. |
I'm sorry I never got a chance to give this a good test drive. I'm considering whether I should move ahead with a new release soon to get the new builtins out the door or hang back for a bit and try to work out whether this is ready to go in. What's your take on how ready this is? |
I tried merging master into this locally. The merge conflicts are only in the total number of warnings/errors/files output in some tests, so that's a no-brainer to fix. However the tests don't seem to to output results at all, a half dozen or so actually crash with Lua errors for output, not lint results. |
@@ -437,7 +437,8 @@ local item_callbacks = { | |||
Cjump = ClosureState.handle_jump, | |||
Eval = ClosureState.handle_eval, | |||
Local = ClosureState.handle_local_or_set_item, | |||
Set = ClosureState.handle_local_or_set_item | |||
Set = ClosureState.handle_local_or_set_item, | |||
OpSet = ClosureState.handle_local_or_set_item, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arichard4 I took a stab at both fixing the Lua error and integrating the test result changes from the last few releases into this branch. I wasn't 100% sure about this fix though, does it look sane to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, missed this earlier.
No, unfortunately that's not right- I'll need to write a different handler for the OpSet case. The problem is that an OpSet is both a read and a write, while this only handles a write- the Set case. For a concrete example, the compound operators test produces this incorrect output:
t.a = i --value assigned to table field 't'.'a' is unused
t.a *= 2 -- because the existing code treats this as only an overwriting Set to t.a, not as also reading the previous value of t.a
return t```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. Feel free to reset to before my merge or rewrite/amend the merge to correct this or just add a new commit to adjust as appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed a revised version
Closes #39
The basic design here:
If you check my fork of luacheck, on the table_fields branch, I wrote a far more complicated version last November that tried to handle control flow (except for break statements) and function calls as well. Unfortunately that got unreviewably complicated; I may submit bits of that in later reviews, but I think that this version is more comprehensible to start with.