summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/infer.lua77
-rw-r--r--script/core/searcher.lua4
-rw-r--r--test/type_inference/init.lua4
3 files changed, 60 insertions, 25 deletions
diff --git a/script/core/infer.lua b/script/core/infer.lua
index 713e94b5..01cd7aaf 100644
--- a/script/core/infer.lua
+++ b/script/core/infer.lua
@@ -2,9 +2,11 @@ local searcher = require 'core.searcher'
local config = require 'config'
local linker = require 'core.linker'
-local BE_LEN = {'#'}
-local CLASS = {'CLASS'}
-local TABLE = {'TABLE'}
+local STRING_OR_TABLE = {'STRING_OR_TABLE'}
+local BE_RETURN = {'BE_RETURN'}
+local BE_CONNACT = {'BE_CONNACT'}
+local CLASS = {'CLASS'}
+local TABLE = {'TABLE'}
local m = {}
@@ -184,9 +186,16 @@ local function cleanInfers(infers)
infers['integer'] = nil
infers['number'] = true
end
+ -- 如果是通过 .. 来推测的,且结果里没有 number 与 integer,则推测为string
+ if infers[BE_CONNACT] then
+ infers[BE_CONNACT] = nil
+ if not infers['number'] and not infers['integer'] then
+ infers['string'] = true
+ end
+ end
-- 如果是通过 # 来推测的,且结果里没有其他的 table 与 string,则加入这2个类型
- if infers[BE_LEN] then
- infers[BE_LEN] = nil
+ if infers[STRING_OR_TABLE] then
+ infers[STRING_OR_TABLE] = nil
if not infers['table'] and not infers['string'] then
infers['table'] = true
infers['string'] = true
@@ -202,6 +211,10 @@ local function cleanInfers(infers)
infers[TABLE] = nil
infers['table'] = true
end
+ if infers[BE_RETURN] then
+ infers[BE_RETURN] = nil
+ infers['nil'] = nil
+ end
end
---合并对象的推断类型
@@ -236,6 +249,16 @@ local function getDocName(doc)
if not doc then
return nil
end
+ if doc.type == 'doc.type' then
+ local list = {}
+ for _, tp in ipairs(doc.types) do
+ list[#list+1] = getDocName(tp)
+ end
+ for _, enum in ipairs(doc.enums) do
+ list[#list+1] = getDocName(enum)
+ end
+ return table.concat(list, '|')
+ end
if doc.type == 'doc.class.name'
or doc.type == 'doc.type.name'
or doc.type == 'doc.alias.name' then
@@ -249,7 +272,7 @@ local function getDocName(doc)
if doc.type == 'doc.type.table' then
local key = getDocName(doc.tkey) or '?'
local value = getDocName(doc.tvalue) or '?'
- return ('<%s, %s>'):format(key, value)
+ return ('table<%s, %s>'):format(key, value)
end
if doc.type == 'doc.type.function' then
return 'function'
@@ -284,25 +307,11 @@ local function searchInfer(source, infers)
infers[TABLE] = true
end
end
- -- X.a -> table
- if source.next and source.next.node == source then
- if source.next.type == 'setfield'
- or source.next.type == 'setindex'
- or source.next.type == 'setmethod' then
- infers['table'] = true
- end
- return
- end
- -- return XX
- if source.parent.type == 'return' then
- infers['any'] = true
- return
- end
if source.parent.type == 'unary' then
local op = source.parent.op.type
-- # XX -> string | table
if op == '#' then
- infers[BE_LEN] = true
+ infers[STRING_OR_TABLE] = true
return
end
if op == '-' then
@@ -335,7 +344,27 @@ local function searchInfer(source, infers)
infers['integer'] = true
return
end
- return
+ if op == '..' then
+ infers[BE_CONNACT] = true
+ return
+ end
+ end
+ -- X.a -> table
+ if source.next and source.next.node == source then
+ if source.next.type == 'setfield'
+ or source.next.type == 'setindex'
+ or source.next.type == 'setmethod'
+ or source.next.type == 'getfield'
+ or source.next.type == 'getindex' then
+ infers['table'] = true
+ end
+ if source.next.type == 'getmethod' then
+ infers[STRING_OR_TABLE] = true
+ end
+ end
+ -- return XX
+ if source.parent.type == 'return' then
+ infers[BE_RETURN] = true
end
end
@@ -359,6 +388,10 @@ function m.searchInfers(source)
local mark = {}
mark[source] = true
searchInfer(source, infers)
+ if source.type == 'field' or source.type == 'method' then
+ mark[source.parent] = true
+ searchInfer(source.parent, infers)
+ end
for _, def in ipairs(defs) do
if not mark[def] then
mark[def] = true
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 4aec6bb2..97e1a7b8 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -148,9 +148,7 @@ function m.getObjectValue(obj)
if obj.type == 'boolean'
or obj.type == 'number'
or obj.type == 'integer'
- or obj.type == 'string'
- or obj.type == 'doc.type.table'
- or obj.type == 'doc.type.arrary' then
+ or obj.type == 'string' then
return obj
end
if obj.value then
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 3de36e5e..99205a74 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -363,12 +363,16 @@ self.<?t?>[#self.t+1] = {}
]]
TEST 'string' [[
+---@class string
+
---@type string[]
local x
local <?y?> = x[1]
]]
TEST 'string' [[
+---@class string
+
---@return string[]
local function f() end
local x = f()