aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/iter.lua
diff options
context:
space:
mode:
authorGregory Anders <8965202+gpanders@users.noreply.github.com>2023-04-21 16:13:39 -0600
committerGitHub <noreply@github.com>2023-04-21 16:13:39 -0600
commitf68af3c3bc92c12f7dbbd32f44df8ab57a58ac98 (patch)
tree2e50afffb1a3b6e6d32f95df55b83fb0eadd24fb /runtime/lua/vim/iter.lua
parentef92b5a9948f2fb6042ae0c842bfb4301b1894c3 (diff)
downloadrneovim-f68af3c3bc92c12f7dbbd32f44df8ab57a58ac98.tar.gz
rneovim-f68af3c3bc92c12f7dbbd32f44df8ab57a58ac98.tar.bz2
rneovim-f68af3c3bc92c12f7dbbd32f44df8ab57a58ac98.zip
refactor(iter): use metatable as packed table tag (#23254)
This is a more robust method for tagging a packed table as it completely eliminates the possibility of mistaking an actual table key as the packed table tag.
Diffstat (limited to 'runtime/lua/vim/iter.lua')
-rw-r--r--runtime/lua/vim/iter.lua35
1 files changed, 20 insertions, 15 deletions
diff --git a/runtime/lua/vim/iter.lua b/runtime/lua/vim/iter.lua
index c5d5ef835b..2545853b41 100644
--- a/runtime/lua/vim/iter.lua
+++ b/runtime/lua/vim/iter.lua
@@ -18,10 +18,13 @@ ListIter.__call = function(self)
return self:next()
end
+--- Packed tables use this as their metatable
+local packedmt = {}
+
---@private
local function unpack(t)
- if type(t) == 'table' and t.__n ~= nil then
- return _G.unpack(t, 1, t.__n)
+ if getmetatable(t) == packedmt then
+ return _G.unpack(t, 1, t.n)
end
return t
end
@@ -30,11 +33,20 @@ end
local function pack(...)
local n = select('#', ...)
if n > 1 then
- return { __n = n, ... }
+ return setmetatable({ n = n, ... }, packedmt)
end
return ...
end
+---@private
+local function sanitize(t)
+ if getmetatable(t) == packedmt then
+ -- Remove length tag
+ t.n = nil
+ end
+ return t
+end
+
--- Add a filter step to the iterator pipeline.
---
--- Example:
@@ -208,12 +220,7 @@ function Iter.totable(self)
break
end
- if type(args) == 'table' then
- -- Removed packed table tag if it exists
- args.__n = nil
- end
-
- t[#t + 1] = args
+ t[#t + 1] = sanitize(args)
end
return t
end
@@ -221,12 +228,10 @@ end
---@private
function ListIter.totable(self)
if self._head == 1 and self._tail == #self._table + 1 and self.next == ListIter.next then
- -- Remove any packed table tags
- for i = 1, #self._table do
- local v = self._table[i]
- if type(v) == 'table' then
- v.__n = nil
- self._table[i] = v
+ -- Sanitize packed table values
+ if getmetatable(self._table[1]) == packedmt then
+ for i = 1, #self._table do
+ self._table[i] = sanitize(self._table[i])
end
end
return self._table