lua-language-server
lua-language-server copied to clipboard
enum error
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
The notification indicates an invalid enumeration value.
Actual Behaviour
The enumeration variable is assigned incorrect values without any notification.
Reproduction steps
---@enum NPBehaveNodeState
NPBehaveNodeState = {
Inactive = "Inactive",
Active = "Active",
StopRequested = "StopRequested",
}
---@class Test
---@field CurrentState NPBehaveNodeState
local test = {}
test.CurrentState = NPBehaveNodeState.Active
-- no error prompt.
test.CurrentState = NPBehaveNodeState.Active123
Additional Notes
No response
Log File
No response
related #2377
I use enums generated at runtime and since there is no way to annotate a variable as @enum
I generate additional @class like this:
---@diagnostic disable: unused-local
--luacheck: ignore
---@enum Status
local _ = {
UNKNOWN = 0,
NEW = 1,
OLD = 2,
}
---@class Status.enum: {}
---@field UNKNOWN Status|Status.UNKNOWN: 0
---@field NEW Status|Status.NEW: 1
---@field OLD Status|Status.OLD: 2
---@return Status.enum
local function generate_enum()
return {}
end
local Status = generate_enum()
---@type Status.OLD
local s_old = Status.OLD
---@type Status
local s = Status.UNKNOWN
s = Status.NEW
s = Status.OLD
s = Status.QWE -- Undefined field `QWE`
s = 0
I would also like = 0 to throw warning
yes. Its kinda pointless to have enum if no errors are thrown when you use invalid values
i'm having to use a class instead
---@class sfxChar
---@field jump string
---@field get_item string
sfxChar = {
jump = 'jump',
get_item = 'get_item',
}
function lol()
print(sfxChar.blaaaa); -- throws error
end
Simpler example which also fails:
---@enum NPBehaveNodeState
NPBehaveNodeState = {
Inactive = 'Inactive',
Active = 'Active',
StopRequested = 'StopRequested',
}
---@type NPBehaveNodeState
local test
-- this errors correctly
test = 'Active123'
-- this doesn't error, incorrect
test = NPBehaveNodeState.Active123
Basically it only validates when passed a literal (string in this case)...
duplicate of https://github.com/LuaLS/lua-language-server/issues/2384
And as I commented there:https://github.com/LuaLS/lua-language-server/issues/2384#issuecomment-2198052928, undefined-field diagnostics only check for typed tables (for performance reason I guess), but the enum binded table are not typed. If somehow the binded tables can be marked with some special flags, then maybe they can also be checked in the undefined-field diagnostics 😕
Currently my workaround is to also annotate the table with ---@class:
---@enum TestEnum.*
local TestEnum = { ---@class TestEnum
a = 1,
b = 2,
c = 3,
}
---@type TestEnum.*
local a = TestEnum.a --< ok
---@type TestEnum.*
local d = TestEnum.d --< undefined field
duplicate of #2384
And as I commented there:#2384 (comment),
undefined-fielddiagnostics only check for typed tables (for performance reason I guess), but the enum binded table are not typed. If somehow the binded tables can be marked with some special flags, then maybe they can also be checked in theundefined-fielddiagnostics 😕Currently my workaround is to also annotate the table with
---@class:---@enum TestEnum.* local TestEnum = { ---@class TestEnum a = 1, b = 2, c = 3, } ---@type TestEnum.* local a = TestEnum.a --< ok ---@type TestEnum.* local d = TestEnum.d --< undefined field
FUCK ME THIS WORKS THANSK
U R THE HERO OF THE DAY
gonna make a replace macro right now
---@enum (.*)
(.*)\{
---@enum $1.*
$2{ ---@class $1
if anyone wants to replace
Actually you don't need to follow my annotation practice exactly 😂 (I mean the TestEnum.*)
You can keep you enum type name as TestEnum, then name the underlying class to something like _TestEnum.
The key point is also annotate the table with ---@class (with whichever name you want)
Maybe that way you can modify less codes @dganzella
The following should also work
---@enum TestEnum
local TestEnum = { ---@class _TestEnum
a = 1,
b = 2,
c = 3,
}
---@type TestEnum
local a = TestEnum.a --< ok
---@type TestEnum
local d = TestEnum.d --< undefined field
Actually you don't need to follow my annotation practice exactly 😂 (I mean the TestEnum
.*) You can keep you enum type name asTestEnum, then name the underlying class to something like_TestEnum. The key point is also annotate the table with---@class(with whichever name you want)Maybe that way you can modify less codes @dganzella
The following should also work
---@enum TestEnum local TestEnum = { ---@class _TestEnum a = 1, b = 2, c = 3, } ---@type TestEnum local a = TestEnum.a --< ok ---@type TestEnum local d = TestEnum.d --< undefined field
haha yes I noticed that and changed the replace macro to add the .* to the class annotation instead of the enum
I did like the .*
Anyway, I was INSTANTLY able to spot two snaeaky issues in my code. Thank you
@sumneko please fix
@sumneko please fix
@sumneko is quite the character
- makes an amazing tool with just a simple missing feature
- refuses to elaborate
- leaves
gigachad
Like many of us, the author has a full time job. 😅 The amazing thing about open source projects is that contributions are welcome, and maybe we can fix something that we desperately want on our own. 👀
Like many of us, the author has a full time job. 😅 The amazing thing about open source projects is that contributions are welcome, and maybe we can fix something that we desperately want on our own. 👀
👀 The amazing thing is that we would need to learn the entire thing just to make something that clearly can be easily done by him since the behaviour is present in other annotations. It's not a different feature or some kind of extension.
Of course I know he is not obliged to do anything, I'm not retarded, the funny thing is just to run a marathon just to give up 2 meters from the goal. And its just a fun remark, not an actual complaint.
Temporary solution:
Modify C:\Users\<UserName>\.vscode\extensions\sumneko.lua-3.10.3-win32-x64\server
Index: script/vm/compiler.lua
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
--- a/script/vm/compiler.lua (revision 2fe2ff371a8d2ee97a46c1b48eb421d9f8ee65ad)
+++ b/script/vm/compiler.lua (date 1723768685862)
@@ -73,6 +73,24 @@
return false
end
+-- 该函数有副作用,会给source绑定node!
+---@param source parser.object
+---@return boolean
+function vm.bindDocsEnum(source)
+ local docs = source.value.bindDocs
+ if not docs then
+ return false
+ end
+ for i = #docs, 1, -1 do
+ local doc = docs[i]
+ if doc.type == 'doc.enum' then
+ vm.setNode(source, vm.compileNode(doc))
+ return true
+ end
+ end
+ return false
+end
+
---@param source parser.object | vm.variable
---@param key string|vm.global|vm.ANY
---@param pushResult fun(res: parser.object, markDoc?: boolean)
@@ -1105,6 +1123,8 @@
local hasMarkDoc
if source.bindDocs then
hasMarkDoc = vm.bindDocs(source)
+ elseif source.value and source.value.bindDocs then
+ hasMarkDoc = vm.bindDocsEnum(source)
end
local hasMarkParam
if not hasMarkDoc then
The structure of Enum is not consistent with that of Class, but the error from Class was borrowed here, so this solution is temporary.
@sumneko can pr?
I tested the patch and it works (can throw undefined error) 🎉 . But seems there is a side effect:
- when hover preview over the table, the content is displayed twice
I guess it's because now the enum type is injected into this table (through the vm.setNode in vm.bindDocsEnum) 🤔
I will look into it today
enum 的问题有点复杂,见下面这个例子:
---@enum A
local t = {
x = 1,
y = 2,
}
---@param x A
local function f(x) end
从下面的用法来看,A 其实等价于 ---@alias A 1|2,问题是 local t 是什么?
目前的实现里,t 什么都不是,直接没有和任何 doc 进行绑定,这就是为什么使用 t.z 不会出现警告。
如果一定要给 t 一个类型,那么应该是 { [any]: A } ,因此你不能将 A 直接绑定给 t。
我目前的想法是生成一个特殊命名的class给 t 。
改的时候就发现了, enum并不是独立的类型, 我觉得给enum类型加个独有字段用于诊断未定义的值最简单
@sumneko (partial) 失效
The following 2 related/duplicated issues can also be closed:
- https://github.com/LuaLS/lua-language-server/issues/1750
- https://github.com/LuaLS/lua-language-server/issues/2384