Skip to content

Commit

Permalink
new diagnostic: missing-fields
Browse files Browse the repository at this point in the history
  • Loading branch information
sumneko committed Jul 20, 2023
1 parent e7bc094 commit 297ac3a
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# changelog

## 3.6.24
* `NEW` diagnostic: `missing-fields`
* `FIX` shake of `codeLens`
* `FIX` [#2145]

Expand Down
72 changes: 72 additions & 0 deletions script/core/diagnostics/missing-fields.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
local vm = require 'vm'
local files = require 'files'
local guide = require 'parser.guide'
local await = require 'await'

---@async
return function (uri, callback)
local state = files.getState(uri)
if not state then
return
end

---@async
guide.eachSourceType(state.ast, 'table', function (src)
await.delay()

local defs = vm.getDefs(src)
local requiresKeys = {}
for _, def in ipairs(defs) do
if def.type == 'doc.class' then
if not def.fields then
goto continue
end
if def.bindSource then
if guide.isInRange(def.bindSource, src.start) then
goto continue
end
end
for _, field in ipairs(def.fields) do
if not field.optional
and not vm.compileNode(field):isNullable() then
local key = vm.getKeyName(field)
if key and not requiresKeys[key] then
requiresKeys[key] = true
requiresKeys[#requiresKeys+1] = key
end
end
end
end
::continue::
end

if #requiresKeys == 0 then
return
end

local myKeys = {}
for _, field in ipairs(src) do
local key = vm.getKeyName(field)
if key then
myKeys[key] = true
end
end

local missedKeys = {}
for _, key in ipairs(requiresKeys) do
if not myKeys[key] then
missedKeys[#missedKeys+1] = ('`%s`'):format(key)
end
end

if #missedKeys == 0 then
return
end

callback {
start = src.start,
finish = src.finish,
message = string.format('Missing fields: %s', table.concat(missedKeys, ', ')),
}
end)
end
1 change: 1 addition & 0 deletions script/proto/diagnostic.lua
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ m.register {
'missing-return-value',
'redundant-return-value',
'missing-return',
'missing-fields',
} {
group = 'unbalanced',
severity = 'Warning',
Expand Down
150 changes: 148 additions & 2 deletions test/diagnostics/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,13 @@ print(A) -- no warning

TEST [[
---@type iolib
_ENV = {}
_ENV = io
<!print!>(stderr) -- `print` is warning but `stderr` is not
]]

TEST [[
---@type iolib
local _ENV = {}
local _ENV = io
<!print!>(stderr) -- `print` is warning but `stderr` is not
]]

Expand Down Expand Up @@ -2206,6 +2206,7 @@ end

TEST [[
---@diagnostic disable: unused-local
---@diagnostic disable: missing-fields
---@class A
---@field private x number
local mt = {}
Expand All @@ -2220,6 +2221,7 @@ end

TEST [[
---@diagnostic disable: unused-local
---@diagnostic disable: missing-fields
---@class A
---@field private x number
local mt = {}
Expand Down Expand Up @@ -2268,3 +2270,147 @@ local function foo(_ENV)
Joe = "human"
end
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@type A
local t = <!{}!>
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@type A
local t = <!{
x = 1,
}!>
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@type A
local t = <!{
x = 1,
y = 2,
}!>
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@type A
local t = {
x = 1,
y = 2,
z = 3,
}
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@type A
local t = {
x = 1,
z = 3,
}
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@param a A
local function f(a) end
f <!{}!>
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@param a A
local function f(a) end
f <!{
x = 1,
}!>
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@param a A
local function f(a) end
f <!{
x = 1,
y = 2,
}!>
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@param a A
local function f(a) end
f {
x = 1,
y = 2,
z = 3,
}
]]

TEST [[
---@diagnostic disable: unused-local
---@class A
---@field x number
---@field y? number
---@field z number
---@param a A
local function f(a) end
f {
x = 1,
z = 3,
}
]]
1 change: 1 addition & 0 deletions test/diagnostics/type-check.lua
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ m.ints = {}
]]

TEST [[
---@diagnostic disable: missing-fields
---@class A
---@field x A
Expand Down

0 comments on commit 297ac3a

Please sign in to comment.