summaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/matcher/vm.lua34
-rw-r--r--server/src/service.lua2
-rw-r--r--server/src/workspace.lua33
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