Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased
<!-- Add all new changes here. They will be moved under a version at release -->
* `FIX` Deduplicate documentation bindings for parameters

## 3.17.1
`2026-01-20`
Expand Down
33 changes: 33 additions & 0 deletions script/parser/luadoc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2199,6 +2199,38 @@ local function bindDocWithSources(sources, binded)
end
end

local docsDedupe = function (sources)
local removeByValue = function(bindDocs, value)
for i = #bindDocs, 1, -1 do
if bindDocs[i] == value then
table.remove(bindDocs, i)
break
end
end
end
for _, source in ipairs(sources) do
if source.bindDocs then
local docs = {}
for i = #source.bindDocs, 1, -1 do
local doc = source.bindDocs[i]
if doc.type == 'doc.param' and doc.param[1] then
local param1 = doc.param[1]
if docs[param1] then
local old = docs[param1]
if old.virtual and not doc.virtual then
removeByValue(source.bindDocs, old)
elseif not old.virtual and doc.virtual then
removeByValue(source.bindDocs, doc)
doc = old
end
Comment on lines +2220 to +2225

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

old.virtualdoc.virtual 状态相同时(都为 true 或都为 false),当前逻辑不会移除任何一个重复的参数文档,这会导致重复的文档仍然存在。你应该处理这种情况,例如,保留文件中先出现的文档(索引较低的那个)。

此外,removeByValue 函数每次调用都会遍历 bindDocs,导致此去重逻辑在最坏情况下的时间复杂度为 O(N^2)。对于有很多参数的函数,这可能会成为性能瓶颈。

我建议修改逻辑以处理所有重复情况,并考虑一个更高效的 O(N) 实现来构建一个新的 bindDocs 列表,而不是在迭代时从中移除元素。

                        if old.virtual and not doc.virtual then
                            removeByValue(source.bindDocs, old)
                        elseif not old.virtual and doc.virtual then
                            removeByValue(source.bindDocs, doc)
                            doc = old
                        else -- both virtual or both not virtual, keep the one with lower index ('doc')
                            removeByValue(source.bindDocs, old)
                        end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同时为virtual或者同时都不是virtual,这是人为写出来的,可以自己避免,正常使用不会这么写,给一个函数加两个一模一样的virtual,或者在一个函数写两个一模一样的@param注释。

最快的情况下O(N^2),通常是为每一个参数都加了虚拟注解,又重新写了每一个参数的真实注解,这种情况我认为也是不合理使用导致的,我们为某种规则的函数,根据规定用plugin定义了参数,说明是大部分都是正确的才会这样用,也就是大部分都不需要重写param

end
docs[param1] = doc
end
end
end
end
end

local bindDocAccept = {
'local' , 'setlocal' , 'setglobal',
'setfield' , 'setmethod' , 'setindex' ,
Expand Down Expand Up @@ -2253,6 +2285,7 @@ local function bindDocs(state)
end
end
end
docsDedupe(sources)
end

local function findTouch(state, doc)
Expand Down
Loading