diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2023-07-20 18:08:35 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2023-07-20 18:08:35 +0800 |
commit | 297ac3aabb38c22648f501038e1e66b6c8f9f936 (patch) | |
tree | e9c40686abd45a1aeba3e6d863d015c2117c8429 /script/core | |
parent | e7bc0940a32a99adc2bbce746d118e59faddcc07 (diff) | |
download | lua-language-server-297ac3aabb38c22648f501038e1e66b6c8f9f936.zip |
new diagnostic: `missing-fields`
Diffstat (limited to 'script/core')
-rw-r--r-- | script/core/diagnostics/missing-fields.lua | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/script/core/diagnostics/missing-fields.lua b/script/core/diagnostics/missing-fields.lua new file mode 100644 index 00000000..e23352bc --- /dev/null +++ b/script/core/diagnostics/missing-fields.lua @@ -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 |