From 66c66d8db8ab5cb6d0c6d85d64556d7cf20b04fa Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 13 Apr 2023 17:34:47 +0100 Subject: [PATCH] fix(loader): reset hashes when running the loader --- runtime/lua/vim/loader.lua | 18 +++++++++++---- test/functional/lua/loader_spec.lua | 36 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 test/functional/lua/loader_spec.lua diff --git a/runtime/lua/vim/loader.lua b/runtime/lua/vim/loader.lua index 38b1e9fc0f..7f953adc21 100644 --- a/runtime/lua/vim/loader.lua +++ b/runtime/lua/vim/loader.lua @@ -5,7 +5,7 @@ local loaders = package.loaders local M = {} ----@alias CacheHash {mtime: {sec:number, nsec:number}, size:number, type: string} +---@alias CacheHash {mtime: {nsec: integer, sec: integer}, size: integer, type?: uv.aliases.fs_stat_types} ---@alias CacheEntry {hash:CacheHash, chunk:string} ---@class ModuleFindOpts @@ -28,12 +28,11 @@ M.enabled = false ---@field _rtp string[] ---@field _rtp_pure string[] ---@field _rtp_key string +---@field _hashes? table local Loader = { VERSION = 3, ---@type table> _indexed = {}, - ---@type table - _hashes = {}, ---@type table _topmods = {}, _loadfile = loadfile, @@ -44,9 +43,13 @@ local Loader = { } --- @param path string ---- @return uv.fs_stat.result +--- @return CacheHash --- @private function Loader.get_hash(path) + if not Loader._hashes then + return uv.fs_stat(path) --[[@as CacheHash]] + end + if not Loader._hashes[path] then -- Note we must never save a stat for a non-existent path. -- For non-existent paths fs_stat() will return nil. @@ -163,13 +166,16 @@ end ---@return string|function ---@private function Loader.loader(modname) + Loader._hashes = {} local ret = M.find(modname)[1] if ret then -- Make sure to call the global loadfile so we respect any augmentations done elsewhere. -- E.g. profiling local chunk, err = loadfile(ret.modpath) + Loader._hashes = nil return chunk or error(err) end + Loader._hashes = nil return '\ncache_loader: module ' .. modname .. ' not found' end @@ -373,7 +379,9 @@ function M.reset(path) end -- Path could be a directory so just clear all the hashes. - Loader._hashes = {} + if Loader._hashes then + Loader._hashes = {} + end end --- Enables the experimental Lua module loader: diff --git a/test/functional/lua/loader_spec.lua b/test/functional/lua/loader_spec.lua new file mode 100644 index 0000000000..e2958d1592 --- /dev/null +++ b/test/functional/lua/loader_spec.lua @@ -0,0 +1,36 @@ +-- Test suite for testing interactions with API bindings +local helpers = require('test.functional.helpers')(after_each) + +local exec_lua = helpers.exec_lua +local command = helpers.command +local eq = helpers.eq + +describe('vim.loader', function() + before_each(helpers.clear) + + it('handles changing files (#23027)', function() + exec_lua[[ + vim.loader.enable() + ]] + + local tmp = helpers.tmpname() + command('edit ' .. tmp) + + eq(1, exec_lua([[ + vim.api.nvim_buf_set_lines(0, 0, -1, true, {'_G.TEST=1'}) + vim.cmd.write() + loadfile(...)() + return _G.TEST + ]], tmp)) + + -- fs latency + helpers.sleep(10) + + eq(2, exec_lua([[ + vim.api.nvim_buf_set_lines(0, 0, -1, true, {'_G.TEST=2'}) + vim.cmd.write() + loadfile(...)() + return _G.TEST + ]], tmp)) + end) +end)