diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2018-12-10 15:05:16 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2018-12-10 15:05:16 +0800 |
commit | 8e6091ef4cfe560d085401540ddd1cb33183ef29 (patch) | |
tree | 49c66010951af513889ad6645bafccda30f5bec7 /server | |
parent | 03651e86bd8a240317cf081a0d0c05dac64f1165 (diff) | |
download | lua-language-server-8e6091ef4cfe560d085401540ddd1cb33183ef29.zip |
根据全局lib推断
Diffstat (limited to 'server')
-rw-r--r-- | server/src/matcher/find_lib.lua | 8 | ||||
-rw-r--r-- | server/src/matcher/library.lua | 12 | ||||
-rw-r--r-- | server/src/matcher/type_inference.lua | 61 | ||||
-rw-r--r-- | server/test/type_inference/init.lua | 4 |
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?>() +]] |