summaryrefslogtreecommitdiff
path: root/script-beta
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2020-08-16 18:57:10 +0800
committer最萌小汐 <sumneko@hotmail.com>2020-08-16 18:57:10 +0800
commit13ebfd293897200bda9cb1840fef6cb03a9c6d43 (patch)
tree84fcf8ae1c6cc76eaafce984d4be88edea30d7d5 /script-beta
parenta02d1537bbf7829c8117ce481a9bbcff7efa8dd7 (diff)
downloadlua-language-server-13ebfd293897200bda9cb1840fef6cb03a9c6d43.zip
类型推断过了
Diffstat (limited to 'script-beta')
-rw-r--r--script-beta/core/hover/label.lua11
-rw-r--r--script-beta/parser/guide.lua75
2 files changed, 78 insertions, 8 deletions
diff --git a/script-beta/core/hover/label.lua b/script-beta/core/hover/label.lua
index a776f0c4..c3607415 100644
--- a/script-beta/core/hover/label.lua
+++ b/script-beta/core/hover/label.lua
@@ -17,10 +17,11 @@ local function asFunction(source, oop)
end
local function asValue(source, title)
- local name = buildName(source)
- local class = 'any'
- local type = 'any'
- local literal, cont
+ local name = buildName(source)
+ local class = 'any'
+ local type = 'any'
+ local literal = ''
+ local cont
local values = vm.getInfers(source)
if values then
for _, value in ipairs(values) do
@@ -57,7 +58,7 @@ local function asValue(source, title)
type = type or 'any'
end
pack[#pack+1] = class or type
- if literal then
+ if literal ~= '' then
pack[#pack+1] = '='
pack[#pack+1] = literal
end
diff --git a/script-beta/parser/guide.lua b/script-beta/parser/guide.lua
index 37ab8088..863d828e 100644
--- a/script-beta/parser/guide.lua
+++ b/script-beta/parser/guide.lua
@@ -2469,6 +2469,47 @@ function m.inferCheckLibraryReturn(status, source)
return true
end
+function m.inferByLibraryArg(status, source)
+ local args = source.parent
+ if not args then
+ return
+ end
+ if args.type ~= 'callargs' then
+ return
+ end
+ local call = args.parent
+ if not call then
+ return
+ end
+ local func = call.node
+ local index
+ for i = 1, #args do
+ if args[i] == source then
+ index = i
+ break
+ end
+ end
+ if not index then
+ return
+ end
+ local lib = status.interface.library and status.interface.library(func)
+ local arg = lib and lib.args and lib.args[index]
+ if not arg then
+ return
+ end
+ if not arg.type then
+ return
+ end
+ if arg.type == '...' or arg.type == 'any' then
+ return
+ end
+ status.results[#status.results+1] = {
+ type = arg.type,
+ value = arg.value,
+ source = arg,
+ }
+end
+
function m.inferByDef(status, obj)
if status.index > 1 then
return
@@ -2659,6 +2700,35 @@ function m.inferByCallReturn(status, source)
end
end
+function m.inferByPCallReturn(status, source)
+ if source.type ~= 'select' then
+ return
+ end
+ local call = source.vararg
+ if not call or call.type ~= 'call' then
+ return
+ end
+ local node = call.node
+ local specialName = node.special
+ local func, index
+ if specialName == 'pcall' then
+ func = call.args[1]
+ index = source.index - 1
+ elseif specialName == 'xpcall' then
+ func = call.args[1]
+ index = source.index - 2
+ else
+ return
+ end
+ local newStatus = m.status(status)
+ m.searchRefs(newStatus, func, 'def')
+ for _, src in ipairs(newStatus.results) do
+ if src.value and src.value.type == 'function' then
+ mergeFunctionReturns(status, src.value, index)
+ end
+ end
+end
+
function m.cleanInfers(infers)
local mark = {}
for i = 1, #infers do
@@ -2695,7 +2765,6 @@ function m.searchInfer(status, obj)
or m.inferCheckBinary(status, obj)
or m.inferCheckLibraryTypes(status, obj)
or m.inferCheckLibrary(status, obj)
- --or m.inferCheckSpecialReturn(status, obj)
or m.inferCheckLibraryReturn(status, obj)
if checked then
m.cleanInfers(status.results)
@@ -2705,7 +2774,7 @@ function m.searchInfer(status, obj)
return
end
- --m.inferByLibraryArg(status, obj)
+ m.inferByLibraryArg(status, obj)
m.inferByDef(status, obj)
m.inferBySet(status, obj)
m.inferByCall(status, obj)
@@ -2713,7 +2782,7 @@ function m.searchInfer(status, obj)
m.inferByUnary(status, obj)
m.inferByBinary(status, obj)
m.inferByCallReturn(status, obj)
- --m.inferByPCallReturn(status, obj)
+ m.inferByPCallReturn(status, obj)
m.cleanInfers(status.results)
if makeCache then
makeCache(status.results)