IntelliJ-Luanalysis
IntelliJ-Luanalysis copied to clipboard
Tables can not easily be declared by inference
Environment
Name | Version |
---|---|
IDEA version | IntelliJ IDEA 2021.2.3 |
Luanalysis version | 1.3.0 |
OS | Windows 10 2004 build 19041.928 x86_64 |
Preferences
Lua
Name | Setting |
---|---|
Language level | Lua 5.1 |
Type Safety
Name | Setting |
---|---|
Strict nil checks | ☑️ |
Unknown type (any) is indexable | ❎ |
Unknown type (any) is callabale | ❎ |
What are the steps to reproduce this issue?
- Download this file: https://gist.github.com/LoganDark/04bd291d585e5f054c63958bbf08ff12 (work in progress actually up-to-date OpenResty types)
- Open it in in your IDE
- You will see Luanalysis sometimes decides the file has 92 errors, and sometimes decides there are no errors at all.
- Press space anywhere in the file and it will probably flip its decision. Same with pressing Ctrl+S or doing pretty much anything
What happens?
https://user-images.githubusercontent.com/4723091/162651248-6bb9b83d-1dae-495e-b567-b7bdf9200736.mp4
What were you expecting to happen?
no errors
Any logs, error output, etc?
Nope
Any other comments?
I can't do this by declaring everything in the table constructor because of #120. The combination of the two make it extremely infuriating to try to declare the existence of a large environment.
It may be worth adopting something similar to Luau's "sealed/unsealed tables", where, in the scope where a table is first declared as {}
, it is "unsealed" and therefore legal to add any new fields/functions to it and the table's type will be inferred using those members. Outside the declaring scope, or if the table was declared with a different literal, then it is "sealed", which means its type is known and will not be inferred further.
Okay so I kind of figured out what I want to do - if I slap ---@module ngx
(which is completely undocumented by the way!) at the top of that file, then all the globals it defines become members of a type called ngx
. Then I can do this:
local ngx = --[[---@type ngx]] require('ngx')
which only works because OpenResty allows me to require
ngx
, but is also inefficient because it's a function call at runtime - whatever, who cares. If that's what it takes for static analysis then I guess I can take the hit.
(edit 2: turns out you can just slap ngx = --[[---@type ngx]] require('ngx')
into any random lua file, even one you don't actually execute, and ngx
will be recognized as a global. Cool beans.)
Weirdly, when I switched the module to using @module
, there are no errors at all! I added the working version to the gist (as ngx.fixed.def.lua
).
edit: Leaving this issue open because the nondeterminism is back. It's just using globals skirts around the issue a bit, but setting properties on nested tables (even within a module) still raises errors.
Using --- @class whatever
on each table that needs to be declared by inference works, but pollutes the global type scope