diff options
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/matcher/vm.lua | 34 | ||||
-rw-r--r-- | server/src/service.lua | 2 | ||||
-rw-r--r-- | server/src/workspace.lua | 33 |
3 files changed, 60 insertions, 9 deletions
diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua index f2b5b47b..3a272f3a 100644 --- a/server/src/matcher/vm.lua +++ b/server/src/matcher/vm.lua @@ -454,7 +454,12 @@ function mt:callRequire(func, values) return end end - self:setFunctionReturn(func, 1, nil) + local requireValue = self:createValue('boolean', nil, true) + self:setFunctionReturn(func, 1, requireValue) + self.requires[#self.requires+1] = { + str = str, + value = requireValue, + } end function mt:call(func, values) @@ -1152,7 +1157,23 @@ function mt:createEnvironment() gValue.child = envValue.child end -local function compile(ast) +function mt:loadRequires() + if not self.lsp or not self.lsp.workspace then + return + end + for _, req in ipairs(self.requires) do + local str = req.str + if type(str) == 'string' then + local uri = self.lsp.workspace:searchPath(str) + -- 如果循环require,这里会返回nil + local destVM = self.lsp:loadText(uri) + if destVM then + end + end + end +end + +local function compile(ast, lsp) local vm = setmetatable({ scope = env { locals = {}, @@ -1170,6 +1191,8 @@ local function compile(ast) }, libraryValue = {}, libraryChild = {}, + requires = {}, + lsp = lsp, }, mt) -- 创建初始环境 @@ -1178,14 +1201,17 @@ local function compile(ast) -- 执行代码 vm:doActions(ast) + -- 合并requires + vm:loadRequires() + return vm end -return function (ast) +return function (ast, lsp) if not ast then return nil end - local suc, res = xpcall(compile, log.error, ast) + local suc, res = xpcall(compile, log.error, ast, lsp) if not suc then return nil end diff --git a/server/src/service.lua b/server/src/service.lua index 0f0b8bbf..c43693f3 100644 --- a/server/src/service.lua +++ b/server/src/service.lua @@ -197,7 +197,7 @@ function mt:compileText(uri) self._needCompile[uri] = nil local ast = parser:ast(obj.text) - obj.vm = matcher.vm(ast) + obj.vm = matcher.vm(ast, self) obj.lines = parser:lines(obj.text, 'utf8') if not obj.vm then return obj diff --git a/server/src/workspace.lua b/server/src/workspace.lua index 4212e6fe..fecc9ab0 100644 --- a/server/src/workspace.lua +++ b/server/src/workspace.lua @@ -64,26 +64,51 @@ function mt:init(rootUri) }, function (list) log.info(('Found [%d] files'):format(#list)) for _, filename in ipairs(list) do - local uri = uriEncode(fs.path(filename)) - self.files[uri] = true + local path = fs.absolute(fs.path(filename)) + local name = path:string():lower() + self.files[name] = uriEncode(path) end end) end function mt:addFile(uri) if uri:sub(-4) == '.lua' then - self.files[uri] = true + local name = uriDecode(uri):string():lower() + self.files[name] = uri end end function mt:removeFile(uri) - self.files[uri] = nil + local name = uriDecode(uri):string():lower() + self.files[name] = nil +end + +function mt:searchPath(str) + str = str:gsub('%.', '/') + local searchers = {} + for i, luapath in ipairs(self.luapath) do + searchers[i] = luapath:gsub('%?', str):lower() + end + local results = {} + for filename, uri in pairs(self.files) do + for _, searcher in ipairs(searchers) do + if filename:sub(-#searcher) == searcher then + results[#results+1] = uri + end + end + end + return results[1] end return function (name, uri) local workspace = setmetatable({ name = name, files = {}, + luapath = { + '?.lua', + '?/init.lua', + '?/?.lua', + }, }, mt) workspace:init(uri) return workspace |