summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server-beta/src/vm/getValue.lua90
-rw-r--r--server-beta/test/hover/init.lua2
-rw-r--r--server-beta/test/type_inference/init.lua8
3 files changed, 99 insertions, 1 deletions
diff --git a/server-beta/src/vm/getValue.lua b/server-beta/src/vm/getValue.lua
index f2a227a1..6faf591e 100644
--- a/server-beta/src/vm/getValue.lua
+++ b/server-beta/src/vm/getValue.lua
@@ -452,7 +452,19 @@ local function checkValue(source)
end
end
+local function hasTypeInResults(results, type)
+ for i = 1, #results do
+ if results[i].type == type then
+ return true
+ end
+ end
+ return false
+end
+
local function inferByCall(results, source)
+ if #results ~= 0 then
+ return
+ end
if not source.parent then
return
end
@@ -469,6 +481,9 @@ local function inferByCall(results, source)
end
local function inferByGetTable(results, source)
+ if #results ~= 0 then
+ return
+ end
local next = source.next
if not next then
return
@@ -577,6 +592,79 @@ local function checkLibraryArg(source)
}
end
+local function inferByUnary(results, source)
+ if #results ~= 0 then
+ return
+ end
+ local parent = source.parent
+ if not parent or parent.type ~= 'unary' then
+ return
+ end
+ local op = parent.op
+ if op.type == '#' then
+ insert(results, {
+ type = 'string',
+ source = vm.librarySource(source)
+ })
+ insert(results, {
+ type = 'table',
+ source = vm.librarySource(source)
+ })
+ elseif op.type == '~' then
+ insert(results, {
+ type = 'integer',
+ source = vm.librarySource(source)
+ })
+ elseif op.type == '-' then
+ insert(results, {
+ type = 'number',
+ source = vm.librarySource(source)
+ })
+ end
+end
+
+local function inferByBinary(results, source)
+ if #results ~= 0 then
+ return
+ end
+ local parent = source.parent
+ if not parent or parent.type ~= 'binary' then
+ return
+ end
+ local op = parent.op
+ if op.type == '<='
+ or op.type == '>='
+ or op.type == '<'
+ or op.type == '>'
+ or op.type == '^'
+ or op.type == '/'
+ or op.type == '+'
+ or op.type == '-'
+ or op.type == '*'
+ or op.type == '%' then
+ insert(results, {
+ type = 'number',
+ source = vm.librarySource(source)
+ })
+ elseif op.type == '|'
+ or op.type == '~'
+ or op.type == '&'
+ or op.type == '<<'
+ or op.type == '>>'
+ -- 整数的可能性比较高
+ or op.type == '//' then
+ insert(results, {
+ type = 'integer',
+ source = vm.librarySource(source)
+ })
+ elseif op.type == '..' then
+ insert(results, {
+ type = 'string',
+ source = vm.librarySource(source)
+ })
+ end
+end
+
local function getValue(source)
local results = checkLiteral(source)
or checkValue(source)
@@ -593,6 +681,8 @@ local function getValue(source)
checkDef(results, source)
inferByCall(results, source)
inferByGetTable(results, source)
+ inferByUnary(results, source)
+ inferByBinary(results, source)
if #results == 0 then
return nil
diff --git a/server-beta/test/hover/init.lua b/server-beta/test/hover/init.lua
index 5349fb96..33999342 100644
--- a/server-beta/test/hover/init.lua
+++ b/server-beta/test/hover/init.lua
@@ -45,7 +45,7 @@ local obj = setmetatable({}, mt)
obj:<?init?>(1, '测试')
]]
[[
-function mt:init(a: number, b: string, c: any)
+function mt:init(a: any, b: any, c: any)
-> table
]]
diff --git a/server-beta/test/type_inference/init.lua b/server-beta/test/type_inference/init.lua
index 0ec0ea19..53ee6131 100644
--- a/server-beta/test/type_inference/init.lua
+++ b/server-beta/test/type_inference/init.lua
@@ -168,6 +168,14 @@ end
<?y?> = x()
]]
+TEST 'string|table' [[
+local y = #<?x?>
+]]
+
+TEST 'integer' [[
+local y = <?x?> << 0
+]]
+
-- 不根据调用者的输入参数来推测
--TEST 'number' [[
--local function x(a)