diff options
Diffstat (limited to 'test/diagnostics')
23 files changed, 793 insertions, 978 deletions
diff --git a/test/diagnostics/await-in-sync.lua b/test/diagnostics/await-in-sync.lua new file mode 100644 index 00000000..277101dd --- /dev/null +++ b/test/diagnostics/await-in-sync.lua @@ -0,0 +1,181 @@ +TEST [[ +function F() + <!coroutine.yield!>() +end +]] + +TEST [[ +---@async +function F() + coroutine.yield() +end +]] + +TEST [[ +---@type async fun() +local f + +function F() + <!f!>() +end +]] + +TEST [[ +---@type async fun() +local f + +---@async +function F() + f() +end +]] + +TEST [[ +local function f(cb) + cb() +end + +return function() + <!f>(function () ---@async + return nil + end) +end +]] + +TEST [[ +local function f(cb) + pcall(cb) +end + +return function() + <!f!>(function () ---@async + return nil + end) +end +]] + +TEST [[ +---@param c any +local function f(c) + return c +end + +return function () + f(function () ---@async + return nil + end) +end +]] + +TEST [[ +---@param ... any +local function f(...) + return ... +end + +return function () + f(function () ---@async + return nil + end) +end +]] + +TEST [[ +---@vararg any +local function f(...) + return ... +end + +return function () + f(function () ---@async + return nil + end) +end +]] + +TEST [[ +local function f(...) + return ... +end + +return function () + f(function () ---@async + return nil + end) +end +]] + +TEST [[ +local function f(...) + return ... +end + +return function () + f(function () ---@async + return nil + end) +end +]] + +TEST [[ +---@param cb fun() +local function f(cb) + return cb +end + +---@async +local function af() + return nil +end + +f(<!af!>) +]] + +TEST [[ +---@param cb async fun() +local function f(cb) + return cb +end + +---@async +local function af() + return nil +end + +f(af) +]] + +TEST [[ +local function f(cb) + cb() +end + +local function af() + <!f!>(function () ---@async + return nil + end) +end + +return af +]] + +TEST [[ +local function f(cb) + cb() +end + +---@async +local function af() + f(function () ---@async + return nil + end) +end + +return af +]] + +TEST [[ +local _ = type(function () ---@async + return nil +end) +]] diff --git a/test/diagnostics/circle-doc-class.lua b/test/diagnostics/circle-doc-class.lua new file mode 100644 index 00000000..089b0c9b --- /dev/null +++ b/test/diagnostics/circle-doc-class.lua @@ -0,0 +1,14 @@ +TEST [[ +---@class <!A : B!> +---@class <!B : C!> +---@class <!C : D!> +---@class <!D : A!> +]] + +TEST [[ +---@class A : B +---@class B : C +---@class C : D +---@class D +]] + diff --git a/test/diagnostics/common.lua b/test/diagnostics/common.lua index 24ec4c8c..9352765f 100644 --- a/test/diagnostics/common.lua +++ b/test/diagnostics/common.lua @@ -1,982 +1,5 @@ -local config = require 'config' -local util = require 'utility' - - - - - - -TEST [[ -local x, <!y!>, <!z!> = 1 -print(x, y, z) -]] - -TEST [[ -local x, y, <!z!> = 1, 2 -print(x, y, z) -]] - -TEST [[ -local x, y, z = print() -print(x, y, z) -]] - -TEST [[ -local x, y, z -print(x, y, z) -]] - -TEST [[ -local x, y, z -x, <!y!>, <!z!> = 1 -print(x, y, z) -]] - -TEST [[ -X, <!Y!>, <!Z!> = 1 -]] - -TEST [[ -T = {} -T.x, <!T.y!>, <!T.z!> = 1 -]] - -TEST [[ -T = {} -T['x'], <!T['y']!>, <!T['z']!> = 1 -]] - ---TEST [[ ------@class <!Class!> ------@class <!Class!> ---]] - -TEST [[ ----@alias <!A!> integer ----@alias <!A!> integer -]] - -TEST [[ ----@class A : <!B!> -]] - -TEST [[ ----@class <!A : B!> ----@class <!B : C!> ----@class <!C : D!> ----@class <!D : A!> -]] - -TEST [[ ----@class A : B ----@class B : C ----@class C : D ----@class D -]] - -TEST [[ ----@type <!A!> -]] - -TEST [[ ----@class A ----@type A|<!B!>|<!C!> -]] - -TEST [[ ----@class AAA ----@alias B AAA - ----@type B -]] - -TEST [[ ----@alias B <!AAA!> -]] - -TEST [[ ----@class A ----@class B ----@alias <!A!> B -]] - -TEST [[ ----@param <!x!> <!Class!> -]] - -TEST [[ ----@class Class ----@param <!y!> Class -local function f(x) - return x -end -f() -]] - -TEST [[ ----@class Class ----@param <!y!> Class -function F(x) - return x -end -F() -]] - -TEST [[ ----@class Class ----@param <!x!> Class ----@param y Class ----@param <!x!> Class -local function f(x, y) - return x, y -end - -local _ -f(_, _) -]] - -TEST [[ ----@field <!x Class!> ----@class Class -]] - -TEST [[ ----@class Class - ----@field <!x Class!> -]] - -TEST [[ ----@class Class ---- ----@field x Class -]] - -TEST [[ ----@class Class ----@field <!x!> Class ----@field <!x!> Class -]] - -TEST [[ ----@class Class : any -]] - -TEST [[ ----@type fun(a: integer) -local f -f(1) -]] - -TEST [[ ----@class c -c = {} -]] - -TEST [[ ----@generic T: any ----@param v T ----@param message any ----@return T ----@return any message -function assert(v, message) - return v, message -end -]] - -TEST [[ ----@type string ----| -]] - -TEST [[ ----@type ----| 'xx' -]] - -TEST [[ ----@class class -local t -]] ----[==[ --- checkUndefinedField 通用 -TEST [[ ----@class Foo ----@field field1 integer -local mt = {} -function mt:Constructor() - self.field2 = 1 -end -function mt:method1() return 1 end -function mt.method2() return 2 end - ----@class Bar: Foo ----@field field4 integer -local mt2 = {} - ----@type Foo -local v -print(v.field1 + 1) -print(v.field2 + 1) -print(v.<!field3!> + 1) -print(v:method1()) -print(v.method2()) -print(v:<!method3!>()) - ----@type Bar -local v2 -print(v2.field1 + 1) -print(v2.field2 + 1) -print(v2.<!field3!> + 1) -print(v2.field4 + 1) -print(v2:method1()) -print(v2.method2()) -print(v2:<!method3!>()) - -local v3 = {} -print(v3.abc) - ----@class Bar2 -local mt3 -function mt3:method() return 1 end -print(mt3:method()) -]] - --- checkUndefinedField 通过type找到class -TEST [[ ----@class Foo -local Foo -function Foo:method1() end - ----@type Foo -local v -v:method1() -v:<!method2!>() -- doc.class.name -]] - --- checkUndefinedField 通过type找到class,涉及到 class 继承版 -TEST [[ ----@class Foo -local Foo -function Foo:method1() end ----@class Bar: Foo -local Bar -function Bar:method3() end - ----@type Bar -local v -v:method1() -v:<!method2!>() -- doc.class.name -v:method3() -]] - --- checkUndefinedField 类名和类变量同名,类变量被直接使用 -TEST [[ ----@class Foo -local Foo -function Foo:method1() end -Foo:<!method2!>() -- doc.class -Foo:<!method2!>() -- doc.class -]] - --- checkUndefinedField 没有@class的不检测 -TEST [[ -local Foo -function Foo:method1() - return Foo:method2() -- table -end -]] - --- checkUndefinedField 类名和类变量不同名,类变量被直接使用、使用self -TEST [[ ----@class Foo -local mt -function mt:method1() - mt.<!method2!>() -- doc.class - self:method1() - return self.<!method2!>() -- doc.class.name -end -]] - --- checkUndefinedField 当会推导成多个class类型时 -TEST [[ ----@class Foo -local mt -function mt:method1() end - ----@class Bar -local mt2 -function mt2:method2() end - ----@type Foo -local v ----@type Bar -local v2 -<!v2!> = v -v2:method1() -v2:<!method2!>() -]] - -TEST [[ ----@type table -T1 = {} -print(T1.f1) ----@type tablelib -T2 = {} -print(T2.<!f2!>) -]] ---]==] -TEST [[ ----@overload fun(...) -local function f() end - -f(1) -]] - -TEST [[ -for i = <!10, 1!> do - print(i) -end -]] - -TEST [[ -for i = <!10, 1, 5!> do - print(i) -end -]] - -TEST [[ -for i = <!100, 10, 1!> do - print(i) -end -]] - -TEST [[ -for i = <!1, -10!> do - print(i) -end -]] - -TEST [[ -for i = 1, 1 do - print(i) -end -]] - -TEST [[ -local m = {} - -function <!m:fff!>() -end - -function <!m:fff!>() -end - -return m -]] - -TEST [[ -local m = {} - -function <!m:fff!>() -end - -do - function <!m:fff!>() - end -end - -return m -]] - -TEST [[ -local m = {} - -m.x = true -m.x = false - -return m -]] - -TEST [[ -local m = {} - -m.x = io.open('') -m.x = nil - -return m -]] - -TEST [[ ----@meta - ----@class A ----@field a boolean - ----@return A -local function f() end - -local r = f() -r.x = 1 - -return r.x -]] - -TEST [[ ----@diagnostic disable-next-line -x = 1 -]] - -TEST [[ ----@diagnostic disable-next-line: lowercase-global -x = 1 -]] - -TEST [[ ----@diagnostic disable-next-line: unused-local -<!x!> = 1 -]] - -TEST [[ ----@diagnostic disable -x = 1 -]] - -TEST [[ ----@diagnostic disable ----@diagnostic enable -<!x!> = 1 -]] - -TEST [[ ----@diagnostic disable ----@diagnostic disable ----@diagnostic enable -x = 1 -]] - -TEST [[ ----@diagnostic disable-next-line: <!xxx!> -]] - -TEST [[ -local mt = {} - -function mt:a(x) - return self, x -end - -function mt:b(y) - self:a(1):b(2) - return y -end - -return mt -]] - -TEST [[ -local function each() - return function () - end -end - -for x in each() do - print(x) -end -]] - -TEST [[ ----@type string -local s - -print(s:upper()) -]] - -TEST [[ -local t = (). -return t -]] - -TEST [[ -return { - [1] = 1, - ['1'] = 1, -} -]] - -TEST [[ -return { - [print()] = 1, - [print()] = 1, -} -]] - -TEST [[ ----@type { x: number, y: number} ----| "'resume'" -]] - -TEST [[ -return { - 1, <!2!>, 3, - [<!2!>] = 4, -} -]] - -TEST [[ ---- @class Emit ---- @field on fun(eventName: string, cb: function) ---- @field on fun(eventName: '"died"', cb: fun(i: integer)) ---- @field on fun(eventName: '"won"', cb: fun(s: string)) -local emit = {} -]] - -TEST [[ ---- @class Emit ---- @field on fun(eventName: string, cb: function) ---- @field <!on!> fun(eventName: '"died"', cb: fun(i: integer)) ---- @field on fun(eventName: '"won"', cb: fun(s: string)) ---- @field <!on!> fun(eventName: '"died"', cb: fun(i: integer)) -local emit = {} -]] - --- redundant-return -TEST [[ -local function f() - <!return!> -end -f() -]] - -TEST [[ -local function f() - return nil -end -f() -]] - -TEST [[ -local function f() - local function x() - <!return!> - end - x() - return true -end -f() -]] - -TEST [[ -local function f() - local function x() - return true - end - return x() -end -f() -]] - -TEST [[ ----@type file* -local f -local _ = f:read '*a' -local _ = f:read('*a') -]] - -TEST [[ -function F() - <!coroutine.yield!>() -end -]] - -TEST [[ ----@async -function F() - coroutine.yield() -end -]] - -TEST [[ ----@type async fun() -local f - -function F() - <!f!>() -end -]] - -TEST [[ ----@type async fun() -local f - ----@async -function F() - f() -end -]] - -TEST [[ -local function f(cb) - cb() -end - -return function() - <!f>(function () ---@async - return nil - end) -end -]] - -TEST [[ -local function f(cb) - pcall(cb) -end - -return function() - <!f!>(function () ---@async - return nil - end) -end -]] - -TEST [[ ----@param c any -local function f(c) - return c -end - -return function () - f(function () ---@async - return nil - end) -end -]] - -TEST [[ ----@param ... any -local function f(...) - return ... -end - -return function () - f(function () ---@async - return nil - end) -end -]] - -TEST [[ ----@vararg any -local function f(...) - return ... -end - -return function () - f(function () ---@async - return nil - end) -end -]] - -TEST [[ -local function f(...) - return ... -end - -return function () - f(function () ---@async - return nil - end) -end -]] - -TEST [[ -local function f(...) - return ... -end - -return function () - f(function () ---@async - return nil - end) -end -]] - -TEST [[ ----@nodiscard -local function f() - return 1 -end - -<!f()!> -]] - -TEST [[ ----@nodiscard -local function f() - return 1 -end - -X = f() -]] - -config.get(nil, 'Lua.diagnostics.neededFileStatus')['not-yieldable'] = 'Any' -TEST [[ ----@param cb fun() -local function f(cb) - return cb -end - ----@async -local function af() - return nil -end - -f(<!af!>) -]] - -TEST [[ ----@param cb async fun() -local function f(cb) - return cb -end - ----@async -local function af() - return nil -end - -f(af) -]] - -TEST [[ -local function f(cb) - cb() -end - -local function af() - <!f!>(function () ---@async - return nil - end) -end - -return af -]] - -TEST [[ -local function f(cb) - cb() -end - ----@async -local function af() - f(function () ---@async - return nil - end) -end - -return af -]] - -TEST [[ -local _ = type(function () ---@async - return nil -end) -]] - -TEST [[ ----@param ... number -local function f(...) - return ... -end - -return f -]] - -TEST [[ ----@type fun(...: string) -]] - -TEST [[ ----@type fun(xxx, yyy, ...): boolean -]] - -TEST [[ -local <!x!> - -return { - x = 1, -} -]] - -TEST [[ ----@class A #1 -]] - -TEST [[ ----@class A 1 -]] - -TEST [[ -return ('1'):upper() -]] - -TEST [[ -local value -value = '1' -value = value:upper() -]] - -TEST [[ -T = {} ----@deprecated # comment -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 [[ ----@type integer? -local x - -T = {} -T[<!x!>] = 1 -]] - -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() -]] - -TEST [[ ----@meta - ----@param x fun() -local function f1(x) -end - ----@return fun() -local function f2() -end - -f1(f2()) -]] - -TEST [[ ----@meta - ----@type fun():integer -local f - ----@param x integer -local function foo(x) end - -foo(f()) -]] - -TEST [[ ----@type string|table -local n - -print(n.x) -]] - -TEST [[ ----@diagnostic disable: unused-local, unused-function, undefined-global - -function F() end - ----@param x boolean -function F(x) end - -F(k()) -]] - -TEST [[ -local function f() - return 1, 2, 3 -end - -local function k() -end - -k(<!f()!>) -]] - -TEST [[ ----@diagnostic disable: unused-local -local function f() - return 1, 2, 3 -end - ----@param x integer -local function k(x) -end - -k(f()) -]] - TEST [[ ---@cast <!x!> integer ]] diff --git a/test/diagnostics/count-down-loop.lua b/test/diagnostics/count-down-loop.lua new file mode 100644 index 00000000..f4e385f5 --- /dev/null +++ b/test/diagnostics/count-down-loop.lua @@ -0,0 +1,29 @@ +TEST [[ +for i = <!10, 1!> do + print(i) +end +]] + +TEST [[ +for i = <!10, 1, 5!> do + print(i) +end +]] + +TEST [[ +for i = <!100, 10, 1!> do + print(i) +end +]] + +TEST [[ +for i = <!1, -10!> do + print(i) +end +]] + +TEST [[ +for i = 1, 1 do + print(i) +end +]] diff --git a/test/diagnostics/deprecated.lua b/test/diagnostics/deprecated.lua index 1086ecb2..c5486752 100644 --- a/test/diagnostics/deprecated.lua +++ b/test/diagnostics/deprecated.lua @@ -1,3 +1,21 @@ TEST [[ local _ = <!unpack!> ]] + +TEST [[ +T = {} +---@deprecated # comment +T.x = 1 + +print(<!T.x!>) +]] + +TEST [[ +T = {} + +---@deprecated +function T:ff() +end + +<!T:ff!>() +]] diff --git a/test/diagnostics/discard-returns.lua b/test/diagnostics/discard-returns.lua new file mode 100644 index 00000000..2e348390 --- /dev/null +++ b/test/diagnostics/discard-returns.lua @@ -0,0 +1,17 @@ +TEST [[ +---@nodiscard +local function f() + return 1 +end + +<!f()!> +]] + +TEST [[ +---@nodiscard +local function f() + return 1 +end + +X = f() +]] diff --git a/test/diagnostics/doc-field-no-class.lua b/test/diagnostics/doc-field-no-class.lua new file mode 100644 index 00000000..87db518c --- /dev/null +++ b/test/diagnostics/doc-field-no-class.lua @@ -0,0 +1,16 @@ +TEST [[ +---@field <!x Class!> +---@class Class +]] + +TEST [[ +---@class Class + +---@field <!x Class!> +]] + +TEST [[ +---@class Class +--- +---@field x Class +]] diff --git a/test/diagnostics/duplicate-doc-alias.lua b/test/diagnostics/duplicate-doc-alias.lua new file mode 100644 index 00000000..0373fee9 --- /dev/null +++ b/test/diagnostics/duplicate-doc-alias.lua @@ -0,0 +1,10 @@ +TEST [[ +---@alias <!A!> integer +---@alias <!A!> integer +]] + +TEST [[ +---@class A +---@class B +---@alias <!A!> B +]] diff --git a/test/diagnostics/duplicate-doc-field.lua b/test/diagnostics/duplicate-doc-field.lua index e69de29b..937e2ea4 100644 --- a/test/diagnostics/duplicate-doc-field.lua +++ b/test/diagnostics/duplicate-doc-field.lua @@ -0,0 +1,22 @@ +TEST [[ +---@class Class +---@field <!x!> Class +---@field <!x!> Class +]] + +TEST [[ +--- @class Emit +--- @field on fun(eventName: string, cb: function) +--- @field on fun(eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(eventName: '"won"', cb: fun(s: string)) +local emit = {} +]] + +TEST [[ +--- @class Emit +--- @field on fun(eventName: string, cb: function) +--- @field <!on!> fun(eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(eventName: '"won"', cb: fun(s: string)) +--- @field <!on!> fun(eventName: '"died"', cb: fun(i: integer)) +local emit = {} +]] diff --git a/test/diagnostics/duplicate-doc-param.lua b/test/diagnostics/duplicate-doc-param.lua new file mode 100644 index 00000000..42eb73d3 --- /dev/null +++ b/test/diagnostics/duplicate-doc-param.lua @@ -0,0 +1,12 @@ +TEST [[ +---@class Class +---@param <!x!> Class +---@param y Class +---@param <!x!> Class +local function f(x, y) + return x, y +end + +local _ +f(_, _) +]] diff --git a/test/diagnostics/duplicate-index.lua b/test/diagnostics/duplicate-index.lua index feb5381d..3289c736 100644 --- a/test/diagnostics/duplicate-index.lua +++ b/test/diagnostics/duplicate-index.lua @@ -15,3 +15,10 @@ return { y = 2, } ]] + +TEST [[ +return { + 1, <!2!>, 3, + [<!2!>] = 4, +} +]] diff --git a/test/diagnostics/duplicate-set-field.lua b/test/diagnostics/duplicate-set-field.lua new file mode 100644 index 00000000..52f70c9d --- /dev/null +++ b/test/diagnostics/duplicate-set-field.lua @@ -0,0 +1,43 @@ +TEST [[ +local m = {} + +function <!m:fff!>() +end + +function <!m:fff!>() +end + +return m +]] + +TEST [[ +local m = {} + +function <!m:fff!>() +end + +do + function <!m:fff!>() + end +end + +return m +]] + +TEST [[ +local m = {} + +m.x = true +m.x = false + +return m +]] + +TEST [[ +local m = {} + +m.x = io.open('') +m.x = nil + +return m +]] diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua index 3fb90f39..d1acd31e 100644 --- a/test/diagnostics/init.lua +++ b/test/diagnostics/init.lua @@ -100,6 +100,16 @@ check 'deprecated' check 'duplicate-index' check 'empty-block' check 'redundant-value' -check 'code-after-block' +check 'code-after-break' +check 'duplicate-doc-alias' +check 'circle-doc-class' +check 'undefined-doc-param' +check 'duplicate-doc-param' +check 'doc-field-no-class' +check 'undefined-field' +check 'count-down-loop' +check 'duplicate-set-field' +check 'redundant-return' +check 'discard-returns' require 'diagnostics.common' diff --git a/test/diagnostics/lowercase-global.lua b/test/diagnostics/lowercase-global.lua index 5e1d70a9..bf73b8c8 100644 --- a/test/diagnostics/lowercase-global.lua +++ b/test/diagnostics/lowercase-global.lua @@ -4,3 +4,36 @@ tostring = 1 ROOT = 1 _G.bb = 1 ]] + +TEST [[ +---@diagnostic disable-next-line +x = 1 +]] + +TEST [[ +---@diagnostic disable-next-line: lowercase-global +x = 1 +]] + +TEST [[ +---@diagnostic disable-next-line: unused-local +<!x!> = 1 +]] + +TEST [[ +---@diagnostic disable +x = 1 +]] + +TEST [[ +---@diagnostic disable +---@diagnostic enable +<!x!> = 1 +]] + +TEST [[ +---@diagnostic disable +---@diagnostic disable +---@diagnostic enable +x = 1 +]] diff --git a/test/diagnostics/need-check-nil.lua b/test/diagnostics/need-check-nil.lua index 246fc655..c4e3bba6 100644 --- a/test/diagnostics/need-check-nil.lua +++ b/test/diagnostics/need-check-nil.lua @@ -4,3 +4,65 @@ local x local s = <!x!>:upper() ]] + +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 [[ +---@type integer? +local x + +T = {} +T[<!x!>] = 1 +]] + +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/diagnostics/redundant-parameter.lua b/test/diagnostics/redundant-parameter.lua index cd9d7a43..3bbb50f6 100644 --- a/test/diagnostics/redundant-parameter.lua +++ b/test/diagnostics/redundant-parameter.lua @@ -133,3 +133,69 @@ m.open(m) TEST [[ table.insert({}, 1, 2, <!3!>) ]] + +TEST [[ +---@overload fun(...) +local function f() end + +f(1) +]] + +TEST [[ +function F() end + +---@param x boolean +function F(x) end + +F(k()) +]] + +TEST [[ +local function f() + return 1, 2, 3 +end + +local function k() +end + +k(<!f()!>) +]] + +TEST [[ +---@diagnostic disable: unused-local +local function f() + return 1, 2, 3 +end + +---@param x integer +local function k(x) +end + +k(f()) +]] + +TEST [[ +---@meta + +---@param x fun() +local function f1(x) +end + +---@return fun() +local function f2() +end + +f1(f2()) +]] + +TEST [[ +---@meta + +---@type fun():integer +local f + +---@param x integer +local function foo(x) end + +foo(f()) +]] diff --git a/test/diagnostics/redundant-return.lua b/test/diagnostics/redundant-return.lua new file mode 100644 index 00000000..11214aab --- /dev/null +++ b/test/diagnostics/redundant-return.lua @@ -0,0 +1,34 @@ +TEST [[ +local function f() + <!return!> +end +f() +]] + +TEST [[ +local function f() + return nil +end +f() +]] + +TEST [[ +local function f() + local function x() + <!return!> + end + x() + return true +end +f() +]] + +TEST [[ +local function f() + local function x() + return true + end + return x() +end +f() +]] diff --git a/test/diagnostics/unbalanced-assignments.lua b/test/diagnostics/unbalanced-assignments.lua new file mode 100644 index 00000000..a0d47f56 --- /dev/null +++ b/test/diagnostics/unbalanced-assignments.lua @@ -0,0 +1,34 @@ +TEST [[ +local x, <!y!>, <!z!> = 1 +]] + +TEST [[ +local x, y, <!z!> = 1, 2 +]] + +TEST [[ +local x, y, z = print() +]] + +TEST [[ +local x, y, z +]] + +TEST [[ +local x, y, z +x, <!y!>, <!z!> = 1 +]] + +TEST [[ +X, <!Y!>, <!Z!> = 1 +]] + +TEST [[ +T = {} +T.x, <!T.y!>, <!T.z!> = 1 +]] + +TEST [[ +T = {} +T['x'], <!T['y']!>, <!T['z']!> = 1 +]] diff --git a/test/diagnostics/undefined-doc-class.lua b/test/diagnostics/undefined-doc-class.lua new file mode 100644 index 00000000..6b7acfd1 --- /dev/null +++ b/test/diagnostics/undefined-doc-class.lua @@ -0,0 +1,23 @@ +TEST [[ +---@class A : <!B!> +]] + +TEST [[ +---@type <!A!> +]] + +TEST [[ +---@class A +---@type A|<!B!>|<!C!> +]] + +TEST [[ +---@class AAA +---@alias B AAA + +---@type B +]] + +TEST [[ +---@alias B <!AAA!> +]] diff --git a/test/diagnostics/undefined-doc-param.lua b/test/diagnostics/undefined-doc-param.lua new file mode 100644 index 00000000..7bfbafa5 --- /dev/null +++ b/test/diagnostics/undefined-doc-param.lua @@ -0,0 +1,21 @@ +TEST [[ +---@param <!x!> Class +]] + +TEST [[ +---@class Class +---@param <!y!> Class +local function f(x) + return x +end +f() +]] + +TEST [[ +---@class Class +---@param <!y!> Class +function F(x) + return x +end +F() +]] diff --git a/test/diagnostics/undefined-field.lua b/test/diagnostics/undefined-field.lua new file mode 100644 index 00000000..4bca5195 --- /dev/null +++ b/test/diagnostics/undefined-field.lua @@ -0,0 +1,132 @@ +TEST [[ +---@class Foo +---@field field1 integer +local mt = {} +function mt:Constructor() + self.field2 = 1 +end +function mt:method1() return 1 end +function mt.method2() return 2 end + +---@class Bar: Foo +---@field field4 integer +local mt2 = {} + +---@type Foo +local v +print(v.field1 + 1) +print(v.field2 + 1) +print(v.<!field3!> + 1) +print(v:method1()) +print(v.method2()) +print(v:<!method3!>()) + +---@type Bar +local v2 +print(v2.field1 + 1) +print(v2.field2 + 1) +print(v2.<!field3!> + 1) +print(v2.field4 + 1) +print(v2:method1()) +print(v2.method2()) +print(v2:<!method3!>()) + +local v3 = {} +print(v3.abc) + +---@class Bar2 +local mt3 +function mt3:method() return 1 end +print(mt3:method()) +]] + +-- checkUndefinedField 通过type找到class +TEST [[ +---@class Foo +local Foo +function Foo:method1() end + +---@type Foo +local v +v:method1() +v:<!method2!>() -- doc.class.name +]] + +-- checkUndefinedField 通过type找到class,涉及到 class 继承版 +TEST [[ +---@class Foo +local Foo +function Foo:method1() end +---@class Bar: Foo +local Bar +function Bar:method3() end + +---@type Bar +local v +v:method1() +v:<!method2!>() -- doc.class.name +v:method3() +]] + +-- checkUndefinedField 类名和类变量同名,类变量被直接使用 +TEST [[ +---@class Foo +local Foo +function Foo:method1() end +Foo:<!method2!>() -- doc.class +Foo:<!method2!>() -- doc.class +]] + +-- checkUndefinedField 没有@class的不检测 +TEST [[ +local Foo +function Foo:method1() + return Foo:method2() -- table +end +]] + +-- checkUndefinedField 类名和类变量不同名,类变量被直接使用、使用self +TEST [[ +---@class Foo +local mt +function mt:method1() + mt.<!method2!>() -- doc.class + self:method1() + return self.<!method2!>() -- doc.class.name +end +]] + +-- checkUndefinedField 当会推导成多个class类型时 +TEST [[ +---@class Foo +local mt +function mt:method1() end + +---@class Bar +local mt2 +function mt2:method2() end + +---@type Foo +local v +---@type Bar +local v2 +v2 = v +v2:method1() +v2:<!method2!>() +]] + +TEST [[ +---@type table +T1 = {} +print(T1.f1) +---@type tablelib +T2 = {} +print(T2.<!f2!>) +]] + +TEST [[ +---@type string|table +local n + +print(n.x) +]] diff --git a/test/diagnostics/undefined-global.lua b/test/diagnostics/undefined-global.lua index 55ef5a00..f5a6396c 100644 --- a/test/diagnostics/undefined-global.lua +++ b/test/diagnostics/undefined-global.lua @@ -29,3 +29,8 @@ print(T5) print(T6) print(T7) ]] + +TEST [[ +---@class c +c = {} +]] diff --git a/test/diagnostics/unknown-diag-code.lua b/test/diagnostics/unknown-diag-code.lua new file mode 100644 index 00000000..33b41886 --- /dev/null +++ b/test/diagnostics/unknown-diag-code.lua @@ -0,0 +1,3 @@ +TEST [[ +---@diagnostic disable-next-line: <!xxx!> +]] |