summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-07-06 15:35:16 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-07-06 15:35:16 +0800
commiteca994d10e4f069a4cc9348d27a4f3723a19f551 (patch)
tree31c2a61261dc939bc0b339e88fac4f41e2c4d5e5
parent997109ebfd4e9ec2bd2b22cc8c35fd1e7cdf0b91 (diff)
downloadlua-language-server-eca994d10e4f069a4cc9348d27a4f3723a19f551.zip
resolve #1285 ignore `nil` in `getfield`
-rw-r--r--changelog.md1
-rw-r--r--script/core/diagnostics/assign-type-mismatch.lua8
-rw-r--r--script/core/diagnostics/cast-local-type.lua10
-rw-r--r--test/diagnostics/type-check.lua24
4 files changed, 42 insertions, 1 deletions
diff --git a/changelog.md b/changelog.md
index 906ffa5a..b462cf58 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,7 @@
# changelog
## 3.5.0
+* `CHG` diagnostic: `type-check` ignores `nil` in `getfield`
* `CHG` diagnostic: `---@diagnostic disable: <ERR_NAME>` can suppress syntax errors
* `CHG` completion: `completion.callSnippet` no longer generate parameter types
* `CHG` hover: show `---@type {x: number, y: number}` as detail instead of `table`
diff --git a/script/core/diagnostics/assign-type-mismatch.lua b/script/core/diagnostics/assign-type-mismatch.lua
index d98aa021..6809760c 100644
--- a/script/core/diagnostics/assign-type-mismatch.lua
+++ b/script/core/diagnostics/assign-type-mismatch.lua
@@ -82,11 +82,19 @@ return function (uri, callback)
valueNode = valueNode:copy():removeOptional()
end
+ if value.type == 'getfield'
+ or value.type == 'getindex' then
+ -- 由于无法对字段进行类型收窄,
+ -- 因此将假值移除再进行检查
+ valueNode = valueNode:copy():setTruthy()
+ end
+
local varNode = vm.compileNode(source)
if vm.canCastType(uri, varNode, valueNode) then
return
end
+ -- local Cat = setmetatable({}, {__index = Animal}) 允许逆变
if value.type == 'select'
and value.sindex == 1
and value.vararg
diff --git a/script/core/diagnostics/cast-local-type.lua b/script/core/diagnostics/cast-local-type.lua
index b7abcef6..c3d6e1bb 100644
--- a/script/core/diagnostics/cast-local-type.lua
+++ b/script/core/diagnostics/cast-local-type.lua
@@ -22,9 +22,17 @@ return function (uri, callback)
return
end
for _, ref in ipairs(loc.ref) do
- if ref.type == 'setlocal' then
+ if ref.type == 'setlocal' and ref.value then
await.delay()
local refNode = vm.compileNode(ref)
+ local value = ref.value
+
+ if value.type == 'getfield'
+ or value.type == 'getindex' then
+ -- 由于无法对字段进行类型收窄,
+ -- 因此将假值移除再进行检查
+ refNode = refNode:copy():setTruthy()
+ end
if not vm.canCastType(uri, locNode, refNode) then
callback {
diff --git a/test/diagnostics/type-check.lua b/test/diagnostics/type-check.lua
index f1f14b48..cc60a969 100644
--- a/test/diagnostics/type-check.lua
+++ b/test/diagnostics/type-check.lua
@@ -664,5 +664,29 @@ local a = {}
local <!b!> = setmetatable({}, {__index = a})
]]
+TEST [[
+---@class A
+---@field x number?
+local a
+
+---@class B
+---@field x number
+local b
+
+b.x = a.x
+]]
+
+TEST [[
+
+---@class A
+---@field x number?
+local a
+
+---@type number
+local t
+
+t = a.x
+]]
+
config.remove(nil, 'Lua.diagnostics.disable', 'unused-local')
config.remove(nil, 'Lua.diagnostics.disable', 'undefined-global')