summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2018-12-10 15:05:16 +0800
committer最萌小汐 <sumneko@hotmail.com>2018-12-10 15:05:16 +0800
commit8e6091ef4cfe560d085401540ddd1cb33183ef29 (patch)
tree49c66010951af513889ad6645bafccda30f5bec7 /server
parent03651e86bd8a240317cf081a0d0c05dac64f1165 (diff)
downloadlua-language-server-8e6091ef4cfe560d085401540ddd1cb33183ef29.zip
根据全局lib推断
Diffstat (limited to 'server')
-rw-r--r--server/src/matcher/find_lib.lua8
-rw-r--r--server/src/matcher/library.lua12
-rw-r--r--server/src/matcher/type_inference.lua61
-rw-r--r--server/test/type_inference/init.lua4
4 files changed, 66 insertions, 19 deletions
diff --git a/server/src/matcher/find_lib.lua b/server/src/matcher/find_lib.lua
index 090859db..79cc05f9 100644
--- a/server/src/matcher/find_lib.lua
+++ b/server/src/matcher/find_lib.lua
@@ -1,4 +1,4 @@
-local libs = require 'matcher.library'
+local library = require 'matcher.library'
local function isGlobal(var)
if var.type ~= 'field' then
@@ -105,7 +105,7 @@ end
local function findLib(var)
local value = var.value or var
- for libname, info in pairs(libs.global) do
+ for libname, info in pairs(library.global) do
local fullKey = checkSource(value, libname, info.lib)
if fullKey then
return info.lib, fullKey, false
@@ -117,7 +117,7 @@ local function findLib(var)
end
end
end
- for libname, info in pairs(libs.library) do
+ for libname, info in pairs(library.library) do
local fullKey = checkSource(value, libname, info.lib)
if fullKey then
return info.lib, fullKey, false
@@ -129,7 +129,7 @@ local function findLib(var)
end
end
end
- for libname, info in pairs(libs.object) do
+ for libname, info in pairs(library.object) do
local fullKey = checkSource(value, libname, info.lib)
if fullKey then
return info.lib, fullKey, false
diff --git a/server/src/matcher/library.lua b/server/src/matcher/library.lua
index dbc96af6..edd3b86e 100644
--- a/server/src/matcher/library.lua
+++ b/server/src/matcher/library.lua
@@ -139,6 +139,18 @@ 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/type_inference.lua b/server/src/matcher/type_inference.lua
index 19205413..577e277d 100644
--- a/server/src/matcher/type_inference.lua
+++ b/server/src/matcher/type_inference.lua
@@ -1,16 +1,27 @@
+local library = require 'matcher.library'
+
local mt = {}
mt.__index = mt
+function mt:isGlobal(var)
+ if var.type ~= 'field' then
+ return false
+ end
+ if not var.parent then
+ return false
+ end
+ return var.parent.key == '_ENV' or var.parent.key == '_G'
+end
+
function mt:setType(obj, type)
if not obj then
return
end
if not obj.group then
- obj.group = {
- type = type,
- }
+ obj.group = {}
end
obj.valuetype = type
+ obj.group.type = type
end
function mt:getType(obj)
@@ -73,18 +84,20 @@ function mt:getBinaryType(obj)
end
function mt:searchGroup(group)
- if not group then
- return
- end
if group.type ~= nil then
return
end
+ group.type = false
+ -- 1. 搜索确定类型
for obj in pairs(group) do
if obj.valuetype then
group.type = obj.valuetype
- return
end
end
+ if group.type then
+ return
+ end
+ -- 2. 推测运算结果
for obj in pairs(group) do
-- TODO 搜索metatable
if obj.type == 'unary' then
@@ -101,22 +114,39 @@ function mt:searchGroup(group)
end
end
end
- group.type = false
end
function mt:searchVar(var)
- if var.valuetype then
- return
- end
if self.lock[var] then
return
end
+ if not var.group then
+ var.group = {}
+ var.group[var] = var
+ end
self.lock[var] = true
self:searchGroup(var.group)
self.lock[var] = nil
- if not self:getType(var) and next(var.childs) then
- self:setType(var, 'table')
- return
+
+ if not self:getType(var) then
+ -- 1. 检查全局lib
+ if self:isGlobal(var) then
+ local lib = library:get('global', var.key)
+ if lib then
+ var.lib = lib
+ if lib.type then
+ self:setType(var, lib.type)
+ self:searchVar(var)
+ return
+ end
+ end
+ end
+ -- 2. 检查索引
+ if next(var.childs) then
+ self:setType(var, 'table')
+ self:searchVar(var)
+ return
+ end
end
end
@@ -127,8 +157,9 @@ function mt:searchVars(vars)
end
function mt:searchCall(call)
- if not self:getType(call.func) then
+ if call.func and not self:getType(call.func) then
self:setType(call.func, 'function')
+ self:searchVar(call.func)
end
end
diff --git a/server/test/type_inference/init.lua b/server/test/type_inference/init.lua
index 4097eb2f..59993b14 100644
--- a/server/test/type_inference/init.lua
+++ b/server/test/type_inference/init.lua
@@ -109,3 +109,7 @@ TEST 'string' [[
TEST 'number' [[
<?x?> = a + b
]]
+
+TEST 'table' [[
+<?table?>()
+]]