Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 45650db

Browse files
committed
fix: typed @field should not override other defined field
1 parent 32fec3c commit 45650db

File tree

3 files changed

+73
-38
lines changed

3 files changed

+73
-38
lines changed

‎changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44
<!-- Add all new changes here. They will be moved under a version at release -->
5+
* `FIX` Typed `@field` (eg `---@field [string] boolean`) should not override other defined field [#2171](https://github.com/LuaLS/lua-language-server/issues/2171), [#2711](https://github.com/LuaLS/lua-language-server/issues/2711)
56

67
## 3.15.0
78
`2025年6月25日`

‎script/vm/compiler.lua

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -434,44 +434,6 @@ function vm.getClassFields(suri, object, key, pushResult)
434434
pushResult(field, true)
435435
goto CONTINUE
436436
end
437-
if hasFounded[key] then
438-
goto CONTINUE
439-
end
440-
local keyType = type(key)
441-
if keyType == 'table' then
442-
-- ---@field [integer] boolean -> class[integer]
443-
local fieldNode = vm.compileNode(field.field)
444-
if vm.isSubType(suri, key.name, fieldNode) then
445-
local nkey = '|' .. key.name
446-
if not searchedFields[nkey] then
447-
pushResult(field, true)
448-
hasFounded[nkey] = true
449-
end
450-
end
451-
else
452-
local keyObject
453-
if keyType == 'number' then
454-
if math.tointeger(key) then
455-
keyObject = { type = 'integer', [1] = key }
456-
else
457-
keyObject = { type = 'number', [1] = key }
458-
end
459-
elseif keyType == 'boolean'
460-
or keyType == 'string' then
461-
keyObject = { type = keyType, [1] = key }
462-
end
463-
if keyObject and field.field.type ~= 'doc.field.name' then
464-
-- ---@field [integer] boolean -> class[1]
465-
local fieldNode = vm.compileNode(field.field)
466-
if vm.isSubType(suri, keyObject, fieldNode) then
467-
local nkey = '|' .. keyType
468-
if not searchedFields[nkey] then
469-
pushResult(field, true)
470-
hasFounded[nkey] = true
471-
end
472-
end
473-
end
474-
end
475437
::CONTINUE::
476438
end
477439
end
@@ -547,6 +509,59 @@ function vm.getClassFields(suri, object, key, pushResult)
547509
end
548510
copyToSearched()
549511

512+
-- search for typed @field, eg: ---@field [string] boolean
513+
-- only if type for this field key is not found
514+
if not searchedFields[key] and key ~= vm.ANY and key ~= vm.ANYDOC then
515+
for _, set in ipairs(sets) do
516+
if set.type == 'doc.class' then
517+
for _, field in ipairs(set.fields) do
518+
local fieldKey = guide.getKeyName(field)
519+
if fieldKey then
520+
-- already processed above
521+
goto CONTINUE
522+
end
523+
local keyType = type(key)
524+
if keyType == 'table' then
525+
-- ---@field [integer] boolean -> class[integer]
526+
local fieldNode = vm.compileNode(field.field)
527+
if vm.isSubType(suri, key.name, fieldNode) then
528+
local nkey = '|' .. key.name
529+
if not searchedFields[nkey] then
530+
pushResult(field, true)
531+
hasFounded[nkey] = true
532+
end
533+
end
534+
else
535+
local keyObject
536+
if keyType == 'number' then
537+
if math.tointeger(key) then
538+
keyObject = { type = 'integer', [1] = key }
539+
else
540+
keyObject = { type = 'number', [1] = key }
541+
end
542+
elseif keyType == 'boolean'
543+
or keyType == 'string' then
544+
keyObject = { type = keyType, [1] = key }
545+
end
546+
if keyObject and field.field.type ~= 'doc.field.name' then
547+
-- ---@field [integer] boolean -> class[1]
548+
local fieldNode = vm.compileNode(field.field)
549+
if vm.isSubType(suri, keyObject, fieldNode) then
550+
local nkey = '|' .. keyType
551+
if not searchedFields[nkey] then
552+
pushResult(field, true)
553+
hasFounded[nkey] = true
554+
end
555+
end
556+
end
557+
end
558+
::CONTINUE::
559+
end
560+
end
561+
end
562+
copyToSearched()
563+
end
564+
550565
for _, set in ipairs(sets) do
551566
if set.type == 'doc.class' then
552567
-- look into extends(if field not found)

‎test/type_inference/common.lua

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,6 +3608,25 @@ local t
36083608
local <?x?> = t.n
36093609
]]
36103610

3611+
TEST 'function' [[
3612+
---@class A
3613+
---@field [string] boolean
3614+
local t
3615+
function t.f() end
3616+
3617+
local <?f?> = t.f
3618+
]]
3619+
3620+
TEST 'function' [[
3621+
---@class A
3622+
---@field [string] boolean
3623+
local t = {
3624+
f = function () end
3625+
}
3626+
3627+
local <?f?> = t.f
3628+
]]
3629+
36113630
TEST 'string' [[
36123631
---@class string
36133632
---@operator mod: string

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /