diff options
-rw-r--r-- | script/core/diagnostics/inject-field.lua | 54 | ||||
-rw-r--r-- | script/core/diagnostics/undefined-field.lua | 8 | ||||
-rw-r--r-- | script/proto/diagnostic.lua | 1 | ||||
-rw-r--r-- | test/diagnostics/init.lua | 1 | ||||
-rw-r--r-- | test/diagnostics/inject-field.lua | 25 |
5 files changed, 81 insertions, 8 deletions
diff --git a/script/core/diagnostics/inject-field.lua b/script/core/diagnostics/inject-field.lua new file mode 100644 index 00000000..62e1d1ca --- /dev/null +++ b/script/core/diagnostics/inject-field.lua @@ -0,0 +1,54 @@ +local files = require 'files' +local vm = require 'vm' +local lang = require 'language' +local guide = require 'parser.guide' +local await = require 'await' + +local skipCheckClass = { + ['unknown'] = true, + ['any'] = true, + ['table'] = true, +} + +---@async +return function (uri, callback) + local ast = files.getState(uri) + if not ast then + return + end + + ---@async + local function checkInjectField(src) + await.delay() + + local node = src.node + if node then + local ok + for view in vm.getInfer(node):eachView(uri) do + if skipCheckClass[view] then + return + end + ok = true + end + if not ok then + return + end + end + local message = lang.script('DIAG_INJECT_FIELD', guide.getKeyName(src)) + if src.type == 'setfield' and src.field then + callback { + start = src.field.start, + finish = src.field.finish, + message = message, + } + elseif src.type == 'setfield' and src.method then + callback { + start = src.method.start, + finish = src.method.finish, + message = message, + } + end + end + guide.eachSourceType(ast.ast, 'setfield', checkInjectField) + guide.eachSourceType(ast.ast, 'setmethod', checkInjectField) +end diff --git a/script/core/diagnostics/undefined-field.lua b/script/core/diagnostics/undefined-field.lua index a83241f5..4fd55966 100644 --- a/script/core/diagnostics/undefined-field.lua +++ b/script/core/diagnostics/undefined-field.lua @@ -8,13 +8,6 @@ local skipCheckClass = { ['unknown'] = true, ['any'] = true, ['table'] = true, - ['nil'] = true, - ['number'] = true, - ['integer'] = true, - ['boolean'] = true, - ['function'] = true, - ['userdata'] = true, - ['lightuserdata'] = true, } ---@async @@ -61,5 +54,4 @@ return function (uri, callback) end guide.eachSourceType(ast.ast, 'getfield', checkUndefinedField) guide.eachSourceType(ast.ast, 'getmethod', checkUndefinedField) - guide.eachSourceType(ast.ast, 'getindex', checkUndefinedField) end diff --git a/script/proto/diagnostic.lua b/script/proto/diagnostic.lua index 9c095531..61b8ff4b 100644 --- a/script/proto/diagnostic.lua +++ b/script/proto/diagnostic.lua @@ -77,6 +77,7 @@ m.register { 'param-type-mismatch', 'cast-type-mismatch', 'return-type-mismatch', + 'inject-field', } { group = 'type-check', severity = 'Warning', diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua index cd6a5c03..99a5dc24 100644 --- a/test/diagnostics/init.lua +++ b/test/diagnostics/init.lua @@ -90,6 +90,7 @@ check 'empty-block' check 'global-element' check 'global-in-nil-env' check 'incomplete-signature-doc' +check 'inject-field' check 'invisible' check 'lowercase-global' check 'missing-fields' diff --git a/test/diagnostics/inject-field.lua b/test/diagnostics/inject-field.lua new file mode 100644 index 00000000..8e2273b5 --- /dev/null +++ b/test/diagnostics/inject-field.lua @@ -0,0 +1,25 @@ +TEST [[ +---@class Class +local m = {} + +m.xx = 1 -- OK + +---@type Class +local m + +m.xx = 1 -- OK +m.<!yy!> = 1 -- Warning +]] + +TEST [[ +---@class Class +local m = {} + +m.xx = 1 -- OK + +---@class Class +local m + +m.xx = 1 -- OK +m.yy = 1 -- OK +]] |