diff options
-rw-r--r-- | server-beta/src/vm/getValue.lua | 48 | ||||
-rw-r--r-- | server-beta/test/type_inference/init.lua | 78 |
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() +--]] |