summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/diagnostics/assign-type-mismatch.lua28
-rw-r--r--script/parser/guide.lua2
-rw-r--r--script/parser/luadoc.lua1
-rw-r--r--script/vm/compiler.lua23
-rw-r--r--test/diagnostics/type-check.lua10
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')