fix(cache): check package.loaded after auto-load and return existing module if present. Fixes #224

This commit is contained in:
Folke Lemaitre 2022-12-29 09:06:23 +01:00
parent b8c5ab5dae
commit 044e28bf8b
No known key found for this signature in database
GPG Key ID: 41F8B1FBACAE2040
1 changed files with 23 additions and 9 deletions

View File

@ -103,6 +103,16 @@ function M.disable()
M.enabled = false M.enabled = false
end end
function M.check_loaded(modname)
---@diagnostic disable-next-line: no-unknown
local mod = package.loaded[modname]
if type(mod) == "table" then
return function()
return mod
end
end
end
---@param modname string ---@param modname string
---@return any ---@return any
function M.loader(modname) function M.loader(modname)
@ -111,12 +121,6 @@ function M.loader(modname)
local chunk, err local chunk, err
if entry and M.check_path(modname, entry.modpath) then if entry and M.check_path(modname, entry.modpath) then
M.stats.find.total = M.stats.find.total + 1 M.stats.find.total = M.stats.find.total + 1
local mod = package.loaded[modname]
if type(mod) == "table" then
return function()
return mod
end
end
chunk, err = M.load(modname, entry.modpath) chunk, err = M.load(modname, entry.modpath)
end end
if not chunk then if not chunk then
@ -127,10 +131,13 @@ function M.loader(modname)
if M.enabled then if M.enabled then
chunk, err = M.load(modname, modpath) chunk, err = M.load(modname, modpath)
else else
chunk = M.check_loaded(modname)
if not chunk then
chunk, err = M._loadfile(modpath) chunk, err = M._loadfile(modpath)
end end
end end
end end
end
return chunk or (err and error(err)) or "not found in lazy cache" return chunk or (err and error(err)) or "not found in lazy cache"
end end
@ -145,6 +152,11 @@ end
---@param modpath string ---@param modpath string
---@return function?, string? error_message ---@return function?, string? error_message
function M.load(modkey, modpath) function M.load(modkey, modpath)
local chunk, err
chunk = M.check_loaded(modkey)
if chunk then
return chunk
end
modpath = modpath:gsub("\\", "/") modpath = modpath:gsub("\\", "/")
local hash = M.hash(modpath) local hash = M.hash(modpath)
if not hash then if not hash then
@ -158,7 +170,7 @@ function M.load(modkey, modpath)
entry.used = os.time() entry.used = os.time()
if M.eq(entry.hash, hash) then if M.eq(entry.hash, hash) then
-- found in cache and up to date -- found in cache and up to date
local chunk, err = loadstring(entry.chunk --[[@as string]], "@" .. entry.modpath) chunk, err = loadstring(entry.chunk --[[@as string]], "@" .. entry.modpath)
if not (err and err:find("cannot load incompatible bytecode", 1, true)) then if not (err and err:find("cannot load incompatible bytecode", 1, true)) then
return chunk, err return chunk, err
end end
@ -175,7 +187,7 @@ function M.load(modkey, modpath)
end) end)
end end
local chunk, err = M._loadfile(entry.modpath) chunk, err = M._loadfile(entry.modpath)
if chunk then if chunk then
M.dirty = true M.dirty = true
entry.chunk = string.dump(chunk) entry.chunk = string.dump(chunk)
@ -184,7 +196,9 @@ function M.load(modkey, modpath)
end end
function M.require(modname) function M.require(modname)
---@diagnostic disable-next-line: no-unknown
local mod = M.loader(modname)() local mod = M.loader(modname)()
---@diagnostic disable-next-line: no-unknown
package.loaded[modname] = mod package.loaded[modname] = mod
return mod return mod
end end