summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/src/matcher/find_lib.lua5
-rw-r--r--server/src/matcher/library.lua36
-rw-r--r--server/src/matcher/vm.lua60
-rw-r--r--server/test/find_lib/init.lua12
-rw-r--r--server/test/main.lua2
5 files changed, 67 insertions, 48 deletions
diff --git a/server/src/matcher/find_lib.lua b/server/src/matcher/find_lib.lua
index 79cc05f9..f6c453b4 100644
--- a/server/src/matcher/find_lib.lua
+++ b/server/src/matcher/find_lib.lua
@@ -104,7 +104,10 @@ local function checkParent(value, name, lib)
end
local function findLib(var)
- local value = var.value or var
+ local value = var.value
+ if value.lib then
+ return value.lib, value.lib.name, false
+ end
for libname, info in pairs(library.global) do
local fullKey = checkSource(value, libname, info.lib)
if fullKey then
diff --git a/server/src/matcher/library.lua b/server/src/matcher/library.lua
index edd3b86e..f940544a 100644
--- a/server/src/matcher/library.lua
+++ b/server/src/matcher/library.lua
@@ -50,17 +50,17 @@ end
local function mergeSource(alllibs, name, lib)
if not lib.source then
- alllibs.global[name] = { lib = lib, child = {} }
+ alllibs.global[name] = lib
return
end
for _, source in ipairs(lib.source) do
local sourceName = source.name or name
if source.type == 'global' then
- alllibs.global[sourceName] = { lib = lib, child = {} }
+ alllibs.global[sourceName] = lib
elseif source.type == 'library' then
- alllibs.library[sourceName] = { lib = lib, child = {} }
+ alllibs.library[sourceName] = lib
elseif source.type == 'object' then
- alllibs.object[sourceName] = { lib = lib, child = {} }
+ alllibs.object[sourceName] = lib
end
end
end
@@ -70,10 +70,10 @@ local function insert(tbl, name, key, value)
return
end
if not tbl[name] then
- tbl[name] = {}
- end
- if not tbl[name].child then
- tbl[name].child = {}
+ tbl[name] = {
+ name = name,
+ child = {},
+ }
end
tbl[name].child[key] = value
end
@@ -114,6 +114,13 @@ local function loadLocale(language, relative)
return nil
end
+local function fix(libs)
+ for name, lib in pairs(libs) do
+ lib.name = name
+ lib.child = {}
+ end
+end
+
local function init()
local language = require 'language'
local alllibs = {
@@ -127,6 +134,7 @@ local function init()
if buf then
libs = table.container()
xpcall(lni.classics, log.error, buf, path:string(), {libs})
+ fix(libs)
end
local relative = fs.relative(path, ROOT)
@@ -139,18 +147,6 @@ local function init()
mergeLibs(alllibs, libs)
end
- function alllibs:get(type, parent, child)
- local info = self[type] and self[type][parent]
- if not info then
- return nil
- end
- if child then
- return info.child[child]
- else
- return info.lib
- end
- end
-
return alllibs
end
diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua
index af2e9bc2..7c3124fb 100644
--- a/server/src/matcher/vm.lua
+++ b/server/src/matcher/vm.lua
@@ -316,17 +316,41 @@ function mt:checkMetaIndex(value, meta)
end
function mt:callSetMetaTable(func, values)
+ if not values[1] then
+ values[1] = self:createValue('nil')
+ end
+ if not values[2] then
+ values[2] = self:createValue('nil')
+ end
self:setFunctionReturn(func, 1, values[1])
-- 检查 __index
self:checkMetaIndex(values[1], values[2])
end
+function mt:callRequire(func, values)
+ if not values[1] then
+ values[1] = self:createValue('nil')
+ end
+ local str = values[1].value
+ if type(str) == 'string' then
+ local lib = library.library[str]
+ if lib then
+ local value = self:getLibValue(lib)
+ self:setFunctionReturn(func, 1, value)
+ return
+ end
+ end
+ self:setFunctionReturn(func, 1, nil)
+end
+
function mt:call(func, values)
local lib = func.lib
if lib and lib.special then
if lib.special == 'setmetatable' then
self:callSetMetaTable(func, values)
+ elseif lib.special == 'require' then
+ self:callRequire(func, values)
end
end
@@ -363,10 +387,10 @@ function mt:createValue(type, source, v)
end
function mt:getLibValue(lib)
- local tp = lib.type
- if not tp then
- return
+ if self.libraryValue[lib] then
+ return self.libraryValue[lib]
end
+ local tp = lib.type
local value
if tp == 'table' then
value = self:buildTable()
@@ -397,6 +421,17 @@ function mt:getLibValue(lib)
else
value = self:createValue(tp)
end
+ self.libraryValue[lib] = value
+ value.lib = lib
+
+ if lib.child then
+ for fName, fLib in pairs(lib.child) do
+ local fField = self:createField(value, fName)
+ local fValue = self:getLibValue(fLib)
+ self:setValue(fField, fValue)
+ end
+ end
+
return value
end
@@ -802,22 +837,10 @@ function mt:createEnvironment()
local pValue = self:setValue(parent, self:buildTable())
-- 设置全局变量
- for name, info in pairs(library.global) do
+ for name, lib in pairs(library.global) do
local field = self:createField(pValue, name)
- if info.lib then
- local value = self:getLibValue(info.lib)
- value = self:setValue(field, value)
- value.lib = info.lib
- end
- if info.child then
- local fValue = self:getValue(field)
- for fname, flib in pairs(info.child) do
- local ffield = self:createField(fValue, fname)
- local value = self:getLibValue(flib)
- value = self:setValue(ffield, value)
- value.lib = flib
- end
- end
+ local value = self:getLibValue(lib)
+ value = self:setValue(field, value)
end
-- 设置 _G 等于 _ENV
@@ -840,6 +863,7 @@ local function compile(ast)
funcs = {},
calls = {},
},
+ libraryValue = {},
}, mt)
-- 创建初始环境
diff --git a/server/test/find_lib/init.lua b/server/test/find_lib/init.lua
index 26dbc893..31d44dfc 100644
--- a/server/test/find_lib/init.lua
+++ b/server/test/find_lib/init.lua
@@ -11,14 +11,10 @@ function TEST(fullkey)
local new_script = script:gsub('<[!?]', ' '):gsub('[!?]>', ' ')
local ast = parser:ast(new_script)
assert(ast)
- local results = matcher.compile(ast)
- assert(results)
- local result = matcher.findResult(results, pos)
- assert(result)
- assert(result.type == 'var')
- local var = result.var
- assert(var)
- local _, name = matcher.findLib(var)
+ local vm = matcher.vm(ast)
+ assert(vm)
+ local result = matcher.findResult(vm.results, pos)
+ local _, name = matcher.findLib(result.object)
assert(name == fullkey)
end
end
diff --git a/server/test/main.lua b/server/test/main.lua
index 8e340157..690c8d3c 100644
--- a/server/test/main.lua
+++ b/server/test/main.lua
@@ -27,7 +27,7 @@ local function main()
--test 'type_inference'
test 'definition'
test 'diagnostics'
- --test 'find_lib'
+ test 'find_lib'
print('测试完成')
end