From 8e6091ef4cfe560d085401540ddd1cb33183ef29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Mon, 10 Dec 2018 15:05:16 +0800 Subject: =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E5=85=A8=E5=B1=80lib=E6=8E=A8?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/matcher/find_lib.lua | 8 ++--- server/src/matcher/library.lua | 12 +++++++ server/src/matcher/type_inference.lua | 61 ++++++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 19 deletions(-) (limited to 'server/src/matcher') 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 -- cgit v1.2.3