diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2018-12-10 10:45:39 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2018-12-10 10:45:39 +0800 |
commit | d19514f1904557a464467bfc9540882b4a214840 (patch) | |
tree | c4a5429fac429ae136938604e5fe3c48a21d59b4 /server | |
parent | 43c7d8c95e07c4dabdcf132020c21bc60024d06e (diff) | |
download | lua-language-server-d19514f1904557a464467bfc9540882b4a214840.zip |
类型推导
Diffstat (limited to 'server')
-rw-r--r-- | server/src/matcher/compile.lua | 14 | ||||
-rw-r--r-- | server/src/matcher/init.lua | 3 | ||||
-rw-r--r-- | server/src/matcher/type_inference.lua | 43 | ||||
-rw-r--r-- | server/test/definition/init.lua | 1 | ||||
-rw-r--r-- | server/test/find_lib/init.lua | 6 | ||||
-rw-r--r-- | server/test/main.lua | 1 | ||||
-rw-r--r-- | server/test/type_inference/init.lua | 28 |
7 files changed, 92 insertions, 4 deletions
diff --git a/server/src/matcher/compile.lua b/server/src/matcher/compile.lua index 557f4f59..bcf2ca91 100644 --- a/server/src/matcher/compile.lua +++ b/server/src/matcher/compile.lua @@ -187,7 +187,9 @@ function mt:searchCall(call, func, lastobj) if lastobj then table.insert(self.results.calls, { call = call, + func = func, lastobj = lastobj, + results = results, }) end @@ -312,6 +314,18 @@ function mt:setValue(var, value) return end var.value = value.value or value + local group = var.group or value.group + if not group then + group = {} + end + if not group[var] then + var.group = group + group[var] = group + end + if not group[value] then + value.group = group + group[value] = group + end if value.childs then var.childs = value.childs for _, child in pairs(value.childs) do diff --git a/server/src/matcher/init.lua b/server/src/matcher/init.lua index cacef3e5..eda4ac7b 100644 --- a/server/src/matcher/init.lua +++ b/server/src/matcher/init.lua @@ -6,6 +6,9 @@ local api = { hover = require 'matcher.hover', diagnostics = require 'matcher.diagnostics', compile = require 'matcher.compile', + typeInference = require 'matcher.type_inference', + findResult = require 'matcher.find_result', + findLib = require 'matcher.find_lib', } return api diff --git a/server/src/matcher/type_inference.lua b/server/src/matcher/type_inference.lua new file mode 100644 index 00000000..59874a7e --- /dev/null +++ b/server/src/matcher/type_inference.lua @@ -0,0 +1,43 @@ +local mt = {} +mt.__index = mt + +function mt:searchGroup(group) + if not group then + return + end + if group.type ~= nil then + return + end + for obj in pairs(group) do + if obj.valuetype then + group.type = obj.valuetype + return + end + end + group.type = false +end + +function mt:searchVar(var) + if var.valuetype then + return + end + if self.lock[var] then + return + end + self.lock[var] = true + self:searchGroup(var.group) + self.lock[var] = nil +end + +function mt:searchVars(vars) + for _, var in ipairs(vars) do + self:searchVar(var) + end +end + +return function (results) + local session = setmetatable({ + lock = {}, + }, mt) + session:searchVars(results.vars) +end diff --git a/server/test/definition/init.lua b/server/test/definition/init.lua index 11a79391..8bbaf65f 100644 --- a/server/test/definition/init.lua +++ b/server/test/definition/init.lua @@ -49,6 +49,7 @@ function TEST(script) assert(ast) local results = matcher.compile(ast) assert(results) + matcher.typeInference(results) local result = matcher.definition(results, pos) if result then diff --git a/server/test/find_lib/init.lua b/server/test/find_lib/init.lua index f8d7f115..18b88399 100644 --- a/server/test/find_lib/init.lua +++ b/server/test/find_lib/init.lua @@ -1,7 +1,5 @@ local matcher = require 'matcher' local parser = require 'parser' -local findResult = require 'matcher.find_result' -local findLib = require 'matcher.find_lib' rawset(_G, 'TEST', true) @@ -15,12 +13,12 @@ function TEST(fullkey) assert(ast) local results = matcher.compile(ast) assert(results) - local result = findResult(results, pos) + local result = matcher.findResult(results, pos) assert(result) assert(result.type == 'var') local var = result.var assert(var) - local _, name = findLib(var) + local _, name = matcher.findLib(var) assert(name == fullkey) end end diff --git a/server/test/main.lua b/server/test/main.lua index 05cc7ee6..3167089e 100644 --- a/server/test/main.lua +++ b/server/test/main.lua @@ -24,6 +24,7 @@ local function main() end test 'compile' + test 'type_inference' test 'definition' test 'find_lib' diff --git a/server/test/type_inference/init.lua b/server/test/type_inference/init.lua new file mode 100644 index 00000000..ee47b223 --- /dev/null +++ b/server/test/type_inference/init.lua @@ -0,0 +1,28 @@ +local parser = require 'parser' +local matcher = require 'matcher' + +rawset(_G, 'TEST', true) + +function TEST(res) + return function (script) + local start = script:find('<?', 1, true) + local finish = script:find('?>', 1, true) + local pos = (start + finish) // 2 + 1 + local new_script = script:gsub('<[!?]', ' '):gsub('[!?]>', ' ') + local ast = parser:ast(new_script) + assert(ast) + local results = matcher.compile(ast) + assert(results) + matcher.typeInference(results) + local result = matcher.findResult(results, pos) + assert(result) + local var = result.var + assert(var) + assert(var.group) + assert(var.group.type == res) + end +end + +TEST 'string' [[ +local <?var?> = '111' +]] |