summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server-beta/src/vm/getValue.lua48
-rw-r--r--server-beta/test/type_inference/init.lua78
2 files changed, 89 insertions, 37 deletions
diff --git a/server-beta/src/vm/getValue.lua b/server-beta/src/vm/getValue.lua
index 18a2af0b..f2a227a1 100644
--- a/server-beta/src/vm/getValue.lua
+++ b/server-beta/src/vm/getValue.lua
@@ -13,6 +13,12 @@ local typeSort = {
NIL = setmetatable({'<nil>'}, { __tostring = function () return 'nil' end })
local function merge(t, b)
+ if not t then
+ t = {}
+ end
+ if not b then
+ return t
+ end
for i = 1, #b do
local o = b[i]
if not t[o] then
@@ -31,6 +37,9 @@ local function alloc(o)
end
local function insert(t, o)
+ if not o then
+ return
+ end
if not t[o] then
t[o] = true
t[#t+1] = o
@@ -530,6 +539,44 @@ local function checkLibraryReturn(source)
}
end
+local function checkLibraryArg(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 = vm.getLibrary(func)
+ local arg = lib and lib.args and lib.args[index]
+ if not arg then
+ return
+ end
+ if arg.type == '...' then
+ return
+ end
+ return alloc {
+ type = arg.type,
+ value = arg.value,
+ source = vm.librarySource(arg),
+ }
+end
+
local function getValue(source)
local results = checkLiteral(source)
or checkValue(source)
@@ -537,6 +584,7 @@ local function getValue(source)
or checkBinary(source)
or checkLibrary(source)
or checkLibraryReturn(source)
+ or checkLibraryArg(source)
if results then
return results
end
diff --git a/server-beta/test/type_inference/init.lua b/server-beta/test/type_inference/init.lua
index c81fc15d..0ec0ea19 100644
--- a/server-beta/test/type_inference/init.lua
+++ b/server-beta/test/type_inference/init.lua
@@ -161,51 +161,55 @@ TEST 'table' [[
<?x?> = setmetatable({})
]]
-TEST 'number' [[
+TEST 'integer' [[
local function x()
return 1
end
<?y?> = x()
]]
-TEST 'number' [[
-local function x(a)
- return <?a?>
-end
-x(1)
-]]
+-- 不根据调用者的输入参数来推测
+--TEST 'number' [[
+--local function x(a)
+-- return <?a?>
+--end
+--x(1)
+--]]
TEST 'table' [[
setmetatable(<?b?>)
]]
-TEST 'number' [[
-local function x(a)
- _ = a + 1
-end
-local b
-x(<?b?>)
-]]
-
-TEST 'number' [[
-local function x(a, ...)
- local _, <?b?>, _ = ...
-end
-x(nil, 'xx', 1, true)
-]]
-
-TEST 'number' [[
-local function x(a, ...)
- return true, 'ss', ...
-end
-local _, _, _, <?b?>, _ = x(nil, true, 1, 'yy')
-]]
-
-TEST 'integer' [[
-for <?i?> in ipairs(t) do
-end
-]]
-
-TEST 'any' [[
-local <?x?> = next()
-]]
+-- 不根据对方函数内的使用情况来推测
+--TEST 'number' [[
+--local function x(a)
+-- _ = a + 1
+--end
+--local b
+--x(<?b?>)
+--]]
+
+--TEST 'number' [[
+--local function x(a, ...)
+-- local _, <?b?>, _ = ...
+--end
+--x(nil, 'xx', 1, true)
+--]]
+
+-- 引用不跨越参数
+--TEST 'number' [[
+--local function x(a, ...)
+-- return true, 'ss', ...
+--end
+--local _, _, _, <?b?>, _ = x(nil, true, 1, 'yy')
+--]]
+
+-- 暂不支持这些特殊情况,之后用其他语法定义
+--TEST 'integer' [[
+--for <?i?> in ipairs(t) do
+--end
+--]]
+--
+--TEST 'any' [[
+--local <?x?> = next()
+--]]