LuaLS / lua-language-server

A language server that offers Lua language support - programmed in Lua
https://luals.github.io
MIT License
3.26k stars 306 forks source link

`userdata` misinterpreted as `number` #1991

Closed AndreasMatthias closed 1 year ago

AndreasMatthias commented 1 year ago

How are you using the lua-language-server?

Other

Which OS are you using?

Linux

What is the issue affecting?

Type Checking

Expected Behaviour

In the example given below, variable ab shall have type userdata.

Actual Behaviour

Variable ab has type number.

Reproduction steps

I have this meta definition file:

---@meta

---@class lpeg
local lpeg = {}

---@param set string
---@return userdata # Lpeg pattern.
function lpeg.S(set)
end

---@param patt userdata # Lpeg pattern.
---@param subject string # String to be matched.
---@param start? integer # Index.
---@return integer | string | table
function lpeg.match(patt, subject, start)
end

return lpeg

And this is the actual lua file:

local lpeg = require('lpeg')

local ab = lpeg.S('ab') ^ 0

local res = lpeg.match(ab, 'aaa')
print(res)

Now lsp-language-server reports a warning for function match saying Cannot assign 'number' to parameter 'userdata'. Function match expects a userdata as first argument, but lsp-language-server things that variable ab is of type number.

Additional Notes

No response

Log File

No response

firas-assaad commented 1 year ago

I'm not familiar with the lpeg API, but does the pattern have to be userdata? Can't you define a class for the pattern with the appropriate operators?

e.g.

---@class lpeg
local lpeg = {}

---@class lpeg_pattern
---@operator pow(number) : lpeg_pattern

---@param set string
---@return lpeg_pattern # Lpeg pattern.
function lpeg.S(set)
end

---@param patt lpeg_pattern # Lpeg pattern.
---@param subject string # String to be matched.
---@param start? integer # Index.
---@return integer | string | table
function lpeg.match(patt, subject, start)
end
firas-assaad commented 1 year ago

By the way, it looks like there's already an addon/library for lpeg: https://github.com/LuaCATS/lpeg/blob/e4115543d25d72c3aeae87d36a100a4e7ff8eea0/library/lpeg.lua

Perhaps you can use it directly or as an inspiration.

AndreasMatthias commented 1 year ago

I'm not familiar with the lpeg API, but does the pattern have to be userdata? Can't you define a class for the pattern with the appropriate operators?

This is very good idea. And now the tooltips display the name of the class instead of userdata which is even better.

By the way, it looks like there's already an addon/library for lpeg: https://github.com/LuaCATS/lpeg/blob/e4115543d25d72c3aeae87d36a100a4e7ff8eea0/library/lpeg.lua

Oh, I guess this is exactly what I was looking for. Thank you.