SUPER STRICT for LUA

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

SUPER STRICT for LUA

Post by ivan »

SUPER STRICT for LUA
SUPER STRICT finds undeclared variables and other mistakes in your Lua source code as soon as the file is loaded.

Code: Select all

local function myFunc()
  a = 5 -- undefined variable 'a'
end
--myFunc() -- an error is detected without even calling myFunc!
Installation of SUPER STRICT is SUPER easy.

Code: Select all

require("sstrict")
Include the "sstrict.lua" file and any subsequent calls to "require" will be checked through SUPER STRICT.

Repository:
https://github.com/2dengine/sstrict.lua
Last edited by ivan on Sat Dec 11, 2021 8:18 am, edited 3 times in total.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: SUPER STRICT for LUA

Post by ivan »

Great news! SUPERSTRICT now detects unused variables in your Lua scripts:
Make sure to use the underscore symbol "_" to avoid this error.

Code: Select all

local list = {1,2,3}
local sum = 0
for i, v in ipairs(list) do -- unused variable 'i'
  sum = sum + v
end
Also pushed an optimization update so that a 2 MB Lua file is parsed in about 12 seconds.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: SUPER STRICT for LUA

Post by grump »

Gave it a quick test.

It doesn't seem to respect package.path correctly.

Code: Select all

package.path = package.path .. ';?/init.lua'
require('sstrict')
require('test') -- should end up requiring ./test/init.lua

Code: Select all

Error: sstrict.lua:656: file not found:test
The test module exists and does work correctly without sstrict.lua.
If you want this to be 100% compatible with LÖVE, you have to respect love.filesystem.getRequirePath() as well.

C modules can't be required (file not found), nor can the built-in bit module, nor love modules.
Byte code is not accepted either, it should at least detect and ignore, or maybe warn about byte code.

Some valid LuaJIT syntax is not supported:

Code: Select all

local foo = 0x1ULL -- works
local foo = 0x1LL -- undefined variable 'LL'
local foo = 0x1ull -- undefined variable 'ull'
local foo = 0x1ll -- undefined variable 'll'
local foo = 1ULL -- undefined variable 'ULL'
local foo = 1LL -- undefined variable 'LL'
local foo = 0x1p1 -- undefined variable 'p1'
local foo = 12.5i -- undefined variable 'i'
Parser shits the bed sometimes with some edge cases:

Code: Select all

global1 = 'foo' -- sstrict complains correctly
--[[]] global2 = 'foo' -- not detected

Code: Select all

--[=[
nothing
]=]
-- (undefined variable 'nothing')

Code: Select all

#--[[ (first line of file)
-- rest of file is ignored
The first line in a file should be ignored if it starts with a # (per specification)

A scenario that is unsolvable with your general approach:

Code: Select all

local function foo()
	return baz
end
setfenv(foo, { baz = 'bar' })()
Basing a Lua parser in pattern matching is a nasty can of worms. Unless the subset you want to support is small enough to make it work, you might end up fixing edge cases until the end of times.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: SUPER STRICT for LUA

Post by ivan »

Thanks for the feedback, grump. I have pushed a fix on BitBucket for the following bugs:

Code: Select all

local foo = 0x1ULL -- works
local foo = 0x1LL -- undefined variable 'LL'
local foo = 0x1ull -- undefined variable 'ull'
local foo = 0x1ll -- undefined variable 'll'
local foo = 1ULL -- undefined variable 'ULL'
local foo = 1LL -- undefined variable 'LL'
I need help/documentation regarding:

Code: Select all

local foo = 0x1p1 -- undefined variable 'p1'
local foo = 12.5i -- undefined variable 'i'
The comments thing is a little more complicated. It is possible to solve these bugs but yea I will have to think about this one.
I promise to look into the require path issue too.
A scenario that is unsolvable with your general approach:
Yes, "setfenv" is not supported. A partial solution could be to use the traditional "strict.lua" in conjunction with SUPERSTRICT. Note that loadstring is not supported either at the time of this post.
Basing a Lua parser in pattern matching is a nasty can of worms
You are correct. Parsing the entire Lua language is a big task. SUPERSTRICT is NOT perfect by any means and it's open source if you want to contribute. Generally speaking it does help in finding bugs that are missed completely by "strict.lua"
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: SUPER STRICT for LUA

