diff options
-rw-r--r-- | server/src/matcher/vm.lua | 47 | ||||
-rw-r--r-- | server/src/service.lua | 18 |
2 files changed, 51 insertions, 14 deletions
diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua index 07b41d62..1891b61b 100644 --- a/server/src/matcher/vm.lua +++ b/server/src/matcher/vm.lua @@ -474,10 +474,7 @@ function mt:callRequire(func, values) end local requireValue = self:createValue('boolean', nil, true) self:setFunctionReturn(func, 1, requireValue) - self.requires[#self.requires+1] = { - str = str, - value = requireValue, - } + self.requires[requireValue] = str end function mt:call(func, values) @@ -1188,22 +1185,44 @@ function mt:mergeRequire(value, destVM) self:mergeValue(value, mainValue) end -function mt:loadRequires(lsp) - for _, req in ipairs(self.requires) do - local str = req.str +function mt:loadRequires() + if not self.lsp or not self.lsp.workspace then + return + end + for value, str in ipairs(self.requires) do + self.requires[value] = nil if type(str) == 'string' then local uri = lsp.workspace:searchPath(str) -- 如果循环require,这里会返回nil + -- 会当场编译VM local destVM = lsp:loadVM(uri) if destVM then - self:mergeRequire(req.value, destVM) + self:mergeRequire(value, destVM) end end end - self.requires = {} end -local function compile(ast, lsp) +function mt:tryLoadRequires() + if not self.lsp or not self.lsp.workspace then + return + end + for value, str in ipairs(self.requires) do + self.requires[value] = nil + if type(str) == 'string' then + local uri = lsp.workspace:searchPath(str) + -- 如果取不到VM,则做个标记,之后再取一次 + local destVM = lsp:getVM(uri) + if destVM then + self:mergeRequire(value, destVM) + else + self.lsp:needRequires(self.uri) + end + end + end +end + +local function compile(ast, lsp, uri) local vm = setmetatable({ scope = env { locals = {}, @@ -1223,6 +1242,7 @@ local function compile(ast, lsp) libraryChild = {}, requires = {}, lsp = lsp, + uri = uri, }, mt) -- 创建初始环境 @@ -1231,14 +1251,17 @@ local function compile(ast, lsp) -- 执行代码 vm:doActions(ast) + -- 合并 + vm:loadRequires() + return vm end -return function (ast, lsp) +return function (ast, lsp, uri) if not ast then return nil end - local suc, res = xpcall(compile, log.error, ast, lsp) + local suc, res = xpcall(compile, log.error, ast, lsp, uri) if not suc then return nil end diff --git a/server/src/service.lua b/server/src/service.lua index 445572b7..43b59d52 100644 --- a/server/src/service.lua +++ b/server/src/service.lua @@ -239,18 +239,32 @@ function mt:compileVM(uri) self._needCompile[uri] = nil local ast = parser:ast(obj.text) - obj.vm = matcher.vm(ast, self) + obj.vm = matcher.vm(ast, self, uri) obj.lines = parser:lines(obj.text, 'utf8') if not obj.vm then return obj end self._needDiagnostics[uri] = true - self._needRequire[uri] = true return obj end +function mt:getVM(uri) + local obj = self._file[uri] + if not obj then + return nil + end + if self._needCompile[uri] then + return nil + end + return obj.vm +end + +function mt:needRequires(uri) + self._needRequire[uri] = true +end + function mt:_loadRequires() if not self.workspace then return |