Closed Rathoz closed 3 weeks ago
I think I've found the cause of this issue, in the compileFunctionParam()
of here: https://github.com/LuaLS/lua-language-server/blob/ba8f90eb0fab18ce8aee2bdbf7007dc63050381d/script/vm/compiler.lua#L1090-L1107
true
immediately after using the first function type's params' inferred view to set into the function object itselfI tried to remove this early break, and it can solve this issue:
local function compileFunctionParam(func, source)
-- local call ---@type fun(f: fun(x: number));call(function (x) end) --> x -> number
local funcNode = vm.compileNode(func)
local found = false
for n in funcNode:eachObject() do
...
found = true -- replace the original `return true`
...
end
if found then
return true
end
callargs
type (in another word callback) and the type narrow function fail to find the exact signature, this will cause the params in the callback function have combined types, and this is undesirable in many cases.
local e = defines.events
script.on_event(e.on_ai_command_completed, function (event)
-- before patch: `event` = `EventData.on_ai_command_completed`
-- after patch: `event` = `EventData|EventData.on_ai_command_completed`
end)
2
signatures matches, one with the event
as EventData.on_ai_command_completed
, the other with type EventData
rvalue
as the type, because the base function is inferred as:
function expect(x: ffi.cdata*, type: "rvalue")
-> gccjit.LValue*|gccjit.RValue*|gccjit.Type*
function expect(x: ffi.cdata*, type: "lvalue"|"rvalue"|"type")
-> gccjit.LValue*|gccjit.RValue*|gccjit.Type*
type
value: "lvalue"|"rvalue"|"type"
, all will match this base function, and no type narrow can be performed 😇
local lval = expect(data, "lvalue")
-> gccjit.LValue*|gccjit.RValue*|gccjit.Type*
-- because "lvalue" now matches the base function signature
PS: I am working on PR #2822 to try to fix that #2509 🤔
I just found out that even with my #2838, now although a
in Foo.Bar()
can be correctly inferred as string|number
, a:lower()
will not trigger warning 😅 . I think that's because the string.lower
actually accepts number
as the 1st param:
https://github.com/LuaLS/lua-language-server/blob/d1320ae5e41086fd9f569c2504a88130447444b8/meta/template/string.lua#L85-L88
string.lower
indeed accepts string|number
as 1st param, just that it doesn't allow number:lower()
call style, and it is not addressed in this issue nor in my PR #2838.
Maybe @Rathoz you have to open another issue for that 😂
Correct on string.lower() accpect string|number.
number
doesn't have any metatable, unlike string
. aString:lower()
is just syntactic sugar for aString.lower(aString)
which thanks the metatable turns into string.lower(aString)
. But do the same on a number aNumber:lower()
is tries to call the function aNumber.lower(aNumber)
, which doesn't exist.
I can open a new issue on it if you like
How are you using the lua-language-server?
Visual Studio Code Extension (sumneko.lua)
Which OS are you using?
Windows
What is the issue affecting?
Type Checking
Expected Behaviour
a
isstring|number
Actual Behaviour
a
isstring
Reproduction steps
Additional Notes
No response
Log File
No response