diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/command/auto-require.lua | 5 | ||||
-rw-r--r-- | test/completion/common.lua | 37 | ||||
-rw-r--r-- | test/definition/luadoc.lua | 6 | ||||
-rw-r--r-- | test/definition/method.lua | 26 | ||||
-rw-r--r-- | test/diagnostics/common.lua | 185 | ||||
-rw-r--r-- | test/full/init.lua | 13 | ||||
-rw-r--r-- | test/full/self.lua | 39 | ||||
-rw-r--r-- | test/hover/init.lua | 55 | ||||
-rw-r--r-- | test/tclient/init.lua | 1 | ||||
-rw-r--r-- | test/tclient/tests/resolve-completion.lua | 58 | ||||
-rw-r--r-- | test/type_inference/init.lua | 837 |
11 files changed, 1214 insertions, 48 deletions
diff --git a/test/command/auto-require.lua b/test/command/auto-require.lua index 9dd19bd2..38cc0012 100644 --- a/test/command/auto-require.lua +++ b/test/command/auto-require.lua @@ -3,9 +3,12 @@ local files = require 'files' local autoRequire = require 'core.command.autoRequire' local client = require 'client' -local findInsertRow = util.getUpvalue(autoRequire, 'findInsertRow') +local findInsertRow = util.getUpvalue(autoRequire, 'findInsertRow') local applyAutoRequire = util.getUpvalue(autoRequire, 'applyAutoRequire') +assert(findInsertRow) +assert(applyAutoRequire) + local originEditText = client.editText local EditResult diff --git a/test/completion/common.lua b/test/completion/common.lua index 538ac401..613f9b0c 100644 --- a/test/completion/common.lua +++ b/test/completion/common.lua @@ -3311,3 +3311,40 @@ TEST [[ end assert(count == 1) end) + +TEST [[ +local x +x.y.z = xxx + +x.y.<??> +]] +{ + { + label = 'z', + kind = define.CompletionItemKind.Field, + } +} + +TEST [[ +local xyz + +---@cast <??> +]] +{ + { + label = 'xyz', + kind = define.CompletionItemKind.Variable, + }, +} + +TEST [[ +local xyz + +---@cast x<??> +]] +{ + { + label = 'xyz', + kind = define.CompletionItemKind.Variable, + } +} diff --git a/test/definition/luadoc.lua b/test/definition/luadoc.lua index 19b4421b..47859b15 100644 --- a/test/definition/luadoc.lua +++ b/test/definition/luadoc.lua @@ -893,3 +893,9 @@ TEST [[ ---@type XXX<<?YYY?>> ]] + +TEST [[ +local <!x!> + +---@cast <?x?> integer +]] diff --git a/test/definition/method.lua b/test/definition/method.lua index aa7aacdc..e4368edb 100644 --- a/test/definition/method.lua +++ b/test/definition/method.lua @@ -29,3 +29,29 @@ end function mt:<!m4!>() end ]] + +TEST [[ +local mt + +function mt:f() + self.<!x!> = 1 +end + +mt.<?x?> +]] + +TEST [[ +function G:f() + self.<!x!> = 1 +end + +G.<?x?> +]] + +TEST [[ +function G.H:f() + self.<!x!> = 1 +end + +G.H.<?x?> +]] diff --git a/test/diagnostics/common.lua b/test/diagnostics/common.lua index 56ad0d59..56d1cbcc 100644 --- a/test/diagnostics/common.lua +++ b/test/diagnostics/common.lua @@ -163,7 +163,7 @@ print() ]] TEST [[ -pairs +print {} {} ]] @@ -218,6 +218,12 @@ x(1, 2, 3, 4, 5) ]] TEST [[ +---@type fun(a, b, ...) +local x +x(1, 2, 3, 4, 5) +]] + +TEST [[ local m = {} function m:x(a, b) return a, b @@ -242,6 +248,66 @@ m:x(1, <!2!>, <!3!>, <!4!>) ]] TEST [[ +local function x(a, b) + return a, b +end +x(1) +]] + +TEST [[ +---@param a integer +---@param b integer +local function x(a, b) + return a, b +end +<!x(1)!> +]] + +TEST [[ +---@param a integer +---@param b integer +local function x(a, b) + return a, b +end +<!x()!> +]] + +TEST [[ +---@param a integer +---@param b integer +---@param ... integer +local function x(a, b, ...) + return a, b, ... +end +x(1, 2) +]] + +TEST [[ +---@param a integer +---@param b? integer +local function x(a, b) + return a, b +end +x(1) +]] + +TEST [[ +---@param b integer? +local function x(a, b) + return a, b +end +x(1) +]] + +TEST [[ +---@param b integer|nil +local function x(a, b) + return a, b +end +x(1) +]] + +TEST [[ local m = {} function m.x() end @@ -273,6 +339,14 @@ TEST [[ local _ <close> = <!1!> ]] +TEST [[ +local _ <close> = <!''!> +]] + +TEST [[ +local c <close> = <!(function () return 1 end)()!> +]] + config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = true TEST [[ local f = <!function () end!> @@ -286,6 +360,21 @@ TEST [[ local <!function f() end!> ]] +TEST [[ +local <!function f() + f() +end!> +]] + + +TEST [[ +local <!function test() +end!> + +local <!function foo () +end!> +]] + config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = nil TEST [[ local mt, x @@ -407,11 +496,13 @@ _G.bb = 1 TEST [[ local f = load('') -f(1, 2, 3) +if f then + f(1, 2, 3) +end ]] TEST [[ -local _ = <!unpack!>() +local _ = <!unpack!> ]] TEST [[ @@ -494,11 +585,10 @@ _ = 1, <!2!> ]] TEST [[ -local function x() +function X() do local k print(k) - x() end local k = 1 print(k) @@ -506,9 +596,8 @@ end ]] TEST [[ -local function x() +function X() local loc - x() print(loc) end ]] @@ -708,7 +797,9 @@ TEST [[ local function f(x, y) return x, y end -f() + +local _ +f(_, _) ]] TEST [[ @@ -741,7 +832,7 @@ TEST [[ TEST [[ ---@type fun(a: integer) local f -f() +f(1) ]] TEST [[ @@ -792,7 +883,7 @@ local mt2 = {} ---@type Foo local v print(v.field1 + 1) -print(v.<!field2!> + 1) +print(v.field2 + 1) print(v.<!field3!> + 1) print(v:method1()) print(v.method2()) @@ -801,7 +892,7 @@ print(v:<!method3!>()) ---@type Bar local v2 print(v2.field1 + 1) -print(v2.<!field2!> + 1) +print(v2.field2 + 1) print(v2.<!field3!> + 1) print(v2.field4 + 1) print(v2:method1()) @@ -868,7 +959,7 @@ TEST [[ local mt function mt:method1() mt.<!method2!>() -- doc.class - self.method1() + self:method1() return self.<!method2!>() -- doc.class.name end ]] @@ -978,7 +1069,7 @@ return m TEST [[ local m = {} -m.x = io.open() +m.x = io.open('') m.x = nil return m @@ -1379,13 +1470,13 @@ TEST [[ ]] TEST [[ -return ('1'):gsub() +return ('1'):upper() ]] TEST [[ local value value = '1' -value = value:gsub() +value = value:upper() ]] TEST [[ @@ -1395,3 +1486,67 @@ T.x = 1 print(<!T.x!>) ]] + +TEST [[ +T = {} + +---@deprecated +function T:ff() +end + +<!T:ff!>() +]] + +TEST [[ +---@type string? +local x + +S = <!x!>:upper() +]] + +TEST [[ +---@type string? +local x + +if x then + S = x:upper() +end +]] + +TEST [[ +---@type string? +local x + +if not x then + x = '' +end + +S = x:upper() +]] + +TEST [[ +---@type fun()? +local x + +S = <!x!>() +]] + +TEST [[ +local x, y +local z = x and y + +print(z.y) +]] + +TEST [[ +local x, y +function x() + y() +end + +function y() + x() +end + +x() +]] diff --git a/test/full/init.lua b/test/full/init.lua index e83a7d6d..3b1d2fe2 100644 --- a/test/full/init.lua +++ b/test/full/init.lua @@ -27,8 +27,17 @@ require 'full.dirty' require 'full.projects' require 'full.self' +local times = {} for name, time in util.sortPairs(DIAGTIMES, function (k1, k2) - return DIAGTIMES[k1] < DIAGTIMES[k2] + return DIAGTIMES[k1] > DIAGTIMES[k2] end) do - print('诊断任务耗时:', name, time) + times[#times+1] = ('诊断任务耗时:%05.3f [%s]'):format(time, name) + if #times >= 10 then + break + end +end + +util.revertTable(times) +for _, time in ipairs(times) do + print(time) end diff --git a/test/full/self.lua b/test/full/self.lua index 93cfe715..cfa6b710 100644 --- a/test/full/self.lua +++ b/test/full/self.lua @@ -5,11 +5,14 @@ local diag = require 'provider.diagnostic' local config = require 'config' local ws = require 'workspace' local guide = require 'parser.guide' +local vm = require 'vm' +local util = require 'utility' local path = ROOT / 'script' local uris = {} +files.reset() fsu.scanDirectory(path, function (path) if path:extension():string() ~= '.lua' then return @@ -47,3 +50,39 @@ end local passed = os.clock() - clock print('基准全量诊断用时:', passed) + +vm.clearNodeCache() + +local clock = os.clock() +local compileDatas = {} + +for uri in files.eachFile() do + local state = files.getState(uri) + local clock = os.clock() + guide.eachSource(state.ast, function (src) + vm.compileNode(src) + end) + compileDatas[uri] = { + passed = os.clock() - clock, + uri = uri, + } +end + +local printTexts = {} +for uri, data in util.sortPairs(compileDatas, function (a, b) + return compileDatas[a].passed > compileDatas[b].passed +end) do + printTexts[#printTexts+1] = ('全量编译耗时:%05.3f [%s]'):format(data.passed, uri) + if #printTexts >= 10 then + break + end +end + +util.revertTable(printTexts) + +for _, text in ipairs(printTexts) do + print(text) +end + +local passed = os.clock() - clock +print('基准全量编译用时:', passed) diff --git a/test/hover/init.lua b/test/hover/init.lua index ee66ef2b..dc725f6c 100644 --- a/test/hover/init.lua +++ b/test/hover/init.lua @@ -280,8 +280,8 @@ TEST [[ ]] [=[ function load(chunk: string|function, chunkname?: string, mode?: "b"|"bt"|"t", env?: table) - -> function - 2. error_message: string + -> function? + 2. error_message: string? ]=] TEST [[ @@ -504,10 +504,10 @@ local <?self?> = setmetatable({ ]] [[ local self: { - __index: table, - __name: string = "obj", id: integer = 1, remove: function, + __index: table, + __name: string = "obj", } ]] @@ -772,7 +772,7 @@ local <?t?> = { ]] [[ local t: { - f: file*, + f?: file*, } ]] @@ -790,8 +790,6 @@ TEST [[ ]] [[ (global) _G: _G { - _G: _G, - _VERSION: string = "Lua 5.4", arg: string[], assert: function, collectgarbage: function, @@ -810,6 +808,8 @@ TEST [[ module: function, newproxy: function, next: function, + os: oslib, + package: packagelib, ...(+22) } ]] @@ -1733,18 +1733,18 @@ t.<?x?>() (field) t.x: unknown ]] -TEST [[ ----@class A -local a - -local b -b = a - -print(b.<?x?>) -]] -[[ -(field) A.x: unknown -]] +--TEST [[ +-----@class A +--local a +-- +--local b +--b = a +-- +--print(b.<?x?>) +--]] +--[[ +--(field) A.x: unknown +--]] TEST [[ ---@return nil @@ -1851,6 +1851,23 @@ local x: { ]] TEST [[ +local <?x?> = { + _x = '', + _y = '', + x = '', + y = '', +} +]] +[[ +local x: { + x: string = "", + y: string = "", + _x: string = "", + _y: string = "", +} +]] + +TEST [[ ---@class A ---@field x string diff --git a/test/tclient/init.lua b/test/tclient/init.lua index 7c8d70ef..9e1db8d4 100644 --- a/test/tclient/init.lua +++ b/test/tclient/init.lua @@ -4,3 +4,4 @@ require 'tclient.tests.multi-workspace' require 'tclient.tests.folders-with-single-file' require 'tclient.tests.load-library' require 'tclient.tests.files-associations' +require 'tclient.tests.resolve-completion' diff --git a/test/tclient/tests/resolve-completion.lua b/test/tclient/tests/resolve-completion.lua new file mode 100644 index 00000000..a7cf2c2f --- /dev/null +++ b/test/tclient/tests/resolve-completion.lua @@ -0,0 +1,58 @@ +local lclient = require 'lclient' +local ws = require 'workspace' +local util = require 'utility' + +---@async +lclient():start(function (client) + client:registerFakers() + client:initialize() + + client:notify('textDocument/didOpen', { + textDocument = { + uri = 'file://test.lua', + languageId = 'lua', + version = 0, + text = [[ +---@type integer +local xxxx + +x +]] + } + }) + + ws.awaitReady() + + local completions = client:awaitRequest('textDocument/completion', { + textDocument = { uri = 'file://test.lua' }, + position = { line = 3, character = 1 }, + }) + + client:awaitRequest('textDocument/didChange', + { + textDocument = { uri = 'file://test.lua' }, + contentChanges = { + { + range = { + start = { line = 3, character = 1 }, + ['end'] = { line = 3, character = 1 }, + }, + text = 'x' + } + } + }) + + local targetItem + for _, item in ipairs(completions.items) do + if item.label == 'xxxx' then + targetItem = item + break + end + end + + assert(targetItem ~= nil) + + local newItem = client:awaitRequest('completionItem/resolve', targetItem) + + assert(newItem.detail == 'integer') +end) diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua index 9ead2861..b71cf987 100644 --- a/test/type_inference/init.lua +++ b/test/type_inference/init.lua @@ -1,8 +1,8 @@ local files = require 'files' local guide = require 'parser.guide' -local infer = require 'vm.infer' local config = require 'config' local catch = require 'catch' +local vm = require 'vm' rawset(_G, 'TEST', true) @@ -31,9 +31,9 @@ function TEST(wanted) files.setText('', newScript) local source = getSource(catched['?'][1][1]) assert(source) - local result = infer.getInfer(source):view() + local result = vm.getInfer(source):view() if wanted ~= result then - infer.getInfer(source):view() + vm.getInfer(source):view() end assert(wanted == result) files.remove('') @@ -77,12 +77,6 @@ function f(<?x?>) end ]] -TEST 'number' [[ -local <?var?> -var = 1 -var = 1.0 -]] - TEST 'string' [[ local var = '111' t.<?x?> = var @@ -95,6 +89,11 @@ var = '111' TEST 'string' [[ local var +<?var?> = '111' +]] + +TEST 'string' [[ +local var var = '111' print(<?var?>) ]] @@ -872,6 +871,37 @@ end ]] TEST 'boolean' [[ +---@generic T: table, V +---@param t T +---@return fun(table: V[], i?: integer):integer, V +---@return T +---@return integer i +local function ipairs(t) end + +---@type table<integer, boolean> +local t + +for _, <?v?> in ipairs(t) do +end +]] + +TEST 'boolean' [[ +---@generic T: table, V +---@param t T +---@return fun(table: V[], i?: integer):integer, V +---@return T +---@return integer i +local function ipairs(t) end + +---@class MyClass +---@field [integer] boolean +local t + +for _, <?v?> in ipairs(t) do +end +]] + +TEST 'boolean' [[ ---@generic T: table, K, V ---@param t T ---@return fun(table: table<K, V>, index: K):K, V @@ -1127,6 +1157,29 @@ local t = f('') print(t.<?x?>) ]] +TEST 'string' [[ +---@generic T +---@param t T[] +---@param callback fun(v: T) +local function f(t, callback) end + +---@type string[] +local t + +f(t, function (<?v?>) end) +]] + +TEST 'unknown' [[ +---@generic T +---@param t T[] +---@param callback fun(v: T) +local function f(t, callback) end + +local t = {} + +f(t, function (<?v?>) end) +]] + TEST 'table' [[ local <?t?> = setmetatable({}, { __index = function () end }) ]] @@ -1216,14 +1269,14 @@ TEST '👍' [[ local <?x?> ]] -TEST 'boolean' [[ +TEST 'integer' [[ ---@type boolean local x <?x?> = 1 ]] -TEST 'Class' [[ +TEST 'integer' [[ ---@class Class local x @@ -1482,3 +1535,765 @@ function mt:f() print(<?self?>) end ]] + +TEST 'string?' [[ +---@return string? +local function f() end + +local <?x?> = f() +]] + +TEST 'AA' [[ +---@class AA +---@overload fun():AA +local AAA + + +local <?x?> = AAA() +]] + +TEST 'AA' [[ +---@class AA +---@overload fun():AA +AAA = {} + + +local <?x?> = AAA() +]] + +TEST 'AA' [[ +---@overload fun():AA +AAA.BBB = {} + + +local <?x?> = AAA.BBB() +]] + +TEST 'AA' [[ +local AAA + +---@overload fun():AA +AAA.BBB = {} + + +local <?x?> = AAA.BBB() +]] + +TEST 'string|integer' [[ +local <?x?> +x = '1' +x = 1 +]] + +TEST 'string' [[ +local x +<?x?> = '1' +x = 1 +]] + +TEST 'integer' [[ +local x +x = '1' +<?x?> = 1 +]] + +TEST 'unknown' [[ +local x +print(<?x?>) +x = '1' +x = 1 +]] + +TEST 'string' [[ +local x +x = '1' +print(<?x?>) +x = 1 +]] + +TEST 'integer' [[ +local x +x = '1' +x = 1 +print(<?x?>) +]] + +TEST 'unknown' [[ +local x + +function A() + print(<?x?>) +end +]] + +TEST 'unknown' [[ +local x + +function A() + print(<?x?>) +end + +x = '1' +x = 1 +]] + +TEST 'string' [[ +local x + +x = '1' + +function A() + print(<?x?>) +end + +x = 1 +]] + +TEST 'integer' [[ +local x + +x = '1' +x = 1 + +function A() + print(<?x?>) +end + +]] + +TEST 'boolean' [[ +local x + +function A() + x = true + print(<?x?>) +end + +x = '1' +x = 1 +]] + +TEST 'unknown' [[ +local x + +function A() + x = true +end + +print(<?x?>) +x = '1' +x = 1 +]] + +TEST 'boolean' [[ +local x + +function A() + x = true + function B() + print(<?x?>) + end +end + +x = '1' +x = 1 +]] + +TEST 'table' [[ +local x + +function A() + x = true + function B() + x = {} + print(<?x?>) + end +end + +x = '1' +x = 1 +]] + +TEST 'boolean' [[ +local x + +function A() + x = true + function B() + x = {} + end + print(<?x?>) +end + +x = '1' +x = 1 +]] + +TEST 'unknown' [[ +local x + +function A() + x = true + function B() + x = {} + end +end + +function C() + print(<?x?>) +end + +x = '1' +x = 1 +]] + +TEST 'integer?' [[ +---@type integer? +local <?x?> +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if <?x?> then + print(x) +end +]] +--[[ +context 0 integer? + +save copy 'block' +save copy 'out' +push 'block' +get +push copy +truthy +falsy ref 'out' +get +save HEAD 'final' +push 'out' + +push copy HEAD +merge 'final' +]] + +TEST 'integer' [[ +---@type integer? +local x + +if x then + print(<?x?>) +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if x then + print(x) +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +if not x then + x = 1 +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +if xxx and x then + print(<?x?>) +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if xxx and x then +end + +print(<?x?>) +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if xxx and x then + return +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +if x ~= nil then + print(<?x?>) +end + +print(x) +]] + +TEST 'integer|nil' [[ +---@type integer? +local x + +if x ~= nil then + print(x) +end + +print(<?x?>) +]] + +TEST 'nil' [[ +---@type integer? +local x + +if x == nil then + print(<?x?>) +end + +print(x) +]] + +TEST 'integer|nil' [[ +---@type integer? +local x + +if x == nil then + print(x) +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +<?x?> = x or 1 +]] + +TEST 'integer' [[ +---@type integer? +local x + +<?x?> = x or y +]] + +TEST 'integer' [[ +---@type integer? +local x + +if not x then + return +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +if not x then + goto ANYWHERE +end + +print(<?x?>) +]] + +TEST 'integer' [=[ +local x + +print(<?x?>--[[@as integer]]) +]=] + +TEST 'integer' [=[ +print(<?io?>--[[@as integer]]) +]=] + +TEST 'integer' [=[ +print(io.<?open?>--[[@as integer]]) +]=] + +TEST 'integer' [=[ +local <?x?> = io['open']--[[@as integer]]) +]=] + +TEST 'integer' [=[ +local <?x?> = 1 + 1--[[@as integer]]) +]=] + +TEST 'integer' [=[ +local <?x?> = not 1--[[@as integer]]) +]=] + +TEST 'integer' [=[ +local <?x?> = ()--[[@as integer]]) +]=] + +TEST 'integer?' [[ +---@param x? integer +local function f(<?x?>) + +end +]] + +TEST 'integer' [[ +local x = 1 +x = <?x?> +]] + +TEST 'integer?' [[ +---@class A +---@field x? integer +local t + +t.<?x?> +]] + +TEST 'integer?' [[ +---@type { x?: integer } +local t + +t.<?x?> +]] + +TEST 'boolean' [[ +---@class A +---@field [integer] boolean +local t + +local <?x?> = t[1] +]] + +TEST 'unknown' [[ +local <?x?> = y and z +]] + +TEST 'integer' [[ +---@type integer? +local x + +assert(x) + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +assert(x ~= nil) + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer | nil +local x + +assert(x) + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer | nil +local x + +assert(x ~= nil) + +print(<?x?>) +]] + +TEST 'integer' [[ +local x + +assert(x == 1) + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +if x and <?x?>.y then +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if x and x.y then +end + +print(<?x?>) +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if x and x.y then + return +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +if not x or <?x?>.y then +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if not x or x.y then + print(<?x?>) +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if x or x.y then + print(<?x?>) +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if x.y or x then + print(<?x?>) +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +if x.y or not x then + print(<?x?>) +end +]] + +TEST 'integer' [[ +---@type integer? +local x + +if not x or not y then + return +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +if not y or not x then + return +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type integer? +local x + +while true do + if not x then + break + end + print(<?x?>) +end +]] + +TEST 'integer?' [[ +---@type integer? +local x + +while true do + if not x then + break + end +end + +print(<?x?>) +]] + +TEST 'integer' [[ +---@type fun():integer? +local iter + +for <?x?> in iter do +end +]] + +TEST 'integer' [[ +local x + +---@type integer +<?x?> = XXX +]] + +TEST 'unknown' [[ +for _ = 1, 999 do + local <?x?> +end +]] + +TEST 'integer' [[ +local x + +---@cast x integer + +print(<?x?>) +]] + +TEST 'unknown' [[ +local x + +---@cast x integer + +local x +print(<?x?>) +]] + +TEST 'unknown' [[ +local x + +if true then + local x + ---@cast x integer + print(x) +end + +print(<?x?>) +]] + +TEST 'boolean|integer' [[ +local x = 1 + +---@cast x +boolean + +print(<?x?>) +]] + +TEST 'boolean' [[ +---@type integer|boolean +local x + +---@cast x -integer + +print(<?x?>) +]] + +TEST 'boolean?' [[ +---@type boolean +local x + +---@cast x +? + +print(<?x?>) +]] + +TEST 'boolean' [[ +---@type boolean? +local x + +---@cast x -? + +print(<?x?>) +]] + +TEST 'string' [[ +---@type string? +local x + +if not x then + return +else + print(<?x?>) +end + +print(x) +]] + +TEST 'string' [[ +---@type string? +local x + +if not x then + return +else + print(x) +end + +print(<?x?>) +]] + +TEST 'true' [[ +---@type boolean | nil +local x + +if not x then + return +end + +print(<?x?>) +]] + +TEST 'true' [[ +---@type boolean +local t + +if t then + print(<?t?>) + return +end + +print(t) +]] + +TEST 'false' [[ +---@type boolean +local t + +if t then + print(t) + return +end + +print(<?t?>) +]] |