summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2018-12-10 10:45:39 +0800
committer最萌小汐 <sumneko@hotmail.com>2018-12-10 10:45:39 +0800
commitd19514f1904557a464467bfc9540882b4a214840 (patch)
treec4a5429fac429ae136938604e5fe3c48a21d59b4
parent43c7d8c95e07c4dabdcf132020c21bc60024d06e (diff)
downloadlua-language-server-d19514f1904557a464467bfc9540882b4a214840.zip
类型推导
-rw-r--r--server/src/matcher/compile.lua14
-rw-r--r--server/src/matcher/init.lua3
-rw-r--r--server/src/matcher/type_inference.lua43
-rw-r--r--server/test/definition/init.lua1
-rw-r--r--server/test/find_lib/init.lua6
-rw-r--r--server/test/main.lua1
-rw-r--r--server/test/type_inference/init.lua28
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'
+]]