Post by grump »

ivan wrote: Mon Jan 11, 2021 1:50 pm I need help/documentation regarding:

Code: Select all

local foo = 0x1p1 -- undefined variable 'p1'
local foo = 12.5i -- undefined variable 'i'
p/P is used for binary exponents. It's a Lua 5.2 thing that's also supported in LuaJIT.
The i/I suffix is an obscure LuaJIT feature (bottom of the page) to specify the imaginary part of complex numbers.

Allowing directives in the code to exclude chunks from checks would be helpful. Something like

Code: Select all

--!nostrict
local function foo()
	return baz
end
--!strict
setfenv(foo, { baz = 'bar' })()
That would allow unsupported/problematic code in projects that want to use sstrict.
User avatar
pgimeno
Party member
Posts: 3673
Joined: Sun Oct 18, 2015 2:58 pm

Re: SUPER STRICT for LUA

Post by pgimeno »

Funny, for me, PUC Lua 5.1 accepts 0x1p3 but not 0x1.0p3.

Formally, hex floats are numbers of the form 0x{hex digits}[. [hex digits]]p[+/-]{dec digits}, or 0x{. hex digits}p[+/-]{dec digits} (case insensitive), where [] indicates optional and {} mandatory. They are always in mantissa-exponent notation, where the mantissa is a hex number and the exponent (the number after the p) is a power of 2 instead of 10.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: SUPER STRICT for LUA

Post by ivan »

Thanks again for the feedback.

I have changed the following patterns:

Code: Select all

hexp = "0x%x+[Pp][%-%+]?%x"
float = "%d*%.%d+[Ii]?"
So I think this should handle most of these weird-looking numbers, but more testing wouldn't hurt.

Additionally the comment bugs should be fixed after the latest patch on Bitbucket.
I have added the love2d require path too. Can you please check that it works on your machine?

I have also added the following one-liner (no spaces) which toggles the error reporting on and off:

Code: Select all

--!strict
This one will need more work and testing because I'm NOT sure that you can disable SUPERSTRICT for just a section of the file.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: SUPER STRICT for LUA

Post by grump »

ivan wrote: Mon Jan 11, 2021 6:32 pm I have added the love2d require path too. Can you please check that it works on your machine?
Nice. package.path and love's require path are working for me now.

Note that [[double brackets]] can have any number of [===]equal signs[===] inside them, but it's still considered a double bracket. There seems to be a parser issue left with that syntax:

Code: Select all

-- this code does not trigger any errors or warnings in sstrict
--[=[ i'm just a comment lol ]=]
global = 1

-- ...while this does
--[[ i'm just a comment lol ]]
global = 1
This one will need more work and testing because I'm NOT sure that you can disable SUPERSTRICT for just a section of the file.
Fair enough, but imo some kind of control is required, because making changes to correct code just to overcome the shortcomings of an analyzer is too much to ask. I think it's perfectly fine to provide an opt out with a fine level of granularity to help resolve the static analysis vs. dynamic runtime problem.

I tried using it with a larger project, but it really doesn't like C modules. And C modules exporting globals is probably double the trouble.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: SUPER STRICT for LUA

Post by ivan »

Sorry about that, I have pushed another fix and the comment issue seems to be resolved now.
Note that [[double brackets]] can have any number of [===]equal signs[===] inside them
Thanks, I was not aware of this!
Fair enough, but imo some kind of control is required, because making changes to correct code just to overcome the shortcomings of an analyzer is too much to ask
Just put --!strict at the top of the file and that should disable all error messages
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: SUPER STRICT for LUA

Post by ivan »

I tried using it with a larger project, but it really doesn't like C modules. And C modules exporting globals is probably double the trouble.
I'll make if work if you show me a concrete example.
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests