diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-11-20 21:57:09 +0800 |
commit | 4ca61ec457822dd14966afa0752340ae8ce180a1 (patch) | |
tree | ae8adb1ad82c717868e551e699fd3cf3bb290089 /test/type_inference | |
parent | c63b2e404d8d2bb984afe3678a5ba2b2836380cc (diff) | |
download | lua-language-server-4ca61ec457822dd14966afa0752340ae8ce180a1.zip |
no longer beta
Diffstat (limited to 'test/type_inference')
-rw-r--r-- | test/type_inference/init.lua | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua new file mode 100644 index 00000000..1b610bb3 --- /dev/null +++ b/test/type_inference/init.lua @@ -0,0 +1,331 @@ +local files = require 'files' +local config = require 'config' +local vm = require 'vm' +local guide = require 'parser.guide' + +rawset(_G, 'TEST', true) + +local function getSource(pos) + local ast = files.getAst('') + return guide.eachSourceContain(ast.ast, pos, function (source) + if source.type == 'local' + or source.type == 'getlocal' + or source.type == 'setlocal' + or source.type == 'setglobal' + or source.type == 'getglobal' + or source.type == 'field' + or source.type == 'method' then + return source + end + end) +end + +function TEST(wanted) + return function (script) + files.removeAll() + local start = script:find('<?', 1, true) + local finish = script:find('?>', 1, true) + local pos = (start + finish) // 2 + 1 + local newScript = script:gsub('<[!?]', ' '):gsub('[!?]>', ' ') + files.setText('', newScript) + local source = getSource(pos) + assert(source) + local result = vm.getInferType(source, 'deep') + assert(wanted == result) + end +end + +TEST 'string' [[ +local <?var?> = '111' +]] + +TEST 'boolean' [[ +local <?var?> = true +]] + +TEST 'integer' [[ +local <?var?> = 1 +]] + +TEST 'number' [[ +local <?var?> = 1.0 +]] + +TEST 'string' [[ +local var = '111' +t.<?x?> = var +]] + +TEST 'string' [[ +local <?var?> +var = '111' +]] + +TEST 'string' [[ +local var +var = '111' +print(<?var?>) +]] + +TEST 'function' [[ +function <?xx?>() +end +]] + +TEST 'function' [[ +local function <?xx?>() +end +]] + +TEST 'function' [[ +local xx +<?xx?> = function () +end +]] + +TEST 'table' [[ +local <?t?> = {} +]] + +TEST 'function' [[ +<?x?>() +]] + +TEST 'table' [[ +<?t?>.x = 1 +]] + +TEST 'boolean' [[ +<?x?> = not y +]] + +TEST 'integer' [[ +<?x?> = #y +]] + +TEST 'number' [[ +<?x?> = - y +]] + +TEST 'integer' [[ +<?x?> = ~ y +]] + +TEST 'integer' [[ +local a = true +local b = 1 +<?x?> = a and b +]] + +TEST 'integer' [[ +local a = false +local b = 1 +<?x?> = a or b +]] + +TEST 'boolean' [[ +<?x?> = a == b +]] + +TEST 'integer' [[ +<?x?> = a << b +]] + +TEST 'string' [[ +<?x?> = a .. b +]] + +TEST 'number' [[ +<?x?> = a + b +]] + +TEST 'table*' [[ +<?table?>() +]] + +TEST 'string' [[ +<?x?> = _VERSION +]] + +TEST 'function' [[ +return ('x').<?sub?> +]] + +TEST 'function' [[ +<?x?> = ('x').sub +]] + +TEST 'function' [[ +<?x?> = _VERSION.sub +]] + +TEST 'table' [[ +<?x?> = setmetatable({}) +]] + +TEST 'integer' [[ +local function x() + return 1 +end +<?y?> = x() +]] + +TEST 'integer|nil' [[ +local function x() + return 1 + return nil +end +<?y?> = x() +]] + +TEST 'any' [[ +local function x() + return a + return nil +end +<?y?> = x() +]] + +TEST 'integer' [[ +local function x() + return 1 +end +_, <?y?> = pcall(x) +]] + +TEST 'integer' [[ +function x() + return 1 +end +_, <?y?> = pcall(x) +]] + +TEST 'os*' [[ +local <?os?> = require 'os' +]] + +TEST 'string|table' [[ +local y = #<?x?> +]] + +TEST 'integer' [[ +local y = <?x?> << 0 +]] + +TEST 'integer' [[ +local function f(<?a?>, b) + return a << b +end +]] + +TEST 'string' [[ +local function f() + return string.sub() +end + +local <?x?> = f() +]] + +-- 不根据调用者的输入参数来推测 +--TEST 'number' [[ +--local function x(a) +-- return <?a?> +--end +--x(1) +--]] + +--TEST 'table' [[ +--setmetatable(<?b?>) +--]] + +TEST 'function' [[ +string.<?sub?>() +]] + +TEST 'function' [[ +(''):<?sub?>() +]] + +-- 不根据对方函数内的使用情况来推测 +TEST 'any' [[ +local function x(a) + _ = a + 1 +end +local b +x(<?b?>) +]] + +TEST 'any' [[ +local function x(a, ...) + local _, <?b?>, _ = ... +end +x(nil, 'xx', 1, true) +]] + +-- 引用不跨越参数 +TEST 'any' [[ +local function x(a, ...) + return true, 'ss', ... +end +local _, _, _, <?b?>, _ = x(nil, true, 1, 'yy') +]] + +-- TODO 暂不支持这些特殊情况,之后用其他语法定义 +--TEST 'integer' [[ +--for <?i?> in ipairs(t) do +--end +--]] + +TEST 'any' [[ +local <?x?> = next() +]] + +TEST 'any' [[ +local a, b +function a() + return b() +end +function b() + return a() +end +local <?x?> = a() +]] + +TEST 'class' [[ +---@class class +local <?x?> +]] + +TEST 'string' [[ +---@type string +local <?x?> +]] + +TEST 'string[]' [[ +---@type string[] +local <?x?> +]] + +TEST 'string|table' [[ +---@type string | table +local <?x?> +]] + +TEST '"enum1"|"enum2"' [[ +---@type '"enum1"' | '"enum2"' +local <?x?> +]] + +TEST 'function' [[ +---@type fun() +local <?x?> +]] + +TEST 'table<string, number>' [[ +---@type table<string, number> +local <?x?> +]] + +TEST 'table' [[ +self.<?t?>[#self.t+1] = {} +]] |