Skip to content
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

Minor quote quality improvements after static analysis #10905

Merged
merged 7 commits into from Oct 12, 2023

Conversation

mytskine
Copy link
Contributor

@mytskine mytskine commented Sep 15, 2023

I searched for a (maintained) static code analyzer for Lua and found selene. I configured and applied it to koreader's source code. Here are fixes for some of the errors and warnings listed by selene. I hope that helps a little. If not, just drop the request.

The first commit clearly fixes a bug. The following commits are more innocuous.

I did not include a commit where I had doubts: In koreader, some calls to io.open() use a mode of "re" or "we". AFAIK, this "e" is undocumented in Lua's io. It's not in POSIX fopen() either. So I was wondering if it's a bug, or if I missed something.


This change is Reviewable

@@ -287,12 +287,12 @@ function ReaderSearch:onShowSearchDialog(text, direction, regex, case_insensitiv
self.wait_button.movable:setMovedOffset(self.search_dialog.movable:getMovedOffset())
UIManager:show(self.wait_button)
UIManager:tickAfterNext(function()
do_search(func, pattern, param, regex, case_insensitive)()
do_search(func, pattern, param)()
Copy link
Member

@Frenzie Frenzie Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This smells like the wrong solution to an accidental regression (depending a bit on what param signifies, maybe it's all fully functional).

Copy link
Member

@NiLuJe NiLuJe Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ought to be safe, everything is in the same function, so these are closure'ed earlier, looks like.

Haven't looked at the history, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly clearer to just keep the larger signature, and populate it instead, though?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it's more of a comment on the commit message than on the change per se. As written it sounds a lot like "apply suggestion from dumb linter that doesn't understand context," which I find unhelpful at best. The question is if it's unnecessary, not if the number of arguments is mismatched. Simply removing some arguments to shut up a linter smells like papering over a deeper problem.

You might say it's similar in that I'd still have to check if it had said something like "unnecessary," but then it's double checking a human, not a dumb linter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly clearer to just keep the larger signature, and populate it instead, though?

Also that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks indeed like these 2 args are not used.
Pinging @zwim from #7883 - to check if this is alright and that it doesn't hide some other problem (a bit head scratching these closures & callbacks...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It really seems that in #290, #295, #345 and #352 those last two parameters can be deleted.
They are used, but not as function-parameters but by the jit-compiler.

(Untested, as I have no time now.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of the code was that do_search() was now wrapped in another container where the context (regex, ci) was defined. So the old parameters of do_search() were no longer needed. Of course, this is not visible in the patch, and the source code of the search is quite long, so I could have misunderstood.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yepp

Comment on lines 70 to 71
local min = 1/0
local finish = 1/0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this may be a recommendation for Lua that's completely irrelevant to LuaJIT. (Not an objection, but not support either.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I just noticed which file this is in. Don't touch that file. ;-)

Copy link
Member

@Frenzie Frenzie Sep 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or at least not without bothering upstream about it https://github.com/bakpakin/luamd


## Why this is bad
`n / 0` equals `math.huge` when n is positive, and `-math.huge` when n is negative. Use these values directly instead, as using the `/ 0` way is confusing to read and non-idiomatic.

But sorry, / 0 confusing to read? I feel a sudden urge to replace all math.huge with 1 / 0 since it's very much not, lol

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As suggested in my opening comment, I also think it's mostly cosmetic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, either put this file or that selene contraption on the ignore list.

@Frenzie
Copy link
Member

Frenzie commented Sep 15, 2023

Thanks for the PR! I'm not quite convinced by the commits other than the first (give or take) and the last but it does probably warrant more investigation.

@NiLuJe
Copy link
Member

NiLuJe commented Sep 15, 2023

It's not in POSIX fopen() either.

It's Linux's O_CLOEXEC, and as LuaJIT's io.open is a very thin wrapper around fopen÷, it just works ;).

(And it's fairly critical for some stuff on Kobo, for instance).

fopen(3)

     e (since glibc 2.7)
          Open the file with the O_CLOEXEC flag.  See open(2) for more information.  This flag is ignored for fdopen().

@Frenzie
Copy link
Member

Frenzie commented Sep 15, 2023

or if I missed something.

Oh yeah, forgot to say, but it's not Lua, it's LuaJIT. It generally doesn't matter but we use some special LuaJIT features and occasionally also things that aren't unique to LuaJIT per se but that are actually from 5.2 or 5.3.

@NiLuJe
Copy link
Member

NiLuJe commented Sep 15, 2023

(And that linters or LSP may have trouble groking, for that matter ;)).

self:onHoldRelease(nil, self:_createHighlightGesture("hold_release"))
self:onHoldRelease()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there is indeed nothing to receive these arguments.
But as this is from #8877 for highlights with Non-Touch devices and the need to create fake events, and there may be some magic/hijacks, pinging its author @comphilip if this makes sense or if it's just leftover from copy/paste or else.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or more probably, this is just building and passing arguments as we do to most onTouchGestureHandler, passing (arg, ges).
It just happens that our own ReadHighlight:onHoldRelease() in that file does not need them, so it was declared without them.
I think the proper way would be to just declare /define ReadHighlight:onHoldRelease(arg, ges) - as most other :onSomething in readerhighlight.lua - even if the implementation does not use them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I'd also argue it's better than the alternative. But your suggestion introduces an unused local variable; something linters always complain in such event handler type situations to my annoyance. :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recent luacheck versions will grok if if prefixed by an underscore, IIRC (e.g., func(_foo, _bar)).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@poire-z You are right. It is creating fake events following touch call protocol (arg, ges). Lua function handler can declare ignore arguments. But changes to self:onHoldRelease() is not a good idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But changes to self:onHoldRelease() is not a good idea

The call in question or the implementation?

(i.e., is that just a NAK on that commit?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the call: removing arguments break event handler function protocol. It may cause unexpected issues in future:

  • If there is a chance that some one will override onHoldRelease and he needs arguments, then the application will crash due to null pointer exception.
  • The event protocol is solid: there are always two arguments passed to event handler. Widget author will be surprised that it is not always true. It will make event handler function need more code to handle such unexpected behavior.

Follow the protocol make life easy.

@poire-z
Copy link
Contributor

poire-z commented Sep 15, 2023

Here are fixes for some of the errors and warnings listed by selene

Are there others ? :)
I'm surprise there are so little - we must be incredibly good :) (or luacheck is good enough to notify us of most problems.)

@pazos
Copy link
Member

pazos commented Sep 16, 2023

Here are fixes for some of the errors and warnings listed by selene

Are there others ? :) I'm surprise there are so little - we must be incredibly good :) (or luacheck is good enough to notify us of most problems.)

a few of them

2023-09-16_01-30

Some categories, like ambiguity or different-requires, are ok to fix.
Addressing missing-parameter, redundant-parameter and unbalanced-assignments would be madness :D

Both luacheck and lua-lsp fail to catch performance issues like the excesive usage of string concatenation.

I think lsp for lua is great but their diagnostics are not so useful (above luacheck).
After all it is lua and any variable could be Any? all the time.

@mytskine
Copy link
Contributor Author

@NiLuJe Thanks for explaining the "e" mode in glibc's open().

@poire-z I filtered out the errors and warnings of selene that I didn't think useful enough (see my config below). It still complained about 3 goto uses and a few unbalanced assignments (e.g. local s, e, m, d = 1, hist_nb).

If someone wants to reproduce the checks, I've attached my config (remove the ".txt" extensions).
luakoreader.yml.txt
selene.toml.txt
I applied the stable release to koreader:

cargo install selene
~/.cargo/bin/selene frontend

@NiLuJe
Copy link
Member

NiLuJe commented Sep 17, 2023

goto

Supported by LuaJIT

@Frenzie
Copy link
Member

Frenzie commented Sep 17, 2023

They have an issue about adding support (for goto that is, not LuaJIT). Also it seems you can compile it various ways with support for the Roblox Lua derivative Luau or some 5.2 features.

a few unbalanced assignments (e.g. local s, e, m, d = 1, hist_nb).

That's debatable. While I'd also prefer to write , nil, nil at the end or to spread it out over multiple lines for clarity, if whatever that's referring to isn't intended for scope control I'd be quite surprised.

Edit: I think that's a pattern @hius07 likes. :-)

05cd59e

@zwim
Copy link
Contributor

zwim commented Sep 17, 2023

goto

Supported by LuaJIT

Yeah, very very seldom goto makes sense.
And 3 times is quite OK fmpov

@NiLuJe
Copy link
Member

NiLuJe commented Sep 17, 2023

I'm possibly the odd duck in being a huge fan of gotos (mostly for error and cleanup handling), but I'll readily agree that they shouldn't be over abused ;).

In the specific case of Lua, it's also sometimes the only way to (somewhat cleanly) handle constructs that would better be handled with a continue keyword, because Lua lacks such a keyword.

@Frenzie
Copy link
Member

Frenzie commented Sep 18, 2023

I wouldn't know for sure without checking but I think we only use goto as continue.

And in any case the popular try/except stuff is just goto with a different name.

@Frenzie Frenzie merged commit 1108302 into koreader:master Oct 12, 2023
1 of 3 checks passed
@Frenzie Frenzie added this to the 2023.10 milestone Oct 12, 2023
@Frenzie Frenzie changed the title Fix lua after static analysis Minor quote quality improvements after static analysis Oct 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants