summaryrefslogtreecommitdiff
path: root/server/src/matcher
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2018-12-21 13:55:13 +0800
committer最萌小汐 <sumneko@hotmail.com>2018-12-21 13:55:13 +0800
commite50a8947ab1c6016e3763e76e0c3bedfa1b9c002 (patch)
treece7c6b45bec0118ff9b5ea918d8995695d8868bc /server/src/matcher
parentdba3476884f6ff53e0b0843fb77b42e5205161e1 (diff)
downloadlua-language-server-e50a8947ab1c6016e3763e76e0c3bedfa1b9c002.zip
支持dofile和loadfile
Diffstat (limited to 'server/src/matcher')
-rw-r--r--server/src/matcher/vm.lua115
1 files changed, 100 insertions, 15 deletions
diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua
index a1c84c3c..adc9df1d 100644
--- a/server/src/matcher/vm.lua
+++ b/server/src/matcher/vm.lua
@@ -466,17 +466,54 @@ function mt:callRequire(func, values)
values[1] = self:createValue('any')
end
local str = values[1].value
- if type(str) == 'string' then
- local lib = library.library[str]
- if lib then
- local value = self:getLibValue(lib, 'library')
- self:setFunctionReturn(func, 1, value)
- return
- end
+ if type(str) ~= 'string' then
+ return
+ end
+ local lib = library.library[str]
+ if lib then
+ local value = self:getLibValue(lib, 'library')
+ self:setFunctionReturn(func, 1, value)
+ return
+ else
+ local requireValue = self:createValue('boolean', nil, true)
+ self:setFunctionReturn(func, 1, requireValue)
+ self.requires[requireValue] = {
+ mode = 'require',
+ str = values[1],
+ }
+ end
+end
+
+function mt:callLoadFile(func, values)
+ if not values[1] then
+ values[1] = self:createValue('any')
+ end
+ local str = values[1].value
+ if type(str) ~= 'string' then
+ return
+ end
+ local requireValue = self:buildFunction()
+ self:setFunctionReturn(func, 1, requireValue)
+ self.requires[requireValue] = {
+ mode = 'loadfile',
+ str = values[1],
+ }
+end
+
+function mt:callDoFile(func, values)
+ if not values[1] then
+ values[1] = self:createValue('any')
+ end
+ local str = values[1].value
+ if type(str) ~= 'string' then
+ return
end
- local requireValue = self:createValue('boolean', nil, true)
+ local requireValue = self:createValue('any')
self:setFunctionReturn(func, 1, requireValue)
- self.requires[requireValue] = values[1]
+ self.requires[requireValue] = {
+ mode = 'dofile',
+ str = values[1],
+ }
end
function mt:call(func, values)
@@ -498,6 +535,10 @@ function mt:call(func, values)
self:callSetMetaTable(func, values)
elseif lib.special == 'require' then
self:callRequire(func, values)
+ elseif lib.special == 'loadfile' then
+ self:callLoadFile(func, values)
+ elseif lib.special == 'dofile' then
+ self:callDoFile(func, values)
end
end
end
@@ -1218,6 +1259,19 @@ function mt:mergeRequire(value, strValue, destVM)
strValue.uri = destVM.uri
end
+function mt:mergeLoadFile(value, strValue, destVM)
+ -- 取出对方的主函数
+ local main = destVM.results.main
+ -- loadfile 的返回值就是对方的主函数
+ local mainValue = deepCopy(main)
+ self:mergeValue(value, mainValue)
+
+ -- 支持 loadfile 'xxx.lua' 的转到定义
+ local strSource = strValue.source
+ self.results.sources[strSource] = strValue
+ strValue.uri = destVM.uri
+end
+
function mt:loadRequires()
if not self.lsp or not self.lsp.workspace then
return
@@ -1227,15 +1281,31 @@ function mt:loadRequires()
self.requires[k] = nil
copy[k] = v
end
- for value, strValue in pairs(copy) do
+ for value, data in pairs(copy) do
+ local strValue = data.str
+ local mode = data.mode
local str = strValue.value
if type(str) == 'string' then
- local uri = self.lsp.workspace:searchPath(self.uri, str)
+ local uri
+ if mode == 'require' then
+ uri = self.lsp.workspace:searchPath(self.uri, str)
+ elseif mode == 'loadfile' then
+ uri = self.lsp.workspace:loadPath(self.uri, str)
+ elseif mode == 'dofile' then
+ uri = self.lsp.workspace:loadPath(self.uri, str)
+ elseif mode == '' then
+ end
-- 如果循环require,这里会返回nil
-- 会当场编译VM
local destVM = self.lsp:loadVM(uri)
if destVM then
- self:mergeRequire(value, strValue, destVM)
+ if mode == 'require' then
+ self:mergeRequire(value, strValue, destVM)
+ elseif mode == 'loadfile' then
+ self:mergeLoadFile(value, strValue, destVM)
+ elseif mode == 'dofile' then
+ self:mergeRequire(value, strValue, destVM)
+ end
end
end
end
@@ -1245,14 +1315,29 @@ function mt:tryLoadRequires()
if not self.lsp or not self.lsp.workspace then
return
end
- for value, strValue in pairs(self.requires) do
+ for value, data in pairs(self.requires) do
+ local strValue = data.str
+ local mode = data.mode
local str = strValue.value
if type(str) == 'string' then
- local uri = self.lsp.workspace:searchPath(self.uri, str)
+ local uri
+ if mode == 'require' then
+ uri = self.lsp.workspace:searchPath(self.uri, str)
+ elseif mode == 'loadfile' then
+ uri = self.lsp.workspace:loadPath(self.uri, str)
+ elseif mode == 'dofile' then
+ uri = self.lsp.workspace:loadPath(self.uri, str)
+ end
-- 如果取不到VM(不编译),则做个标记,之后再取一次
local destVM = self.lsp:getVM(uri)
if destVM then
- self:mergeRequire(value, strValue, destVM)
+ if mode == 'require' then
+ self:mergeRequire(value, strValue, destVM)
+ elseif mode == 'loadfile' then
+ self:mergeLoadFile(value, strValue, destVM)
+ elseif mode == 'dofile' then
+ self:mergeRequire(value, strValue, destVM)
+ end
self.requires[value] = nil
else
self.lsp:needRequires(self.uri)