diff options
-rw-r--r-- | script/core/diagnostics/assign-type-mismatch.lua | 28 | ||||
-rw-r--r-- | script/parser/guide.lua | 2 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 1 | ||||
-rw-r--r-- | script/vm/compiler.lua | 23 | ||||
-rw-r--r-- | test/diagnostics/type-check.lua | 10 |
5 files changed, 60 insertions, 4 deletions
diff --git a/script/core/diagnostics/assign-type-mismatch.lua b/script/core/diagnostics/assign-type-mismatch.lua index 536cfaff..a3d63ca8 100644 --- a/script/core/diagnostics/assign-type-mismatch.lua +++ b/script/core/diagnostics/assign-type-mismatch.lua @@ -15,6 +15,21 @@ local checkTypes = { 'tableindex' } +---@param source parser.object +---@return boolean +local function hasMarkType(source) + if not source.bindDocs then + return false + end + for _, doc in ipairs(source.bindDocs) do + if doc.type == 'doc.type' + or doc.type == 'doc.class' then + return true + end + end + return false +end + ---@async return function (uri, callback) local state = files.getState(uri) @@ -35,11 +50,24 @@ return function (uri, callback) return end end + --[[ + ---@class A + local mt + ---@type X + mt._x = nil -- don't warn this + ]] + if value.type == 'nil' then + if hasMarkType(source) then + return + end + end + local valueNode = vm.compileNode(value) if source.type == 'setindex' then -- boolean[1] = nil valueNode = valueNode:copy():removeOptional() end + local varNode = vm.compileNode(source) if vm.canCastType(uri, varNode, valueNode) then return diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 29ca98c1..cb10efa2 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -14,7 +14,7 @@ local type = type ---@field locals parser.object[] ---@field returns? parser.object[] ---@field exps parser.object[] ----@field keys parser.object[] +---@field keys parser.object ---@field uri uri ---@field start integer ---@field finish integer diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index c2019d8d..6c63e2f9 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -143,6 +143,7 @@ Symbol <- ({} { ---@field originalComment parser.object ---@field as? parser.object ---@field touch? integer +---@field module? string local function trim(str) return str:match '^%s*(%S+)%s*$' diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index 1abad3e3..7e26e08f 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -14,10 +14,15 @@ local vm = require 'vm.vm' ---@field func parser.object -- 该函数有副作用,会给source绑定node! +---@param source parser.object +---@return boolean local function bindDocs(source) + local docs = source.bindDocs + if not docs then + return false + end local isParam = source.parent.type == 'funcargs' or (source.parent.type == 'in' and source.finish <= source.parent.keys.finish) - local docs = source.bindDocs for i = #docs, 1, -1 do local doc = docs[i] if doc.type == 'doc.type' then @@ -47,6 +52,9 @@ local function bindDocs(source) end if doc.type == 'doc.module' then local name = doc.module + if not name then + return true + end local uri = rpath.findUrisByRequirePath(guide.getUri(source), name)[1] if not uri then return true @@ -1380,9 +1388,18 @@ local compilerSwitch = util.switch() else ---@cast key string vm.compileByParentNode(source.node, key, false, function (src) - vm.setNode(source, vm.compileNode(src)) if src.value then - vm.setNode(source, vm.compileNode(src.value)) + if bindDocs(src) then + vm.setNode(source, vm.compileNode(src)) + else + vm.setNode(source, vm.compileNode(src.value)) + local node = vm.getNode(src) + if node then + vm.setNode(source, node) + end + end + else + vm.setNode(source, vm.compileNode(src)) end end) end diff --git a/test/diagnostics/type-check.lua b/test/diagnostics/type-check.lua index 862bc0bf..f4765370 100644 --- a/test/diagnostics/type-check.lua +++ b/test/diagnostics/type-check.lua @@ -599,5 +599,15 @@ function F() end ]] +TEST [[ +---@class X + +---@class A +local mt = G + +---@type X +mt._x = nil +]] + config.remove(nil, 'Lua.diagnostics.disable', 'unused-local') config.remove(nil, 'Lua.diagnostics.disable', 'undefined-global') |