diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2024-08-16 16:55:57 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2024-08-16 16:55:57 +0800 |
commit | 080d672ee4bbc082a24aef95821860afa78a7d9f (patch) | |
tree | 687c6229d6a904d1e31ee240254d83f93d83508d /script/vm | |
parent | 18ae29cd86dd7e6caa45eba9ac05c44170970df3 (diff) | |
download | lua-language-server-080d672ee4bbc082a24aef95821860afa78a7d9f.zip |
Add setting: `Lua.type.checkTableShape`
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/type.lua | 130 |
1 files changed, 69 insertions, 61 deletions
diff --git a/script/vm/type.lua b/script/vm/type.lua index 4835065a..3bc51cd8 100644 --- a/script/vm/type.lua +++ b/script/vm/type.lua @@ -284,6 +284,71 @@ local function isAlias(name, suri) return false end +local function checkTableShape(parent, child, uri, mark, errs) + local set = parent:getSets(uri) + local missedKeys = {} + local failedCheck + local myKeys + for _, def in ipairs(set) do + if not def.fields or #def.fields == 0 then + goto continue + end + if not myKeys then + myKeys = {} + for _, field in ipairs(child) do + local key = vm.getKeyName(field) or field.tindex + if key then + myKeys[key] = vm.compileNode(field) + end + end + end + + for _, field in ipairs(def.fields) do + local key = vm.getKeyName(field) + if not key then + local fieldnode = vm.compileNode(field.field)[1] + if fieldnode and fieldnode.type == 'doc.type.integer' then + ---@cast fieldnode parser.object + key = vm.getKeyName(fieldnode) + end + end + if not key then + goto continue + end + + local ok + local nodeField = vm.compileNode(field) + if myKeys[key] then + ok = vm.isSubType(uri, myKeys[key], nodeField, mark, errs) + if ok == false then + errs[#errs+1] = 'TYPE_ERROR_PARENT_ALL_DISMATCH' -- error display can be greatly improved + errs[#errs+1] = myKeys[key] + errs[#errs+1] = nodeField + failedCheck = true + end + elseif not nodeField:isNullable() then + if type(key) == "number" then + missedKeys[#missedKeys+1] = ('`[%s]`'):format(key) + else + missedKeys[#missedKeys+1] = ('`%s`'):format(key) + end + failedCheck = true + end + end + ::continue:: + end + if #missedKeys > 0 then + errs[#errs+1] = 'DIAG_MISSING_FIELDS' + errs[#errs+1] = parent + errs[#errs+1] = table.concat(missedKeys, ', ') + end + if failedCheck then + return false + end + + return true +end + ---@param uri uri ---@param child vm.node|string|vm.node.object ---@param parent vm.node|string|vm.node.object @@ -483,68 +548,11 @@ function vm.isSubType(uri, child, parent, mark, errs) return true end if childName == 'table' and not guide.isBasicType(parentName) then - local set = parent:getSets(uri) - local missedKeys = {} - local failedCheck - local myKeys - for _, def in ipairs(set) do - if not def.fields or #def.fields == 0 then - goto continue - end - if not myKeys then - myKeys = {} - for _, field in ipairs(child) do - local key = vm.getKeyName(field) or field.tindex - if key then - myKeys[key] = vm.compileNode(field) - end - end - end - - for _, field in ipairs(def.fields) do - local key = vm.getKeyName(field) - if not key then - local fieldnode = vm.compileNode(field.field)[1] - if fieldnode and fieldnode.type == 'doc.type.integer' then - ---@cast fieldnode parser.object - key = vm.getKeyName(fieldnode) - end - end - if not key then - goto continue - end - - local ok - local nodeField = vm.compileNode(field) - if myKeys[key] then - ok = vm.isSubType(uri, myKeys[key], nodeField, mark, errs) - if ok == false then - errs[#errs+1] = 'TYPE_ERROR_PARENT_ALL_DISMATCH' -- error display can be greatly improved - errs[#errs+1] = myKeys[key] - errs[#errs+1] = nodeField - failedCheck = true - end - elseif not nodeField:isNullable() then - if type(key) == "number" then - missedKeys[#missedKeys+1] = ('`[%s]`'):format(key) - else - missedKeys[#missedKeys+1] = ('`%s`'):format(key) - end - failedCheck = true - end - end - ::continue:: - end - if #missedKeys > 0 then - errs[#errs+1] = 'DIAG_MISSING_FIELDS' - errs[#errs+1] = parent - errs[#errs+1] = table.concat(missedKeys, ', ') - end - if failedCheck then - return false + if config.get(uri, 'Lua.type.checkTableShape') then + return checkTableShape(parent, child, uri, mark, errs) + else + return true end - - return true end -- check class parent |